{"version":3,"sources":["../src/player/classic/react/index.ts","../src/shared/attributes.ts","../src/utils/console.ts","../src/shared/scopes.ts","../src/player/scopes.ts","../src/player/steps.ts","../src/player/classic/classic.ts","../src/shared/globals.ts","../src/player/classic/react/EmpiricaContext.tsx","../src/player/react/Consent.tsx","../src/player/react/Finished.tsx","../src/player/react/Loading.tsx","../src/player/react/NoGames.tsx","../src/player/utils.ts","../src/player/react/PlayerCreate.tsx","../src/player/react/hooks.ts","../src/player/react/EmpiricaParticipant.tsx","../src/player/context.ts","../src/admin/observables.ts","../src/shared/tajriba_connection.ts","../src/utils/object.ts","../src/player/connection.ts","../src/player/provider.ts","../src/player/classic/react/Lobby.tsx","../src/player/classic/react/hooks.ts","../src/player/classic/react/Steps.tsx","../src/player/classic/react/Quiz.tsx","../src/player/classic/react/Slider.tsx","../src/player/classic/react/chat/Chat.tsx","../src/player/react/EmpiricaMenu.tsx","../src/player/react/Logo.tsx","../src/player/classic/react/examples/Sweeper.tsx"],"sourcesContent":["export { Attribute, Attributes } from \"../../../shared/attributes\";\nexport type {\n  AttributeChange,\n  AttributeOptions,\n  AttributeUpdate,\n} from \"../../../shared/attributes\";\nexport type { Constructor } from \"../../../shared/helpers\";\nexport type {\n  Attributable,\n  AttributeInput,\n  ScopeConstructor,\n  ScopeIdent,\n  ScopeUpdate,\n  Scope as SharedScope,\n} from \"../../../shared/scopes\";\nexport type { Json, JsonArray, JsonValue } from \"../../../utils/json\";\nexport type { ConsentProps } from \"../../react/Consent\";\nexport type { PlayerCreateProps } from \"../../react/PlayerCreate\";\nexport type { WithChildren } from \"../../react/helpers\";\nexport { Scope, Scopes } from \"../../scopes\";\nexport { Step, Steps } from \"../../steps\";\nexport type { StepChange, StepTick, StepUpdate } from \"../../steps\";\nexport {\n  EmpiricaClassicKinds,\n  Game,\n  Player,\n  PlayerGame,\n  PlayerRound,\n  PlayerStage,\n  Round,\n  Stage,\n} from \"../classic\";\nexport type { Context } from \"../classic\";\nexport { EmpiricaContext } from \"./EmpiricaContext\";\nexport type { EmpiricaContextProps } from \"./EmpiricaContext\";\nexport { Lobby } from \"./Lobby\";\nexport { Quiz } from \"./Quiz\";\nexport { Slider } from \"./Slider\";\nexport type { SliderProps } from \"./Slider\";\nexport type { StepsFunc, StepsProps } from \"./Steps\";\nexport { Chat } from \"./chat/Chat\";\nexport type { ChatProps } from \"./chat/Chat\";\nexport { Sweeper } from \"./examples/Sweeper\";\nexport {\n  useGame,\n  usePartModeCtx,\n  usePartModeCtxKey,\n  usePlayer,\n  usePlayers,\n  useRound,\n  useStage,\n  useStageTimer,\n} from \"./hooks\";\nimport \"./slider.css\";\n","import { SetAttributeInput } from \"@empirica/tajriba\";\nimport { BehaviorSubject, Observable } from \"rxjs\";\nimport { error, trace } from \"../utils/console\";\nimport { JsonValue } from \"../utils/json\";\n\nexport interface AttributeChange {\n  /** deleted is true with the attribute was deleted. */\n  deleted?: boolean;\n  /** deletedAt is the time when the Attribute was deleted. int64 Date + Time\n   * value given in Epoch with ns precision */\n  deletedAt?: number;\n  /** createdAt is the time the Attribute was created. int64 Date + Time\n   * value given in Epoch with ns precision */\n  createdAt?: string;\n  /** id is the identifier for the Attribute. */\n  id: string;\n  /** index is the index of the attribute if the value is a vector. */\n  index?: number | null;\n  /** isNew is true if the Attribute was just created. */\n  isNew?: boolean;\n  /** key is the attribute key being updated. */\n  key: string;\n  /** nodeID is the identifier for the Attribute's Node. */\n  nodeID?: string;\n  /** node is the Attribute's Node. */\n  node?: {\n    __typename: \"Scope\";\n    id: string;\n    kind?: string;\n    name?: string;\n  };\n  /** value is the value of the updated attribute. */\n  val?: string | null;\n  /** vector indicates whether the value is a vector. */\n  vector: boolean;\n  /** version is the version number of this Attribute, starting at 1. */\n  version: number;\n}\n\nexport interface AttributeUpdate {\n  attribute: AttributeChange;\n  removed: boolean;\n}\n\nexport class Attributes {\n  protected attrs = new Map<string, Map<string, Attribute>>();\n  protected updates = new Map<string, Map<string, AttributeChange | boolean>>();\n\n  constructor(\n    attributesObs: Observable<AttributeUpdate>,\n    donesObs: Observable<string[]>,\n    readonly setAttributes: (input: SetAttributeInput[]) => Promise<unknown>\n  ) {\n    attributesObs.subscribe({\n      next: ({ attribute, removed }) => {\n        this.update(attribute, removed);\n      },\n    });\n\n    donesObs.subscribe({\n      next: (scopeIDs) => {\n        this.next(scopeIDs);\n      },\n    });\n  }\n\n  attribute(scopeID: string, key: string): Attribute {\n    let scopeMap = this.attrs.get(scopeID);\n    if (!scopeMap) {\n      scopeMap = new Map();\n      this.attrs.set(scopeID, scopeMap);\n    }\n\n    let attr = scopeMap.get(key);\n    if (!attr) {\n      attr = new Attribute(this.setAttributes, scopeID, key);\n      scopeMap.set(key, attr);\n    }\n\n    return attr;\n  }\n\n  attributes(scopeID: string): Attribute[] {\n    let scopeMap = this.attrs.get(scopeID);\n    if (!scopeMap) {\n      scopeMap = new Map();\n      this.attrs.set(scopeID, scopeMap);\n    }\n\n    return Array.from(scopeMap.values());\n  }\n\n  attributePeek(scopeID: string, key: string): Attribute | undefined {\n    let scopeUpdateMap = this.updates.get(scopeID);\n    if (scopeUpdateMap) {\n      const updated = scopeUpdateMap.get(key);\n      if (updated) {\n        if (typeof updated === \"boolean\") {\n          return;\n        } else {\n          if (!updated.val) {\n            return;\n          } else {\n            const attr = new Attribute(this.setAttributes, scopeID, key);\n            attr._update(updated);\n            return attr;\n          }\n        }\n      }\n    }\n\n    let scopeMap = this.attrs.get(scopeID);\n    if (!scopeMap) {\n      return;\n    }\n\n    let attr = scopeMap.get(key);\n    if (!attr) {\n      return;\n    }\n\n    if (attr.value === undefined) {\n      return;\n    }\n\n    return attr;\n  }\n\n  nextAttributeValue(scopeID: string, key: string): JsonValue | undefined {\n    const attr = this.attributePeek(scopeID, key);\n    if (!attr) {\n      return;\n    }\n\n    return attr.value;\n  }\n\n  private update(attr: AttributeChange, removed: boolean) {\n    let nodeID = attr.nodeID;\n    if (!nodeID) {\n      if (!attr.node?.id) {\n        error(`new attribute without node ID`);\n        return;\n      }\n      nodeID = attr.node.id;\n    }\n\n    let scopeMap = this.updates.get(nodeID);\n    if (!scopeMap) {\n      scopeMap = new Map();\n      this.updates.set(nodeID, scopeMap);\n    }\n\n    if (removed) {\n      scopeMap.set(attr.key, true);\n    } else {\n      let key = attr.key;\n      if (attr.index !== undefined && attr.index !== null) {\n        key = `${key}[${attr.index}]`;\n      }\n      scopeMap.set(key, attr);\n    }\n  }\n\n  scopeWasUpdated(scopeID?: string): boolean {\n    if (!scopeID) {\n      return false;\n    }\n\n    return this.updates.has(scopeID);\n  }\n\n  protected next(scopeIDs: string[]) {\n    for (const [scopeID, attrs] of this.updates) {\n      if (!scopeIDs.includes(scopeID)) {\n        continue;\n      }\n\n      let scopeMap = this.attrs.get(scopeID);\n\n      if (!scopeMap) {\n        scopeMap = new Map();\n        this.attrs.set(scopeID, scopeMap);\n      }\n\n      for (const [key, attrOrDel] of attrs) {\n        if (typeof attrOrDel === \"boolean\") {\n          let attr = scopeMap.get(key);\n          if (attr) {\n            attr._update(undefined);\n          }\n        } else {\n          let attr = scopeMap.get(attrOrDel.key);\n          if (!attr) {\n            attr = new Attribute(this.setAttributes, scopeID, attrOrDel.key);\n            scopeMap.set(attrOrDel.key, attr);\n          }\n\n          attr._update(attrOrDel);\n        }\n      }\n    }\n\n    for (const scopeID of scopeIDs) {\n      this.updates.delete(scopeID);\n    }\n  }\n}\n\nexport interface AttributeOptions {\n  /**\n   * Private indicates the attribute will not be visible to other Participants.\n   */\n  private: boolean;\n  /**\n   * Protected indicates the attribute will not be updatable by other\n   * Participants.\n   */\n  protected: boolean;\n  /** Immutable creates an Attribute that cannot be updated. */\n  immutable: boolean;\n  /** ephemeral indicates the Attribute should not be persisted. Ephemeral\n   * Attributes are not stored in the database and are only synced to the\n   * connected clients. An ephemeral Attribute cannot become non-ephemeral and\n   * vice versa. */\n  ephemeral: boolean;\n  /**\n   * Index, only used if the Attribute is a vector, indicates which index to\n   * update the value at.\n   */\n  index: number | null;\n  /**\n   * Append, only used if the Attribute is a vector, indicates to append the\n   * attribute to the vector.\n   */\n  append: boolean | null;\n}\n\nexport class Attribute {\n  private attr?: AttributeChange;\n  private attrs?: Attribute[];\n\n  private val = new BehaviorSubject<JsonValue | undefined>(undefined);\n  private serVal?: string;\n\n  constructor(\n    private setAttributes: (input: SetAttributeInput[]) => Promise<unknown>,\n    readonly scopeID: string,\n    readonly key: string\n  ) {}\n\n  get id() {\n    return this.attr?.id;\n  }\n\n  get createdAt() {\n    return this.attr ? new Date(this.attr!.createdAt!) : null;\n  }\n\n  get obs(): Observable<JsonValue | undefined> {\n    return this.val;\n  }\n\n  get value() {\n    return this.val.getValue();\n  }\n\n  get nodeID() {\n    return this.scopeID;\n  }\n\n  // items returns the attribute changes for the current attribute, if it is a\n  // vector. Otherwise it returns null;\n  get items() {\n    if (!this.attrs) {\n      return null;\n    }\n\n    return this.attrs;\n  }\n\n  set(value: JsonValue, ao?: Partial<AttributeOptions>) {\n    const attrProps = this._prepSet(value, ao);\n    if (!attrProps) {\n      return;\n    }\n\n    this.setAttributes([attrProps]);\n    trace(`SET ${this.key} = ${value} (${this.scopeID})`);\n  }\n\n  _prepSet(\n    value: JsonValue,\n    ao?: Partial<AttributeOptions>,\n    item?: boolean\n  ): SetAttributeInput | undefined {\n    if (ao?.append !== undefined && ao!.index !== undefined) {\n      error(`cannot set both append and index`);\n\n      throw new Error(`cannot set both append and index`);\n    }\n\n    const serVal = JSON.stringify(value);\n\n    if (!item && (ao?.index !== undefined || ao?.append)) {\n      let index = ao!.index || 0;\n      if (ao?.append) {\n        index = this.attrs?.length || 0;\n      }\n\n      if (!this.attrs) {\n        this.attrs = [];\n      }\n\n      // if (index + 1 > (this.attrs?.length || 0)) {\n      //   this.attrs.length = index! + 1;\n      // }\n\n      if (!this.attrs[index]) {\n        this.attrs[index] = new Attribute(\n          this.setAttributes,\n          this.scopeID,\n          this.key\n        );\n      } else {\n        const existing = this.attrs[index];\n        if (existing && existing.serVal === serVal) {\n          return;\n        }\n      }\n\n      this.attrs![index]!._prepSet(value, ao, true);\n      const v = this._recalcVectorVal();\n      this.val.next(v);\n    } else {\n      if (this.serVal === serVal) {\n        return;\n      }\n\n      this.val.next(value);\n    }\n\n    this.serVal = serVal;\n\n    const attrProps: SetAttributeInput = {\n      key: this.key,\n      nodeID: this.scopeID,\n      val: serVal,\n    };\n\n    if (ao) {\n      // TODO Fix this. Should check if compatible with existing attribute and\n      // only set fields set on ao.\n      attrProps.private = ao.private;\n      attrProps.protected = ao.protected;\n      attrProps.immutable = ao.immutable;\n      attrProps.ephemeral = ao.ephemeral;\n      attrProps.append = ao.append;\n      attrProps.index = ao.index;\n    }\n\n    return attrProps;\n  }\n\n  private _recalcVectorVal(): JsonValue {\n    return this.attrs!.map((a) =>\n      !a || a.val == undefined ? null : a.value || null\n    );\n  }\n\n  // internal only\n  _update(attr?: AttributeChange, item?: boolean) {\n    if (attr && this.attr && this.attr.id === attr.id) {\n      return;\n    }\n\n    if (attr && attr.vector && !item) {\n      // TODO check if is vector\n\n      if (attr.index === undefined) {\n        error(`vector attribute missing index`);\n        return;\n      }\n\n      if (this.attrs == undefined) {\n        this.attrs = [];\n      }\n\n      while (this.attrs.length < attr.index! + 1) {\n        const newAttr = new Attribute(\n          this.setAttributes,\n          this.scopeID,\n          this.key\n        );\n        this.attrs.push(newAttr);\n      }\n\n      const newAttr = new Attribute(this.setAttributes, this.scopeID, this.key);\n      newAttr._update(attr, true);\n      this.attrs[attr.index!] = newAttr;\n      const value = this._recalcVectorVal();\n      this.val.next(value);\n\n      return;\n    }\n\n    this.attr = attr;\n    this.serVal = attr?.val === undefined || attr?.val === null ? \"\" : attr.val;\n    let value: JsonValue | undefined = undefined;\n    if (this.attr?.val) {\n      value = JSON.parse(this.attr.val);\n    }\n    this.val.next(value);\n  }\n}\n","/* c8 ignore start */\n\nconst isBrowser =\n  typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n\nenum Color {\n  Bold = 1,\n\n  Black = 30,\n  Red,\n  Green,\n  Yellow,\n  Blue,\n  Magenta,\n  Cyan,\n  White,\n\n  DarkGray = 90,\n}\n\nexport type LogLine = { level: string; args: any[] };\nexport class LogsMock {\n  public logs: LogLine[] = [];\n\n  log(line: LogLine) {\n    this.logs.push(line);\n  }\n\n  clear() {\n    this.logs = [];\n  }\n}\n\nlet logsMock: LogsMock | undefined;\nexport function captureLogs(cb: () => void): LogLine[] {\n  const lm = mockLogging();\n  cb();\n  const ret = lm.logs;\n  stopMockLogging();\n\n  return ret;\n}\n\nexport async function captureLogsAsync(\n  cb: () => Promise<void>\n): Promise<LogLine[]> {\n  const lm = mockLogging();\n  await cb();\n  const ret = lm.logs;\n  stopMockLogging();\n\n  return ret;\n}\n\nexport function mockLogging() {\n  if (!logsMock) {\n    logsMock = new LogsMock();\n  }\n\n  return logsMock;\n}\n\nexport function stopMockLogging() {\n  logsMock = undefined;\n}\n\nconst colorHex = {\n  [Color.Bold]: \"font-weight: bold\",\n  [Color.Black]: \"color: #000000\",\n  [Color.Red]: \"color: #cc0000\",\n  [Color.Green]: \"color: #4e9a06\",\n  [Color.Yellow]: \"color: #c4a000\",\n  [Color.Blue]: \"color: #729fcf\",\n  [Color.Magenta]: \"color: #75507b\",\n  [Color.Cyan]: \"color: #06989a\",\n  [Color.White]: \"color: #d3d7cf\",\n  [Color.DarkGray]: \"color: #555753\",\n};\n\nexport const levels: { [key: string]: number } = {\n  trace: 0,\n  debug: 1,\n  log: 2,\n  info: 2,\n  warn: 3,\n  error: 4,\n};\n\nconst reversLevels: { [key: number]: string } = {};\nfor (const key in levels) {\n  reversLevels[levels[key]!] = key;\n}\n\nlet currentLevel = 2;\n\nexport function setLogLevel(level: keyof typeof levels) {\n  const lvl = levels[level];\n  if (lvl === undefined) {\n    return;\n  }\n\n  currentLevel = lvl;\n}\n\nfunction formatConsoleDate(date: Date, level: string[]) {\n  var hour = date.getHours();\n  var minutes = date.getMinutes();\n  var seconds = date.getSeconds();\n  var milliseconds = date.getMilliseconds();\n\n  const str =\n    (hour < 10 ? \"0\" + hour : hour) +\n    \":\" +\n    (minutes < 10 ? \"0\" + minutes : minutes) +\n    \":\" +\n    (seconds < 10 ? \"0\" + seconds : seconds) +\n    \".\" +\n    (\"00\" + milliseconds).slice(-3);\n\n  if (isBrowser) {\n    const ts = colorize(str, Color.DarkGray).concat(level);\n    return [ts[0] + \" \" + level[0], ts[1], level[1]];\n  }\n\n  return colorize(str, Color.DarkGray).concat(level);\n}\n\nconst createLogger = (lvl: number, level: string[]) => {\n  return (...args: any[]) => {\n    if (lvl < currentLevel) {\n      return;\n    }\n\n    if (logsMock) {\n      logsMock.log({ level: reversLevels[lvl]!, args: args });\n\n      return;\n    }\n\n    if (args.length === 1) {\n      switch (typeof args[0]) {\n        case \"string\":\n          for (const line of args[0].split(\"\\n\")) {\n            console.log(...formatConsoleDate(new Date(), level).concat(line));\n          }\n          return;\n\n        case \"object\":\n          if (args[0] instanceof Error) {\n            const error = args[0] as Error;\n            const prettyErr =\n              error.name +\n              \": \" +\n              error.message.replace(new RegExp(`^${error.name}[: ]*`), \"\") +\n              \"\\n\" +\n              (error.stack || \"\")\n                .split(\"\\n\")\n                .map((line) => line.trim())\n                .map((line) => {\n                  if (line.startsWith(error.name + \": \" + error.message))\n                    return null;\n\n                  if (line.startsWith(\"at\")) {\n                    return \"  \" + line;\n                  }\n\n                  return line;\n                })\n                .filter(Boolean)\n                .join(\"\\n\");\n\n            for (const line of prettyErr.split(\"\\n\")) {\n              console.log(...formatConsoleDate(new Date(), level).concat(line));\n            }\n\n            return;\n          }\n      }\n    }\n\n    console.log(...formatConsoleDate(new Date(), level).concat(args));\n  };\n};\n\nfunction colorize(s: string, ...cc: Color[]): string[] {\n  if (isBrowser) {\n    const attr = [];\n    for (const c of cc) {\n      attr.push(colorHex[c]);\n    }\n\n    return [`%c${s}`, attr.join(\"; \")];\n  }\n\n  let out = \"\";\n  for (const c of cc) {\n    out += `\\x1b[${c}m`;\n  }\n  out += `${s}\\x1b[0m`;\n\n  return [out];\n}\n\nexport const trace = createLogger(0, colorize(\"TRC\", Color.Magenta));\nexport const debug = createLogger(1, colorize(\"DBG\", Color.Yellow));\nexport const log = createLogger(2, colorize(\"LOG\", Color.Yellow));\nexport const info = createLogger(2, colorize(\"INF\", Color.Green));\nexport const warn = createLogger(3, colorize(\"WRN\", Color.Cyan));\nexport const error = createLogger(4, colorize(\"ERR\", Color.Red, Color.Bold));\n\n// export {\n//   trace,\n//   debug,\n//   log,\n//   info,\n//   warn,\n//   error,\n// };\n\n// export function warn(...args: string[]) {}\n","import { BehaviorSubject, Observable } from \"rxjs\";\nimport { Attribute, AttributeOptions, Attributes } from \"../shared/attributes\";\nimport { Constructor } from \"../shared/helpers\";\nimport { warn } from \"../utils/console\";\nimport { JsonValue } from \"../utils/json\";\n\nexport type Attributable = {\n  get: (key: string) => JsonValue | undefined;\n  getAttribute: (key: string) => Attribute | undefined;\n  set: (key: string, value: JsonValue, ao?: Partial<AttributeOptions>) => void;\n  append: (\n    key: string,\n    value: JsonValue,\n    ao?: Partial<AttributeOptions>\n  ) => void;\n};\n\nexport interface ScopeIdent {\n  id: string;\n  kind: string;\n}\n\nexport interface ScopeUpdate {\n  scope: ScopeIdent;\n  removed: boolean;\n}\n\nexport type ScopeConstructor<\n  Context,\n  Kinds extends { [key: string]: ScopeConstructor<Context, Kinds> }\n> = Constructor<Scope<Context, Kinds>>;\n\nexport class Scopes<\n  Context,\n  Kinds extends { [key: string]: ScopeConstructor<Context, Kinds> },\n  Skope extends Scope<Context, Kinds> = Scope<Context, Kinds>\n> {\n  protected scopes = new Map<string, BehaviorSubject<Skope>>();\n  // newScopes is used to track scopes that have appeared for the first time.\n  protected newScopes = new Map<string, boolean>();\n  protected scopesByKind = new Map<keyof Kinds, Map<string, Skope>>();\n  protected kindUpdated = new Set<keyof Kinds>();\n\n  constructor(\n    scopesObs: Observable<ScopeUpdate>,\n    donesObs: Observable<string[]>,\n    protected ctx: Context,\n    protected kinds: Kinds,\n    protected attributes: Attributes\n  ) {\n    scopesObs.subscribe({\n      next: ({ scope, removed }) => {\n        this.update(scope, removed);\n      },\n    });\n\n    donesObs.subscribe({\n      next: (scopeIDs) => {\n        this.next(scopeIDs);\n      },\n    });\n  }\n\n  scope(id: string): Skope | undefined {\n    return this.scopes.get(id)?.getValue();\n  }\n\n  scopeObs(id: string): Observable<Skope> | undefined {\n    return this.scopes.get(id);\n  }\n\n  byKind<T extends Skope>(kind: keyof Kinds) {\n    let map = this.scopesByKind.get(kind);\n    if (!map) {\n      map = new Map();\n      this.scopesByKind.set(kind, map);\n    }\n\n    return map! as Map<string, T>;\n  }\n\n  kindWasUpdated(kind: keyof Kinds): boolean {\n    return this.kindUpdated.has(kind);\n  }\n\n  protected next(scopeIDs: string[]) {\n    this.kindUpdated.clear();\n    for (const [_, scopeSubject] of this.scopes) {\n      const scope = scopeSubject.getValue();\n      if (\n        (scope._updated || this.attributes.scopeWasUpdated(scope.id)) &&\n        scopeIDs.includes(scope.id)\n      ) {\n        scope._updated = false;\n        scopeSubject.next(scope);\n      }\n    }\n  }\n\n  protected update(scope: ScopeIdent, removed: boolean) {\n    const existing = this.scopes.get(scope.id)?.getValue();\n\n    if (removed) {\n      if (!existing) {\n        warn(\"scopes: missing scope on removal\", scope.id, scope.kind);\n\n        return;\n      }\n\n      existing._deleted = true;\n      existing._updated = true;\n      this.scopes.delete(scope.id);\n\n      if (!scope.kind) {\n        warn(\"scopes: scope missing kind on scope on removal\");\n\n        return;\n      }\n\n      const kind = scope.kind as keyof Kinds;\n\n      // Using ! because scopes by kind must exist, since this scope was found.\n      this.scopesByKind.get(kind)!.delete(scope.id);\n\n      this.kindUpdated.add(kind);\n\n      return;\n    }\n\n    if (existing) {\n      existing._deleted = false;\n      return;\n    }\n\n    if (!scope.kind) {\n      warn(\"scopes: scope missing kind on scope\");\n\n      return;\n    }\n\n    const kind = scope.kind as keyof Kinds;\n    const scopeClass = this.kinds[kind];\n    if (!scopeClass) {\n      warn(`scopes: unknown scope kind: ${scope.kind}`);\n\n      return;\n    }\n\n    const obj = this.create(scopeClass, scope);\n    const subj = new BehaviorSubject(obj);\n    this.scopes.set(scope.id, subj);\n    this.newScopes.set(scope.id, true);\n\n    let skm = this.scopesByKind.get(kind);\n    if (!skm) {\n      skm = new Map();\n      this.scopesByKind.set(kind, skm);\n    }\n\n    skm.set(scope.id, obj);\n\n    obj._updated = true;\n    this.kindUpdated.add(kind);\n  }\n\n  protected create(\n    scopeClass: ScopeConstructor<Context, Kinds>,\n    scope: ScopeIdent\n  ) {\n    return new scopeClass!(this.ctx, scope, this.attributes) as Skope;\n  }\n}\n\nexport type AttributeInput = {\n  key: string;\n  value: JsonValue;\n  ao?: Partial<AttributeOptions>;\n};\n\nexport class Scope<\n  Context,\n  Kinds extends { [key: string]: ScopeConstructor<Context, Kinds> }\n> {\n  /**\n   * @internal\n   */\n  _deleted = false;\n\n  /**\n   * @internal\n   */\n  _updated = false;\n\n  constructor(\n    /**\n     * @internal\n     */\n    readonly ctx: Context,\n    /**\n     * @internal\n     */\n    readonly scope: ScopeIdent,\n    /**\n     * @internal\n     */\n    protected attributes: Attributes\n  ) {}\n\n  get id() {\n    return this.scope.id;\n  }\n\n  /**\n   * @internal\n   */\n  get kind() {\n    // Using ! because we don't allow scopes without kind\n    return this.scope.kind!;\n  }\n\n  get(key: string): JsonValue | undefined {\n    return this.attributes.attribute(this.scope.id, key).value;\n  }\n\n  getAttribute(key: string): Attribute | undefined {\n    return this.attributes.attribute(this.scope.id, key);\n  }\n\n  obs(key: string): Observable<JsonValue | undefined> {\n    return this.attributes.attribute(this.scope.id, key).obs;\n  }\n\n  set(values: AttributeInput[]): void;\n  set(key: string, value: JsonValue, ao?: Partial<AttributeOptions>): void;\n  set(\n    keyOrAttributes: string | AttributeInput[],\n    value?: JsonValue,\n    ao?: Partial<AttributeOptions>\n  ) {\n    if (typeof keyOrAttributes === \"string\") {\n      if (value === undefined) {\n        value = null;\n      }\n\n      return this.attributes\n        .attribute(this.scope.id, keyOrAttributes)\n        .set(value, ao);\n    }\n\n    const nextProps = [];\n    for (const attr of keyOrAttributes) {\n      const at = this.attributes\n        .attribute(this.scope.id, attr.key)\n        ._prepSet(attr.value, attr.ao);\n      if (!at) {\n        continue;\n      }\n\n      nextProps.push(at);\n    }\n\n    if (nextProps.length === 0) {\n      return;\n    }\n\n    this.attributes.setAttributes(nextProps);\n  }\n\n  append(key: string, value: JsonValue, ao?: Partial<AttributeOptions>) {\n    if (!ao) {\n      ao = {};\n    }\n    ao.append = true;\n\n    return this.attributes.attribute(this.scope.id, key).set(value, ao);\n  }\n\n  inspect() {\n    const attrs = this.attributes.attributes(this.scope.id);\n\n    const out: { [key: string]: JsonValue | undefined } = {};\n    for (const attr of attrs) {\n      out[attr.key] = attr.value;\n    }\n\n    return out;\n  }\n\n  /**\n   * @internal\n   */\n  hasUpdated() {\n    return this._updated || this.attributes.scopeWasUpdated(this.id);\n  }\n}\n","import { Observable } from \"rxjs\";\nimport { Attributes } from \"../shared/attributes\";\nimport {\n  Scope as SharedScope,\n  ScopeConstructor,\n  ScopeIdent,\n  Scopes as SharedScopes,\n  ScopeUpdate,\n} from \"../shared/scopes\";\nimport { Steps } from \"./steps\";\n\nexport class Scopes<\n  Context,\n  Kinds extends { [key: string]: ScopeConstructor<Context, Kinds> }\n> extends SharedScopes<Context, Kinds, Scope<Context, Kinds>> {\n  constructor(\n    scopesObs: Observable<ScopeUpdate>,\n    donesObs: Observable<string[]>,\n    ctx: Context,\n    kinds: Kinds,\n    attributes: Attributes,\n    private steps: Steps\n  ) {\n    super(scopesObs, donesObs, ctx, kinds, attributes);\n  }\n\n  protected create(\n    scopeClass: ScopeConstructor<Context, Kinds>,\n    scope: ScopeIdent\n  ) {\n    return new scopeClass!(\n      this.ctx,\n      scope,\n      this,\n      this.attributes,\n      this.steps\n    ) as Scope<Context, Kinds>;\n  }\n}\n\nexport class Scope<\n  Context,\n  Kinds extends { [key: string]: ScopeConstructor<Context, Kinds> }\n> extends SharedScope<Context, Kinds> {\n  constructor(\n    ctx: Context,\n    scope: ScopeIdent,\n    readonly scopes: Scopes<Context, Kinds>,\n    attributes: Attributes,\n    private steps: Steps\n  ) {\n    super(ctx, scope, attributes);\n  }\n\n  scopeByKey(key: string) {\n    const id = this.get(key);\n    if (!id || typeof id !== \"string\") {\n      return;\n    }\n\n    return this.scopes.scope(id);\n  }\n\n  protected ticker(id: string) {\n    return this.steps.step(id);\n  }\n\n  protected tickerByKey(key: string) {\n    const id = this.get(key);\n    if (!id || typeof id !== \"string\") {\n      return;\n    }\n\n    return this.ticker(id);\n  }\n}\n","import { BehaviorSubject, map, Observable } from \"rxjs\";\n\nexport interface StepChange {\n  id: string;\n  running: boolean;\n  elapsed?: number;\n  remaining?: number;\n}\n\nexport interface StepUpdate {\n  step: StepChange;\n  removed: boolean;\n}\n\nexport interface StepTick {\n  started: boolean;\n  ended: boolean;\n  elapsed: number;\n  remaining: number;\n  duration: number;\n}\n\ntype schds = {\n  cb: (args: void) => void;\n  from: number;\n  dur: number;\n};\n\nlet scheduled: schds[] = [];\n\nexport let mockNow: number | null = null;\nexport function setNow(now: number) {\n  if (mockNow && mockNow > now) {\n    if (now === 0) {\n      // This is a reset scheduled should be empty\n      scheduled = [];\n      /* c8 ignore next 3 */\n    } else {\n      throw \"time must move forward\";\n    }\n  }\n\n  mockNow = now;\n\n  const rescheduled: schds[] = [];\n  for (const s of scheduled) {\n    if (mockNow >= s.from + s.dur) {\n      s.cb();\n    } else {\n      rescheduled.push(s);\n    }\n  }\n\n  scheduled = rescheduled;\n}\n\nfunction pnow() {\n  if (mockNow !== null) {\n    return mockNow;\n  } else {\n    // TODO sync time\n    return performance.now();\n  }\n}\n\nfunction timeout(callback: (args: void) => void, ms: number) {\n  if (mockNow !== null) {\n    const schd = {\n      cb: callback,\n      from: mockNow,\n      dur: ms,\n    };\n    scheduled.push(schd);\n  } else {\n    setTimeout(callback, ms);\n  }\n}\n\n// The number of milliseconds elapsed since January 1, 1970 00:00:00 UTC, with\n// leap seconds ignored.\nexport type Epoch = number;\n\nexport class Step {\n  private running = false;\n  private ticker = new BehaviorSubject<StepTick | undefined>(undefined);\n  private startAt: number = 0;\n  private endAt: number = 0;\n\n  constructor(step: StepChange, ticker: Observable<DOMHighResTimeStamp>) {\n    ticker.pipe(map(this.recalc.bind(this))).subscribe({\n      next: (val) => {\n        this.ticker.next(val);\n      },\n    });\n\n    this._update(step);\n  }\n\n  private recalc(t: DOMHighResTimeStamp) {\n    if (!this.running) {\n      return undefined;\n    }\n\n    return {\n      started: t >= this.startAt,\n      ended: t >= this.endAt,\n      elapsed: Math.round(t - this.startAt),\n      remaining: Math.round(this.endAt - t),\n      duration: this.endAt - this.startAt,\n    } as StepTick;\n  }\n\n  obs(): Observable<StepTick | undefined> {\n    return this.ticker;\n  }\n\n  get current() {\n    return this.recalc(pnow());\n  }\n\n  // internal only\n  _update(step: StepChange) {\n    if (!step.running) {\n      this.running = false;\n      this.ticker.next(undefined);\n\n      return;\n    }\n\n    if (\n      step.elapsed === null ||\n      step.remaining === null ||\n      step.elapsed === undefined ||\n      step.remaining === undefined\n    ) {\n      this.running = false;\n\n      return;\n    }\n\n    const now = pnow();\n\n    this.startAt = now - step.elapsed * 1000;\n    this.endAt = now + step.remaining * 1000;\n    this.running = step.elapsed >= 0 && step.remaining >= 0;\n\n    this.ticker.next(this.recalc(now));\n  }\n\n  // internal only\n  _stop() {\n    this.running = false;\n    this.ticker.next(undefined);\n  }\n}\n\nexport class Steps {\n  private steps = new Map<string, Step>();\n  private updates = new Map<string, StepChange | boolean>();\n  private _hadUpdates = false;\n\n  private ticker: BehaviorSubject<Epoch>;\n\n  constructor(stepsObs: Observable<StepUpdate>, donesObs: Observable<void>) {\n    stepsObs.subscribe({\n      next: ({ step, removed }) => {\n        this.update(step, removed);\n      },\n    });\n\n    donesObs.subscribe({\n      next: () => {\n        this.next();\n      },\n    });\n\n    this.ticker = new BehaviorSubject<Epoch>(Math.floor(pnow()));\n    const controller = new AbortController();\n    timerInterval(1000, controller.signal, (t) => {\n      this.ticker.next(t);\n    });\n  }\n\n  step(stepID: string): Step | undefined {\n    return this.steps.get(stepID);\n  }\n\n  hadUpdates() {\n    const hadUpdates = this._hadUpdates;\n    this._hadUpdates = false;\n\n    return hadUpdates;\n  }\n\n  private update(step: StepChange, removed: boolean) {\n    if (removed) {\n      this.updates.set(step.id, true);\n    } else {\n      this.updates.set(step.id, step);\n    }\n\n    this._hadUpdates = true;\n  }\n\n  private next() {\n    for (const [id, stepOrDel] of this.updates) {\n      let step = this.steps.get(id);\n      if (typeof stepOrDel === \"boolean\") {\n        if (step) {\n          step._stop();\n          this.steps.delete(id);\n        }\n      } else {\n        if (!step) {\n          step = new Step(stepOrDel, this.ticker);\n          this.steps.set(id, step);\n        }\n\n        step._update(stepOrDel);\n      }\n    }\n\n    this.updates.clear();\n  }\n}\n\n/* c8 ignore next 6 */\nexport const root: any =\n  typeof self === \"object\" && self.self == self\n    ? self\n    : typeof global === \"object\" && global.global == global\n    ? global\n    : {};\n\n// nodejs support\nif (!root[\"requestAnimationFrame\"]) {\n  type timecb = (t: DOMHighResTimeStamp) => void;\n  root[\"requestAnimationFrame\"] = (cb: timecb) => cb(pnow());\n}\n\n// Inspiration:\n// https://www.youtube.com/watch?v=MCi6AZMkxcU\n// https://gist.github.com/jakearchibald/cb03f15670817001b1157e62a076fe95\nfunction timerInterval(\n  ms: number = 1000,\n  signal: AbortSignal,\n  callback: (time: number) => void\n) {\n  // Performance should be available in Nodejs 10+.\n  // Get the last rounded second, which will go negative, but that's fine, since\n  // it will immediately send out its first tick, then be on the second.\n  const start = Math.floor(pnow() / 1000) * 1000;\n\n  function frame(time: number) {\n    /* c8 ignore next */\n    if (signal.aborted) return;\n    callback(time);\n    scheduleFrame(time);\n  }\n\n  function scheduleFrame(time: number) {\n    const elapsed = time - start;\n    const roundedElapsed = Math.round(elapsed / ms) * ms;\n    const targetNext = start + roundedElapsed + ms;\n    const delay = targetNext - pnow();\n    timeout(() => requestAnimationFrame(frame), delay);\n  }\n\n  scheduleFrame(start);\n}\n\n// export function useAnimationInterval(\n//   ms: number,\n//   callback: (time: number) => void\n// ) {\n//   const callbackRef = React.useRef(callback);\n//   React.useEffect(() => {\n//     callbackRef.current = callback;\n//   }, [callback]);\n\n//   React.useEffect(() => {\n//     const controller = new AbortController();\n//     animationInterval(ms, controller.signal, callbackRef.current);\n//     return () => controller.abort();\n//   }, [ms]);\n// }\n","import { BehaviorSubject, Observable, Subject } from \"rxjs\";\nimport { Attributes } from \"../../shared/attributes\";\nimport { Globals } from \"../../shared/globals\";\nimport { Constructor } from \"../../shared/helpers\";\nimport { TajribaProvider } from \"../provider\";\nimport { Scope, Scopes } from \"../scopes\";\nimport { Steps } from \"../steps\";\n\nexport const endedStatuses = [\"ended\", \"terminated\", \"failed\"];\nexport type EndedStatuses = typeof endedStatuses[number];\n\nexport class Game extends Scope<Context, EmpiricaClassicKinds> {\n  get hasEnded() {\n    return endedStatuses.includes(this.get(\"status\") as EndedStatuses);\n  }\n\n  get stage() {\n    return this.scopeByKey(\"stageID\") as Stage | undefined;\n  }\n\n  get round() {\n    return this.stage?.round;\n  }\n}\n\nexport class Player extends Scope<Context, EmpiricaClassicKinds> {\n  get game() {\n    const { game } = this.ctx;\n    if (!game) {\n      return;\n    }\n\n    const key = `playerGameID-${game.id}`;\n    return this.scopeByKey(key) as PlayerGame | undefined;\n  }\n\n  get round() {\n    const { stage } = this.ctx;\n    if (!stage) {\n      return;\n    }\n\n    const { round } = stage;\n    if (!round) {\n      return;\n    }\n\n    const key = `playerRoundID-${round.id}`;\n    return this.scopeByKey(key) as PlayerRound | undefined;\n  }\n\n  get stage() {\n    const { stage } = this.ctx;\n    if (!stage) {\n      return;\n    }\n\n    const key = `playerStageID-${stage.id}`;\n    return this.scopeByKey(key) as PlayerStage | undefined;\n  }\n\n  hasUpdated() {\n    if (super.hasUpdated()) {\n      return true;\n    }\n\n    return Boolean(\n      this.round?.hasUpdated() ||\n        this.stage?.hasUpdated() ||\n        this.game?.hasUpdated()\n    );\n  }\n}\n\nexport class PlayerGame extends Scope<Context, EmpiricaClassicKinds> {}\n\nexport class PlayerRound extends Scope<Context, EmpiricaClassicKinds> {}\n\nexport class PlayerStage extends Scope<Context, EmpiricaClassicKinds> {}\n\nexport class Round extends Scope<Context, EmpiricaClassicKinds> {}\n\nexport class Stage extends Scope<Context, EmpiricaClassicKinds> {\n  get round() {\n    return this.scopeByKey(\"roundID\") as Round | undefined;\n  }\n\n  get timer() {\n    return this.tickerByKey(\"timerID\");\n  }\n}\n\n// TODO update context\nexport class Context {\n  public game?: Game | null;\n  public stage?: Stage | null;\n}\n\nexport type EmpiricaClassicKinds = {\n  game: Constructor<Game>;\n  player: Constructor<Player>;\n  playerGame: Constructor<PlayerGame>;\n  playerRound: Constructor<PlayerRound>;\n  playerStage: Constructor<PlayerStage>;\n  round: Constructor<Round>;\n  stage: Constructor<Stage>;\n};\n\nexport const kinds = {\n  game: Game,\n  player: Player,\n  playerGame: PlayerGame,\n  playerRound: PlayerRound,\n  playerStage: PlayerStage,\n  round: Round,\n  stage: Stage,\n};\n\nexport type EmpiricaClassicContext = {\n  game: BehaviorSubject<Game | null | undefined>;\n  player: BehaviorSubject<Player | null | undefined>;\n  players: BehaviorSubject<Player[] | undefined>;\n  round: BehaviorSubject<Round | null | undefined>;\n  stage: BehaviorSubject<Stage | null | undefined>;\n  globals: BehaviorSubject<Globals | undefined>;\n};\n\nexport function EmpiricaClassic(\n  participantID: string,\n  provider: TajribaProvider\n): EmpiricaClassicContext {\n  const attributesDones = new Subject<string[]>();\n  const scopesDones = new Subject<string[]>();\n\n  const ctx = new Context();\n  const attributes = new Attributes(\n    provider.attributes,\n    attributesDones,\n    provider.setAttributes\n  );\n  const steps = new Steps(\n    provider.steps,\n    provider.dones as unknown as Observable<void>\n  );\n  const scopes = new Scopes(\n    provider.scopes,\n    scopesDones,\n    ctx,\n    kinds,\n    attributes,\n    steps\n  );\n  const participantIDs = new Set<string>();\n\n  const glob = new Globals(provider.globals);\n\n  const ret = {\n    game: new BehaviorSubject<Game | null | undefined>(undefined),\n    player: new BehaviorSubject<Player | null | undefined>(undefined),\n    players: new BehaviorSubject<Player[] | undefined>(undefined),\n    round: new BehaviorSubject<Round | null | undefined>(undefined),\n    stage: new BehaviorSubject<Stage | null | undefined>(undefined),\n    globals: glob.self,\n  };\n\n  provider.participants.subscribe({\n    next: ({ participant, removed }) => {\n      if (removed) {\n        if (participantIDs.has(participant.id)) {\n          participantIDs.delete(participant.id);\n        }\n      } else {\n        if (!participantIDs.has(participant.id)) {\n          participantIDs.add(participant.id);\n        }\n      }\n    },\n  });\n\n  let scopesUpdated = new Set<string>();\n  provider.attributes.subscribe({\n    next: (attr) => {\n      const nodeID = attr.attribute.node?.id || attr.attribute.nodeID;\n      if (!nodeID) {\n        return;\n      }\n\n      scopesUpdated.add(nodeID);\n    },\n  });\n\n  provider.dones.subscribe({\n    next: () => {\n      const current = getCurrent(ret);\n      const updated = getMainObjects(participantID, scopes, attributes);\n      ctx.game = updated.game;\n      ctx.stage = updated.stage;\n\n      if (scopeChanged(current.game, updated.game)) {\n        ret.game.next(updated.game);\n      }\n\n      if (scopeChanged(current.player, updated.player)) {\n        ret.player.next(updated.player);\n      }\n\n      if (scopeChanged(current.round, updated.round)) {\n        ret.round.next(updated.round);\n      }\n\n      if (scopeChanged(current.stage, updated.stage) || steps.hadUpdates()) {\n        ret.stage.next(updated.stage);\n      }\n\n      let playersChanged = false;\n      const players: Player[] = [];\n      for (let i = 0; i < (updated.players || []).length; i++) {\n        let p = updated.players![i];\n\n        if (p) {\n          const partID = attributes.nextAttributeValue(\n            p.id,\n            \"participantID\"\n          ) as string;\n          if (!participantIDs.has(partID)) {\n            p = undefined;\n          }\n        }\n\n        if (!playersChanged && scopeChanged(p, (current.players || [])[i])) {\n          playersChanged = true;\n        }\n\n        if (\n          !playersChanged &&\n          scopeChanged(p?.stage, (current.players || [])[i]?.stage)\n        ) {\n          playersChanged = true;\n        }\n\n        if (\n          !playersChanged &&\n          scopeChanged(p?.round, (current.players || [])[i]?.round)\n        ) {\n          playersChanged = true;\n        }\n\n        if (\n          !playersChanged &&\n          scopeChanged(p?.game, (current.players || [])[i]?.game)\n        ) {\n          playersChanged = true;\n        }\n\n        if (p) {\n          players.push(p);\n        }\n      }\n\n      if (playersChanged) {\n        ret.players.next(players);\n      }\n\n      const scopeIDs = Array.from(scopesUpdated);\n      scopesDones.next(scopeIDs);\n      attributesDones.next(scopeIDs);\n      scopesUpdated.clear();\n    },\n  });\n\n  return ret;\n}\n\ntype mainObjects = {\n  game?: Game | null;\n  player?: Player | null;\n  round?: Round | null;\n  stage?: Stage | null;\n  players?: Player[];\n};\n\nfunction scopeChanged(\n  current?: Scope<Context, EmpiricaClassicKinds> | null,\n  updated?: Scope<Context, EmpiricaClassicKinds> | null\n): boolean {\n  if (!current && !updated) {\n    if (current === undefined && updated === null) {\n      return true;\n    }\n\n    return false;\n  }\n\n  if (!current || !updated) {\n    return true;\n  }\n\n  return current.id !== updated.id || updated.hasUpdated();\n}\n\nfunction getCurrent(ctx: EmpiricaClassicContext): mainObjects {\n  return {\n    game: ctx.game.getValue(),\n    player: ctx.player.getValue(),\n    round: ctx.round.getValue(),\n    stage: ctx.stage.getValue(),\n    players: ctx.players.getValue(),\n  };\n}\n\nfunction getMainObjects(\n  participantID: string,\n  scopes: Scopes<Context, EmpiricaClassicKinds>,\n  attributes: Attributes\n): mainObjects {\n  const players = Array.from(scopes.byKind(\"player\").values()) as Player[];\n  players.sort();\n\n  const res: mainObjects = {\n    players,\n    game: null,\n    player: null,\n    round: null,\n    stage: null,\n  };\n\n  if (players.length === 0) {\n    return res;\n  }\n\n  res.player = players.find((p) => {\n    const pID = attributes.nextAttributeValue(p.id, \"participantID\") as string;\n    return pID === participantID;\n  }) as Player;\n\n  if (!res.player) {\n    return res;\n  }\n\n  res.game = nextScopeByKey(scopes, attributes, res.player, \"gameID\") as Game;\n  if (!res.game) {\n    return res;\n  }\n\n  for (const player of players || []) {\n    const key = `playerGameID-${res.game.id}`;\n    if (!nextScopeByKey(scopes, attributes, player, key)) {\n      return res;\n    }\n  }\n\n  res.stage = nextScopeByKey(scopes, attributes, res.game, \"stageID\") as Stage;\n  if (!res.stage) {\n    return res;\n  }\n\n  for (const player of players || []) {\n    const key = `playerStageID-${res.stage.id}`;\n    if (!nextScopeByKey(scopes, attributes, player, key)) {\n      delete res.stage;\n      return res;\n    }\n  }\n\n  res.round = nextScopeByKey(scopes, attributes, res.stage, \"roundID\") as Round;\n  if (!res.round) {\n    return res;\n  }\n\n  for (const player of players || []) {\n    const key = `playerRoundID-${res.round.id}`;\n    if (!nextScopeByKey(scopes, attributes, player, key)) {\n      delete res.stage;\n      delete res.round;\n      return res;\n    }\n  }\n\n  return res;\n}\n\nfunction nextScopeByKey(\n  scopes: Scopes<Context, EmpiricaClassicKinds>,\n  attributes: Attributes,\n  scope: Scope<Context, EmpiricaClassicKinds>,\n  key: string\n) {\n  const id = attributes.nextAttributeValue(scope.id, key);\n  if (!id || typeof id !== \"string\") {\n    return null;\n  }\n\n  return scopes.scope(id) || null;\n}\n","import { SubAttributesPayload } from \"@empirica/tajriba\";\nimport { BehaviorSubject, Observable } from \"rxjs\";\nimport { JsonValue } from \"../utils/json\";\n\nexport class Globals {\n  protected attrs = new Map<string, BehaviorSubject<JsonValue | undefined>>();\n  private updates = new Map<string, JsonValue | undefined>();\n  public self: BehaviorSubject<Globals | undefined>;\n\n  constructor(globals: Observable<SubAttributesPayload>) {\n    this.self = new BehaviorSubject<Globals | undefined>(undefined);\n\n    globals.subscribe({\n      next: ({ attribute, done }) => {\n        if (attribute) {\n          let val = undefined;\n          if (attribute.val) {\n            val = JSON.parse(attribute.val);\n          }\n\n          this.updates.set(attribute.key, val);\n        }\n\n        if (done) {\n          for (const [key, val] of this.updates) {\n            this.obs(key).next(val);\n          }\n\n          this.updates.clear();\n\n          if (this.self) {\n            this.self.next(this);\n          }\n        }\n      },\n    });\n  }\n\n  get(key: string): JsonValue | undefined {\n    const o = this.attrs.get(key);\n    if (o) {\n      return o.getValue();\n    }\n\n    return undefined;\n  }\n\n  obs(key: string) {\n    let o = this.attrs.get(key);\n    if (!o) {\n      o = new BehaviorSubject<JsonValue | undefined>(undefined);\n      this.attrs.set(key, o);\n    }\n\n    return o;\n  }\n}\n","import React from \"react\";\nimport { Consent, ConsentProps } from \"../../react/Consent\";\nimport { Finished } from \"../../react/Finished\";\nimport { Loading } from \"../../react/Loading\";\nimport { NoGames } from \"../../react/NoGames\";\nimport { PlayerCreate, PlayerCreateProps } from \"../../react/PlayerCreate\";\nimport {\n  useConsent,\n  useGlobal,\n  usePartConnected,\n  usePlayerID,\n  useTajribaConnected,\n} from \"../../react/hooks\";\nimport { Lobby as DefaultLobby } from \"./Lobby\";\nimport { Steps, StepsFunc } from \"./Steps\";\nimport { useGame, usePlayer, usePlayers, useRound, useStage } from \"./hooks\";\n\nexport interface EmpiricaContextProps {\n  children: React.ReactNode;\n  noGames?: React.ElementType;\n  consent?: React.ElementType<ConsentProps>;\n  playerCreate?: React.ElementType<PlayerCreateProps>;\n  lobby?: React.ElementType;\n  introSteps?: React.ElementType[] | StepsFunc;\n  exitSteps?: React.ElementType[] | StepsFunc;\n  finished?: React.ElementType;\n  loading?: React.ElementType;\n  connecting?: React.ElementType;\n\n  // An unmanaged game will render the children whether the game, round or stage\n  // are available or not. It is up to the developer to handle the presence of\n  // the game, round and stage. Other parts are still managed: the consent, the\n  // player creation, the intro and exit steps.\n  // This is not recommended for most games.\n  // This is useful for experiments that implement custom assignment and games\n  // that want to persist render state between rounds or stages. E.g.: keep a\n  // video chat up between stages.\n  unmanagedGame?: boolean;\n\n  // Unmanaged assignement will render the children as soon as the player is\n  // connected. It is up to the developer to handle everything after the player\n  // is connected: intro steps, lobby, game, round, stage and exit steps.\n  unmanagedAssignment?: boolean;\n\n  // Disable the consent screen. It is up to the developer to handle the consent\n  // screen.\n  disableConsent?: boolean;\n\n  // Disable the NoGames screen. It is up to the developer to handle the NoGames\n  // condition.\n  disableNoGames?: boolean;\n\n  // Disable capturing URL params (?what=hello&some=thing) onto the Player under\n  // the `urlParams` key.\n  disableURLParamsCapture?: boolean;\n}\n\nexport function EmpiricaContext({\n  noGames: NoGamesComp = NoGames,\n  consent: ConsentComp = Consent,\n  playerCreate: PlayerCreateForm = PlayerCreate,\n  introSteps = [],\n  lobby = DefaultLobby,\n  exitSteps = [],\n  finished = Finished,\n  loading: LoadingComp = Loading,\n  connecting: ConnectingComp = Loading,\n  unmanagedGame = false,\n  unmanagedAssignment = false,\n  disableConsent = false,\n  disableNoGames = false,\n  disableURLParamsCapture = false,\n  children,\n}: EmpiricaContextProps) {\n  const tajribaConnected = useTajribaConnected();\n  const participantConnected = usePartConnected();\n  const globals = useGlobal();\n  const player = usePlayer();\n  const game = useGame();\n  const [connecting, hasPlayer, onPlayerID] = usePlayerID();\n  const [consented, onConsent] = useConsent();\n\n  if (!tajribaConnected || connecting) {\n    return <ConnectingComp />;\n  }\n\n  if (player && player.get(\"ended\")) {\n    return <Exit exitSteps={exitSteps} finished={finished} />;\n  }\n\n  if (\n    !globals ||\n    (hasPlayer && (!participantConnected || !player || game === undefined))\n  ) {\n    return <LoadingComp />;\n  }\n\n  if (\n    !disableNoGames &&\n    !globals.get(\"experimentOpen\") &&\n    (!hasPlayer || !player?.get(\"gameID\"))\n  ) {\n    return <NoGamesComp />;\n  }\n\n  if (!disableConsent && !consented) {\n    return <ConsentComp onConsent={onConsent!} />;\n  }\n\n  if (!hasPlayer) {\n    return (\n      <PlayerCreateForm onPlayerID={onPlayerID!} connecting={connecting} />\n    );\n  }\n\n  if (!player || (!unmanagedGame && !game)) {\n    return <LoadingComp />;\n  }\n\n  // TODO Put in a useEffect, this is dirty.\n  if (!disableURLParamsCapture && !player.get(\"urlParams\")) {\n    const urlParams = new URLSearchParams(window.location.search);\n    player.set(\"urlParams\", Object.fromEntries(urlParams.entries()));\n  }\n\n  if (unmanagedAssignment) {\n    return <>{children}</>;\n  }\n\n  if (game && game.hasEnded) {\n    if (!player.get(\"ended\")) {\n      return <LoadingComp />;\n    }\n\n    return <Exit exitSteps={exitSteps} finished={finished} />;\n  }\n\n  return (\n    <Steps progressKey=\"intro\" doneKey=\"introDone\" steps={introSteps}>\n      <EmpiricaInnerContext\n        exitSteps={exitSteps}\n        lobby={lobby}\n        finished={finished}\n        loading={LoadingComp}\n        unmanagedGame={unmanagedGame}\n      >\n        {children}\n      </EmpiricaInnerContext>\n    </Steps>\n  );\n}\n\ninterface EmpiricaInnerContextProps {\n  children: React.ReactNode;\n  lobby: React.ElementType;\n  exitSteps: React.ElementType[] | StepsFunc;\n  finished: React.ElementType;\n  loading: React.ElementType;\n  unmanagedGame: boolean;\n}\n\nfunction EmpiricaInnerContext({\n  children,\n  lobby: Lobby,\n  finished,\n  exitSteps,\n  loading: LoadingComp,\n  unmanagedGame = false,\n}: EmpiricaInnerContextProps) {\n  const player = usePlayer();\n  const game = useGame();\n  const allReady = useAllReady();\n\n  if (!game) {\n    if (unmanagedGame) {\n      return <>{children}</>;\n    } else {\n      return <LoadingComp />;\n    }\n  }\n\n  if (!Boolean(game.get(\"status\"))) {\n    return <Lobby />;\n  }\n\n  if (game.hasEnded) {\n    if (!player?.get(\"ended\")) {\n      return <LoadingComp />;\n    }\n\n    return <Exit exitSteps={exitSteps} finished={finished} />;\n  }\n\n  if (unmanagedGame || allReady) {\n    return <>{children}</>;\n  }\n\n  return <LoadingComp />;\n}\n\nfunction Exit({\n  exitSteps,\n  finished: Finished,\n}: {\n  exitSteps: React.ElementType[] | StepsFunc;\n  finished: React.ElementType;\n}) {\n  const gameReady = useGameReady();\n\n  if (!gameReady) {\n    return <Loading />;\n  }\n\n  return (\n    <Steps progressKey=\"exitStep\" doneKey=\"exitStepDone\" steps={exitSteps}>\n      <Finished />\n    </Steps>\n  );\n}\n\nfunction useAllReady() {\n  const player = usePlayer();\n  const players = usePlayers();\n  const game = useGame();\n  const stage = useStage();\n  const round = useRound();\n\n  if (\n    !player ||\n    !players ||\n    !stage ||\n    !round ||\n    !game ||\n    !player.game ||\n    !player.round ||\n    !player.stage\n  ) {\n    return false;\n  }\n\n  const playerCount = game.get(\"actualPlayerCount\") as number | undefined;\n\n  if (playerCount !== undefined && players.length < playerCount) {\n    return false;\n  }\n\n  for (const p of players) {\n    if (!p.game || !p.round || !p.stage) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nfunction useGameReady() {\n  const player = usePlayer();\n  const players = usePlayers();\n  const game = useGame();\n\n  // Player was never even assigned to a game, so no game.\n  if (player && !player.get(\"gameID\")) {\n    return true;\n  }\n\n  // Game never started, so no player.game.\n  if (player && game && !game.get(\"start\")) {\n    return true;\n  }\n\n  if (!player || !players || !game || !player.game) {\n    return false;\n  }\n\n  const playerCount = game.get(\"actualPlayerCount\") as number | undefined;\n\n  if (playerCount !== undefined && players.length < playerCount) {\n    return false;\n  }\n\n  for (const p of players) {\n    if (!p.game) {\n      return false;\n    }\n  }\n\n  return true;\n}\n","import React from \"react\";\n\nexport interface ConsentProps {\n  title?: string;\n  text?: string;\n  buttonText?: string;\n  onConsent: () => void;\n}\n\nconst defaultTitle = \"Do you consent to participate in this experiment?\";\n\nconst defaultText = `This experiment is part of a scientific project. Your decision\nto participate in this experiment is entirely voluntary. There\nare no known or anticipated risks to participating in this\nexperiment. There is no way for us to identify you. The only\ninformation we will have, in addition to your responses, is\nthe timestamps of your interactions with our site. The results\nof our research may be presented at scientific meetings or\npublished in scientific journals. Clicking on the \"I AGREE\"\nbutton indicates that you are at least 18 years of age, and\nagree to participate voluntary.`;\n\nconst defaultButtonText = \"I AGREE\";\n\nexport function Consent({\n  title = defaultTitle,\n  text = defaultText,\n  buttonText = defaultButtonText,\n  onConsent,\n}: ConsentProps) {\n  return (\n    <div\n      className=\"relative h-full z-10 overflow-y-auto\"\n      aria-labelledby=\"modal-title\"\n      role=\"dialog\"\n      aria-modal=\"true\"\n    >\n      <div className=\"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0\">\n        <div\n          className=\"absolute inset-0 bg-gray-500 bg-opacity-75 transition-opacity\"\n          aria-hidden=\"true\"\n        ></div>\n\n        <span\n          className=\"hidden sm:inline-block sm:align-middle sm:h-screen\"\n          aria-hidden=\"true\"\n        >\n          &#8203;\n        </span>\n\n        <div className=\"inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6\">\n          <div>\n            <div className=\"mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100\">\n              <svg\n                className=\"h-6 w-6 text-green-600\"\n                xmlns=\"http://www.w3.org/2000/svg\"\n                fill=\"none\"\n                viewBox=\"0 0 24 24\"\n                stroke=\"currentColor\"\n                aria-hidden=\"true\"\n              >\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth=\"2\"\n                  d=\"M5 13l4 4L19 7\"\n                />\n              </svg>\n            </div>\n            <div className=\"mt-3 sm:mt-5\">\n              <h3\n                className=\"text-lg text-center leading-6 font-medium text-gray-900\"\n                id=\"modal-title\"\n              >\n                {title}\n              </h3>\n              <div className=\"mt-2\">\n                <div className=\"text-sm text-gray-500 text-justify\">{text}</div>\n              </div>\n            </div>\n          </div>\n          <div className=\"mt-5 sm:mt-6\">\n            <button\n              type=\"button\"\n              className=\"inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-empirica-600 text-base font-medium text-white hover:bg-empirica-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-empirica-500 sm:text-sm\"\n              onClick={onConsent}\n            >\n              {buttonText}\n            </button>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n","import React from \"react\";\n\nexport function Finished() {\n  return (\n    <div className=\"h-full flex flex-col items-center justify-center\">\n      <h2 className=\"font-medium text-gray-700\">Finished</h2>\n      <p className=\"mt-2 text-gray-400\">Thank you for participating</p>\n    </div>\n  );\n}\n","import React from \"react\";\n\nexport function Loading() {\n  // <!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->\n  return (\n    <div className=\"h-full w-full flex items-center justify-center\">\n      <svg\n        width=\"44\"\n        height=\"44\"\n        viewBox=\"0 0 44 44\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        className=\"text-empirica-200 stroke-current\"\n      >\n        <g fill=\"none\" fillRule=\"evenodd\" strokeWidth=\"2\">\n          <circle cx=\"22\" cy=\"22\" r=\"1\">\n            <animate\n              attributeName=\"r\"\n              begin=\"0s\"\n              dur=\"1.8s\"\n              values=\"1; 20\"\n              calcMode=\"spline\"\n              keyTimes=\"0; 1\"\n              keySplines=\"0.165, 0.84, 0.44, 1\"\n              repeatCount=\"indefinite\"\n            />\n            <animate\n              attributeName=\"stroke-opacity\"\n              begin=\"0s\"\n              dur=\"1.8s\"\n              values=\"1; 0\"\n              calcMode=\"spline\"\n              keyTimes=\"0; 1\"\n              keySplines=\"0.3, 0.61, 0.355, 1\"\n              repeatCount=\"indefinite\"\n            />\n          </circle>\n          <circle cx=\"22\" cy=\"22\" r=\"1\">\n            <animate\n              attributeName=\"r\"\n              begin=\"-0.9s\"\n              dur=\"1.8s\"\n              values=\"1; 20\"\n              calcMode=\"spline\"\n              keyTimes=\"0; 1\"\n              keySplines=\"0.165, 0.84, 0.44, 1\"\n              repeatCount=\"indefinite\"\n            />\n            <animate\n              attributeName=\"stroke-opacity\"\n              begin=\"-0.9s\"\n              dur=\"1.8s\"\n              values=\"1; 0\"\n              calcMode=\"spline\"\n              keyTimes=\"0; 1\"\n              keySplines=\"0.3, 0.61, 0.355, 1\"\n              repeatCount=\"indefinite\"\n            />\n          </circle>\n        </g>\n      </svg>\n    </div>\n  );\n}\n","import React from \"react\";\nimport { isDevelopment } from \"../utils\";\n\nexport function NoGames() {\n  return (\n    <div className=\"h-screen flex items-center justify-center\">\n      <div className=\"w-92 flex flex-col items-center\">\n        <h2 className=\"text-gray-700 font-medium\">No experiments available</h2>\n        <p className=\"mt-2 text-gray-400 text-justify\">\n          There are currently no available experiments. Please wait until an\n          experiment becomes available or come back at a later date.\n        </p>\n        {isDevelopment ? (\n          <p className=\"mt-4 text-gray-700\">\n            Go to{\" \"}\n            <a\n              href=\"/admin\"\n              target=\"empirica-admin\"\n              className=\"text-empirica-500\"\n            >\n              Admin\n            </a>{\" \"}\n            to get started\n          </p>\n        ) : (\n          \"\"\n        )}\n      </div>\n    </div>\n  );\n}\n","export const isDevelopment = process.env.NODE_ENV === \"development\";\nexport const isProduction = process.env.NODE_ENV === \"production\";\nexport const isTest = process.env.NODE_ENV === \"test\";\n\nexport const createNewParticipant = (key = \"participantKey\") => {\n  const url = new URL(document.location.href);\n  url.searchParams.set(key, new Date().getTime().toString());\n  window.open(url.href, \"_blank\")?.focus();\n};\n","import React, { FormEvent, useState } from \"react\";\n\nexport interface PlayerCreateProps {\n  onPlayerID: (playerID: string) => void;\n  connecting: boolean;\n}\n\nexport function PlayerCreate({ onPlayerID, connecting }: PlayerCreateProps) {\n  const [playerID, setPlayerID] = useState(\"\");\n\n  const handleSubmit = (evt: FormEvent) => {\n    evt.preventDefault();\n    if (!playerID || playerID.trim() === \"\") {\n      return;\n    }\n\n    onPlayerID(playerID);\n  };\n\n  return (\n    <div className=\"min-h-screen bg-empirica-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8\">\n      <div className=\"sm:mx-auto sm:w-full sm:max-w-md\">\n        <h2 className=\"mt-6 text-center text-3xl font-extrabold text-gray-900\">\n          Enter your Player Identifier\n        </h2>\n      </div>\n\n      <div className=\"mt-8 sm:mx-auto sm:w-full sm:max-w-md\">\n        <div className=\"bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10\">\n          <form\n            className=\"space-y-6\"\n            action=\"#\"\n            method=\"POST\"\n            onSubmit={handleSubmit}\n          >\n            <fieldset disabled={connecting}>\n              <div>\n                <label\n                  htmlFor=\"email\"\n                  className=\"block text-sm font-medium text-gray-700\"\n                >\n                  Identifier\n                </label>\n                <div className=\"mt-1\">\n                  <input\n                    id=\"playerID\"\n                    name=\"playerID\"\n                    type=\"text\"\n                    autoComplete=\"off\"\n                    required\n                    autoFocus\n                    className=\"appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-empirica-500 focus:border-empirica-500 sm:text-sm\"\n                    value={playerID}\n                    onChange={(e) => setPlayerID(e.target.value)}\n                  />\n                  <p\n                    className=\"mt-2 text-sm text-gray-500\"\n                    id=\"playerID-description\"\n                  >\n                    This should be given to you. E.g. email, code...\n                  </p>\n                </div>\n              </div>\n\n              <div>\n                <button\n                  type=\"submit\"\n                  className=\"w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-empirica-600 hover:bg-empirica-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-empirica-500\"\n                >\n                  Enter\n                </button>\n              </div>\n            </fieldset>\n          </form>\n        </div>\n      </div>\n    </div>\n  );\n}\n","import { useContext, useEffect, useState } from \"react\";\nimport { Observable, merge } from \"rxjs\";\nimport { Globals } from \"../../shared/globals\";\nimport { TajribaConnection } from \"../../shared/tajriba_connection\";\nimport { Session } from \"../connection\";\nimport { ParticipantContext } from \"../context\";\nimport { ParticipantCtx } from \"./EmpiricaParticipant\";\n\nexport function useParticipantContext() {\n  return useContext(ParticipantCtx);\n}\n\nexport function useTajribaConnecting() {\n  return useTajribaCtxKey<boolean, \"connecting\">(\"connecting\");\n}\n\nexport function useTajribaConnected() {\n  return useTajribaCtxKey<boolean, \"connected\">(\"connected\");\n}\n\nexport function usePartConnecting() {\n  return usePartCtxKey<boolean, \"connecting\">(\"connecting\");\n}\n\nexport function usePartConnected() {\n  return usePartCtxKey<boolean, \"connected\">(\"connected\");\n}\n\nexport function useTajriba() {\n  const ctx = useParticipantContext();\n  return ctx?.tajriba;\n}\n\nexport function useGlobal() {\n  const ctx = usePartCtxKey<Globals, \"globals\">(\"globals\");\n  const [val, setVal] = useState<{ g: Globals | undefined }>({ g: undefined });\n\n  useEffect(() => {\n    if (!ctx || !ctx.self) {\n      return;\n    }\n\n    const sub = ctx.self.subscribe({\n      next(g) {\n        setVal({ g });\n      },\n    });\n\n    return sub.unsubscribe.bind(sub);\n  }, [ctx]);\n\n  return val.g;\n}\n\nconst defaultConsentKey = \"empirica:consent\";\n\nexport function useConsent(\n  ns: string = \"\"\n): [boolean, (() => void) | undefined] {\n  const key = `${defaultConsentKey}${ns ? `:${ns}` : \"\"}`;\n  const getConsented = () => Boolean(window.localStorage[key]);\n  const [consented, setConsented] = useState(getConsented());\n\n  function onConsent() {\n    window.localStorage[key] = true;\n    setConsented(true);\n  }\n\n  return [consented, consented ? undefined : onConsent];\n}\n\nexport function usePlayerID(): [\n  boolean,\n  string | undefined,\n  ((v: string) => void) | undefined\n] {\n  const ctx = useParticipantContext();\n  const [connecting, setConnecting] = useState<boolean>(true);\n  const [playerID, setPlayerID] = useState<string | undefined>(undefined);\n  const [changePlayerID, setChangePlayerID] = useState<\n    ((v: string) => void) | undefined\n  >(undefined);\n\n  useEffect(() => {\n    if (!ctx) {\n      return;\n    }\n\n    let _connecting = true;\n    let session: Session | undefined;\n    const sub = merge(\n      ctx.participant.connecting,\n      ctx.session.sessions\n    ).subscribe({\n      next(sessionOrConnecting) {\n        if (typeof sessionOrConnecting === \"boolean\") {\n          setConnecting(sessionOrConnecting);\n          _connecting = sessionOrConnecting;\n        } else {\n          session = sessionOrConnecting;\n        }\n\n        if (_connecting) {\n          setPlayerID(undefined);\n          setChangePlayerID(undefined);\n        } else if (!session) {\n          setPlayerID(undefined);\n          setChangePlayerID(() => async (playerIdentifier: string) => {\n            await ctx.register(playerIdentifier);\n          });\n        } else {\n          setPlayerID(session.participant.identifier);\n          setChangePlayerID(undefined);\n        }\n      },\n    });\n\n    return sub.unsubscribe.bind(sub);\n  }, [ctx]);\n\n  return [connecting, playerID, changePlayerID];\n}\n\nfunction useTajribaCtxKey<T, K extends keyof TajribaConnection>(name: K) {\n  return useCtxKey<T, TajribaConnection, K>(useTajriba, name);\n}\n\nfunction usePartCtxKey<T, K extends keyof ParticipantContext>(name: K) {\n  return useCtxKey<T, ParticipantContext, K>(useParticipantContext, name);\n}\n\nfunction useCtxKey<T, O extends {}, K extends keyof O>(\n  ctxFunc: () => O | undefined,\n  name: K\n) {\n  const ctx = ctxFunc();\n  const [val, setVal] = useState<T | undefined>(undefined);\n\n  useEffect(() => {\n    if (!ctx || !ctx[name]) {\n      return;\n    }\n\n    const obs = (<unknown>ctx[name]) as Observable<T>;\n\n    const sub = obs.subscribe({\n      next(g) {\n        setVal(g);\n      },\n    });\n\n    return sub.unsubscribe.bind(sub);\n  }, [ctx]);\n\n  return val;\n}\n","import React from \"react\";\nimport { Mode, ParticipantContext, ParticipantModeContext } from \"../context\";\nimport { WithChildren } from \"./helpers\";\n\nexport const ParticipantCtx = React.createContext<\n  ParticipantContext | undefined\n>(undefined);\n\nexport type EmpiricaParticipantProps = WithChildren<{\n  url: string;\n  ns: string;\n  modeFunc?: Mode<any>;\n}>;\n\n// We want to only initialize the connection once per namespace, so we keep\n// previously created connections.\n// TODO: cleanup old connections.\n// It's ok to just keep the previous connection for simple cases where we're\n// only using one connection, but if EmpiricaParticipant is used multiple times\n// on a page, and some are reset, we would be leaking connections.\nconst contexts: { [key: string]: ParticipantContext } = {};\n\nexport function EmpiricaParticipant({\n  url,\n  ns,\n  modeFunc,\n  children,\n}: EmpiricaParticipantProps) {\n  let partCtx: ParticipantContext;\n\n  if (ns in contexts) {\n    partCtx = contexts[ns]!;\n  } else {\n    if (modeFunc) {\n      partCtx = new ParticipantModeContext(url, ns, modeFunc);\n    } else {\n      partCtx = new ParticipantContext(url, ns);\n    }\n\n    contexts[ns] = partCtx;\n  }\n\n  return (\n    <ParticipantCtx.Provider value={partCtx}>\n      {children}\n    </ParticipantCtx.Provider>\n  );\n}\n","import { TajribaParticipant } from \"@empirica/tajriba\";\nimport { BehaviorSubject, Subject } from \"rxjs\";\nimport { subscribeAsync } from \"../admin/observables\";\nimport { Globals } from \"../shared/globals\";\nimport {\n  ErrNotConnected,\n  TajribaConnection,\n} from \"../shared/tajriba_connection\";\nimport { warn } from \"../utils/console\";\nimport { bsu } from \"../utils/object\";\nimport { ParticipantConnection, ParticipantSession } from \"./connection\";\nimport { TajribaProvider } from \"./provider\";\n\nexport class ParticipantContext {\n  /** @internal */\n  readonly tajriba: TajribaConnection;\n  /** @internal */\n  readonly participant: ParticipantConnection;\n  /** @internal */\n  readonly session: ParticipantSession;\n  /** @internal */\n  readonly resetSession: Subject<void>;\n  /** @internal */\n  readonly provider = bsu<TajribaProvider>();\n  /** @internal */\n  readonly globals = bsu<Globals>();\n\n  constructor(url: string, ns: string) {\n    this.tajriba = new TajribaConnection(url);\n    this.resetSession = new Subject<void>();\n    this.session = new ParticipantSession(ns, this.resetSession);\n    this.participant = new ParticipantConnection(\n      this.tajriba,\n      this.session.sessions,\n      this.resetSession.next.bind(this.resetSession)\n    );\n\n    subscribeAsync(this.participant.connected, async (connected) => {\n      const part = this.participant.participant.getValue();\n\n      if (connected && part) {\n        if (!this.provider.getValue()) {\n          this.provider.next(\n            new TajribaProvider(\n              part.changes(),\n              this.tajriba.tajriba.globalAttributes(),\n              part.setAttributes.bind(part)\n            )\n          );\n        }\n      } else {\n        const provider = this.provider.getValue();\n        if (provider) {\n          this.provider.next(undefined);\n        }\n      }\n    });\n\n    subscribeAsync(this.tajriba.connected, async (connected) => {\n      if (connected) {\n        this.globals.next(new Globals(this.tajriba.tajriba.globalAttributes()));\n      } else {\n        const glob = this.globals.getValue();\n        if (glob) {\n          this.globals.next(undefined);\n        }\n      }\n    });\n  }\n\n  get connecting() {\n    return this.participant.connecting;\n  }\n\n  get connected() {\n    return this.participant.connected;\n  }\n\n  async register(playerIdentifier: string) {\n    if (!this.tajriba.connected.getValue()) {\n      throw ErrNotConnected;\n    }\n\n    const [token, participant] = await this.tajriba.tajriba.registerParticipant(\n      playerIdentifier\n    );\n\n    if (!token) {\n      throw new Error(\"invalid registration\");\n    }\n\n    this.session.updateSession(token, participant);\n  }\n\n  stop() {\n    this.tajriba.stop();\n    this.participant.stop();\n  }\n}\n\nexport type Mode<T> = (participantID: string, provider: TajribaProvider) => T;\n\nexport class ParticipantMode<T> {\n  private _mode = new BehaviorSubject<T | undefined>(undefined);\n\n  constructor(\n    participant: BehaviorSubject<TajribaParticipant | undefined>,\n    provider: BehaviorSubject<TajribaProvider | undefined>,\n    modeFunc: Mode<T>\n  ) {\n    subscribeAsync(provider, async (provider) => {\n      const id = participant.getValue()?.id;\n\n      // TODO Fix! Hack. If we detect this condition, reload\n      // We are getting a new provider while we already had one. Presumably\n      // the player is gone (tajriba reset), but we're still getting a\n      // provider, while we shouldn't.\n      if (id && provider && this._mode.getValue()) {\n        warn(\"spurious provider condition\");\n        window.location.reload();\n      }\n\n      if (id && provider) {\n        this._mode.next(modeFunc(id, provider));\n      } else {\n        const mode = this._mode.getValue();\n        if (mode) {\n          this._mode.next(undefined);\n        }\n      }\n    });\n  }\n\n  get mode() {\n    return this._mode;\n  }\n}\n\nexport class ParticipantModeContext<T> extends ParticipantContext {\n  private _mode: ParticipantMode<T>;\n\n  constructor(url: string, ns: string, modeFunc: Mode<T>) {\n    super(url, ns);\n    this._mode = new ParticipantMode<T>(\n      this.participant.participant,\n      this.provider,\n      modeFunc\n    );\n  }\n\n  get mode() {\n    return this._mode.mode;\n  }\n}\n","import { E_CANCELED, Mutex } from \"async-mutex\";\nimport { Observable, Subject, concatMap, takeUntil } from \"rxjs\";\nimport { warn } from \"../utils/console\";\n\nexport async function awaitObsValue<T>(\n  obs: Observable<T>,\n  value: T\n): Promise<T> {\n  let res: (value: T) => void;\n  const prom = new Promise<T>((r) => {\n    res = r;\n  });\n\n  const unsub = obs.subscribe((val) => {\n    if (val === value) {\n      res(val);\n    }\n  });\n\n  const val = await prom;\n  unsub.unsubscribe();\n\n  return val;\n}\n\nexport async function awaitObsValueExist<T>(obs: Observable<T>): Promise<T> {\n  let res: (value: T) => void;\n  const prom = new Promise<T>((r) => {\n    res = r;\n  });\n\n  const unsub = obs.subscribe((val) => {\n    if (val) {\n      res(val);\n    }\n  });\n\n  const val = await prom;\n  unsub.unsubscribe();\n\n  return val;\n}\n\nexport async function awaitObsValueChange<T>(obs: Observable<T>): Promise<T> {\n  let res: (value: T) => void;\n  const prom = new Promise<T>((r) => {\n    res = r;\n  });\n\n  let once = false;\n  let v: T;\n  const unsub = obs.subscribe((val) => {\n    if (once && val !== v) {\n      res(val);\n    }\n    once = true;\n    v = val;\n  });\n\n  const val = await prom;\n  unsub.unsubscribe();\n\n  return val;\n}\n\n// Subscribe to an observable and use the lock for sequential execution of async\n// functions.\nexport function lockedAsyncSubscribe<T>(\n  mutex: Mutex,\n  obs: Observable<T>,\n  fn: (val: T) => Promise<any>\n) {\n  return obs.subscribe({\n    next: async (val) => {\n      try {\n        const release = await mutex.acquire();\n        try {\n          await fn(val);\n        } catch (err) {\n          console.error(\"error in async observable subscription\");\n          console.error(err);\n        } finally {\n          release();\n        }\n      } catch (err) {\n        if (err !== E_CANCELED) {\n          console.error(\n            \"error acquiring lock in async observable subscription\"\n          );\n          console.error(err);\n        }\n      }\n    },\n  });\n}\n\n// This does not behave correctly with a ReplaySubject\nexport function subscribeAsync<T>(\n  obs: Observable<T>,\n  fn: (val: T) => Promise<any>\n) {\n  const cancel = new Subject<void>();\n  obs.pipe(concatMap(fn), takeUntil(cancel)).subscribe();\n  return {\n    closed: false,\n    unsubscribe() {\n      if (this.closed) {\n        warn(\"closing a closed async observable subscription\");\n        return;\n      }\n      this.closed = true;\n      cancel.next();\n      cancel.unsubscribe();\n    },\n  };\n}\n\nexport interface AsyncObserver<T> {\n  next: (value: T) => void;\n  error: (err: any) => void;\n  complete: () => void;\n}\n\nexport interface Unsubscribable {\n  unsubscribe(): void;\n}\n\nexport interface AsyncSubscribable<T> {\n  subscribe(observer: Partial<AsyncObserver<T>>): Promise<Unsubscribable>;\n}\n\n// A ReplaySubject that supports async subscribers\nexport class AsyncReplaySubject<T> {\n  private values: T[] = [];\n  private subscribers: ((val: T) => Promise<void>)[] = [];\n\n  async next(value: T) {\n    this.values.push(value);\n    for (const sub of this.subscribers) {\n      await sub(value);\n    }\n  }\n\n  async subscribe({ next }: { next: (val: T) => Promise<void> }) {\n    this.subscribers.push(next);\n    for (const v of this.values) {\n      await next(v);\n    }\n\n    let closed = false;\n    return {\n      get closed() {\n        return closed;\n      },\n      unsubscribe: () => {\n        if (closed) {\n          warn(\"closing a closed async observable subscription\");\n          return;\n        }\n\n        closed = true;\n        this.subscribers = this.subscribers.filter((s) => s !== next);\n      },\n    };\n  }\n}\n\n// A Subject that supports async subscribers\nexport class AsyncSubject<T> {\n  private subscribers: ((val: T) => Promise<void>)[] = [];\n\n  constructor(private value: T) {}\n\n  async next(value: T) {\n    for (const sub of this.subscribers) {\n      await sub(value);\n    }\n  }\n\n  async subscribe({ next }: { next: (val: T) => Promise<void> }) {\n    this.subscribers.push(next);\n    await next(this.value);\n\n    let closed = false;\n    return {\n      get closed() {\n        return closed;\n      },\n      unsubscribe: () => {\n        if (closed) {\n          warn(\"closing a closed async observable subscription\");\n          return;\n        }\n\n        closed = true;\n        this.subscribers = this.subscribers.filter((s) => s !== next);\n      },\n    };\n  }\n}\n","import { ParticipantIdent, Tajriba } from \"@empirica/tajriba\";\nimport { BehaviorSubject } from \"rxjs\";\nimport { error } from \"../utils/console\";\nimport { bs } from \"../utils/object\";\n\nexport const ErrNotConnected = new Error(\"not connected\");\n\nexport class TajribaConnection {\n  readonly tajriba: Tajriba;\n  private _connected = bs(false);\n  private _connecting: BehaviorSubject<boolean> = bs(true);\n  private _stopped = bs(false);\n\n  constructor(private url: string) {\n    this.tajriba = Tajriba.connect(this.url);\n    this._connected.next(this.tajriba.connected);\n\n    this.tajriba.on(\"connected\", () => {\n      this._connected.next(true);\n      this._connecting.next(false);\n    });\n\n    this.tajriba.on(\"disconnected\", () => {\n      if (this._connected.getValue()) {\n        this._connected.next(false);\n      }\n      if (!this._connecting.getValue()) {\n        this._connecting.next(true);\n      }\n    });\n\n    this.tajriba.on(\"error\", (err) => {\n      error(\"connection error\", err);\n    });\n  }\n\n  get connecting() {\n    return this._connecting;\n  }\n\n  get connected() {\n    return this._connected;\n  }\n\n  get stopped() {\n    return this._stopped;\n  }\n\n  async sessionParticipant(token: string, pident: ParticipantIdent) {\n    if (!this._connected.getValue()) {\n      throw ErrNotConnected;\n    }\n\n    return await this.tajriba.sessionParticipant(token, pident);\n  }\n\n  async sessionAdmin(token: string) {\n    if (!this._connected.getValue()) {\n      throw ErrNotConnected;\n    }\n\n    return await this.tajriba.sessionAdmin(token);\n  }\n\n  stop() {\n    if (this._stopped.getValue()) {\n      return;\n    }\n\n    if (this.tajriba) {\n      this.tajriba.removeAllListeners(\"connected\");\n      this.tajriba.removeAllListeners(\"disconnected\");\n      this.tajriba.stop();\n    }\n\n    this._connecting.next(false);\n    this._connected.next(false);\n    this._stopped.next(true);\n  }\n}\n","/* c8 ignore start */\n\nimport { BehaviorSubject } from \"rxjs\";\n\nexport function bs<T>(init: T) {\n  return new BehaviorSubject<T>(init);\n}\n\nexport function bsu<T>(init: T | undefined = undefined) {\n  return new BehaviorSubject<T | undefined>(init);\n}\n\nexport function deepEqual(obj1: any, obj2: any) {\n  if (obj1 === obj2)\n    // it's just the same object. No need to compare.\n    return true;\n\n  if (isPrimitive(obj1) && isPrimitive(obj2))\n    // compare primitives\n    return obj1 === obj2;\n\n  if (Object.keys(obj1).length !== Object.keys(obj2).length) return false;\n\n  // compare objects with same number of keys\n  for (let key in obj1) {\n    if (!(key in obj2)) return false; //other object doesn't have this prop\n    if (!deepEqual(obj1[key], obj2[key])) return false;\n  }\n\n  return true;\n}\n\n//check if value is primitive\nfunction isPrimitive(obj: any) {\n  return obj !== Object(obj);\n}\n","import { ParticipantIdent, TajribaParticipant } from \"@empirica/tajriba\";\nimport { BehaviorSubject, merge, Observable, SubscriptionLike } from \"rxjs\";\nimport { subscribeAsync } from \"../admin/observables\";\nimport {\n  ErrNotConnected,\n  TajribaConnection,\n} from \"../shared/tajriba_connection\";\nimport { error } from \"../utils/console\";\nimport { bs, bsu } from \"../utils/object\";\n\nexport class ParticipantConnection {\n  private _tajribaPart = bsu<TajribaParticipant>();\n  private _connected = bs(false);\n  private _connecting = bs(false);\n  private _stopped = bs(false);\n  private _sessionsSub: SubscriptionLike;\n\n  constructor(\n    taj: TajribaConnection,\n    sessions: BehaviorSubject<Session | undefined>,\n    private resetSession: () => void\n  ) {\n    let session: Session | undefined;\n    let connected = false;\n    this._sessionsSub = subscribeAsync(\n      merge(taj.connected, sessions),\n      async (sessionOrConnected) => {\n        if (typeof sessionOrConnected === \"boolean\") {\n          connected = sessionOrConnected;\n        } else {\n          session = sessionOrConnected;\n        }\n\n        if (!session || !connected) {\n          return;\n        }\n\n        if (this._connected.getValue() || this._connecting.getValue()) {\n          return;\n        }\n\n        this._connecting.next(true);\n\n        try {\n          const tajPart = await taj.sessionParticipant(\n            session.token,\n            session.participant\n          );\n\n          this._tajribaPart.next(tajPart);\n          if (tajPart.connected) {\n            this._connected.next(true);\n            this._connecting.next(false);\n          }\n\n          tajPart.on(\"connected\", () => {\n            if (!this._connected.getValue()) {\n              this._connected.next(true);\n              this._connecting.next(false);\n            }\n          });\n          tajPart.on(\"disconnected\", () => {\n            if (this._connected.getValue()) {\n              this._connected.next(false);\n            }\n            if (this._connecting.getValue()) {\n              this._connecting.next(false);\n            }\n          });\n          tajPart.on(\"error\", (err) => {\n            error(\"connection error\", err);\n          });\n          tajPart.on(\"accessDenied\", () => {\n            if (this._connected.getValue()) {\n              this._connected.next(false);\n            }\n            if (this._connecting.getValue()) {\n              this._connecting.next(false);\n            }\n            console.log(\n              \"accessDenied\",\n              session?.participant.id,\n              session?.token\n            );\n            this.resetSession();\n          });\n        } catch (err) {\n          if (err !== ErrNotConnected) {\n            error(\"new conn error\", err);\n            this.resetSession();\n          }\n        }\n      }\n    );\n  }\n\n  stop() {\n    if (this._stopped.getValue()) {\n      return;\n    }\n\n    const taj = this._tajribaPart.getValue();\n    if (taj) {\n      taj.removeAllListeners(\"connected\");\n      taj.removeAllListeners(\"disconnected\");\n      taj.stop();\n      this._tajribaPart.next(undefined);\n    }\n\n    this._sessionsSub.unsubscribe();\n\n    this._connecting.next(false);\n    this._connected.next(false);\n    this._stopped.next(true);\n  }\n\n  get connecting() {\n    return this._connecting;\n  }\n\n  get connected() {\n    return this._connected;\n  }\n\n  get stopped() {\n    return this._stopped;\n  }\n\n  get participant() {\n    return this._tajribaPart;\n  }\n}\n\nexport interface Session {\n  token: string;\n  participant: ParticipantIdent;\n}\n\ninterface Storage {\n  clear(): void;\n  getItem(key: string): string | null;\n  removeItem(key: string): void;\n  setItem(key: string, value: string): void;\n}\n\nexport class MemStorage {\n  static vals: { [key: string]: any } = {};\n  static clear(): void {\n    this.vals = {};\n  }\n  static getItem(key: string): string | null {\n    return this.vals[key];\n  }\n  static removeItem(key: string): void {\n    delete this.vals[key];\n  }\n  static setItem(key: string, value: string): void {\n    this.vals[key] = value;\n  }\n}\n\nconst isBrowser =\n  typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n\nlet storage: Storage;\nif (isBrowser) {\n  storage = window.localStorage;\n}\n\nexport class ParticipantSession {\n  static tokenKey = \"empirica:token\";\n  static partKey = \"empirica:participant\";\n  static storage: Storage = storage;\n\n  private _sessions: BehaviorSubject<Session | undefined>;\n  private _token?: string;\n  protected _participant?: ParticipantIdent;\n\n  constructor(private ns: string, resetSession: Observable<void>) {\n    this._token = this.strg.getItem(this.tokenKey) || undefined;\n\n    const participantStr = this.strg.getItem(this.partKey) || undefined;\n\n    if (participantStr) {\n      this._participant = JSON.parse(participantStr);\n    }\n\n    const sess = this.calcSession();\n    this._sessions = bsu<Session>(sess);\n\n    resetSession.subscribe({\n      next: () => {\n        this.clearSession();\n      },\n    });\n  }\n\n  get sessions() {\n    return this._sessions;\n  }\n\n  get session() {\n    return this._sessions.getValue();\n  }\n\n  get token() {\n    return this._token;\n  }\n\n  get participant() {\n    return this._participant;\n  }\n\n  get tokenKey() {\n    return `${ParticipantSession.tokenKey}:${this.ns}`;\n  }\n\n  get partKey() {\n    return `${ParticipantSession.partKey}:${this.ns}`;\n  }\n\n  updateSession(token: string, participant: ParticipantIdent) {\n    this.strg.setItem(this.tokenKey, token);\n    this.strg.setItem(this.partKey, JSON.stringify(participant));\n    this._token = token;\n    this._participant = participant;\n    this._sessions.next(this.calcSession());\n  }\n\n  clearSession() {\n    delete this._token;\n    delete this._participant;\n    this.strg.removeItem(this.tokenKey);\n    this.strg.removeItem(this.partKey);\n    this._sessions.next(undefined);\n  }\n\n  private calcSession(): Session | undefined {\n    if (this._token && this._participant) {\n      return {\n        token: this._token,\n        participant: this._participant,\n      };\n    }\n\n    return undefined;\n  }\n\n  private get strg() {\n    return ParticipantSession.storage;\n  }\n}\n","import {\n  ChangePayload,\n  ParticipantChange,\n  SetAttributeInput,\n  SubAttributesPayload,\n} from \"@empirica/tajriba\";\nimport { Observable, Subject, groupBy } from \"rxjs\";\nimport { AttributeChange, AttributeUpdate } from \"../shared/attributes\";\nimport { ScopeIdent, ScopeUpdate } from \"../shared/scopes\";\nimport { trace } from \"../utils/console\";\nimport { StepChange, StepUpdate } from \"./steps\";\n\nexport interface ParticipantUpdate {\n  participant: ParticipantChange;\n  removed: boolean;\n}\n\nexport class TajribaProvider {\n  public scopes = new Subject<ScopeUpdate>();\n  public attributes = new Subject<AttributeUpdate>();\n  public participants = new Subject<ParticipantUpdate>();\n  public steps = new Subject<StepUpdate>();\n  public dones = new Subject<string[]>();\n\n  constructor(\n    changes: Observable<ChangePayload>,\n    readonly globals: Observable<SubAttributesPayload>,\n    readonly setAttributes: (input: SetAttributeInput[]) => Promise<any>\n  ) {\n    let scopeIDs: string[] = [];\n    changes.pipe(groupBy((chg) => chg?.change?.__typename)).subscribe({\n      next: (group) => {\n        switch (group.key) {\n          case \"ScopeChange\":\n            group.subscribe({\n              next: (msg) => {\n                if (\n                  !msg.change ||\n                  msg.removed === null ||\n                  msg.removed === undefined\n                ) {\n                  trace(\"AttributeChange empty\");\n                } else {\n                  this.scopes.next({\n                    scope: <ScopeIdent>msg.change,\n                    removed: msg.removed,\n                  });\n                }\n\n                if (msg.done) {\n                  this.dones.next(scopeIDs);\n                }\n              },\n            });\n\n            break;\n          case \"AttributeChange\":\n            group.subscribe({\n              next: (msg) => {\n                if (\n                  !msg.change ||\n                  msg.removed === null ||\n                  msg.removed === undefined\n                ) {\n                  trace(\"AttributeChange empty\");\n                } else {\n                  const atChange = <AttributeChange>msg.change;\n                  scopeIDs.push(atChange.nodeID || atChange.node!.id);\n                  this.attributes.next({\n                    attribute: atChange,\n                    removed: msg.removed,\n                  });\n                }\n\n                if (msg.done) {\n                  this.dones.next(scopeIDs);\n                  scopeIDs = [];\n                }\n              },\n            });\n\n            break;\n          case \"ParticipantChange\":\n            group.subscribe({\n              next: (msg) => {\n                if (\n                  !msg.change ||\n                  msg.removed === null ||\n                  msg.removed === undefined\n                ) {\n                  trace(\"ParticipantChange empty\");\n                } else {\n                  this.participants.next({\n                    participant: <ParticipantChange>msg.change,\n                    removed: msg.removed,\n                  });\n                }\n\n                if (msg.done) {\n                  this.dones.next([]);\n                }\n              },\n            });\n\n            break;\n          case \"StepChange\":\n            group.subscribe({\n              next: (msg) => {\n                if (\n                  !msg.change ||\n                  msg.removed === null ||\n                  msg.removed === undefined\n                ) {\n                  trace(\"StepChange empty\");\n                } else {\n                  this.steps.next({\n                    step: <StepChange>msg.change,\n                    removed: msg.removed,\n                  });\n                }\n\n                if (msg.done) {\n                  this.dones.next([]);\n                }\n              },\n            });\n\n            break;\n          default:\n            group.subscribe({\n              next: (change) => {\n                if (change.done) {\n                  this.dones.next([]);\n                }\n              },\n            });\n\n            break;\n        }\n      },\n    });\n  }\n}\n","import React from \"react\";\nimport { warn } from \"../../../utils/console\";\nimport { Loading } from \"../../react/Loading\";\nimport { usePlayer } from \"./hooks\";\n\nexport function Lobby() {\n  const player = usePlayer();\n\n  if (!player) {\n    return <Loading />;\n  }\n\n  const treatment = player.get(\"treatment\") as { playerCount: number };\n\n  if (!treatment || !treatment.playerCount) {\n    warn(\"lobby: no treatment found on player\");\n\n    return <Loading />;\n  }\n\n  return (\n    <div className=\"flex h-full items-center justify-center\">\n      <div className=\"text-center\">\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox=\"0 0 640 512\"\n          className=\"mx-auto h-12 w-12 text-gray-400\"\n          stroke=\"none\"\n          fill=\"currentColor\"\n          aria-hidden=\"true\"\n        >\n          <path d=\"M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-128c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM320 256c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-192c44.1 0 80 35.9 80 80s-35.9 80-80 80-80-35.9-80-80 35.9-80 80-80zm244 192h-40c-15.2 0-29.3 4.8-41.1 12.9 9.4 6.4 17.9 13.9 25.4 22.4 4.9-2.1 10.2-3.3 15.7-3.3h40c24.2 0 44 21.5 44 48 0 8.8 7.2 16 16 16s16-7.2 16-16c0-44.1-34.1-80-76-80zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-128c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zm304.1 180c-33.4 0-41.7 12-80.1 12-38.4 0-46.7-12-80.1-12-36.3 0-71.6 16.2-92.3 46.9-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM480 432c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16v-44.8c0-16.6 4.9-32.7 14.1-46.4 13.8-20.5 38.4-32.8 65.7-32.8 27.4 0 37.2 12 80.2 12s52.8-12 80.1-12c27.3 0 51.9 12.3 65.7 32.8 9.2 13.7 14.1 29.8 14.1 46.4V432zM157.1 268.9c-11.9-8.1-26-12.9-41.1-12.9H76c-41.9 0-76 35.9-76 80 0 8.8 7.2 16 16 16s16-7.2 16-16c0-26.5 19.8-48 44-48h40c5.5 0 10.8 1.2 15.7 3.3 7.5-8.5 16.1-16 25.4-22.4z\" />\n        </svg>\n        <h3 className=\"mt-2 text-sm font-medium text-gray-900\">\n          {treatment.playerCount > 1\n            ? \"Waiting for other players\"\n            : \"Game loading\"}\n        </h3>\n        <p className=\"mt-1 text-sm text-gray-500\">\n          Please wait for the game to be ready.\n        </p>\n      </div>\n    </div>\n  );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { BehaviorSubject, Observable, Subscription } from \"rxjs\";\nimport { ParticipantModeContext } from \"../../context\";\nimport { useParticipantContext } from \"../../react/hooks\";\nimport type { StepTick } from \"../../steps\";\nimport { EmpiricaClassicContext, Game, Player, Round, Stage } from \"../classic\";\n\nexport function usePlayer() {\n  return usePartModeCtxKey<EmpiricaClassicContext, \"player\", Player | null>(\n    \"player\"\n  );\n}\n\nexport function useGame() {\n  return usePartModeCtxKey<EmpiricaClassicContext, \"game\", Game | null>(\"game\");\n}\n\nexport function useRound() {\n  return usePartModeCtxKey<EmpiricaClassicContext, \"round\", Round | null>(\n    \"round\"\n  );\n}\n\nexport function useStage() {\n  return usePartModeCtxKey<EmpiricaClassicContext, \"stage\", Stage | null>(\n    \"stage\"\n  );\n}\n\nexport function useStageTimer() {\n  const stage = useStage();\n\n  const [val, setVal] = useState<{ tick: StepTick | undefined }>({\n    tick: stage?.timer?.current,\n  });\n\n  const timerSubscription = useRef<Subscription | null>(null);\n\n  useEffect(() => {\n    if (!stage || !stage.timer) {\n      return;\n    }\n\n    if (timerSubscription.current === null) {\n      timerSubscription.current = stage.timer.obs().subscribe({\n        next(val) {\n          setVal({ tick: val });\n        },\n      });\n    }\n\n    return () => {\n      timerSubscription?.current?.unsubscribe.bind(timerSubscription.current);\n      timerSubscription.current = null;\n    };\n  }, [stage?.timer]);\n\n  return val.tick;\n}\n\nexport function usePlayers() {\n  return usePartModeCtxKey<EmpiricaClassicContext, \"players\", Player[]>(\n    \"players\"\n  );\n}\n\nexport function usePartModeCtx<M>() {\n  const ctx = useParticipantContext() as ParticipantModeContext<M>;\n  const [mode, setMode] = useState<{ data: M | undefined }>({\n    data: ctx?.mode?.getValue(),\n  });\n\n  useEffect(() => {\n    if (!ctx || !ctx.mode) {\n      return;\n    }\n\n    const sub = ctx.mode.subscribe({\n      next(m) {\n        setMode({ data: m });\n      },\n    });\n\n    return sub.unsubscribe.bind(sub);\n  }, [ctx]);\n\n  return mode.data;\n}\n\nexport function usePartModeCtxKey<M, K extends keyof M, R>(\n  name: K\n): R | undefined {\n  const mode = usePartModeCtx<M>();\n  const iniVal =\n    mode &&\n    ((<unknown>mode[name]) as BehaviorSubject<R | undefined> | undefined);\n  const [val, setVal] = useState<{ data: R | undefined }>({\n    data: iniVal?.getValue(),\n  });\n\n  useEffect(() => {\n    if (!mode) {\n      return;\n    }\n\n    const obs = (<unknown>mode[name]) as Observable<R>;\n\n    const sub = obs.subscribe({\n      next(val) {\n        setVal({ data: val });\n      },\n    });\n\n    return sub.unsubscribe.bind(sub);\n  }, [mode]);\n\n  return val.data;\n}\n","import React, { useEffect, useState } from \"react\";\nimport { Attributable } from \"../../../shared/scopes\";\nimport { error } from \"../../../utils/console\";\nimport { WithChildren } from \"../../react/helpers\";\nimport { Game, Player } from \"../classic\";\nimport { useGame, usePlayer } from \"./hooks\";\n\nexport type StepsFunc = (props: {\n  game?: Game | null;\n  player?: Player | null;\n}) => React.ElementType[] | undefined;\n\nexport type StepsProps = WithChildren<{\n  steps: React.ElementType[] | StepsFunc;\n  progressKey: string;\n  doneKey: string;\n  object?: Attributable;\n}>;\n\nexport function Steps({\n  steps,\n  progressKey,\n  doneKey,\n  object,\n  children,\n}: StepsProps) {\n  let obj: Attributable;\n  const game = useGame();\n  const player = usePlayer();\n  const [stps, setStps] = useState<React.ElementType[]>([]);\n  const [stpsSet, setStpsSet] = useState<boolean>(false);\n\n  useEffect(() => {\n    let s: React.ElementType[];\n    if (typeof steps === \"function\") {\n      s = steps({ game, player })!;\n    } else {\n      s = steps;\n    }\n    setStps(s);\n    setStpsSet(true);\n  }, [steps]);\n\n  useEffect(() => {\n    if (obj && !obj.get(doneKey) && stpsSet && (!stps || stps.length === 0)) {\n      obj.set(doneKey, true);\n    }\n  }, [stps]);\n\n  // Find state receiver\n  if (object) {\n    obj = object;\n  } else if (player) {\n    obj = player;\n  } else {\n    error(\"no receiver and no player in Steps\");\n    return <div>Missing attribute</div>;\n  }\n\n  // Are we already done\n  if (obj.get(doneKey)) {\n    return <>{children}</>;\n  }\n\n  const index = (obj.get(progressKey) as number) || 0;\n\n  const next = () => {\n    if (index + 1 >= stps.length) {\n      obj.set(doneKey, true);\n    } else {\n      obj.set(progressKey, index + 1);\n    }\n  };\n\n  const previous = () => {\n    if (index > 0) {\n      obj.set(progressKey, index - 1);\n    }\n  };\n\n  const Step = stps[index];\n  if (!Step) {\n    return <></>;\n  }\n\n  return <Step index={index} previous={previous} next={next}></Step>;\n}\n","import React, { FormEvent, useState } from \"react\";\n\nexport function Quiz({ next }: { next: () => void }) {\n  const labelClassName = \"block text-sm font-medium text-gray-700 mb-2\";\n  const inputClassName =\n    \"appearance-none block px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-empirica-500 focus:border-empirica-500 sm:text-sm\";\n\n  const [sum, setSum] = useState(\"\");\n  const [horse, setHorse] = useState(\"\");\n\n  function handleSubmit(e: FormEvent) {\n    e.preventDefault();\n\n    if (sum !== \"4\" || horse !== \"white\") {\n      alert(\"Incorrect! Read the instructions and please try again.\");\n    } else {\n      next();\n    }\n  }\n\n  return (\n    <div className=\"flex justify-center\">\n      <div className=\"mt-6 sm:mt-24\">\n        <h3 className=\"text-2xl font-semi-bold text-gray-900\">Quiz</h3>\n        <form className=\"mt-4\" onSubmit={handleSubmit}>\n          <p className=\"mb-5\">\n            <label className={labelClassName}>What is 2+2?</label>\n            <input\n              className={inputClassName}\n              type=\"text\"\n              dir=\"auto\"\n              id=\"sum\"\n              name=\"sum\"\n              placeholder=\"e.g. 3\"\n              value={sum}\n              onChange={(e) => setSum(e.target.value)}\n              autoComplete=\"off\"\n              autoFocus\n              required\n            />\n          </p>\n          <p className=\"mb-5\">\n            <label className={labelClassName}>\n              What color was Napoleon's white horse?\n            </label>\n            <input\n              className={inputClassName}\n              type=\"text\"\n              dir=\"auto\"\n              id=\"horse\"\n              name=\"horse\"\n              placeholder=\"brown\"\n              value={horse}\n              onChange={(e) => setHorse(e.target.value)}\n              autoComplete=\"off\"\n              required\n            />\n          </p>\n\n          <button\n            type=\"submit\"\n            className=\"inline-flex items-center px-4 py-2 border text-sm font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-empirica-500\"\n          >\n            Submit\n          </button>\n        </form>\n      </div>\n    </div>\n  );\n}\n","import React, { ChangeEventHandler, RefObject, useRef } from \"react\";\n\nexport interface SliderProps {\n  value: number;\n  onChange: ChangeEventHandler<HTMLInputElement>;\n  min?: number;\n  max?: number;\n  stepSize?: number;\n  disabled?: boolean;\n}\n\nexport function Slider({\n  value,\n  onChange,\n  min = 0,\n  max = 100,\n  stepSize = 1,\n  disabled = false,\n}: SliderProps) {\n  const noVal = value === null || value === undefined;\n  const val = noVal ? (max - min) / 2 : value;\n  const cls = noVal ? \"slider-thumb-zero\" : \"slider-thumb\";\n  const ref: RefObject<HTMLOutputElement> = useRef(null);\n\n  if (value !== null && ref.current) {\n    const nmin = min ? min : 0;\n    const nmax = max ? max : 100;\n    const newVal = Number(((value - nmin) * 100) / (nmax - nmin));\n\n    ref.current.style.left = `calc(${newVal}% + (${8 - newVal * 0.15}px))`;\n  }\n\n  return (\n    <div className=\"relative w-full\">\n      <input\n        className={cls}\n        type=\"range\"\n        min={min}\n        max={max}\n        step={stepSize}\n        value={val}\n        onChange={onChange}\n        disabled={disabled}\n      />\n      {noVal ? (\n        \"\"\n      ) : (\n        <output\n          ref={ref}\n          className=\"font-mono absolute w-12 h-7 flex items-center justify-center left-1/2 bottom-7 rounded transform -translate-x-1/2 bg-gray-200\"\n        >\n          {value}\n        </output>\n      )}\n    </div>\n  );\n}\n","import React, {\n  FormEvent,\n  KeyboardEvent,\n  MouseEvent,\n  useEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport { Attribute } from \"../../../../shared/attributes\";\nimport { Attributable } from \"../../../../shared/scopes\";\nimport { Loading } from \"../../../react\";\nimport { WithChildren } from \"../../../react/helpers\";\nimport { usePlayer } from \"../hooks\";\n\nexport type ChatProps = WithChildren<{\n  scope: Attributable;\n  attribute: string;\n  loading?: React.ElementType;\n}>;\n\nexport type Message = {\n  text: string;\n  sender: {\n    id: string;\n    name: string;\n    avatar: string;\n  };\n};\n\nexport function Chat({\n  scope,\n  attribute = \"messages\",\n  loading: LoadingComp = Loading,\n}: ChatProps) {\n  const player = usePlayer();\n\n  if (!scope || !player) {\n    return <LoadingComp />;\n  }\n\n  const handleNewMessage = (text: string) => {\n    scope.append(attribute, {\n      text,\n      sender: {\n        id: player!.id,\n        name: player!.get(\"name\") || player!.id,\n        avatar: player!.get(\"avatar\"),\n      },\n    } as Message);\n  };\n\n  const msgs = scope.getAttribute(attribute)?.items || [];\n\n  return (\n    <div className=\"h-full w-full flex flex-col\">\n      <Messages msgs={msgs} />\n\n      <Input onNewMessage={handleNewMessage} />\n    </div>\n  );\n}\n\ntype MessagesProps = WithChildren<{\n  msgs: Attribute[];\n}>;\n\nfunction Messages(props: MessagesProps) {\n  const { msgs } = props;\n  const scroller = useRef<HTMLDivElement>(null);\n  const [msgCount, setMsgCount] = useState(0);\n\n  useEffect(() => {\n    if (!scroller.current) {\n      return;\n    }\n\n    if (msgCount !== msgs.length) {\n      setMsgCount(msgs.length);\n      scroller.current.scrollTop = scroller.current.scrollHeight;\n    }\n  }, [scroller, props, msgCount]);\n\n  if (msgs.length === 0) {\n    return (\n      <div className=\"h-full w-full flex justify-center items-center\">\n        <div className=\"flex flex-col justify-center items-center w-2/3 space-y-2\">\n          <div className=\"w-24 h-24 text-gray-200\">\n            <svg\n              xmlns=\"http://www.w3.org/2000/svg\"\n              className=\"h-full w-full fill-current\"\n              viewBox=\"0 0 512 512\"\n            >\n              <path d=\"M123.6 391.3c12.9-9.4 29.6-11.8 44.6-6.4c26.5 9.6 56.2 15.1 87.8 15.1c124.7 0 208-80.5 208-160s-83.3-160-208-160S48 160.5 48 240c0 32 12.4 62.8 35.7 89.2c8.6 9.7 12.8 22.5 11.8 35.5c-1.4 18.1-5.7 34.7-11.3 49.4c17-7.9 31.1-16.7 39.4-22.7zM21.2 431.9c1.8-2.7 3.5-5.4 5.1-8.1c10-16.6 19.5-38.4 21.4-62.9C17.7 326.8 0 285.1 0 240C0 125.1 114.6 32 256 32s256 93.1 256 208s-114.6 208-256 208c-37.1 0-72.3-6.4-104.1-17.9c-11.9 8.7-31.3 20.6-54.3 30.6c-15.1 6.6-32.3 12.6-50.1 16.1c-.8 .2-1.6 .3-2.4 .5c-4.4 .8-8.7 1.5-13.2 1.9c-.2 0-.5 .1-.7 .1c-5.1 .5-10.2 .8-15.3 .8c-6.5 0-12.3-3.9-14.8-9.9c-2.5-6-1.1-12.8 3.4-17.4c4.1-4.2 7.8-8.7 11.3-13.5c1.7-2.3 3.3-4.6 4.8-6.9c.1-.2 .2-.3 .3-.5z\" />\n            </svg>\n          </div>\n\n          <h4 className=\"text-gray-700 font-semibold\">No chat yet</h4>\n\n          <p className=\"text-gray-500 text-center\">\n            Send a message to start the conversation.\n          </p>\n        </div>\n      </div>\n    );\n  }\n\n  return (\n    <div className=\"h-full overflow-auto pl-2 pr-4 pb-2\" ref={scroller}>\n      {msgs.map((msg) => (\n        <MessageComp key={msg.id} attribute={msg} />\n      ))}\n    </div>\n  );\n}\n\ntype MessageProps = WithChildren<{\n  attribute: Attribute;\n}>;\n\nfunction MessageComp({ attribute }: MessageProps) {\n  const msg = attribute.value as Message;\n  const ts = attribute.createdAt;\n\n  let avatar = msg.sender.avatar;\n  if (!avatar) {\n    avatar = `https://avatars.dicebear.com/api/identicon/${msg.sender.id}.svg`;\n  }\n\n  let avatarImage = (\n    <img\n      className=\"inline-block h-9 w-9 rounded-full\"\n      src={avatar}\n      alt={msg.sender.id}\n    />\n  );\n  if (!avatar.startsWith(\"http\")) {\n    avatarImage = (\n      <div className=\"inline-block h-9 w-9 rounded-full\">{avatar}</div>\n    );\n  }\n\n  return (\n    <div className=\"flex items-start my-2\">\n      <div className=\"flex-shrink-0\">{avatarImage}</div>\n      <div className=\"ml-3 text-sm\">\n        <p>\n          <span className=\"font-semibold text-gray-900 group-hover:text-gray-800\">\n            {msg.sender.name}\n          </span>\n\n          <span className=\"pl-2 text-gray-400\">{ts && relTime(ts)}</span>\n        </p>\n        <p className=\"text-gray-900 group-hover:text-gray-800\">{msg.text}</p>\n      </div>\n    </div>\n  );\n}\n\ntype InputProps = WithChildren<{\n  onNewMessage: (msg: string) => void;\n}>;\n\nfunction Input({ onNewMessage }: InputProps) {\n  const [text, setText] = useState(\"\");\n\n  const resize = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n    const target = e.target as HTMLTextAreaElement;\n    target.style.height = \"inherit\";\n    target.style.height = `${Math.min(target.scrollHeight, 200)}px`;\n  };\n\n  const handleSubmit = (\n    e:\n      | FormEvent<HTMLFormElement>\n      | KeyboardEvent<HTMLTextAreaElement>\n      | MouseEvent<HTMLButtonElement>\n  ) => {\n    e.preventDefault();\n\n    const txt = text.trim();\n    if (txt === \"\") {\n      return;\n    }\n\n    if (txt.length > 1024) {\n      e.preventDefault();\n\n      alert(\"Max message length is 1024\");\n\n      return;\n    }\n\n    onNewMessage(txt);\n    setText(\"\");\n  };\n\n  const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n    if (e.key === \"Enter\" && e.shiftKey === false) {\n      handleSubmit(e);\n      resize(e);\n    }\n  };\n\n  const handleKeyUp = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n    resize(e);\n  };\n\n  return (\n    <form\n      className=\"p-2 flex items-strech gap-2 border-t\"\n      onSubmit={handleSubmit}\n    >\n      <textarea\n        name=\"message\"\n        id=\"message\"\n        rows={1}\n        className=\"peer resize-none bg-transparent block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-200 placeholder:text-gray-300 focus:ring-2 focus:ring-inset focus:ring-empirica-500 sm:text-sm sm:leading-6\"\n        placeholder=\"Say something\"\n        onKeyDown={handleKeyDown}\n        onKeyUp={handleKeyUp}\n        value={text}\n        onChange={(e) => setText(e.target.value)}\n      />\n\n      <button\n        type=\"button\"\n        className=\"rounded-md bg-gray-100 w-9 h-9 p-2 text-sm font-semibold text-gray-500 shadow-sm hover:bg-gray-200 hover:text-empirica-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-empirica-500\"\n        onClick={handleSubmit}\n      >\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          className=\"h-full w-full fill-current\"\n          viewBox=\"0 0 512 512\"\n        >\n          <path d=\"M498.1 5.6c10.1 7 15.4 19.1 13.5 31.2l-64 416c-1.5 9.7-7.4 18.2-16 23s-18.9 5.4-28 1.6L284 427.7l-68.5 74.1c-8.9 9.7-22.9 12.9-35.2 8.1S160 493.2 160 480V396.4c0-4 1.5-7.8 4.2-10.7L331.8 202.8c5.8-6.3 5.6-16-.4-22s-15.7-6.4-22-.7L106 360.8 17.7 316.6C7.1 311.3 .3 300.7 0 288.9s5.9-22.8 16.1-28.7l448-256c10.7-6.1 23.9-5.5 34 1.4z\" />\n        </svg>\n      </button>\n    </form>\n  );\n}\n\nfunction relTime(date: Date) {\n  const difference = (new Date().getTime() - date.getTime()) / 1000;\n\n  if (difference < 60) {\n    return `now`;\n  } else if (difference < 3600) {\n    return `${Math.floor(difference / 60)}m`;\n  } else if (difference < 86400) {\n    return `${Math.floor(difference / 3600)}h`;\n  } else if (difference < 2620800) {\n    return `${Math.floor(difference / 86400)} days ago`;\n  } else if (difference < 31449600) {\n    return `${Math.floor(difference / 2620800)} months ago`;\n  } else {\n    return `${Math.floor(difference / 31449600)} years ago`;\n  }\n}\n\n// function getRelativeTimeString(\n//   date: Date | number,\n//   lang = navigator.language\n// ): string {\n//   // Allow dates or times to be passed\n//   const timeMs = typeof date === \"number\" ? date : date.getTime();\n\n//   // Get the amount of seconds between the given date and now\n//   const deltaSeconds = Math.round((timeMs - Date.now()) / 1000);\n\n//   // Array reprsenting one minute, hour, day, week, month, etc in seconds\n//   const cutoffs = [\n//     60,\n//     3600,\n//     86400,\n//     86400 * 7,\n//     86400 * 30,\n//     86400 * 365,\n//     Infinity,\n//   ];\n\n//   // Array equivalent to the above but in the string representation of the units\n//   const units: Intl.RelativeTimeFormatUnit[] = [\n//     \"second\",\n//     \"minute\",\n//     \"hour\",\n//     \"day\",\n//     \"week\",\n//     \"month\",\n//     \"year\",\n//   ];\n\n//   // Grab the ideal cutoff unit\n//   const unitIndex = cutoffs.findIndex(\n//     (cutoff) => cutoff > Math.abs(deltaSeconds)\n//   );\n\n//   // Get the divisor to divide from the seconds. E.g. if our unit is \"day\" our divisor\n//   // is one day in seconds, so we can divide our seconds by this to get the # of days\n//   const divisor = unitIndex ? cutoffs[unitIndex - 1] : 1;\n\n//   // Intl.RelativeTimeFormat do its magic\n//   const rtf = new Intl.RelativeTimeFormat(lang, { numeric: \"auto\" });\n//   return rtf.format(Math.floor(deltaSeconds / divisor!), units[unitIndex]!);\n// }\n","import React from \"react\";\nimport { createNewParticipant, isDevelopment } from \"../utils\";\nimport { Logo } from \"./Logo\";\nimport { useParticipantContext } from \"./hooks\";\n\nexport type EmpiricaMenuProps = {\n  position:\n    | \"top\"\n    | \"top-left\"\n    | \"top-right\"\n    | \"bottom\"\n    | \"bottom-left\"\n    | \"bottom-right\";\n};\n\nexport function EmpiricaMenu({ position = \"bottom-left\" }: EmpiricaMenuProps) {\n  const ctx = useParticipantContext();\n\n  if (!ctx) {\n    return null;\n  }\n\n  function resetSession() {\n    ctx!.session.clearSession();\n    window.location.reload();\n  }\n\n  let className =\n    \"backdrop-blur-md bg-gray-200/50 rounded fixed z-20 flex space-x-1 text-gray-500\";\n  switch (position) {\n    case \"top\":\n      className += \" top-0 mt-2 ml-1/2 -translate-x-1/2\";\n      break;\n    case \"top-left\":\n      className += \" top-0 left-0 mt-2 ml-2\";\n      break;\n    case \"top-right\":\n      className += \" top-0 right-0 mt-2 mr-2\";\n      break;\n    case \"bottom\":\n      className += \" bottom-0 mb-2 ml-1/2 -translate-x-1/2\";\n      break;\n    case \"bottom-right\":\n      className += \" bottom-0 right-0 mb-2 mr-2\";\n      break;\n    case \"bottom-left\":\n    default:\n      className += \" bottom-0 left-0 mb-2 ml-2\";\n      break;\n  }\n\n  const buttons = [\n    {\n      onClick: () => {\n        window.open(\"https://empirica.ly\", \"_blank\");\n      },\n      icon: <Logo />,\n      title: \"Empirica\",\n      inDevOnly: position === \"top\" || position === \"bottom\",\n    },\n    {\n      onClick: () => createNewParticipant(),\n      icon: (\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          className=\"h-full w-full stroke-current\"\n        >\n          <path d=\"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\" />\n          <circle cx=\"9\" cy=\"7\" r=\"4\" />\n          <line x1=\"19\" x2=\"19\" y1=\"8\" y2=\"14\" />\n          <line x1=\"22\" x2=\"16\" y1=\"11\" y2=\"11\" />\n        </svg>\n      ),\n      inDevOnly: true,\n      title: \"New Participant\",\n    },\n    {\n      onClick: resetSession,\n      icon: (\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          className=\"h-full w-full stroke-current\"\n        >\n          <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n          <path d=\"M3 3v5h5\" />\n        </svg>\n      ),\n      inDevOnly: true,\n      title: \"Reset Session\",\n    },\n    {\n      onClick: () => {\n        window.open(\"/admin\", \"_blank\");\n      },\n      icon: (\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          className=\"h-full w-full stroke-current\"\n        >\n          <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\" />\n        </svg>\n      ),\n      inDevOnly: true,\n      title: \"Admin\",\n    },\n    {\n      onClick: () => {\n        window.open(\"https://docs.empirica.ly\", \"_blank\");\n      },\n      icon: (\n        <svg\n          xmlns=\"http://www.w3.org/2000/svg\"\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          className=\"h-full w-full stroke-current\"\n        >\n          <path d=\"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z\" />\n          <path d=\"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z\" />\n        </svg>\n      ),\n      inDevOnly: true,\n      title: \"Documentation\",\n    },\n  ];\n\n  return (\n    <div className={className}>\n      {buttons.map((button, i) => {\n        let sizing = \"\";\n\n        // Logo needs to be a little larger to git visual scale of other icons.\n        if (i === 0) {\n          sizing = \"w-9 h-8 p-1.5 pl-2.5\";\n          if (buttons.length === 0) {\n            sizing += \" pr-2.5\";\n          }\n        } else if (i === buttons.length - 1) {\n          // Adding a little padding to the right of the last button for\n          // aesthetics.\n          sizing += \"w-8.5 h-8 p-2 pr-2.5\";\n        }\n\n        return <ToolButton key={i} {...button} sizing={sizing} />;\n      })}\n    </div>\n  );\n}\n\nexport type ToolButtonProps = {\n  onClick: () => void;\n  icon: React.ReactNode;\n  inDevOnly?: boolean;\n  sizing?: string;\n  title?: string;\n};\n\nfunction ToolButton({\n  onClick,\n  icon,\n  title,\n  sizing = \"\",\n  inDevOnly = false,\n}: ToolButtonProps) {\n  if (inDevOnly && !isDevelopment) {\n    return <></>;\n  }\n\n  let size = \"w-8 h-8 p-2\";\n\n  if (sizing) {\n    size = sizing;\n  }\n\n  let className =\n    \"block bg-transparent hover:text-empirica-600 hover:bg-gray-300 rounded \" +\n    size;\n\n  return (\n    <button onClick={onClick} className={className} title={title}>\n      {icon}\n    </button>\n  );\n}\n","import React from \"react\";\n\nexport function Logo() {\n  return (\n    <svg\n      className=\"h-full w-full fill-current\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      viewBox=\"0 0 195 185\"\n    >\n      <path d=\"M25.164 81.9737C22.31 81.9737 19.998 84.2877 20 87.1417L20.028 128.458C20.03 131.309 22.341 133.619 25.192 133.619C28.046 133.619 30.359 131.304 30.357 128.451L30.328 87.1347C30.326 84.2837 28.015 81.9737 25.164 81.9737Z\" />\n      <path d=\"M87.1367 61.3158C84.2837 61.3158 81.9707 63.6298 81.9727 66.4828L82.0017 118.128C82.0037 120.979 84.3147 123.29 87.1667 123.29C90.0197 123.29 92.3327 120.976 92.3307 118.122L92.3007 66.4778C92.2997 63.6258 89.9877 61.3158 87.1367 61.3158Z\" />\n      <path d=\"M107.793 20C104.94 20 102.628 22.313 102.629 25.166L102.661 159.442C102.662 162.294 104.974 164.605 107.826 164.605C110.679 164.605 112.991 162.293 112.99 159.44L112.957 25.163C112.957 22.311 110.645 20 107.793 20Z\" />\n      <path d=\"M128.451 20C125.598 20 123.286 22.313 123.287 25.166L123.319 159.442C123.32 162.294 125.632 164.605 128.484 164.605C131.337 164.605 133.649 162.293 133.648 159.44L133.615 25.163C133.615 22.311 131.303 20 128.451 20Z\" />\n      <path d=\"M149.11 20C146.257 20 143.944 22.313 143.946 25.167L143.977 102.634C143.978 105.485 146.29 107.796 149.141 107.796C151.994 107.796 154.307 105.483 154.306 102.63L154.274 25.162C154.273 22.311 151.961 20 149.11 20Z\" />\n      <path d=\"M169.75 40.6579C166.897 40.6579 164.585 42.9709 164.586 45.8239L164.617 138.785C164.618 141.637 166.93 143.948 169.782 143.948C172.635 143.948 174.947 141.634 174.946 138.781L174.914 45.8209C174.914 42.9689 172.602 40.6579 169.75 40.6579Z\" />\n      <path d=\"M45.8203 61.3158C42.9673 61.3158 40.6553 63.6288 40.6563 66.4818L40.6873 159.443C40.6883 162.295 43.0003 164.606 45.8523 164.606C48.7053 164.606 51.0173 162.292 51.0163 159.439L50.9843 66.4788C50.9843 63.6268 48.6723 61.3158 45.8203 61.3158Z\" />\n      <path d=\"M66.4785 61.3158C63.6255 61.3158 61.3135 63.6288 61.3145 66.4818L61.3455 159.443C61.3465 162.295 63.6585 164.606 66.5105 164.606C69.3635 164.606 71.6755 162.292 71.6745 159.439L71.6425 66.4788C71.6415 63.6268 69.3305 61.3158 66.4785 61.3158Z\" />\n    </svg>\n  );\n}\n\n// export function Logo() {\n//   return (\n//     <div className=\"absolute bottom-0 right-0 h-20 w-20\">\n//       <svg\n//         className=\"h-full w-full\"\n//         fill=\"none\"\n//         xmlns=\"http://www.w3.org/2000/svg\"\n//         viewBox=\"0 0 250 250\"\n//       >\n//         <circle cx=\"50\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"50\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"50\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"50\" cy=\"139\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"50\" cy=\"167\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"50\" cy=\"195\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"78\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"78\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"78\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"78\" cy=\"139\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"78\" cy=\"167\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"78\" cy=\"195\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"106\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"106\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"106\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"106\" cy=\"139\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"106\" cy=\"167\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"106\" cy=\"195\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"134\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"134\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"134\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"162\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"162\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"162\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"190\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"190\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle\n//           cx=\"78\"\n//           cy=\"167\"\n//           r=\"7\"\n//           fill=\"#838383\"\n//           stroke=\"#838383\"\n//           strokeWidth=\"4\"\n//         />\n//         <circle\n//           cx=\"106\"\n//           cy=\"111\"\n//           r=\"7\"\n//           fill=\"#838383\"\n//           stroke=\"#838383\"\n//           strokeWidth=\"4\"\n//         />\n//         <circle\n//           cx=\"190\"\n//           cy=\"83\"\n//           r=\"7\"\n//           fill=\"#838383\"\n//           stroke=\"#838383\"\n//           strokeWidth=\"4\"\n//         />\n//         <circle cx=\"190\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <rect x=\"127\" y=\"132\" width=\"71\" height=\"14\" fill=\"#838383\" />\n//         <rect x=\"127\" y=\"160\" width=\"71\" height=\"14\" fill=\"#838383\" />\n//         <rect x=\"127\" y=\"188\" width=\"71\" height=\"14\" fill=\"#838383\" />\n//       </svg>\n//     </div>\n//   );\n// }\n\n// export default function Logo() {\n//   return (\n//     <div className=\"absolute bottom-0 right-0 h-20 w-20\">\n//       <svg\n//         className=\"h-full w-full\"\n//         fill=\"none\"\n//         xmlns=\"http://www.w3.org/2000/svg\"\n//         viewBox=\"0 0 250 250\"\n//       >\n//         <circle cx=\"47\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"47\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"47\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"47\" cy=\"139\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"47\" cy=\"167\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"47\" cy=\"195\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"73\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"73\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"73\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"73\" cy=\"139\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"73\" cy=\"167\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"73\" cy=\"195\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"99\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"99\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"99\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"99\" cy=\"139\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"99\" cy=\"167\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"99\" cy=\"195\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"125\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"125\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"125\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"125\" cy=\"139\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"125\" cy=\"167\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"125\" cy=\"195\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"151\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"151\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"151\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"151\" cy=\"139\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"151\" cy=\"167\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"151\" cy=\"195\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"177\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"177\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"177\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"177\" cy=\"139\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"177\" cy=\"167\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"177\" cy=\"195\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"203\" cy=\"55\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"203\" cy=\"83\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle\n//           cx=\"47\"\n//           cy=\"55\"\n//           r=\"7\"\n//           fill=\"#838383\"\n//           stroke=\"#838383\"\n//           strokeWidth=\"4\"\n//         />\n//         <circle\n//           cx=\"99\"\n//           cy=\"167\"\n//           r=\"7\"\n//           fill=\"#838383\"\n//           stroke=\"#838383\"\n//           strokeWidth=\"4\"\n//         />\n//         <circle\n//           cx=\"125\"\n//           cy=\"111\"\n//           r=\"7\"\n//           fill=\"#838383\"\n//           stroke=\"#838383\"\n//           strokeWidth=\"4\"\n//         />\n//         <circle\n//           cx=\"177\"\n//           cy=\"139\"\n//           r=\"7\"\n//           fill=\"#838383\"\n//           stroke=\"#838383\"\n//           strokeWidth=\"4\"\n//         />\n//         <circle\n//           cx=\"203\"\n//           cy=\"83\"\n//           r=\"7\"\n//           fill=\"#838383\"\n//           stroke=\"#838383\"\n//           strokeWidth=\"4\"\n//         />\n//         <circle cx=\"203\" cy=\"111\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"203\" cy=\"139\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"203\" cy=\"167\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//         <circle cx=\"203\" cy=\"195\" r=\"7\" stroke=\"#838383\" strokeWidth=\"4\" />\n//       </svg>\n//     </div>\n//   );\n// }\n","import React, { useEffect } from \"react\";\nimport { usePlayer, useRound } from \"../hooks\";\n\nconst buttonStyle = {\n  width: 40,\n  height: 40,\n  backgroundColor: \"#888\",\n  color: \"black\",\n  verticalAlign: \"top\",\n  fontSize: \"32px\",\n  borderLeft: \"5px solid rgb(220,220,220)\",\n  borderTop: \"5px solid rgb(220,220,220)\",\n  borderBottom: \"5px solid #333\",\n  borderRight: \"5px solid #333\",\n  display: \"inline-block\",\n};\n\nconst visitStyle = {\n  width: 40,\n  height: 40,\n  itemsAlign: \"center\",\n  backgroundColor: \"#555\",\n  color: \"white\",\n  fontWeight: \"bold\",\n  border: \"1px solid black\",\n  verticalAlign: \"top\",\n  fontSize: \"24px\",\n  display: \"inline-block\",\n};\n\ntype cell = number | string;\ntype row = [cell, cell, cell, cell, cell, cell, cell, cell, cell, cell];\ntype grid = [row, row, row, row, row, row, row, row, row, row];\n\nexport function Sweeper() {\n  const round = useRound();\n  if (!round) {\n    return null;\n  }\n  const player = usePlayer();\n  if (!player) {\n    return null;\n  }\n\n  const visited = round.get(\"visited\") as Array<Array<number>>;\n  const bombs = round.get(\"bombs\") as Array<Array<number | \"X\">>;\n  const lost = round.get(\"lost\") as boolean;\n\n  useEffect(function () {\n    generateBombs();\n  }, []);\n\n  function generateBombs() {\n    if (bombs || !round) {\n      return;\n    }\n\n    let bombArr = new Array(10)\n      .fill(0)\n      .map(() => new Array(10).fill(0)) as grid;\n\n    for (let i = 0; i < bombArr.length; i++) {\n      let bombPos = Math.floor(Math.random() * 10);\n      bombArr[i]![bombPos] = \"X\";\n    }\n\n    for (let i = 0; i < bombArr.length; i++) {\n      for (let j = 0; j < bombArr[i]!.length; j++) {\n        if (bombArr[i]![j] !== \"X\") {\n          let sum = 0;\n\n          if (i > 0 && bombArr[i - 1]![j] == \"X\") sum++;\n          if (i < bombArr.length - 1 && bombArr[i + 1]![j] == \"X\") sum++;\n          if (j < bombArr.length - 1 && bombArr[i]![j + 1] == \"X\") sum++;\n          if (j > 0 && bombArr[i]![j - 1] == \"X\") sum++;\n          if (i < bombArr.length - 1 && j > 0 && bombArr[i + 1]![j - 1] == \"X\")\n            sum++;\n          if (\n            i < bombArr.length - 1 &&\n            j < bombArr.length - 1 &&\n            bombArr[i + 1]![j + 1] == \"X\"\n          )\n            sum++;\n          if (i > 0 && j > 0 && bombArr[i - 1]![j - 1] == \"X\") sum++;\n          if (i > 0 && j < bombArr.length - 1 && bombArr[i - 1]![j + 1] == \"X\")\n            sum++;\n\n          bombArr[i]![j] = sum;\n        }\n      }\n    }\n\n    round.set(\"bombs\", bombArr);\n\n    let cover = Array(10)\n      .fill(0)\n      .map(() => Array(10).fill(0));\n\n    round.set(\"visited\", cover);\n  }\n\n  const visitCell = (i: number, j: number) => {\n    if (lost || !bombs || !visited) {\n      return;\n    }\n\n    if (bombs[i]![j] === \"X\") {\n      round.set(\"lost\", true);\n    }\n\n    dfsCells(i, j);\n    visited[i]![j] = 1;\n    round.set(\"visited\", [...visited]);\n  };\n\n  function dfsCells(i: number, j: number) {\n    if (!round || !bombs || !visited) {\n      return;\n    }\n\n    if (\n      i < 0 ||\n      i > visited.length - 1 ||\n      j < 0 ||\n      j > visited[0]!.length - 1 ||\n      visited[i]![j] == 1 ||\n      bombs[i]![j] == \"X\"\n    )\n      return;\n\n    visited[i]![j] = 1;\n\n    round.set(\"visited\", [...visited]);\n\n    const cell = bombs[i]![j]!;\n    if (typeof cell === \"number\" && cell < 1) {\n      dfsCells(i + 1, j);\n      dfsCells(i - 1, j);\n      dfsCells(i, j + 1);\n      dfsCells(i, j - 1);\n    }\n  }\n\n  if (!bombs) {\n    return null;\n  }\n\n  return (\n    <div className=\"text-sm relative\">\n      {lost ? (\n        <>\n          <div className=\"absolute h-full w-full flex items-center justify-center text-6xl white font-black bg-opacity-50 bg-gray-300\">\n            YOU LOST\n          </div>\n          <div className=\"absolute h-full w-full flex items-center justify-center text-6xl white font-black mt-1 ml-1 text-white\">\n            YOU LOST\n          </div>\n        </>\n      ) : (\n        \"\"\n      )}\n\n      {bombs.map((arr, index) => (\n        <div key={index}>\n          {arr.map((_, i) => (\n            <div\n              key={i}\n              onClick={() => visitCell(index, i)}\n              style={visited[index]![i] == 0 ? buttonStyle : visitStyle}\n            >\n              <div className=\"h-full w-full flex items-center justify-center\">\n                {visited[index]![i] == 0\n                  ? null\n                  : bombs[index]![i] == 0\n                  ? \"\"\n                  : bombs[index]![i]}\n              </div>\n            </div>\n          ))}\n        </div>\n      ))}\n    </div>\n  );\n}\n"],"mappings":"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","names":["Scope","Scopes","error","attr","newAttr","value","import_rxjs","map","kind","Scopes","Scope","import_rxjs","import_rxjs","import_rxjs","Scope","import_react","React","import_react","React","import_react","React","import_react","React","import_react","React","import_react","import_rxjs","import_react","import_rxjs","import_rxjs","import_rxjs","import_rxjs","isBrowser","import_rxjs","React","import_react","import_react","val","React","import_react","Steps","React","Step","React","Steps","Lobby","Finished","import_react","React","import_react","React","import_react","import_react","import_react","React","import_react","React"]}