@netless/window-manager 0.4.0-canary.11 → 0.4.0-canary.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/constants.ts","../src/Register/storage.ts","../src/Register/loader.ts","../src/Register/index.ts","../src/Utils/Common.ts","../src/AppListener.ts","../src/Utils/error.ts","../src/Utils/Reactive.ts","../src/App/Storage/utils.ts","../src/App/Storage/StorageEvent.ts","../src/App/Storage/index.ts","../src/AppContext.ts","../src/AttributesDelegate.ts","../src/Utils/log.ts","../src/Base/Context.ts","../src/Base/index.ts","../src/AppProxy.ts","../src/View/ViewManager.ts","../src/View/MainView.ts","../src/AppManager.ts","../src/ContainerResizeObserver.ts","../src/BoxManager.ts","../node_modules/svelte/internal/index.mjs","../src/Cursor/Cursor.svelte","../src/Cursor/icons.ts","../src/image/pencil-cursor.png","../src/image/selector-cursor.png","../src/image/eraser-cursor.png","../src/image/shape-cursor.svg","../src/image/text-cursor.svg","../src/Cursor/Cursor.ts","../src/Cursor/index.ts","../src/BuiltinApps.ts","../src/index.ts","../src/ReconnectRefresher.ts","../src/Utils/RoomHacker.ts","../src/Helper.ts"],"sourcesContent":["export enum Events {\n AppMove = \"AppMove\",\n AppFocus = \"AppFocus\",\n AppResize = \"AppResize\",\n AppBoxStateChange = \"AppBoxStateChange\",\n GetAttributes = \"GetAttributes\",\n UpdateWindowManagerWrapper = \"UpdateWindowManagerWrapper\",\n InitReplay = \"InitReplay\",\n WindowCreated = \"WindowCreated\",\n SetMainViewScenePath = \"SetMainViewScenePath\",\n SetMainViewSceneIndex = \"SetMainViewSceneIndex\",\n SwitchViewsToFreedom = \"SwitchViewsToFreedom\",\n MoveCameraToContain = \"MoveCameraToContain\"\n}\n\nexport const MagixEventName = \"__WindowManger\";\n\nexport enum AppAttributes {\n Size = \"size\",\n Position = \"position\",\n SceneIndex = \"SceneIndex\",\n ZIndex = \"zIndex\",\n}\n\nexport enum AppEvents {\n setBoxSize = \"setBoxSize\",\n setBoxMinSize = \"setBoxMinSize\",\n destroy = \"destroy\",\n}\n\nexport enum AppStatus {\n StartCreate = \"StartCreate\",\n}\n\nexport enum CursorState {\n Leave = \"leave\",\n Normal = \"normal\",\n}\n\nexport const REQUIRE_VERSION = \"2.16.0\";\n\nexport const MIN_WIDTH = 340 / 720;\nexport const MIN_HEIGHT = 340 / 720;\n\nexport const SET_SCENEPATH_DELAY = 100; // 设置 scenePath 的延迟事件\n\nexport const DEFAULT_CONTAINER_RATIO = 9 / 16;\n","const DatabaseName = \"__WindowManagerAppCache\";\n\nlet db: IDBDatabase;\nlet store: IDBObjectStore;\n\nexport const initDb = async () => {\n db = await createDb();\n}\n\nexport const setItem = (key: string, val: any) => {\n if (!db) return;\n return addRecord(db, { kind: key, sourceCode: val })\n};\n\nexport const getItem = async (key: string): Promise<string | null> => {\n if (!db) return null;\n return await query(db, key);\n};\n\nexport const removeItem = (key: string) => {\n if (!db) return;\n return deleteRecord(db, key);\n};\n\nfunction createDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DatabaseName, 2);\n request.onerror = (e) => {\n reject(e);\n }\n\n request.onupgradeneeded = (event: any) => {\n const db = event.target.result as IDBDatabase;\n if (!db.objectStoreNames.contains(\"apps\")) {\n store = db.createObjectStore(\"apps\", { keyPath: \"kind\" });\n store.createIndex(\"kind\", \"kind\", { unique: true });\n }\n }\n\n request.onsuccess = () => {\n const db = request.result;\n resolve(db);\n }\n })\n}\n\nfunction query<T>(db: IDBDatabase, val: string): Promise<T | null> {\n return new Promise((resolve, reject) => {\n const index = db.transaction([\"apps\"]).objectStore(\"apps\").index(\"kind\");\n const request = index.get(val);\n request.onerror = (e) => reject(e);\n request.onsuccess = () => {\n if (request.result) {\n resolve(request.result);\n } else {\n resolve(null);\n }\n }\n })\n}\n\nfunction addRecord(db: IDBDatabase, payload: any): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = db.transaction([\"apps\"], \"readwrite\").objectStore(\"apps\").add(payload);\n request.onsuccess = () => resolve();\n request.onerror = () => reject();\n })\n}\n\nfunction deleteRecord(db: IDBDatabase, key: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = db.transaction([\"apps\"], \"readwrite\").objectStore(\"apps\").delete(key);\n request.onsuccess = () => resolve();\n request.onerror = () => reject();\n })\n}\n","import { getItem, setItem } from \"./storage\";\nimport type { NetlessApp } from \"../typings\";\n\nconst Prefix = \"NetlessApp\";\n\nconst TIMEOUT = 10000; // 10 秒超时\n\nexport const getScript = async (url: string): Promise<string> => {\n const item = await getItem(url);\n if (item) {\n return item;\n } else {\n const result = await fetchWithTimeout(url, { timeout: TIMEOUT });\n const text = await result.text();\n await setItem(url, text);\n return text;\n }\n};\n\nexport const executeScript = (text: string, appName: string): NetlessApp => {\n let result = Function(text + `;return ${appName}`)();\n if (typeof result === \"undefined\") {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n result = window[appName];\n }\n return result;\n};\n\nexport const loadApp = async (\n url: string,\n key: string,\n name?: string\n): Promise<NetlessApp | undefined> => {\n const appName = name || Prefix + key;\n const text = await getScript(url);\n try {\n return executeScript(text, appName);\n } catch (error: any) {\n if (error.message.includes(\"Can only have one anonymous define call per script file\")) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const define = window.define;\n if (\"function\" == typeof define && define.amd) {\n delete define.amd;\n }\n return executeScript(text, appName);\n }\n }\n};\n\nasync function fetchWithTimeout(resource: string, options: RequestInit & { timeout: number }) {\n const { timeout = 10000 } = options;\n\n const controller = new AbortController();\n const id = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(resource, {\n ...options,\n signal: controller.signal,\n headers: {\n \"content-type\": \"text/plain\",\n },\n });\n clearTimeout(id);\n\n return response;\n}\n","import Emittery from \"emittery\";\nimport type { NetlessApp, RegisterEvents, RegisterParams } from \"../typings\";\nimport { loadApp } from \"./loader\";\n\nclass AppRegister {\n public kindEmitters: Map<string, Emittery<RegisterEvents>> = new Map();\n public registered: Map<string, RegisterParams> = new Map();\n public appClassesCache: Map<string, Promise<NetlessApp>> = new Map();\n public appClasses: Map<string, () => Promise<NetlessApp>> = new Map();\n\n public async register(params: RegisterParams): Promise<void> {\n this.registered.set(params.kind, params);\n \n const srcOrAppOrFunction = params.src\n let downloadApp: () => Promise<NetlessApp>\n \n if (typeof srcOrAppOrFunction === \"string\") {\n downloadApp = async () => {\n const appClass = await loadApp(srcOrAppOrFunction, params.kind);\n if (appClass) {\n return appClass\n } else {\n throw new Error(`[WindowManager]: load remote script failed, ${srcOrAppOrFunction}`);\n }\n }\n } else if (typeof srcOrAppOrFunction === \"function\") {\n downloadApp = srcOrAppOrFunction\n } else {\n downloadApp = async () => srcOrAppOrFunction\n }\n\n this.appClasses.set(params.kind, async () => {\n let app = this.appClassesCache.get(params.kind)\n if (!app) {\n app = downloadApp()\n this.appClassesCache.set(params.kind, app)\n }\n return app\n });\n \n if (params.addHooks) {\n const emitter = this.createKindEmitter(params.kind);\n if (emitter) {\n params.addHooks(emitter);\n }\n }\n }\n\n public async notifyApp<T extends keyof RegisterEvents>(kind: string, event: T, payload: RegisterEvents[T]) {\n const emitter = this.kindEmitters.get(kind);\n await emitter?.emit(event, payload);\n }\n\n private createKindEmitter(kind: string) {\n if (!this.kindEmitters.has(kind)) {\n const emitter = new Emittery<RegisterEvents>();\n this.kindEmitters.set(kind, emitter);\n }\n return this.kindEmitters.get(kind);\n }\n}\n\nexport const appRegister = new AppRegister();\n","import { appRegister } from \"../Register\";\nimport { debounce } from \"lodash\";\nimport { emitter } from \"../index\";\nimport { v4 } from \"uuid\";\nimport type { PublicEvent } from \"../index\";\nimport type { Displayer, ViewVisionMode, Room, View } from \"white-web-sdk\";\nimport type Emittery from \"emittery\";\n\nexport const genAppId = async (kind: string) => {\n const impl = await appRegister.appClasses.get(kind)?.();\n if (impl && impl.config?.singleton) {\n return kind;\n }\n return `${kind}-${v4().replace(\"-\", \"\").slice(0, 8)}`;\n};\n\nexport const setViewFocusScenePath = (view: View, focusScenePath: string) => {\n if (view.focusScenePath !== focusScenePath) {\n view.focusScenePath = focusScenePath;\n }\n};\n\nexport const setScenePath = (room: Room | undefined, scenePath: string) => {\n if (room && room.isWritable) {\n if (room.state.sceneState.scenePath !== scenePath) {\n room.setScenePath(scenePath);\n }\n }\n};\n\nexport const getScenePath = (\n room: Room | undefined,\n dir: string | undefined,\n index: number\n): string | undefined => {\n if (room && dir) {\n const scenes = entireScenes(room);\n const scene = scenes[dir]?.[index];\n if (scene) {\n return `${dir}/${scene.name}`;\n }\n }\n};\n\nexport const setViewMode = (view: View, mode: ViewVisionMode) => {\n if (!(view as any).didRelease && view.mode !== mode) {\n view.mode = mode;\n }\n};\n\nexport const emitError = (error: Error) => {\n if (emitter.listenerCount(\"error\") > 0) {\n emitter.emit(\"error\", error);\n } else {\n console.log(\"[WindowManager]:\", error);\n }\n};\n\nexport const addEmitterOnceListener = (event: any, listener: any) => {\n emitter.once(event).then(listener);\n};\n\nexport const notifyMainViewModeChange = debounce(\n (callbacks: Emittery<PublicEvent>, mode: ViewVisionMode) => {\n callbacks.emit(\"mainViewModeChange\", mode);\n },\n 200\n);\n\nexport const makeValidScenePath = (displayer: Displayer, scenePath: string, index = 0) => {\n const scenes = entireScenes(displayer)[scenePath];\n if (!scenes) return;\n const firstSceneName = scenes[index].name;\n if (scenePath === \"/\") {\n return `/${firstSceneName}`;\n } else {\n return `${scenePath}/${firstSceneName}`;\n }\n};\n\nexport const entireScenes = (displayer: Displayer) => {\n return displayer.entireScenes();\n};\n\nexport const isValidScenePath = (scenePath: string) => {\n return scenePath.startsWith(\"/\");\n};\n\nexport const ensureValidScenePath = (scenePath: string) => {\n if (scenePath.endsWith(\"/\")) {\n return scenePath.slice(0, -1);\n } else {\n return scenePath;\n }\n};\n\nexport const getVersionNumber = (version: string) => {\n const versionString = version\n .split(\".\")\n .map(s => s.padStart(2, \"0\"))\n .join(\"\");\n return parseInt(versionString);\n};\n\nexport const wait = (time: number) => new Promise(resolve => setTimeout(resolve, time));\n","import { callbacks } from './index';\nimport { Events, MagixEventName } from './constants';\nimport type { Event } from \"white-web-sdk\";\nimport type { AppManager } from \"./AppManager\";\nimport type { TeleBoxState } from \"@netless/telebox-insider\";\nimport { setViewFocusScenePath } from './Utils/Common';\n\nexport class AppListeners {\n private displayer = this.manager.displayer;\n\n constructor(private manager: AppManager) {}\n\n private get boxManager() {\n return this.manager.boxManager;\n }\n\n public addListeners() {\n this.displayer.addMagixEventListener(MagixEventName, this.mainMagixEventListener);\n }\n\n public removeListeners() {\n this.displayer.removeMagixEventListener(MagixEventName, this.mainMagixEventListener);\n }\n\n private mainMagixEventListener = (event: Event) => {\n if (event.authorId !== this.displayer.observerId) {\n const data = event.payload;\n switch (data.eventName) {\n case Events.AppMove: {\n this.appMoveHandler(data.payload);\n break;\n }\n case Events.AppResize: {\n this.appResizeHandler(data.payload);\n break;\n }\n case Events.AppBoxStateChange: {\n this.boxStateChangeHandler(data.payload);\n break;\n }\n case Events.SetMainViewScenePath: {\n this.setMainViewScenePathHandler(data.payload);\n break;\n }\n case Events.MoveCameraToContain: {\n this.moveCameraToContainHandler(data.payload);\n break;\n }\n default:\n break;\n }\n }\n };\n\n private appMoveHandler = (payload: any) => {\n this.boxManager?.moveBox(payload);\n };\n\n private appResizeHandler = (payload: any) => {\n this.boxManager?.resizeBox(Object.assign(payload, { skipUpdate: true }));\n this.manager.room?.refreshViewSize();\n };\n\n private boxStateChangeHandler = (state: TeleBoxState) => {\n callbacks.emit(\"boxStateChange\", state);\n }\n\n private setMainViewScenePathHandler = ({ nextScenePath }: { nextScenePath: string }) => {\n setViewFocusScenePath(this.manager.mainView, nextScenePath);\n callbacks.emit(\"mainViewScenePathChange\", nextScenePath);\n }\n\n private moveCameraToContainHandler = (payload: any) => {\n this.manager.mainView.moveCameraToContain(payload);\n }\n}\n","\nexport class AppCreateError extends Error {\n override message = \"[WindowManager]: app duplicate exists and cannot be created again\";\n}\n\nexport class AppNotRegisterError extends Error {\n constructor(kind: string) {\n super(`[WindowManager]: app ${kind} need register or provide src`);\n }\n}\n\nexport class AppManagerNotInitError extends Error {\n override message = \"[WindowManager]: AppManager must be initialized\";\n}\n\nexport class WhiteWebSDKInvalidError extends Error {\n constructor(version: string) {\n super(`[WindowManager]: white-web-sdk version must large than ${version}`);\n }\n}\n\nexport class ParamsInvalidError extends Error {\n override message = \"[WindowManager]: kind must be a valid string\";\n}\n\nexport class BoxNotCreatedError extends Error {\n override message = \"[WindowManager]: box need created\";\n}\n\nexport class InvalidScenePath extends Error {\n override message = `[WindowManager]: ScenePath should start with \"/\"`;\n}\n\nexport class BoxManagerNotFoundError extends Error {\n override message = \"[WindowManager]: boxManager not found\";\n}\n","import { listenUpdated, unlistenUpdated, reaction, UpdateEventKind } from \"white-web-sdk\";\nimport type { AkkoObjectUpdatedProperty , AkkoObjectUpdatedListener } from \"white-web-sdk\";\nimport { isObject } from \"lodash\";\n\n// 兼容 13 和 14 版本 SDK\nexport const onObjectByEvent = (event: UpdateEventKind) => {\n return (object: any, func: () => void) => {\n if (object === undefined) return;\n if (listenUpdated) {\n const listener = (events: readonly AkkoObjectUpdatedProperty<any>[]) => {\n const kinds = events.map(e => e.kind);\n if (kinds.includes(event)) {\n func();\n }\n }\n listenUpdated(object, listener);\n func();\n return () => unlistenUpdated(object, listener);\n } else {\n return reaction(\n () => object,\n () => {\n func();\n }, {\n fireImmediately: true,\n }\n )\n }\n }\n}\n\nexport const safeListenPropsUpdated = <T>(\n getProps: () => T,\n callback: AkkoObjectUpdatedListener<T>,\n onDestroyed?: (props: unknown) => void\n ) => {\n let disposeListenUpdated: (() => void) | null = null;\n const disposeReaction = reaction(\n getProps,\n () => {\n if (disposeListenUpdated) {\n disposeListenUpdated();\n disposeListenUpdated = null;\n }\n const props = getProps();\n if (isObject(props)) {\n disposeListenUpdated = () => unlistenUpdated(props, callback);\n listenUpdated(props, callback);\n } else {\n onDestroyed?.(props);\n }\n },\n { fireImmediately: true }\n );\n\n return () => {\n disposeListenUpdated?.();\n disposeReaction();\n };\n}\n\nexport const onObjectRemoved = onObjectByEvent(UpdateEventKind.Removed);\nexport const onObjectInserted = onObjectByEvent(UpdateEventKind.Inserted);\n","import { has } from \"lodash\";\nimport { genUID } from \"side-effect-manager\";\nimport type { AutoRefValue, ExtractRawValue, RefValue } from \"./typings\";\n\nexport const plainObjectKeys = Object.keys as <T>(o: T) => Array<Extract<keyof T, string>>;\n\nexport function isRef<TValue = unknown>(e: unknown): e is RefValue<TValue> {\n return Boolean(has(e, '__isRef'));\n}\n\nexport function makeRef<TValue>(v: TValue): RefValue<TValue> {\n return { k: genUID(), v, __isRef: true };\n}\n\nexport function makeAutoRef<TValue>(v: TValue): AutoRefValue<TValue> {\n return isRef<ExtractRawValue<TValue>>(v) ? v : makeRef(v as ExtractRawValue<TValue>);\n}\n","export type StorageEventListener<T> = (event: T) => void;\n\nexport class StorageEvent<TMessage> {\n listeners = new Set<StorageEventListener<TMessage>>();\n\n get length(): number {\n return this.listeners.size;\n }\n\n dispatch(message: TMessage): void {\n this.listeners.forEach(callback => callback(message));\n }\n\n addListener(listener: StorageEventListener<TMessage>): void {\n this.listeners.add(listener);\n }\n\n removeListener(listener: StorageEventListener<TMessage>): void {\n this.listeners.delete(listener);\n }\n}\n","import type { AkkoObjectUpdatedProperty } from \"white-web-sdk\";\nimport { get, has, mapValues, isObject, size, noop } from \"lodash\";\nimport { SideEffectManager } from \"side-effect-manager\";\nimport type { AppContext } from \"../../AppContext\";\nimport { safeListenPropsUpdated } from \"../../Utils/Reactive\";\nimport { isRef, makeRef, plainObjectKeys } from \"./utils\";\nimport type { Diff, MaybeRefValue, RefValue, StorageStateChangedEvent } from \"./typings\";\nimport { StorageEvent } from \"./StorageEvent\";\n\nexport * from './typings';\n\nexport const STORAGE_NS = \"_WM-STORAGE_\";\n\nexport class Storage<TState extends Record<string, any> = any> implements Storage<TState> {\n readonly id: string | null;\n\n private readonly _context: AppContext;\n private readonly _sideEffect = new SideEffectManager();\n private _state: TState;\n private _destroyed = false;\n\n private _refMap = new WeakMap<any, RefValue>();\n\n /**\n * `setState` alters local state immediately before sending to server. This will cache the old value for onStateChanged diffing.\n */\n private _lastValue = new Map<string | number | symbol, TState[Extract<keyof TState, string>]>();\n\n constructor(context: AppContext, id?: string, defaultState?: TState) {\n if (defaultState && !isObject(defaultState)) {\n throw new Error(`Default state for Storage ${id} is not an object.`);\n }\n\n this._context = context;\n this.id = id || null;\n\n this._state = {} as TState;\n const rawState = this._getRawState(this._state);\n\n if (this.id !== null && this._context.getIsWritable()) {\n if (rawState === this._state || !isObject(rawState)) {\n if (!get(this._context.getAttributes(), [STORAGE_NS])) {\n this._context.updateAttributes([STORAGE_NS], {});\n }\n this._context.updateAttributes([STORAGE_NS, this.id], this._state);\n }\n if (defaultState) {\n this.setState(defaultState);\n }\n }\n\n // strip mobx\n plainObjectKeys(rawState).forEach(key => {\n if (this.id === null && key === STORAGE_NS) {\n return;\n }\n try {\n const rawValue = isObject(rawState[key]) ? JSON.parse(JSON.stringify(rawState[key])) : rawState[key];\n if (isRef<TState[Extract<keyof TState, string>]>(rawValue)) {\n this._state[key] = rawValue.v;\n if (isObject(rawValue.v)) {\n this._refMap.set(rawValue.v, rawValue);\n }\n } else {\n this._state[key] = rawValue;\n }\n } catch (e) {\n console.error(e);\n }\n });\n\n this._sideEffect.addDisposer(\n safeListenPropsUpdated(\n () => this.id === null ? context.getAttributes() : get(context.getAttributes(), [STORAGE_NS, this.id]),\n this._updateProperties.bind(this),\n this.destroy.bind(this)\n )\n );\n }\n\n get state(): Readonly<TState> {\n if (this._destroyed) {\n console.warn(`Accessing state on destroyed Storage \"${this.id}\"`)\n }\n return this._state;\n }\n\n readonly onStateChanged = new StorageEvent<StorageStateChangedEvent<TState>>();\n\n ensureState(state: Partial<TState>): void {\n return this.setState(\n plainObjectKeys(state).reduce((payload, key) => {\n if (!has(this._state, key)) {\n payload[key] = state[key];\n }\n return payload;\n }, {} as Partial<TState>)\n );\n }\n\n setState(state: Partial<TState>): void {\n if (this._destroyed) {\n console.error(new Error(`Cannot call setState on destroyed Storage \"${this.id}\".`));\n return;\n }\n\n if (!this._context.getIsWritable()) {\n console.error(new Error(`Cannot setState on Storage \"${this.id}\" without writable access`), state);\n return;\n }\n\n const keys = plainObjectKeys(state);\n if (keys.length > 0) {\n keys.forEach(key => {\n const value = state[key];\n if (value === this._state[key]) {\n return;\n }\n\n if (value === void 0) {\n this._lastValue.set(key, this._state[key]);\n delete this._state[key];\n this._setRawState(key, value);\n } else {\n this._lastValue.set(key, this._state[key]);\n this._state[key] = value as TState[Extract<keyof TState, string>];\n\n let payload: MaybeRefValue<typeof value> = value;\n if (isObject(value)) {\n let refValue = this._refMap.get(value);\n if (!refValue) {\n refValue = makeRef(value);\n this._refMap.set(value, refValue);\n }\n payload = refValue;\n }\n\n this._setRawState(key, payload)\n }\n });\n }\n }\n\n /**\n * Empty storage data.\n */\n emptyStorage(): void {\n if (size(this._state) <= 0) {\n return;\n }\n\n if (this._destroyed) {\n console.error(new Error(`Cannot empty destroyed Storage \"${this.id}\".`));\n return;\n }\n\n if (!this._context.getIsWritable()) {\n console.error(new Error(`Cannot empty Storage \"${this.id}\" without writable access.`));\n return;\n }\n\n this.setState(mapValues(this._state, noop as () => undefined));\n }\n\n /**\n * Delete storage index with all of its data and destroy the Storage instance.\n */\n deleteStorage(): void {\n if (this.id === null) {\n throw new Error(`Cannot delete main Storage`);\n }\n\n if (!this._context.getIsWritable()) {\n console.error(new Error(`Cannot delete Storage \"${this.id}\" without writable access.`));\n return;\n }\n\n this.destroy();\n\n this._context.updateAttributes([STORAGE_NS, this.id], void 0);\n }\n\n get destroyed(): boolean {\n return this._destroyed;\n }\n\n /**\n * Destroy the Storage instance. The data will be kept.\n */\n destroy() {\n this._destroyed = true;\n this._sideEffect.flushAll();\n }\n\n private _getRawState(): TState | undefined\n private _getRawState(defaultValue: TState): TState\n private _getRawState(defaultValue?: TState): TState | undefined {\n if (this.id === null) {\n return get(this._context.getAttributes(), [], defaultValue);\n } else {\n return get(this._context.getAttributes(), [STORAGE_NS, this.id], defaultValue);\n }\n }\n\n private _setRawState(key: string, value: any): void {\n if (this.id === null) {\n if (key === STORAGE_NS) {\n throw new Error(`Cannot set attribute internal filed \"${STORAGE_NS}\"`)\n }\n return this._context.updateAttributes([key], value);\n } else {\n return this._context.updateAttributes([STORAGE_NS, this.id, key], value);\n }\n }\n\n private _updateProperties(actions: ReadonlyArray<AkkoObjectUpdatedProperty<TState, string>>): void {\n if (this._destroyed) {\n console.error(new Error(`Cannot call _updateProperties on destroyed Storage \"${this.id}\".`));\n return;\n }\n\n if (actions.length > 0) {\n const diffs: Diff<TState> = {};\n\n for (let i = 0; i < actions.length; i++) {\n try {\n const action = actions[i]\n const key = action.key as Extract<keyof TState, string>;\n\n if (this.id === null && key === STORAGE_NS) {\n continue\n }\n\n const value = isObject(action.value) ? JSON.parse(JSON.stringify(action.value)) : action.value;\n let oldValue: TState[Extract<keyof TState, string>] | undefined;\n if (this._lastValue.has(key)) {\n oldValue = this._lastValue.get(key);\n this._lastValue.delete(key);\n }\n\n switch (action.kind) {\n case 2: {\n // Removed\n if (has(this._state, key)) {\n oldValue = this._state[key];\n delete this._state[key];\n }\n diffs[key] = { oldValue };\n break;\n }\n default: {\n let newValue = value;\n\n if (isRef<TState[Extract<keyof TState, string>]>(value)) {\n const { k, v } = value;\n const curValue = this._state[key];\n if (isObject(curValue) && this._refMap.get(curValue)?.k === k) {\n newValue = curValue;\n } else {\n newValue = v;\n if (isObject(v)) {\n this._refMap.set(v, value);\n }\n }\n }\n\n if (newValue !== this._state[key]) {\n oldValue = this._state[key];\n this._state[key] = newValue;\n }\n\n diffs[key] = { newValue, oldValue };\n break;\n }\n }\n } catch (e) {\n console.error(e)\n }\n }\n\n this.onStateChanged.dispatch(diffs);\n }\n }\n}\n","import {\n autorun,\n listenDisposed,\n listenUpdated,\n reaction,\n unlistenDisposed,\n unlistenUpdated,\n toJS\n} from 'white-web-sdk';\nimport { BoxNotCreatedError } from './Utils/error';\nimport type { Room, SceneDefinition, View } from \"white-web-sdk\";\nimport type { ReadonlyTeleBox } from \"@netless/telebox-insider\";\nimport type Emittery from \"emittery\";\nimport type { BoxManager } from \"./BoxManager\";\nimport type { AppEmitterEvent } from \"./index\";\nimport type { AppManager } from \"./AppManager\";\nimport type { AppProxy } from \"./AppProxy\";\nimport { Storage } from './App/Storage';\nimport type { MagixEventAddListener, MagixEventDispatcher, MagixEventRemoveListener } from './App/MagixEvent';\n\nexport class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOptions = any> {\n public readonly emitter: Emittery<AppEmitterEvent<TAttributes>>;\n public readonly mobxUtils = {\n autorun,\n reaction,\n toJS\n };\n public readonly objectUtils = {\n listenUpdated,\n unlistenUpdated,\n listenDisposed,\n unlistenDisposed\n };\n\n private store = this.manager.store;\n public readonly isAddApp: boolean;\n public readonly isReplay = this.manager.isReplay;\n\n constructor(\n private manager: AppManager,\n private boxManager: BoxManager,\n public appId: string,\n private appProxy: AppProxy,\n private appOptions?: TAppOptions | (() => TAppOptions),\n ) {\n this.emitter = appProxy.appEmitter;\n this.isAddApp = appProxy.isAddApp;\n }\n\n public getDisplayer = () => {\n return this.manager.displayer;\n }\n\n /** @deprecated Use context.storage.state instead. */\n public getAttributes = (): TAttributes | undefined => {\n return this.appProxy.attributes;\n }\n\n public getScenes = (): SceneDefinition[] | undefined => {\n const appAttr = this.store.getAppAttributes(this.appId);\n if (appAttr?.isDynamicPPT) {\n const appProxy = this.manager.appProxies.get(this.appId);\n if (appProxy) {\n return appProxy.scenes;\n }\n } else {\n return appAttr?.options[\"scenes\"];\n }\n }\n\n public getView = (): View | undefined => {\n return this.appProxy.view;\n }\n\n public getInitScenePath = () => {\n return this.manager.getAppInitPath(this.appId);\n }\n\n /** Get App writable status. */\n public getIsWritable = (): boolean => {\n return this.manager.canOperate;\n }\n\n /** Get the App Window UI box. */\n public getBox = (): ReadonlyTeleBox => {\n const box = this.boxManager.getBox(this.appId);\n if (box) {\n return box;\n } else {\n throw new BoxNotCreatedError();\n }\n }\n\n public getRoom = (): Room | undefined => {\n return this.manager.room;\n }\n\n /** @deprecated Use context.storage.setState instead. */\n public setAttributes = (attributes: TAttributes) => {\n this.manager.safeSetAttributes({ [this.appId]: attributes });\n }\n\n /** @deprecated Use context.storage.setState instead. */\n public updateAttributes = (keys: string[], value: any) => {\n if (this.manager.attributes[this.appId]) {\n this.manager.safeUpdateAttributes([this.appId, ...keys], value);\n }\n }\n\n public setScenePath = async (scenePath: string): Promise<void> => {\n if (!this.appProxy.box) return;\n this.appProxy.setFullPath(scenePath);\n }\n\n public mountView = (dom: HTMLDivElement): void => {\n const view = this.getView();\n if (view) {\n view.divElement = dom;\n setTimeout(() => {\n // 渲染需要时间,延迟 refresh\n this.getRoom()?.refreshViewSize();\n }, 1000);\n }\n }\n\n /** Get the local App options. */\n public getAppOptions = (): TAppOptions | undefined => {\n return typeof this.appOptions === 'function' ? (this.appOptions as () => TAppOptions)() : this.appOptions\n }\n\n private _storage?: Storage<TAttributes>\n\n /** Main Storage for attributes. */\n public get storage(): Storage<TAttributes> {\n if (!this._storage) {\n this._storage = new Storage(this);\n }\n return this._storage;\n }\n\n /**\n * Create separated storages for flexible state management.\n * @param storeId Namespace for the storage. Storages of the same namespace share the same data.\n * @param defaultState Default state for initial storage creation.\n * @returns \n */\n public createStorage = <TState>(storeId: string, defaultState?: TState): Storage<TState> => {\n const storage = new Storage(this, storeId, defaultState);\n this.emitter.on(\"destroy\", () => {\n storage.destroy();\n });\n return storage;\n }\n\n /** Dispatch events to other clients (and self). */\n public dispatchMagixEvent: MagixEventDispatcher<TMagixEventPayloads> = (this.manager.displayer as Room).dispatchMagixEvent.bind(this.manager.displayer)\n\n /** Listen to events from others clients (and self messages). */\n public addMagixEventListener: MagixEventAddListener<TMagixEventPayloads> = this.manager.displayer.addMagixEventListener.bind(this.manager.displayer)\n\n /** Remove a Magix event listener. */\n public removeMagixEventListener = this.manager.displayer.removeMagixEventListener.bind(this.manager.displayer) as MagixEventRemoveListener<TMagixEventPayloads>\n}\n","import { AppAttributes } from \"./constants\";\nimport { get, pick } from \"lodash\";\nimport { setViewFocusScenePath } from \"./Utils/Common\";\nimport type { AddAppParams, AppSyncAttributes } from \"./index\";\nimport type { Camera, Size, View } from \"white-web-sdk\";\nimport type { Cursor } from \"./Cursor/Cursor\";\n\nexport enum Fields {\n Apps = \"apps\",\n Focus = \"focus\",\n State = \"state\",\n BoxState = \"boxState\",\n MainViewCamera = \"mainViewCamera\",\n MainViewSize = \"mainViewSize\",\n Broadcaster = \"broadcaster\",\n Cursors = \"cursors\",\n Position = \"position\",\n CursorState = \"cursorState\",\n FullPath = \"fullPath\",\n}\n\nexport type Apps = {\n [key: string]: AppSyncAttributes;\n};\n\nexport type Position = {\n x: number;\n y: number;\n type: PositionType;\n id?: string;\n};\n\nexport type PositionType = \"main\" | \"app\";\n\nexport type StoreContext = {\n getAttributes: () => any;\n safeUpdateAttributes: (keys: string[], value: any) => void;\n safeSetAttributes: (attributes: any) => void;\n}\nexport class AttributesDelegate {\n\n constructor(private context: StoreContext) {}\n\n public setContext(context: StoreContext) {\n this.context = context;\n }\n\n public get attributes() {\n return this.context.getAttributes();\n }\n\n public apps(): Apps {\n return get(this.attributes, [Fields.Apps]);\n }\n\n public get focus(): string | undefined {\n return get(this.attributes, [Fields.Focus]);\n }\n\n public getAppAttributes(id: string): AppSyncAttributes {\n return get(this.apps(), [id]);\n }\n\n public getAppState(id: string) {\n return get(this.apps(), [id, Fields.State]);\n }\n\n public getMaximized() {\n return get(this.attributes, [\"maximized\"]);\n }\n\n public getMinimized() {\n return get(this.attributes, [\"minimized\"]);\n }\n\n public setupAppAttributes(params: AddAppParams, id: string, isDynamicPPT: boolean) {\n const attributes = this.attributes;\n if (!attributes.apps) {\n this.context.safeSetAttributes({ apps: {} });\n }\n const attrNames = [\"scenePath\", \"title\"];\n if (!isDynamicPPT) {\n attrNames.push(\"scenes\");\n }\n const options = pick(params.options, attrNames);\n const attrs: AppSyncAttributes = { kind: params.kind, options, isDynamicPPT };\n if (typeof params.src === \"string\") {\n attrs.src = params.src;\n }\n attrs.createdAt = Date.now();\n this.context.safeUpdateAttributes([Fields.Apps, id], attrs);\n this.context.safeUpdateAttributes([Fields.Apps, id, Fields.State], {\n [AppAttributes.Size]: {},\n [AppAttributes.Position]: {},\n [AppAttributes.SceneIndex]: 0,\n });\n }\n\n public updateAppState(appId: string, stateName: AppAttributes, state: any) {\n if (get(this.attributes, [Fields.Apps, appId, Fields.State])) {\n this.context.safeUpdateAttributes([Fields.Apps, appId, Fields.State, stateName], state);\n }\n }\n\n public cleanAppAttributes(id: string) {\n this.context.safeUpdateAttributes([Fields.Apps, id], undefined);\n this.context.safeSetAttributes({ [id]: undefined });\n const focus = this.attributes[Fields.Focus];\n if (focus === id) {\n this.cleanFocus();\n }\n }\n\n public cleanFocus() {\n this.context.safeSetAttributes({ [Fields.Focus]: undefined });\n }\n\n public getAppSceneIndex(id: string) {\n return this.getAppState(id)?.[AppAttributes.SceneIndex];\n }\n\n public getAppScenePath(id: string) {\n return this.getAppAttributes(id)?.options?.scenePath;\n }\n\n public getMainViewScenePath() {\n return this.attributes[\"_mainScenePath\"];\n }\n\n public getMainViewSceneIndex() {\n return this.attributes[\"_mainSceneIndex\"];\n }\n\n public getBoxState() {\n return this.attributes[Fields.BoxState];\n }\n\n public setMainViewScenePath(scenePath: string) {\n this.context.safeSetAttributes({ _mainScenePath: scenePath });\n }\n\n public setMainViewSceneIndex(index: number) {\n this.context.safeSetAttributes({ _mainSceneIndex: index });\n }\n\n public getMainViewCamera(): MainViewCamera {\n return get(this.attributes, [Fields.MainViewCamera]);\n }\n\n public getMainViewSize(): MainViewSize {\n return get(this.attributes, [Fields.MainViewSize]);\n }\n\n public setMainViewCamera(camera: (Camera & { id: string }) | undefined) {\n this.context.safeSetAttributes({ [Fields.MainViewCamera]: { ...camera } });\n }\n\n public setMainViewSize(size: (Size & { id: string }) | undefined) {\n this.context.safeSetAttributes({ [Fields.MainViewSize]: { ...size } });\n }\n\n public setAppFocus(appId: string, focus: boolean) {\n if (focus) {\n this.context.safeSetAttributes({ [Fields.Focus]: appId });\n } else {\n this.context.safeSetAttributes({ [Fields.Focus]: undefined });\n }\n }\n\n public updateCursor(uid: string, position: Position) {\n if (!get(this.attributes, [Fields.Cursors])) {\n this.context.safeUpdateAttributes([Fields.Cursors], {});\n }\n if (!get(this.attributes, [Fields.Cursors, uid])) {\n this.context.safeUpdateAttributes([Fields.Cursors, uid], {});\n }\n this.context.safeUpdateAttributes([Fields.Cursors, uid, Fields.Position], position);\n }\n\n public updateCursorState(uid: string, cursorState: string | undefined) {\n if (!get(this.attributes, [Fields.Cursors, uid])) {\n this.context.safeUpdateAttributes([Fields.Cursors, uid], {});\n }\n this.context.safeUpdateAttributes([Fields.Cursors, uid, Fields.CursorState], cursorState);\n }\n\n public getCursorState(uid: string) {\n return get(this.attributes, [Fields.Cursors, uid, Fields.CursorState]);\n }\n\n public cleanCursor(uid: string) {\n this.context.safeUpdateAttributes([Fields.Cursors, uid], undefined);\n }\n\n // TODO 状态中保存一个 SceneName 优化性能\n public setMainViewFocusPath(mainView: View) {\n const scenePath = this.getMainViewScenePath();\n if (scenePath) {\n setViewFocusScenePath(mainView, scenePath);\n }\n }\n}\n\nexport type MainViewSize = {\n id: string;\n width: number;\n height: number;\n};\n\nexport type MainViewCamera = {\n id: string;\n centerX: number;\n centerY: number;\n scale: number;\n};\n\nexport type Cursors = {\n [key: string]: Cursor;\n};\n\n\nexport const store = new AttributesDelegate({\n getAttributes: () => {\n throw new Error(\"getAttributes not implemented\")\n },\n safeSetAttributes: () => {\n throw new Error(\"safeSetAttributes not implemented\")\n },\n safeUpdateAttributes: () => {\n throw new Error(\"safeUpdateAttributes not implemented\")\n },\n});\n","import { WindowManager } from \"../index\";\n\nexport const log = (...args: any[]): void => {\n if (WindowManager.debug) {\n console.log(`[WindowManager]:`, ...args);\n }\n};\n","import { emitter } from \"../index\";\nimport type { AppManager } from \"../AppManager\";\n\nexport class Context {\n public observerId: number;\n\n constructor(private manager: AppManager) {\n this.observerId = manager.displayer.observerId;\n\n emitter.on(\"observerIdChange\", id => {\n this.observerId = id;\n });\n };\n\n public get uid() {\n return this.manager.room?.uid || \"\";\n }\n\n public findMember = (memberId: number) => {\n const roomMembers = this.manager.room?.state.roomMembers;\n return roomMembers?.find(member => member.memberId === memberId);\n }\n\n public findMemberByUid = (uid: string) => {\n const roomMembers = this.manager.room?.state.roomMembers;\n return roomMembers?.find(member => member.payload?.uid === uid);\n }\n\n public updateManagerRect() {\n this.manager.boxManager?.updateManagerRect();\n }\n\n public blurFocusBox() {\n this.manager.boxManager?.blurAllBox();\n }\n}\n\nlet context: Context;\n\nexport const createContext = (manager: AppManager) => {\n if (!context) {\n context = new Context(manager);\n }\n return context;\n};\n","import type { AppManager } from \"../AppManager\";\nimport { store } from \"../AttributesDelegate\";\nimport { createContext } from \"./Context\";\n\nexport class Base {\n public store = store;\n public context = createContext(this.manager);\n\n constructor(public manager: AppManager) {}\n}\n","import Emittery from \"emittery\";\nimport { AppAttributes, AppEvents, Events } from \"./constants\";\nimport { AppContext } from \"./AppContext\";\nimport { appRegister } from \"./Register\";\nimport { autorun } from \"white-web-sdk\";\nimport { emitter } from \"./index\";\nimport { Fields } from \"./AttributesDelegate\";\nimport { get } from \"lodash\";\nimport { log } from \"./Utils/log\";\nimport {\n setScenePath,\n setViewFocusScenePath,\n getScenePath\n} from \"./Utils/Common\";\nimport type {\n AppEmitterEvent,\n AppInitState,\n BaseInsertParams,\n setAppOptions,\n AppListenerKeys,\n} from \"./index\";\nimport type { SceneState, View, SceneDefinition } from \"white-web-sdk\";\nimport type { AppManager } from \"./AppManager\";\nimport type { NetlessApp } from \"./typings\";\nimport type { ReadonlyTeleBox } from \"@netless/telebox-insider\";\nimport { Base } from \"./Base\";\nimport { BoxManagerNotFoundError } from \"./Utils/error\";\n\nexport class AppProxy extends Base {\n public id: string;\n public scenePath?: string;\n public appEmitter: Emittery<AppEmitterEvent>;\n public scenes?: SceneDefinition[];\n\n private appListener: any;\n private boxManager = this.manager.boxManager;\n private appProxies = this.manager.appProxies;\n private viewManager = this.manager.viewManager;\n private kind: string;\n public isAddApp: boolean;\n private status: \"normal\" | \"destroyed\" = \"normal\";\n private stateKey: string;\n private appResult?: NetlessApp<any>;\n private appContext?: AppContext<any, any>;\n\n constructor(\n private params: BaseInsertParams,\n manager: AppManager,\n appId: string,\n isAddApp: boolean\n ) {\n super(manager);\n this.kind = params.kind;\n this.id = appId;\n this.stateKey = `${this.id}_state`;\n this.appProxies.set(this.id, this);\n this.appEmitter = new Emittery();\n this.appListener = this.makeAppEventListener(this.id);\n this.isAddApp = isAddApp;\n\n this.initScenes();\n\n if (this.params.options?.scenePath) {\n // 只有传入了 scenePath 的 App 才会创建 View\n this.createView();\n }\n }\n\n private initScenes() {\n const options = this.params.options;\n if (options) {\n this.scenePath = options.scenePath;\n if (this.appAttributes?.isDynamicPPT && this.scenePath) {\n this.scenes = this.manager.displayer.entireScenes()[this.scenePath];\n } else {\n this.scenes = options.scenes;\n }\n }\n }\n\n public get view(): View | undefined {\n return this.manager.viewManager.getView(this.id);\n }\n\n public get isWritable(): boolean {\n return this.manager.canOperate && !this.box?.readonly;\n }\n\n public get attributes() {\n return this.manager.attributes[this.id];\n }\n\n public get appAttributes() {\n return this.store.getAppAttributes(this.id);\n }\n\n public getFullScenePath(): string | undefined {\n if (this.scenePath) {\n return get(this.appAttributes, [Fields.FullPath], this.getFullScenePathFromScenes());\n }\n }\n\n private getFullScenePathFromScenes() {\n const sceneIndex = get(this.appAttributes, [\"state\", \"SceneIndex\"], 0);\n const fullPath = getScenePath(this.manager.room, this.scenePath, sceneIndex);\n if (fullPath) {\n this.setFullPath(fullPath);\n }\n return fullPath;\n }\n\n public setFullPath(path: string) {\n this.manager.safeUpdateAttributes([\"apps\", this.id, Fields.FullPath], path);\n }\n\n public async baseInsertApp(\n skipUpdate = false,\n ): Promise<{ appId: string; app: NetlessApp }> {\n const params = this.params;\n if (!params.kind) {\n throw new Error(\"[WindowManager]: kind require\");\n }\n const appImpl = await appRegister.appClasses.get(params.kind)?.();\n const appParams = appRegister.registered.get(params.kind);\n if (appImpl) {\n await this.setupApp(this.id, skipUpdate, appImpl, params.options, appParams?.appOptions);\n } else {\n throw new Error(`[WindowManager]: app load failed ${params.kind} ${params.src}`);\n }\n this.context.updateManagerRect();\n return {\n appId: this.id,\n app: appImpl,\n };\n }\n\n private focusApp() {\n this.focusBox();\n this.store.setMainViewFocusPath(this.manager.mainView);\n }\n\n public get box(): ReadonlyTeleBox | undefined {\n return this.boxManager?.getBox(this.id);\n }\n\n public focusBox() {\n this.boxManager?.focusBox({ appId: this.id });\n }\n\n private async setupApp(\n appId: string,\n skipUpdate: boolean,\n app: NetlessApp,\n options?: setAppOptions,\n appOptions?: any\n ) {\n log(\"setupApp\", appId, app, options);\n if (!this.boxManager) {\n throw new BoxManagerNotFoundError();\n }\n const context = new AppContext(this.manager, this.boxManager, appId, this, appOptions);\n this.appContext = context;\n try {\n emitter.once(`${appId}${Events.WindowCreated}` as any).then(async () => {\n let boxInitState: AppInitState | undefined;\n if (!skipUpdate) {\n boxInitState = this.getAppInitState(appId);\n this.boxManager?.updateBoxState(boxInitState);\n }\n this.appEmitter.onAny(this.appListener);\n this.appAttributesUpdateListener(appId);\n this.setViewFocusScenePath();\n setTimeout(async () => {\n // 延迟执行 setup, 防止初始化的属性没有更新成功\n const result = await app.setup(context);\n this.appResult = result;\n appRegister.notifyApp(app.kind, \"created\", { appId, result });\n this.afterSetupApp(boxInitState);\n this.fixMobileSize();\n }, 50);\n });\n this.boxManager?.createBox({\n appId: appId,\n app,\n options,\n canOperate: this.manager.canOperate,\n smartPosition: this.isAddApp,\n });\n } catch (error: any) {\n console.error(error);\n throw new Error(`[WindowManager]: app setup error: ${error.message}`);\n }\n }\n\n // 兼容移动端创建时会出现 PPT 不适配的问题\n private fixMobileSize() {\n const box = this.boxManager?.getBox(this.id);\n if (box) {\n this.boxManager?.resizeBox({\n appId: this.id,\n width: box.intrinsicWidth + 0.001,\n height: box.intrinsicHeight + 0.001,\n skipUpdate: true,\n });\n }\n }\n\n private afterSetupApp(boxInitState: AppInitState | undefined): void {\n if (boxInitState) {\n if (!boxInitState?.x || !boxInitState.y) {\n this.boxManager?.setBoxInitState(this.id);\n }\n }\n }\n\n public onSeek(time: number) {\n this.appEmitter.emit(\"seek\", time);\n const boxInitState = this.getAppInitState(this.id);\n this.boxManager?.updateBoxState(boxInitState);\n }\n\n public async onReconnected() {\n this.appEmitter.emit(\"reconnected\", undefined);\n const currentAppState = this.getAppInitState(this.id);\n await this.destroy(true, false, true);\n const params = this.params;\n const appProxy = new AppProxy(params, this.manager, this.id, this.isAddApp);\n await appProxy.baseInsertApp(true);\n this.boxManager?.updateBoxState(currentAppState);\n }\n\n public getAppInitState = (id: string) => {\n const attrs = this.store.getAppState(id);\n if (!attrs) return;\n const position = attrs?.[AppAttributes.Position];\n const focus = this.store.focus;\n const size = attrs?.[AppAttributes.Size];\n const sceneIndex = attrs?.[AppAttributes.SceneIndex];\n const maximized = this.attributes?.[\"maximized\"];\n const minimized = this.attributes?.[\"minimized\"];\n const zIndex = attrs?.zIndex;\n let payload = { maximized, minimized, zIndex } as AppInitState;\n if (position) {\n payload = { ...payload, id: id, x: position.x, y: position.y };\n }\n if (focus === id) {\n payload = { ...payload, focus: true };\n }\n if (size) {\n payload = { ...payload, width: size.width, height: size.height };\n }\n if (sceneIndex) {\n payload = { ...payload, sceneIndex };\n }\n return payload;\n };\n\n public emitAppSceneStateChange(sceneState: SceneState) {\n this.appEmitter.emit(\"sceneStateChange\", sceneState);\n }\n\n public emitAppIsWritableChange() {\n this.appEmitter.emit(\"writableChange\", this.isWritable);\n }\n\n private makeAppEventListener(appId: string) {\n return (eventName: AppListenerKeys, data: any) => {\n if (!this.manager.canOperate) return;\n switch (eventName) {\n case \"setBoxSize\": {\n this.boxManager?.resizeBox({\n appId,\n width: data.width,\n height: data.height,\n skipUpdate: false,\n });\n break;\n }\n case \"setBoxMinSize\": {\n this.boxManager?.setBoxMinSize({\n appId,\n minWidth: data.minwidth,\n minHeight: data.minheight,\n });\n break;\n }\n case \"setBoxTitle\": {\n this.boxManager?.setBoxTitle({ appId, title: data.title });\n break;\n }\n case AppEvents.destroy: {\n if (this.status === \"destroyed\") return;\n this.destroy(true, false, true, data?.error);\n if (data?.error) {\n console.error(data?.error);\n }\n break;\n }\n case \"focus\": {\n this.boxManager?.focusBox({ appId: this.id });\n emitter.emit(\"focus\", { appId: this.id });\n break;\n }\n default: {\n break;\n }\n }\n };\n }\n\n private appAttributesUpdateListener = (appId: string) => {\n this.manager.refresher?.add(appId, () => {\n return autorun(() => {\n const attrs = this.manager.attributes[appId];\n if (attrs) {\n this.appEmitter.emit(\"attributesUpdate\", attrs);\n }\n });\n });\n this.manager.refresher?.add(this.stateKey,() => {\n return autorun(() => {\n const appState = this.appAttributes?.state;\n if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {\n this.boxManager?.setZIndex(appId, appState.zIndex);\n }\n });\n });\n };\n\n public setScenePath(): void {\n if (!this.manager.canOperate) return;\n const fullScenePath = this.getFullScenePath();\n if (this.manager.room && fullScenePath && this.view) {\n setScenePath(this.manager.room, fullScenePath);\n }\n }\n\n public setViewFocusScenePath() {\n const fullPath = this.getFullScenePath();\n if (fullPath && this.view) {\n setViewFocusScenePath(this.view, fullPath);\n }\n }\n\n private async createView(): Promise<View> {\n const view = await this.viewManager.createView(this.id);\n this.setViewFocusScenePath();\n return view;\n }\n\n public async destroy(\n needCloseBox: boolean,\n cleanAttrs: boolean,\n skipUpdate: boolean,\n error?: Error\n ) {\n if (this.status === \"destroyed\") return;\n this.status = \"destroyed\";\n await appRegister.notifyApp(this.kind, \"destroy\", { appId: this.id });\n await this.appEmitter.emit(\"destroy\", { error });\n this.appEmitter.clearListeners();\n emitter.emit(`destroy-${this.id}` as any, { error });\n if (needCloseBox) {\n this.boxManager?.closeBox(this.id, skipUpdate);\n }\n if (cleanAttrs) {\n this.store.cleanAppAttributes(this.id);\n }\n this.appProxies.delete(this.id);\n\n this.viewManager.destroyView(this.id);\n this.manager.appStatus.delete(this.id);\n this.manager.refresher?.remove(this.id);\n this.manager.refresher?.remove(this.stateKey);\n }\n\n public close(): Promise<void> {\n return this.destroy(true, true, false);\n }\n}\n","import type { View , Displayer} from \"white-web-sdk\";\n\nexport class ViewManager {\n public views: Map<string, View> = new Map();\n\n constructor(private displayer: Displayer) {}\n\n public createView(id: string): View {\n const view = createView(this.displayer);\n this.views.set(id, view);\n return view;\n }\n\n public getView(id: string): View | undefined {\n return this.views.get(id);\n }\n\n public destroyView(id: string): void {\n const view = this.views.get(id);\n if (view) {\n view.release();\n this.views.delete(id);\n }\n }\n\n public setViewScenePath(id: string, scenePath: string): void {\n const view = this.views.get(id);\n if (view) {\n view.focusScenePath = scenePath;\n }\n }\n\n public destroy() {\n this.views.forEach(view => {\n view.release();\n });\n this.views.clear();\n }\n}\n\n\nexport const createView = (displayer: Displayer): View => {\n const view = displayer.views.createView();\n setDefaultCameraBound(view);\n return view;\n};\n\nexport const setDefaultCameraBound = (view: View) => {\n view.setCameraBound({\n maxContentMode: () => 10,\n minContentMode: () => 0.1,\n });\n};\n","import { AnimationMode, reaction } from \"white-web-sdk\";\nimport { Base } from \"../Base\";\nimport { callbacks, emitter } from \"../index\";\nimport { createView } from \"./ViewManager\";\nimport { debounce, isEmpty, isEqual } from \"lodash\";\nimport { Fields } from \"../AttributesDelegate\";\nimport { setViewFocusScenePath } from \"../Utils/Common\";\nimport { SideEffectManager } from \"side-effect-manager\";\nimport type { Camera, Size, View } from \"white-web-sdk\";\nimport type { AppManager } from \"../AppManager\";\n\nexport class MainViewProxy extends Base {\n private scale?: number;\n private started = false;\n private mainViewIsAddListener = false;\n private mainView: View;\n private viewId = \"mainView\";\n\n private sideEffectManager = new SideEffectManager();\n\n constructor(manager: AppManager) {\n super(manager);\n this.mainView = this.createMainView();\n this.moveCameraSizeByAttributes();\n emitter.once(\"mainViewMounted\").then(() => {\n this.addMainViewListener();\n setTimeout(() => {\n this.start();\n if (!this.mainViewCamera || !this.mainViewSize) {\n this.setCameraAndSize();\n }\n }, 200); // 等待 mainView 挂载完毕再进行监听,否则会触发不必要的 onSizeUpdated\n });\n const playgroundSizeChangeListener = () => {\n this.sizeChangeHandler(this.mainViewSize);\n };\n this.sideEffectManager.add(() => {\n emitter.on(\"playgroundSizeChange\", playgroundSizeChangeListener);\n return () => emitter.off(\"playgroundSizeChange\", playgroundSizeChangeListener);\n });\n }\n\n private get mainViewCamera() {\n return this.store.getMainViewCamera();\n }\n\n private get mainViewSize() {\n return this.store.getMainViewSize();\n }\n\n private moveCameraSizeByAttributes() {\n this.moveCameraToContian(this.mainViewSize);\n this.moveCamera(this.mainViewCamera);\n }\n\n public start() {\n if (this.started) return;\n this.sizeChangeHandler(this.mainViewSize);\n this.addCameraListener();\n this.manager.refresher?.add(Fields.MainViewCamera, this.cameraReaction);\n this.started = true;\n }\n\n public setCameraAndSize(): void {\n this.store.setMainViewCamera({ ...this.mainView.camera, id: this.context.uid });\n this.store.setMainViewSize({ ...this.mainView.size, id: this.context.uid });\n }\n\n private cameraReaction = () => {\n return reaction(\n () => this.mainViewCamera,\n camera => {\n if (camera && camera.id !== this.context.uid) {\n this.moveCameraToContian(this.mainViewSize);\n this.moveCamera(camera);\n }\n },\n {\n fireImmediately: true,\n }\n );\n };\n\n private sizeChangeHandler = debounce((size: Size) => {\n if (size) {\n this.moveCameraToContian(size);\n this.moveCamera(this.mainViewCamera);\n }\n }, 30);\n\n public get view(): View {\n return this.mainView;\n }\n\n public get cameraState() {\n return { ...this.view.camera, ...this.view.size };\n }\n\n public createMainView(): View {\n const mainView = createView(this.manager.displayer);\n const mainViewScenePath = this.store.getMainViewScenePath();\n if (mainViewScenePath) {\n setViewFocusScenePath(mainView, mainViewScenePath);\n }\n return mainView;\n }\n\n private onCameraUpdatedByDevice = (camera: Camera) => {\n this.store.setMainViewCamera({ ...camera, id: this.context.uid });\n if (!isEqual(this.mainViewSize, { ...this.mainView.size, id: this.context.uid })) {\n this.setMainViewSize(this.view.size);\n }\n };\n\n public addMainViewListener(): void {\n if (this.mainViewIsAddListener) return;\n if (this.view.divElement) {\n this.view.divElement.addEventListener(\"click\", this.mainViewClickListener);\n this.view.divElement.addEventListener(\"touchend\", this.mainViewClickListener);\n this.mainViewIsAddListener = true;\n }\n }\n\n public removeMainViewListener(): void {\n if (this.view.divElement) {\n this.view.divElement.removeEventListener(\"click\", this.mainViewClickListener);\n this.view.divElement.removeEventListener(\"touchend\", this.mainViewClickListener);\n }\n }\n\n private mainViewClickListener = () => {\n this.mainViewClickHandler();\n };\n\n public async mainViewClickHandler(): Promise<void> {\n if (!this.manager.canOperate) return;\n this.store.cleanFocus();\n this.context.blurFocusBox();\n }\n\n public setMainViewSize = debounce(size => {\n this.store.setMainViewSize({ ...size, id: this.context.uid });\n }, 50);\n\n private addCameraListener() {\n this.view.callbacks.on(\"onCameraUpdatedByDevice\", this.onCameraUpdatedByDevice);\n this.view.callbacks.on(\"onCameraUpdated\", this.onCameraOrSizeUpdated);\n this.view.callbacks.on(\"onSizeUpdated\", this.onCameraOrSizeUpdated);\n }\n\n private removeCameraListener() {\n this.view.callbacks.off(\"onCameraUpdatedByDevice\", this.onCameraUpdatedByDevice);\n this.view.callbacks.off(\"onCameraUpdated\", this.onCameraOrSizeUpdated);\n this.view.callbacks.off(\"onSizeUpdated\", this.onCameraOrSizeUpdated);\n }\n\n private onCameraOrSizeUpdated = () => {\n callbacks.emit(\"cameraStateChange\", this.cameraState);\n };\n\n public moveCameraToContian(size: Size): void {\n if (!isEmpty(size)) {\n this.view.moveCameraToContain({\n width: size.width,\n height: size.height,\n originX: -size.width / 2,\n originY: -size.height / 2,\n animationMode: AnimationMode.Immediately,\n });\n this.scale = this.view.camera.scale;\n }\n }\n\n public moveCamera(camera: Camera): void {\n if (!isEmpty(camera)) {\n if (isEqual(camera, this.view.camera)) return;\n const { centerX, centerY, scale } = camera;\n const needScale = scale * (this.scale || 1);\n this.view.moveCamera({\n centerX: centerX,\n centerY: centerY,\n scale: needScale,\n animationMode: AnimationMode.Immediately,\n });\n }\n }\n\n public stop() {\n this.removeMainViewListener();\n this.removeCameraListener();\n this.manager.refresher?.remove(Fields.MainViewCamera);\n this.manager.refresher?.remove(Fields.MainViewSize);\n this.started = false;\n }\n\n public destroy() {\n this.stop();\n this.sideEffectManager.flushAll();\n }\n}\n","import pRetry from \"p-retry\";\nimport { AppAttributes, AppStatus, Events, MagixEventName } from \"./constants\";\nimport { AppListeners } from \"./AppListener\";\nimport { AppProxy } from \"./AppProxy\";\nimport { autorun, isPlayer, isRoom, ScenePathType } from \"white-web-sdk\";\nimport { callbacks, emitter, WindowManager, reconnectRefresher } from \"./index\";\nimport { genAppId, makeValidScenePath, setScenePath, setViewFocusScenePath } from \"./Utils/Common\";\nimport { log } from \"./Utils/log\";\nimport { MainViewProxy } from \"./View/MainView\";\nimport { onObjectRemoved, safeListenPropsUpdated } from \"./Utils/Reactive\";\nimport { get, sortBy } from \"lodash\";\nimport { store } from \"./AttributesDelegate\";\nimport { ViewManager } from \"./View/ViewManager\";\nimport type { ReconnectRefresher } from \"./ReconnectRefresher\";\nimport type { BoxManager } from \"./BoxManager\";\nimport type { Displayer, DisplayerState, Room } from \"white-web-sdk\";\nimport type { AddAppParams, BaseInsertParams, TeleBoxRect, EmitterEvent } from \"./index\";\n\nexport class AppManager {\n public displayer: Displayer;\n public viewManager: ViewManager;\n public appProxies: Map<string, AppProxy> = new Map();\n public appStatus: Map<string, AppStatus> = new Map();\n public store = store;\n public mainViewProxy: MainViewProxy;\n public refresher?: ReconnectRefresher;\n public isReplay = this.windowManger.isReplay;\n\n private appListeners: AppListeners;\n public boxManager?: BoxManager;\n\n private _prevSceneIndex: number | undefined;\n private _prevFocused: string | undefined;\n\n constructor(public windowManger: WindowManager) {\n this.displayer = windowManger.displayer;\n this.store.setContext({\n getAttributes: () => this.attributes,\n safeSetAttributes: attributes => this.safeSetAttributes(attributes),\n safeUpdateAttributes: (keys, val) => this.safeUpdateAttributes(keys, val),\n });\n this.mainViewProxy = new MainViewProxy(this);\n this.viewManager = new ViewManager(this.displayer);\n this.appListeners = new AppListeners(this);\n this.displayer.callbacks.on(this.eventName, this.displayerStateListener);\n this.appListeners.addListeners();\n\n this.refresher = reconnectRefresher;\n this.refresher.setRoom(this.room);\n this.refresher.setContext({ emitter });\n\n emitter.once(\"onCreated\").then(() => this.onCreated());\n emitter.on(\"onReconnected\", () => this.onReconnected());\n if (isPlayer(this.displayer)) {\n emitter.on(\"seek\", time => {\n this.appProxies.forEach(appProxy => {\n appProxy.onSeek(time);\n });\n this.attributesUpdateCallback(this.attributes.apps);\n this.onAppDelete(this.attributes.apps);\n });\n }\n }\n\n private async onCreated() {\n await this.attributesUpdateCallback(this.attributes.apps);\n this.boxManager?.updateManagerRect();\n emitter.onAny(this.boxEventListener);\n this.refresher?.add(\"apps\", () => {\n return safeListenPropsUpdated(\n () => this.attributes.apps,\n () => {\n this.attributesUpdateCallback(this.attributes.apps);\n }\n );\n });\n this.refresher?.add(\"appsClose\", () => {\n return onObjectRemoved(this.attributes.apps, () => {\n this.onAppDelete(this.attributes.apps);\n });\n });\n this.refresher?.add(\"maximized\", () => {\n return autorun(() => {\n const maximized = this.attributes.maximized;\n this.boxManager?.setMaximized(Boolean(maximized));\n });\n });\n this.refresher?.add(\"minimized\", () => {\n return autorun(() => {\n const minimized = this.attributes.minimized;\n if (this.boxManager?.minimized !== minimized) {\n if (minimized === true) {\n this.boxManager?.blurAllBox();\n }\n setTimeout(() => {\n this.boxManager?.setMinimized(Boolean(minimized));\n }, 0);\n }\n });\n });\n this.refresher?.add(\"mainViewIndex\", () => {\n return autorun(() => {\n const mainSceneIndex = get(this.attributes, \"_mainSceneIndex\");\n if (mainSceneIndex !== undefined && this._prevSceneIndex !== mainSceneIndex) {\n callbacks.emit(\"mainViewSceneIndexChange\", mainSceneIndex);\n this._prevSceneIndex = mainSceneIndex;\n }\n });\n });\n this.refresher?.add(\"focusedChange\", () => {\n return autorun(() => {\n const focused = get(this.attributes, \"focus\");\n if (this._prevFocused !== focused) {\n callbacks.emit(\"focusedChange\", focused);\n this._prevFocused = focused;\n }\n });\n })\n if (!this.attributes.apps || Object.keys(this.attributes.apps).length === 0) {\n const mainScenePath = this.store.getMainViewScenePath();\n if (!mainScenePath) return;\n const sceneState = this.displayer.state.sceneState;\n if (sceneState.scenePath !== mainScenePath) {\n setScenePath(this.room, mainScenePath);\n }\n }\n this.displayerWritableListener(!this.room?.isWritable);\n this.displayer.callbacks.on(\"onEnableWriteNowChanged\", this.displayerWritableListener);\n this._prevFocused = this.attributes.focus;\n }\n\n /**\n * 插件更新 attributes 时的回调\n *\n * @param {*} attributes\n * @memberof WindowManager\n */\n public async attributesUpdateCallback(apps: any) {\n if (apps && WindowManager.container) {\n const appIds = Object.keys(apps);\n const appsWithCreatedAt = appIds.map(appId => {\n return {\n id: appId,\n createdAt: apps[appId].createdAt,\n };\n });\n for (const { id } of sortBy(appsWithCreatedAt, \"createdAt\")) {\n if (!this.appProxies.has(id) && !this.appStatus.has(id)) {\n const app = apps[id];\n\n pRetry(\n async () => {\n this.appStatus.set(id, AppStatus.StartCreate);\n // 防御 appAttributes 有可能为 undefined 的情况,这里做一个重试\n const appAttributes = this.attributes[id];\n if (!appAttributes) {\n throw new Error(\"appAttributes is undefined\");\n }\n await this.baseInsertApp(\n {\n kind: app.kind,\n options: app.options,\n isDynamicPPT: app.isDynamicPPT,\n },\n id,\n false\n );\n this.focusByAttributes(apps);\n },\n { retries: 3 }\n ).catch(err => {\n console.warn(`[WindowManager]: Insert App Error`, err);\n this.appStatus.delete(id);\n });\n }\n }\n }\n }\n\n public refresh() {\n this.attributesUpdateCallback(this.attributes.apps);\n }\n\n public setBoxManager(boxManager: BoxManager) {\n this.boxManager = boxManager;\n }\n\n public resetMaximized() {\n this.boxManager?.setMaximized(Boolean(this.store.getMaximized()));\n }\n\n public resetMinimized() {\n this.boxManager?.setMinimized(Boolean(this.store.getMinimized()));\n }\n\n private onAppDelete = (apps: any) => {\n const ids = Object.keys(apps);\n this.appProxies.forEach((appProxy, id) => {\n if (!ids.includes(id)) {\n appProxy.destroy(true, false, true);\n }\n });\n };\n\n public bindMainView(divElement: HTMLDivElement, disableCameraTransform: boolean) {\n const mainView = this.mainViewProxy.view;\n mainView.disableCameraTransform = disableCameraTransform;\n mainView.divElement = divElement;\n if (!mainView.focusScenePath) {\n this.setMainViewFocusPath();\n }\n emitter.emit(\"mainViewMounted\");\n }\n\n public setMainViewFocusPath() {\n const scenePath = this.store.getMainViewScenePath();\n if (scenePath) {\n setViewFocusScenePath(this.mainView, scenePath);\n }\n }\n\n public async addApp(params: AddAppParams, isDynamicPPT: boolean): Promise<string | undefined> {\n log(\"addApp\", params);\n const { appId, needFocus } = await this.beforeAddApp(params, isDynamicPPT);\n const appProxy = await this.baseInsertApp(params, appId, true, needFocus);\n this.afterAddApp(appProxy);\n return appProxy?.id;\n }\n\n private async beforeAddApp(params: AddAppParams, isDynamicPPT: boolean) {\n const appId = await genAppId(params.kind);\n this.appStatus.set(appId, AppStatus.StartCreate);\n const attrs = params.attributes ?? {};\n this.safeUpdateAttributes([appId], attrs);\n this.store.setupAppAttributes(params, appId, isDynamicPPT);\n const needFocus = !this.boxManager?.minimized;\n if (needFocus) {\n this.store.setAppFocus(appId, true);\n }\n return { appId, needFocus };\n }\n\n private afterAddApp(appProxy: AppProxy | undefined) {\n if (appProxy && appProxy.box) {\n const box = appProxy.box;\n emitter.emit(\"move\", {\n appId: appProxy.id,\n x: box?.intrinsicX,\n y: box?.intrinsicY,\n });\n this.store.updateAppState(appProxy.id, AppAttributes.ZIndex, box.zIndex);\n }\n if (this.boxManager?.minimized) {\n this.boxManager?.setMinimized(false, false);\n }\n }\n\n public async closeApp(appId: string) {\n const appProxy = this.appProxies.get(appId);\n if (appProxy) {\n appProxy.destroy(true, true, false);\n }\n }\n\n private async baseInsertApp(\n params: BaseInsertParams,\n appId: string,\n isAddApp: boolean,\n focus?: boolean\n ) {\n if (this.appProxies.has(appId)) {\n console.warn(\"[WindowManager]: app duplicate exists and cannot be created again\");\n return;\n }\n const appProxy = new AppProxy(params, this, appId, isAddApp);\n if (appProxy) {\n await appProxy.baseInsertApp(focus);\n this.appStatus.delete(appId);\n return appProxy;\n } else {\n this.appStatus.delete(appId);\n throw new Error(\"[WindowManger]: initialize AppProxy failed\");\n }\n }\n\n private displayerStateListener = (state: Partial<DisplayerState>) => {\n const sceneState = state.sceneState;\n if (sceneState) {\n const scenePath = sceneState.scenePath;\n this.appProxies.forEach(appProxy => {\n if (appProxy.scenePath && scenePath.startsWith(appProxy.scenePath)) {\n appProxy.emitAppSceneStateChange(sceneState);\n appProxy.setFullPath(scenePath);\n }\n });\n }\n if (state.roomMembers) {\n this.windowManger.cursorManager?.setRoomMembers(state.roomMembers);\n this.windowManger.cursorManager?.cleanMemberAttributes(state.roomMembers);\n }\n this.appProxies.forEach(appProxy => {\n appProxy.appEmitter.emit(\"roomStateChange\", state);\n });\n emitter.emit(\"observerIdChange\", this.displayer.observerId);\n };\n\n public displayerWritableListener = (isReadonly: boolean) => {\n const isWritable = !isReadonly;\n const isManualWritable =\n this.windowManger.readonly === undefined || this.windowManger.readonly === false;\n if (this.windowManger.readonly === undefined) {\n this.boxManager?.setReadonly(isReadonly);\n } else {\n this.boxManager?.setReadonly(!(isWritable && isManualWritable));\n }\n this.appProxies.forEach(appProxy => {\n appProxy.emitAppIsWritableChange();\n });\n if (isWritable === true) {\n this.mainView.disableCameraTransform = false;\n } else {\n this.mainView.disableCameraTransform = true;\n }\n };\n\n private get eventName() {\n return isRoom(this.displayer) ? \"onRoomStateChanged\" : \"onPlayerStateChanged\";\n }\n\n public get attributes() {\n return this.windowManger.attributes;\n }\n\n public get canOperate() {\n return this.windowManger.canOperate;\n }\n\n public get room() {\n return isRoom(this.displayer) ? (this.displayer as Room) : undefined;\n }\n\n public get mainView() {\n return this.mainViewProxy.view;\n }\n\n public get focusApp() {\n if (this.store.focus) {\n return this.appProxies.get(this.store.focus);\n }\n }\n\n public safeSetAttributes(attributes: any) {\n this.windowManger.safeSetAttributes(attributes);\n }\n\n public safeUpdateAttributes(keys: string[], value: any) {\n this.windowManger.safeUpdateAttributes(keys, value);\n }\n\n public async setMainViewScenePath(scenePath: string) {\n if (this.room) {\n const scenePathType = this.displayer.scenePathType(scenePath);\n if (scenePathType === ScenePathType.None) {\n throw new Error(`[WindowManager]: ${scenePath} not valid scene`);\n } else if (scenePathType === ScenePathType.Page) {\n await this._setMainViewScenePath(scenePath);\n } else if (scenePathType === ScenePathType.Dir) {\n const validScenePath = makeValidScenePath(this.displayer, scenePath);\n if (validScenePath) {\n await this._setMainViewScenePath(validScenePath);\n }\n }\n }\n }\n\n private async _setMainViewScenePath(scenePath: string) {\n this.safeSetAttributes({ _mainScenePath: scenePath });\n this.setMainViewFocusPath();\n this.store.setMainViewFocusPath(this.mainView);\n this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath: scenePath });\n }\n\n public async setMainViewSceneIndex(index: number) {\n if (this.room) {\n this.safeSetAttributes({ _mainSceneIndex: index });\n const mainViewScenePath = this.store.getMainViewScenePath() as string;\n if (mainViewScenePath) {\n const sceneList = mainViewScenePath.split(\"/\");\n sceneList.pop();\n let sceneDir = sceneList.join(\"/\");\n if (sceneDir === \"\") {\n sceneDir = \"/\";\n }\n const scenePath = makeValidScenePath(this.displayer, sceneDir, index);\n if (scenePath) {\n this.store.setMainViewScenePath(scenePath);\n this.setMainViewFocusPath();\n }\n }\n }\n }\n\n public getAppInitPath(appId: string): string | undefined {\n const attrs = this.store.getAppAttributes(appId);\n if (attrs) {\n return attrs?.options?.scenePath;\n }\n }\n\n public safeDispatchMagixEvent(event: string, payload: any) {\n if (this.canOperate) {\n (this.displayer as Room).dispatchMagixEvent(event, payload);\n }\n }\n\n private boxEventListener = (eventName: keyof EmitterEvent, payload: any) => {\n switch (eventName) {\n case \"move\": {\n this.dispatchInternalEvent(Events.AppMove, payload);\n this.store.updateAppState(payload.appId, AppAttributes.Position, {\n x: payload.x,\n y: payload.y,\n });\n break;\n }\n case \"focus\": {\n this.windowManger.safeSetAttributes({ focus: payload.appId });\n break;\n }\n case \"resize\": {\n if (payload.width && payload.height) {\n this.dispatchInternalEvent(Events.AppResize, payload);\n this.store.updateAppState(payload.appId, AppAttributes.Size, {\n width: payload.width,\n height: payload.height,\n });\n }\n break;\n }\n case \"close\": {\n const appProxy = this.appProxies.get(payload.appId);\n if (appProxy) {\n appProxy.destroy(false, true, payload.error);\n }\n break;\n }\n case \"boxStateChange\": {\n this.dispatchInternalEvent(Events.AppBoxStateChange, payload);\n break;\n }\n default:\n break;\n }\n };\n\n public focusByAttributes(apps: any) {\n if (apps && Object.keys(apps).length === this.boxManager?.boxSize) {\n const focusAppId = this.store.focus;\n if (focusAppId) {\n this.boxManager.focusBox({ appId: focusAppId });\n }\n }\n }\n\n public async onReconnected() {\n const appProxies = Array.from(this.appProxies.values());\n const reconnected = appProxies.map(appProxy => {\n return appProxy.onReconnected();\n });\n await Promise.all(reconnected);\n }\n\n public notifyContainerRectUpdate(rect: TeleBoxRect) {\n this.appProxies.forEach(appProxy => {\n appProxy.appEmitter.emit(\"containerRectUpdate\", rect);\n });\n }\n\n public dispatchInternalEvent(event: Events, payload: any) {\n this.safeDispatchMagixEvent(MagixEventName, {\n eventName: event,\n payload: payload,\n });\n }\n\n public destroy() {\n this.displayer.callbacks.off(this.eventName, this.displayerStateListener);\n this.displayer.callbacks.off(\"onEnableWriteNowChanged\", this.displayerWritableListener);\n this.appListeners.removeListeners();\n emitter.offAny(this.boxEventListener);\n emitter.clearListeners();\n if (this.appProxies.size) {\n this.appProxies.forEach(appProxy => {\n appProxy.destroy(true, false, true);\n });\n }\n this.viewManager.destroy();\n this.boxManager?.destroy();\n this.refresher?.destroy();\n this.mainViewProxy.destroy();\n callbacks.clearListeners();\n this._prevSceneIndex = undefined;\n }\n}\n","import { ResizeObserver as ResizeObserverPolyfill } from \"@juggle/resize-observer\";\nimport { WindowManager } from \"./index\";\nimport type { EmitterType} from \"./index\";\n\nconst ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;\n\nexport class ContainerResizeObserver {\n private containerResizeObserver?: ResizeObserver;\n\n constructor(private emitter: EmitterType) {}\n\n public static create(\n container: HTMLElement,\n sizer: HTMLElement,\n wrapper: HTMLDivElement,\n emitter: EmitterType,\n ) {\n const containerResizeObserver = new ContainerResizeObserver(emitter);\n containerResizeObserver.observePlaygroundSize(container, sizer, wrapper);\n return containerResizeObserver;\n }\n\n public observePlaygroundSize(\n container: HTMLElement,\n sizer: HTMLElement,\n wrapper: HTMLDivElement\n ) {\n this.updateSizer(container.getBoundingClientRect(), sizer, wrapper);\n\n this.containerResizeObserver = new ResizeObserver(entries => {\n const containerRect = entries[0]?.contentRect;\n if (containerRect) {\n this.updateSizer(containerRect, sizer, wrapper);\n this.emitter.emit(\"playgroundSizeChange\", containerRect)\n }\n });\n\n this.containerResizeObserver.observe(container);\n }\n\n private updateSizer(\n { width, height }: DOMRectReadOnly,\n sizer: HTMLElement,\n wrapper: HTMLDivElement\n ) {\n if (width && height) {\n if (height / width > WindowManager.containerSizeRatio) {\n height = width * WindowManager.containerSizeRatio;\n sizer.classList.toggle(\"netless-window-manager-sizer-horizontal\", true);\n } else {\n width = height / WindowManager.containerSizeRatio;\n sizer.classList.toggle(\"netless-window-manager-sizer-horizontal\", false);\n }\n wrapper.style.width = `${width}px`;\n wrapper.style.height = `${height}px`;\n }\n }\n\n public disconnect() {\n this.containerResizeObserver?.disconnect();\n }\n}\n","import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from \"./constants\";\nimport { debounce, maxBy } from \"lodash\";\nimport {\n TELE_BOX_MANAGER_EVENT,\n TELE_BOX_STATE,\n TeleBoxCollector,\n TeleBoxManager,\n} from \"@netless/telebox-insider\";\nimport { emitter, WindowManager } from \"./index\";\nimport type { AddAppOptions, AppInitState, EmitterType, CallbacksType } from \"./index\";\nimport type {\n TeleBoxManagerUpdateConfig,\n TeleBoxManagerCreateConfig,\n ReadonlyTeleBox,\n TeleBoxManagerConfig,\n TeleBoxColorScheme,\n TeleBoxRect,\n} from \"@netless/telebox-insider\";\nimport type Emittery from \"emittery\";\nimport type { NetlessApp } from \"./typings\";\nimport type { View } from \"white-web-sdk\";\n\nexport { TELE_BOX_STATE };\n\nexport type CreateBoxParams = {\n appId: string;\n app: NetlessApp;\n view?: View;\n emitter?: Emittery;\n options?: AddAppOptions;\n canOperate?: boolean;\n smartPosition?: boolean;\n};\n\ntype AppId = { appId: string };\n\ntype MoveBoxParams = AppId & { x: number; y: number };\n\ntype ResizeBoxParams = AppId & { width: number; height: number; skipUpdate: boolean };\n\ntype SetBoxMinSizeParams = AppId & { minWidth: number; minHeight: number };\n\ntype SetBoxTitleParams = AppId & { title: string };\n\nexport type CreateTeleBoxManagerConfig = {\n collectorContainer?: HTMLElement;\n collectorStyles?: Partial<CSSStyleDeclaration>;\n prefersColorScheme?: TeleBoxColorScheme;\n};\n\nexport type BoxManagerContext = {\n safeSetAttributes: (attributes: any) => void;\n getMainView: () => View;\n updateAppState: (appId: string, field: AppAttributes, value: any) => void;\n emitter: EmitterType;\n callbacks: CallbacksType;\n canOperate: () => boolean;\n notifyContainerRectUpdate: (rect: TeleBoxRect) => void;\n cleanFocus: () => void;\n};\n\nexport const createBoxManager = (\n manager: WindowManager,\n callbacks: CallbacksType,\n emitter: EmitterType,\n options: CreateTeleBoxManagerConfig\n) => {\n return new BoxManager(\n {\n safeSetAttributes: (attributes: any) => manager.safeSetAttributes(attributes),\n getMainView: () => manager.mainView,\n updateAppState: (...args) => manager.appManager?.store.updateAppState(...args),\n canOperate: () => manager.canOperate,\n notifyContainerRectUpdate: (rect: TeleBoxRect) =>\n manager.appManager?.notifyContainerRectUpdate(rect),\n cleanFocus: () => manager.appManager?.store.cleanFocus(),\n callbacks,\n emitter,\n },\n options\n );\n};\n\nexport class BoxManager {\n public teleBoxManager: TeleBoxManager;\n\n constructor(\n private context: BoxManagerContext,\n private createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig\n ) {\n const { emitter, callbacks } = context;\n this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);\n this.teleBoxManager.events.on(TELE_BOX_MANAGER_EVENT.State, state => {\n if (state) {\n this.context.callbacks.emit(\"boxStateChange\", state);\n this.context.emitter.emit(\"boxStateChange\", state);\n }\n });\n this.teleBoxManager.events.on(\"minimized\", minimized => {\n this.context.safeSetAttributes({ minimized });\n if (minimized) {\n this.context.cleanFocus();\n this.blurAllBox();\n }\n });\n this.teleBoxManager.events.on(\"maximized\", maximized => {\n this.context.safeSetAttributes({ maximized });\n });\n this.teleBoxManager.events.on(\"removed\", boxes => {\n boxes.forEach(box => {\n emitter.emit(\"close\", { appId: box.id });\n });\n });\n this.teleBoxManager.events.on(\n \"intrinsic_move\",\n debounce((box: ReadonlyTeleBox): void => {\n emitter.emit(\"move\", { appId: box.id, x: box.intrinsicX, y: box.intrinsicY });\n }, 50)\n );\n this.teleBoxManager.events.on(\n \"intrinsic_resize\",\n debounce((box: ReadonlyTeleBox): void => {\n emitter.emit(\"resize\", {\n appId: box.id,\n width: box.intrinsicWidth,\n height: box.intrinsicHeight,\n });\n }, 200)\n );\n this.teleBoxManager.events.on(\"focused\", box => {\n if (box) {\n if (this.canOperate) {\n emitter.emit(\"focus\", { appId: box.id });\n } else {\n this.teleBoxManager.blurBox(box.id);\n }\n }\n });\n this.teleBoxManager.events.on(\"dark_mode\", darkMode => {\n callbacks.emit(\"darkModeChange\", darkMode);\n });\n this.teleBoxManager.events.on(\"prefers_color_scheme\", colorScheme => {\n callbacks.emit(\"prefersColorSchemeChange\", colorScheme);\n });\n this.teleBoxManager.events.on(\"z_index\", box => {\n this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);\n });\n emitter.on(\"playgroundSizeChange\", this.playgroundSizeChangeListener);\n }\n\n private playgroundSizeChangeListener = () => {\n this.updateManagerRect();\n }\n\n private get mainView() {\n return this.context.getMainView();\n }\n\n private get canOperate() {\n return this.context.canOperate();\n }\n\n public get boxState() {\n return this.teleBoxManager.state;\n }\n\n public get maximized() {\n return this.teleBoxManager.maximized;\n }\n\n public get minimized() {\n return this.teleBoxManager.minimized;\n }\n\n public get darkMode() {\n return this.teleBoxManager.darkMode;\n }\n\n public get prefersColorScheme(): TeleBoxColorScheme {\n return this.teleBoxManager.prefersColorScheme;\n }\n\n public get boxSize() {\n return this.teleBoxManager.boxes.length;\n }\n\n public createBox(params: CreateBoxParams): void {\n if (!this.teleBoxManager) return;\n let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};\n const { width, height } = params.app.config ?? {};\n const title = params.options?.title || params.appId;\n const rect = this.teleBoxManager.containerRect;\n\n if (minwidth > 1) {\n minwidth = minwidth / rect.width;\n }\n\n if (minheight > 1) {\n minheight = minheight / rect.height;\n }\n\n const createBoxConfig: TeleBoxManagerCreateConfig = {\n title,\n minWidth: minwidth,\n minHeight: minheight,\n width,\n height,\n id: params.appId,\n };\n this.teleBoxManager.create(createBoxConfig, params.smartPosition);\n this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);\n }\n\n public setBoxInitState(appId: string): void {\n const box = this.teleBoxManager.queryOne({ id: appId });\n if (box) {\n if (box.state === TELE_BOX_STATE.Maximized) {\n this.context.emitter.emit(\"resize\", {\n appId: appId,\n x: box.x,\n y: box.y,\n width: box.intrinsicWidth,\n height: box.intrinsicHeight,\n });\n }\n }\n }\n\n public setupBoxManager(\n createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig\n ): TeleBoxManager {\n const root = WindowManager.wrapper ? WindowManager.wrapper : document.body;\n const rect = root.getBoundingClientRect();\n const initManagerState: TeleBoxManagerConfig = {\n root: root,\n containerRect: {\n x: 0,\n y: 0,\n width: rect.width,\n height: rect.height,\n },\n fence: false,\n prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,\n };\n\n const manager = new TeleBoxManager(initManagerState);\n if (this.teleBoxManager) {\n this.teleBoxManager.destroy();\n }\n this.teleBoxManager = manager;\n const container = createTeleBoxManagerConfig?.collectorContainer || WindowManager.wrapper;\n if (container) {\n this.setCollectorContainer(container);\n }\n return manager;\n }\n\n public setCollectorContainer(container: HTMLElement) {\n const collector = new TeleBoxCollector({\n styles: this.createTeleBoxManagerConfig?.collectorStyles,\n }).mount(container);\n this.teleBoxManager.setCollector(collector);\n }\n\n public getBox(appId: string): ReadonlyTeleBox | undefined {\n return this.teleBoxManager.queryOne({ id: appId });\n }\n\n public closeBox(appId: string, skipUpdate = false): ReadonlyTeleBox | undefined {\n return this.teleBoxManager.remove(appId, skipUpdate);\n }\n\n public boxIsFocus(appId: string): boolean | undefined {\n const box = this.getBox(appId);\n return box?.focus;\n }\n\n public getFocusBox(): ReadonlyTeleBox | undefined {\n const boxes = this.teleBoxManager.query({ focus: true });\n return boxes[0];\n }\n\n public getTopBox(): ReadonlyTeleBox | undefined {\n const boxes = this.teleBoxManager.query();\n return maxBy(boxes, \"zIndex\");\n }\n\n public updateBoxState(state?: AppInitState): void {\n if (!state) return;\n const box = this.getBox(state.id);\n if (box) {\n this.teleBoxManager.update(\n box.id,\n {\n x: state.x,\n y: state.y,\n width: state.width || 0.5,\n height: state.height || 0.5,\n zIndex: state.zIndex,\n },\n true\n );\n setTimeout(() => {\n if (state.focus) {\n this.teleBoxManager.focusBox(box.id, true);\n }\n if (state.maximized != null) {\n this.teleBoxManager.setMaximized(Boolean(state.maximized), true);\n }\n if (state.minimized != null) {\n this.teleBoxManager.setMinimized(Boolean(state.minimized), true);\n }\n }, 50);\n this.context.callbacks.emit(\"boxStateChange\", this.teleBoxManager.state);\n }\n }\n\n public updateManagerRect(): void {\n const rect = this.mainView.divElement?.getBoundingClientRect();\n if (rect && rect.width > 0 && rect.height > 0) {\n const containerRect = { x: 0, y: 0, width: rect.width, height: rect.height };\n this.teleBoxManager.setContainerRect(containerRect);\n this.context.notifyContainerRectUpdate(this.teleBoxManager.containerRect);\n }\n }\n\n public moveBox({ appId, x, y }: MoveBoxParams): void {\n this.teleBoxManager.update(appId, { x, y }, true);\n }\n\n public focusBox({ appId }: AppId, skipUpdate = true): void {\n this.teleBoxManager.focusBox(appId, skipUpdate);\n }\n\n public resizeBox({ appId, width, height, skipUpdate }: ResizeBoxParams): void {\n this.teleBoxManager.update(appId, { width, height }, skipUpdate);\n }\n\n public setBoxMinSize(params: SetBoxMinSizeParams): void {\n this.teleBoxManager.update(\n params.appId,\n {\n minWidth: params.minWidth,\n minHeight: params.minHeight,\n },\n true\n );\n }\n\n public setBoxTitle(params: SetBoxTitleParams): void {\n this.teleBoxManager.update(params.appId, { title: params.title }, true);\n }\n\n public blurAllBox(): void {\n this.teleBoxManager.blurAll();\n }\n\n public updateAll(config: TeleBoxManagerUpdateConfig): void {\n this.teleBoxManager.updateAll(config);\n }\n\n public setMaximized(maximized: boolean) {\n if (maximized !== this.maximized) {\n this.teleBoxManager.setMaximized(maximized, true);\n }\n }\n\n public setMinimized(minimized: boolean, skipUpdate = true) {\n this.teleBoxManager.setMinimized(minimized, skipUpdate);\n }\n\n public focusTopBox(): void {\n const boxes = this.teleBoxManager.query();\n if (boxes.length >= 1) {\n const box = this.getTopBox();\n if (box) {\n this.focusBox({ appId: box.id }, false);\n }\n }\n }\n\n public setReadonly(readonly: boolean) {\n this.teleBoxManager.setReadonly(readonly);\n }\n\n public setPrefersColorScheme(colorScheme: TeleBoxColorScheme) {\n this.teleBoxManager.setPrefersColorScheme(colorScheme);\n }\n\n public setZIndex(id: string, zIndex: number, skipUpdate = true) {\n this.teleBoxManager.update(id, { zIndex }, skipUpdate);\n }\n\n public destroy() {\n emitter.off(\"playgroundSizeChange\", this.playgroundSizeChangeListener);\n this.teleBoxManager.destroy();\n }\n}\n","function noop() { }\nconst identity = x => x;\nfunction assign(tar, src) {\n // @ts-ignore\n for (const k in src)\n tar[k] = src[k];\n return tar;\n}\nfunction is_promise(value) {\n return value && typeof value === 'object' && typeof value.then === 'function';\n}\nfunction add_location(element, file, line, column, char) {\n element.__svelte_meta = {\n loc: { file, line, column, char }\n };\n}\nfunction run(fn) {\n return fn();\n}\nfunction blank_object() {\n return Object.create(null);\n}\nfunction run_all(fns) {\n fns.forEach(run);\n}\nfunction is_function(thing) {\n return typeof thing === 'function';\n}\nfunction safe_not_equal(a, b) {\n return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');\n}\nlet src_url_equal_anchor;\nfunction src_url_equal(element_src, url) {\n if (!src_url_equal_anchor) {\n src_url_equal_anchor = document.createElement('a');\n }\n src_url_equal_anchor.href = url;\n return element_src === src_url_equal_anchor.href;\n}\nfunction not_equal(a, b) {\n return a != a ? b == b : a !== b;\n}\nfunction is_empty(obj) {\n return Object.keys(obj).length === 0;\n}\nfunction validate_store(store, name) {\n if (store != null && typeof store.subscribe !== 'function') {\n throw new Error(`'${name}' is not a store with a 'subscribe' method`);\n }\n}\nfunction subscribe(store, ...callbacks) {\n if (store == null) {\n return noop;\n }\n const unsub = store.subscribe(...callbacks);\n return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;\n}\nfunction get_store_value(store) {\n let value;\n subscribe(store, _ => value = _)();\n return value;\n}\nfunction component_subscribe(component, store, callback) {\n component.$$.on_destroy.push(subscribe(store, callback));\n}\nfunction create_slot(definition, ctx, $$scope, fn) {\n if (definition) {\n const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);\n return definition[0](slot_ctx);\n }\n}\nfunction get_slot_context(definition, ctx, $$scope, fn) {\n return definition[1] && fn\n ? assign($$scope.ctx.slice(), definition[1](fn(ctx)))\n : $$scope.ctx;\n}\nfunction get_slot_changes(definition, $$scope, dirty, fn) {\n if (definition[2] && fn) {\n const lets = definition[2](fn(dirty));\n if ($$scope.dirty === undefined) {\n return lets;\n }\n if (typeof lets === 'object') {\n const merged = [];\n const len = Math.max($$scope.dirty.length, lets.length);\n for (let i = 0; i < len; i += 1) {\n merged[i] = $$scope.dirty[i] | lets[i];\n }\n return merged;\n }\n return $$scope.dirty | lets;\n }\n return $$scope.dirty;\n}\nfunction update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn) {\n if (slot_changes) {\n const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n slot.p(slot_context, slot_changes);\n }\n}\nfunction update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {\n const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);\n update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn);\n}\nfunction get_all_dirty_from_scope($$scope) {\n if ($$scope.ctx.length > 32) {\n const dirty = [];\n const length = $$scope.ctx.length / 32;\n for (let i = 0; i < length; i++) {\n dirty[i] = -1;\n }\n return dirty;\n }\n return -1;\n}\nfunction exclude_internal_props(props) {\n const result = {};\n for (const k in props)\n if (k[0] !== '$')\n result[k] = props[k];\n return result;\n}\nfunction compute_rest_props(props, keys) {\n const rest = {};\n keys = new Set(keys);\n for (const k in props)\n if (!keys.has(k) && k[0] !== '$')\n rest[k] = props[k];\n return rest;\n}\nfunction compute_slots(slots) {\n const result = {};\n for (const key in slots) {\n result[key] = true;\n }\n return result;\n}\nfunction once(fn) {\n let ran = false;\n return function (...args) {\n if (ran)\n return;\n ran = true;\n fn.call(this, ...args);\n };\n}\nfunction null_to_empty(value) {\n return value == null ? '' : value;\n}\nfunction set_store_value(store, ret, value) {\n store.set(value);\n return ret;\n}\nconst has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);\nfunction action_destroyer(action_result) {\n return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;\n}\n\nconst is_client = typeof window !== 'undefined';\nlet now = is_client\n ? () => window.performance.now()\n : () => Date.now();\nlet raf = is_client ? cb => requestAnimationFrame(cb) : noop;\n// used internally for testing\nfunction set_now(fn) {\n now = fn;\n}\nfunction set_raf(fn) {\n raf = fn;\n}\n\nconst tasks = new Set();\nfunction run_tasks(now) {\n tasks.forEach(task => {\n if (!task.c(now)) {\n tasks.delete(task);\n task.f();\n }\n });\n if (tasks.size !== 0)\n raf(run_tasks);\n}\n/**\n * For testing purposes only!\n */\nfunction clear_loops() {\n tasks.clear();\n}\n/**\n * Creates a new task that runs on each raf frame\n * until it returns a falsy value or is aborted\n */\nfunction loop(callback) {\n let task;\n if (tasks.size === 0)\n raf(run_tasks);\n return {\n promise: new Promise(fulfill => {\n tasks.add(task = { c: callback, f: fulfill });\n }),\n abort() {\n tasks.delete(task);\n }\n };\n}\n\n// Track which nodes are claimed during hydration. Unclaimed nodes can then be removed from the DOM\n// at the end of hydration without touching the remaining nodes.\nlet is_hydrating = false;\nfunction start_hydrating() {\n is_hydrating = true;\n}\nfunction end_hydrating() {\n is_hydrating = false;\n}\nfunction upper_bound(low, high, key, value) {\n // Return first index of value larger than input value in the range [low, high)\n while (low < high) {\n const mid = low + ((high - low) >> 1);\n if (key(mid) <= value) {\n low = mid + 1;\n }\n else {\n high = mid;\n }\n }\n return low;\n}\nfunction init_hydrate(target) {\n if (target.hydrate_init)\n return;\n target.hydrate_init = true;\n // We know that all children have claim_order values since the unclaimed have been detached if target is not <head>\n let children = target.childNodes;\n // If target is <head>, there may be children without claim_order\n if (target.nodeName === 'HEAD') {\n const myChildren = [];\n for (let i = 0; i < children.length; i++) {\n const node = children[i];\n if (node.claim_order !== undefined) {\n myChildren.push(node);\n }\n }\n children = myChildren;\n }\n /*\n * Reorder claimed children optimally.\n * We can reorder claimed children optimally by finding the longest subsequence of\n * nodes that are already claimed in order and only moving the rest. The longest\n * subsequence subsequence of nodes that are claimed in order can be found by\n * computing the longest increasing subsequence of .claim_order values.\n *\n * This algorithm is optimal in generating the least amount of reorder operations\n * possible.\n *\n * Proof:\n * We know that, given a set of reordering operations, the nodes that do not move\n * always form an increasing subsequence, since they do not move among each other\n * meaning that they must be already ordered among each other. Thus, the maximal\n * set of nodes that do not move form a longest increasing subsequence.\n */\n // Compute longest increasing subsequence\n // m: subsequence length j => index k of smallest value that ends an increasing subsequence of length j\n const m = new Int32Array(children.length + 1);\n // Predecessor indices + 1\n const p = new Int32Array(children.length);\n m[0] = -1;\n let longest = 0;\n for (let i = 0; i < children.length; i++) {\n const current = children[i].claim_order;\n // Find the largest subsequence length such that it ends in a value less than our current value\n // upper_bound returns first greater value, so we subtract one\n // with fast path for when we are on the current longest subsequence\n const seqLen = ((longest > 0 && children[m[longest]].claim_order <= current) ? longest + 1 : upper_bound(1, longest, idx => children[m[idx]].claim_order, current)) - 1;\n p[i] = m[seqLen] + 1;\n const newLen = seqLen + 1;\n // We can guarantee that current is the smallest value. Otherwise, we would have generated a longer sequence.\n m[newLen] = i;\n longest = Math.max(newLen, longest);\n }\n // The longest increasing subsequence of nodes (initially reversed)\n const lis = [];\n // The rest of the nodes, nodes that will be moved\n const toMove = [];\n let last = children.length - 1;\n for (let cur = m[longest] + 1; cur != 0; cur = p[cur - 1]) {\n lis.push(children[cur - 1]);\n for (; last >= cur; last--) {\n toMove.push(children[last]);\n }\n last--;\n }\n for (; last >= 0; last--) {\n toMove.push(children[last]);\n }\n lis.reverse();\n // We sort the nodes being moved to guarantee that their insertion order matches the claim order\n toMove.sort((a, b) => a.claim_order - b.claim_order);\n // Finally, we move the nodes\n for (let i = 0, j = 0; i < toMove.length; i++) {\n while (j < lis.length && toMove[i].claim_order >= lis[j].claim_order) {\n j++;\n }\n const anchor = j < lis.length ? lis[j] : null;\n target.insertBefore(toMove[i], anchor);\n }\n}\nfunction append(target, node) {\n target.appendChild(node);\n}\nfunction append_styles(target, style_sheet_id, styles) {\n const append_styles_to = get_root_for_style(target);\n if (!append_styles_to.getElementById(style_sheet_id)) {\n const style = element('style');\n style.id = style_sheet_id;\n style.textContent = styles;\n append_stylesheet(append_styles_to, style);\n }\n}\nfunction get_root_for_style(node) {\n if (!node)\n return document;\n const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;\n if (root && root.host) {\n return root;\n }\n return node.ownerDocument;\n}\nfunction append_empty_stylesheet(node) {\n const style_element = element('style');\n append_stylesheet(get_root_for_style(node), style_element);\n return style_element;\n}\nfunction append_stylesheet(node, style) {\n append(node.head || node, style);\n}\nfunction append_hydration(target, node) {\n if (is_hydrating) {\n init_hydrate(target);\n if ((target.actual_end_child === undefined) || ((target.actual_end_child !== null) && (target.actual_end_child.parentElement !== target))) {\n target.actual_end_child = target.firstChild;\n }\n // Skip nodes of undefined ordering\n while ((target.actual_end_child !== null) && (target.actual_end_child.claim_order === undefined)) {\n target.actual_end_child = target.actual_end_child.nextSibling;\n }\n if (node !== target.actual_end_child) {\n // We only insert if the ordering of this node should be modified or the parent node is not target\n if (node.claim_order !== undefined || node.parentNode !== target) {\n target.insertBefore(node, target.actual_end_child);\n }\n }\n else {\n target.actual_end_child = node.nextSibling;\n }\n }\n else if (node.parentNode !== target || node.nextSibling !== null) {\n target.appendChild(node);\n }\n}\nfunction insert(target, node, anchor) {\n target.insertBefore(node, anchor || null);\n}\nfunction insert_hydration(target, node, anchor) {\n if (is_hydrating && !anchor) {\n append_hydration(target, node);\n }\n else if (node.parentNode !== target || node.nextSibling != anchor) {\n target.insertBefore(node, anchor || null);\n }\n}\nfunction detach(node) {\n node.parentNode.removeChild(node);\n}\nfunction destroy_each(iterations, detaching) {\n for (let i = 0; i < iterations.length; i += 1) {\n if (iterations[i])\n iterations[i].d(detaching);\n }\n}\nfunction element(name) {\n return document.createElement(name);\n}\nfunction element_is(name, is) {\n return document.createElement(name, { is });\n}\nfunction object_without_properties(obj, exclude) {\n const target = {};\n for (const k in obj) {\n if (has_prop(obj, k)\n // @ts-ignore\n && exclude.indexOf(k) === -1) {\n // @ts-ignore\n target[k] = obj[k];\n }\n }\n return target;\n}\nfunction svg_element(name) {\n return document.createElementNS('http://www.w3.org/2000/svg', name);\n}\nfunction text(data) {\n return document.createTextNode(data);\n}\nfunction space() {\n return text(' ');\n}\nfunction empty() {\n return text('');\n}\nfunction listen(node, event, handler, options) {\n node.addEventListener(event, handler, options);\n return () => node.removeEventListener(event, handler, options);\n}\nfunction prevent_default(fn) {\n return function (event) {\n event.preventDefault();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction stop_propagation(fn) {\n return function (event) {\n event.stopPropagation();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction self(fn) {\n return function (event) {\n // @ts-ignore\n if (event.target === this)\n fn.call(this, event);\n };\n}\nfunction trusted(fn) {\n return function (event) {\n // @ts-ignore\n if (event.isTrusted)\n fn.call(this, event);\n };\n}\nfunction attr(node, attribute, value) {\n if (value == null)\n node.removeAttribute(attribute);\n else if (node.getAttribute(attribute) !== value)\n node.setAttribute(attribute, value);\n}\nfunction set_attributes(node, attributes) {\n // @ts-ignore\n const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);\n for (const key in attributes) {\n if (attributes[key] == null) {\n node.removeAttribute(key);\n }\n else if (key === 'style') {\n node.style.cssText = attributes[key];\n }\n else if (key === '__value') {\n node.value = node[key] = attributes[key];\n }\n else if (descriptors[key] && descriptors[key].set) {\n node[key] = attributes[key];\n }\n else {\n attr(node, key, attributes[key]);\n }\n }\n}\nfunction set_svg_attributes(node, attributes) {\n for (const key in attributes) {\n attr(node, key, attributes[key]);\n }\n}\nfunction set_custom_element_data(node, prop, value) {\n if (prop in node) {\n node[prop] = typeof node[prop] === 'boolean' && value === '' ? true : value;\n }\n else {\n attr(node, prop, value);\n }\n}\nfunction xlink_attr(node, attribute, value) {\n node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);\n}\nfunction get_binding_group_value(group, __value, checked) {\n const value = new Set();\n for (let i = 0; i < group.length; i += 1) {\n if (group[i].checked)\n value.add(group[i].__value);\n }\n if (!checked) {\n value.delete(__value);\n }\n return Array.from(value);\n}\nfunction to_number(value) {\n return value === '' ? null : +value;\n}\nfunction time_ranges_to_array(ranges) {\n const array = [];\n for (let i = 0; i < ranges.length; i += 1) {\n array.push({ start: ranges.start(i), end: ranges.end(i) });\n }\n return array;\n}\nfunction children(element) {\n return Array.from(element.childNodes);\n}\nfunction init_claim_info(nodes) {\n if (nodes.claim_info === undefined) {\n nodes.claim_info = { last_index: 0, total_claimed: 0 };\n }\n}\nfunction claim_node(nodes, predicate, processNode, createNode, dontUpdateLastIndex = false) {\n // Try to find nodes in an order such that we lengthen the longest increasing subsequence\n init_claim_info(nodes);\n const resultNode = (() => {\n // We first try to find an element after the previous one\n for (let i = nodes.claim_info.last_index; i < nodes.length; i++) {\n const node = nodes[i];\n if (predicate(node)) {\n const replacement = processNode(node);\n if (replacement === undefined) {\n nodes.splice(i, 1);\n }\n else {\n nodes[i] = replacement;\n }\n if (!dontUpdateLastIndex) {\n nodes.claim_info.last_index = i;\n }\n return node;\n }\n }\n // Otherwise, we try to find one before\n // We iterate in reverse so that we don't go too far back\n for (let i = nodes.claim_info.last_index - 1; i >= 0; i--) {\n const node = nodes[i];\n if (predicate(node)) {\n const replacement = processNode(node);\n if (replacement === undefined) {\n nodes.splice(i, 1);\n }\n else {\n nodes[i] = replacement;\n }\n if (!dontUpdateLastIndex) {\n nodes.claim_info.last_index = i;\n }\n else if (replacement === undefined) {\n // Since we spliced before the last_index, we decrease it\n nodes.claim_info.last_index--;\n }\n return node;\n }\n }\n // If we can't find any matching node, we create a new one\n return createNode();\n })();\n resultNode.claim_order = nodes.claim_info.total_claimed;\n nodes.claim_info.total_claimed += 1;\n return resultNode;\n}\nfunction claim_element_base(nodes, name, attributes, create_element) {\n return claim_node(nodes, (node) => node.nodeName === name, (node) => {\n const remove = [];\n for (let j = 0; j < node.attributes.length; j++) {\n const attribute = node.attributes[j];\n if (!attributes[attribute.name]) {\n remove.push(attribute.name);\n }\n }\n remove.forEach(v => node.removeAttribute(v));\n return undefined;\n }, () => create_element(name));\n}\nfunction claim_element(nodes, name, attributes) {\n return claim_element_base(nodes, name, attributes, element);\n}\nfunction claim_svg_element(nodes, name, attributes) {\n return claim_element_base(nodes, name, attributes, svg_element);\n}\nfunction claim_text(nodes, data) {\n return claim_node(nodes, (node) => node.nodeType === 3, (node) => {\n const dataStr = '' + data;\n if (node.data.startsWith(dataStr)) {\n if (node.data.length !== dataStr.length) {\n return node.splitText(dataStr.length);\n }\n }\n else {\n node.data = dataStr;\n }\n }, () => text(data), true // Text nodes should not update last index since it is likely not worth it to eliminate an increasing subsequence of actual elements\n );\n}\nfunction claim_space(nodes) {\n return claim_text(nodes, ' ');\n}\nfunction find_comment(nodes, text, start) {\n for (let i = start; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeType === 8 /* comment node */ && node.textContent.trim() === text) {\n return i;\n }\n }\n return nodes.length;\n}\nfunction claim_html_tag(nodes) {\n // find html opening tag\n const start_index = find_comment(nodes, 'HTML_TAG_START', 0);\n const end_index = find_comment(nodes, 'HTML_TAG_END', start_index);\n if (start_index === end_index) {\n return new HtmlTagHydration();\n }\n init_claim_info(nodes);\n const html_tag_nodes = nodes.splice(start_index, end_index + 1);\n detach(html_tag_nodes[0]);\n detach(html_tag_nodes[html_tag_nodes.length - 1]);\n const claimed_nodes = html_tag_nodes.slice(1, html_tag_nodes.length - 1);\n for (const n of claimed_nodes) {\n n.claim_order = nodes.claim_info.total_claimed;\n nodes.claim_info.total_claimed += 1;\n }\n return new HtmlTagHydration(claimed_nodes);\n}\nfunction set_data(text, data) {\n data = '' + data;\n if (text.wholeText !== data)\n text.data = data;\n}\nfunction set_input_value(input, value) {\n input.value = value == null ? '' : value;\n}\nfunction set_input_type(input, type) {\n try {\n input.type = type;\n }\n catch (e) {\n // do nothing\n }\n}\nfunction set_style(node, key, value, important) {\n node.style.setProperty(key, value, important ? 'important' : '');\n}\nfunction select_option(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n if (option.__value === value) {\n option.selected = true;\n return;\n }\n }\n select.selectedIndex = -1; // no option should be selected\n}\nfunction select_options(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n option.selected = ~value.indexOf(option.__value);\n }\n}\nfunction select_value(select) {\n const selected_option = select.querySelector(':checked') || select.options[0];\n return selected_option && selected_option.__value;\n}\nfunction select_multiple_value(select) {\n return [].map.call(select.querySelectorAll(':checked'), option => option.__value);\n}\n// unfortunately this can't be a constant as that wouldn't be tree-shakeable\n// so we cache the result instead\nlet crossorigin;\nfunction is_crossorigin() {\n if (crossorigin === undefined) {\n crossorigin = false;\n try {\n if (typeof window !== 'undefined' && window.parent) {\n void window.parent.document;\n }\n }\n catch (error) {\n crossorigin = true;\n }\n }\n return crossorigin;\n}\nfunction add_resize_listener(node, fn) {\n const computed_style = getComputedStyle(node);\n if (computed_style.position === 'static') {\n node.style.position = 'relative';\n }\n const iframe = element('iframe');\n iframe.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ' +\n 'overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: -1;');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.tabIndex = -1;\n const crossorigin = is_crossorigin();\n let unsubscribe;\n if (crossorigin) {\n iframe.src = \"data:text/html,<script>onresize=function(){parent.postMessage(0,'*')}</script>\";\n unsubscribe = listen(window, 'message', (event) => {\n if (event.source === iframe.contentWindow)\n fn();\n });\n }\n else {\n iframe.src = 'about:blank';\n iframe.onload = () => {\n unsubscribe = listen(iframe.contentWindow, 'resize', fn);\n };\n }\n append(node, iframe);\n return () => {\n if (crossorigin) {\n unsubscribe();\n }\n else if (unsubscribe && iframe.contentWindow) {\n unsubscribe();\n }\n detach(iframe);\n };\n}\nfunction toggle_class(element, name, toggle) {\n element.classList[toggle ? 'add' : 'remove'](name);\n}\nfunction custom_event(type, detail, bubbles = false) {\n const e = document.createEvent('CustomEvent');\n e.initCustomEvent(type, bubbles, false, detail);\n return e;\n}\nfunction query_selector_all(selector, parent = document.body) {\n return Array.from(parent.querySelectorAll(selector));\n}\nclass HtmlTag {\n constructor() {\n this.e = this.n = null;\n }\n c(html) {\n this.h(html);\n }\n m(html, target, anchor = null) {\n if (!this.e) {\n this.e = element(target.nodeName);\n this.t = target;\n this.c(html);\n }\n this.i(anchor);\n }\n h(html) {\n this.e.innerHTML = html;\n this.n = Array.from(this.e.childNodes);\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert(this.t, this.n[i], anchor);\n }\n }\n p(html) {\n this.d();\n this.h(html);\n this.i(this.a);\n }\n d() {\n this.n.forEach(detach);\n }\n}\nclass HtmlTagHydration extends HtmlTag {\n constructor(claimed_nodes) {\n super();\n this.e = this.n = null;\n this.l = claimed_nodes;\n }\n c(html) {\n if (this.l) {\n this.n = this.l;\n }\n else {\n super.c(html);\n }\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert_hydration(this.t, this.n[i], anchor);\n }\n }\n}\nfunction attribute_to_object(attributes) {\n const result = {};\n for (const attribute of attributes) {\n result[attribute.name] = attribute.value;\n }\n return result;\n}\nfunction get_custom_elements_slots(element) {\n const result = {};\n element.childNodes.forEach((node) => {\n result[node.slot || 'default'] = true;\n });\n return result;\n}\n\nconst active_docs = new Set();\nlet active = 0;\n// https://github.com/darkskyapp/string-hash/blob/master/index.js\nfunction hash(str) {\n let hash = 5381;\n let i = str.length;\n while (i--)\n hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n return hash >>> 0;\n}\nfunction create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {\n const step = 16.666 / duration;\n let keyframes = '{\\n';\n for (let p = 0; p <= 1; p += step) {\n const t = a + (b - a) * ease(p);\n keyframes += p * 100 + `%{${fn(t, 1 - t)}}\\n`;\n }\n const rule = keyframes + `100% {${fn(b, 1 - b)}}\\n}`;\n const name = `__svelte_${hash(rule)}_${uid}`;\n const doc = get_root_for_style(node);\n active_docs.add(doc);\n const stylesheet = doc.__svelte_stylesheet || (doc.__svelte_stylesheet = append_empty_stylesheet(node).sheet);\n const current_rules = doc.__svelte_rules || (doc.__svelte_rules = {});\n if (!current_rules[name]) {\n current_rules[name] = true;\n stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);\n }\n const animation = node.style.animation || '';\n node.style.animation = `${animation ? `${animation}, ` : ''}${name} ${duration}ms linear ${delay}ms 1 both`;\n active += 1;\n return name;\n}\nfunction delete_rule(node, name) {\n const previous = (node.style.animation || '').split(', ');\n const next = previous.filter(name\n ? anim => anim.indexOf(name) < 0 // remove specific animation\n : anim => anim.indexOf('__svelte') === -1 // remove all Svelte animations\n );\n const deleted = previous.length - next.length;\n if (deleted) {\n node.style.animation = next.join(', ');\n active -= deleted;\n if (!active)\n clear_rules();\n }\n}\nfunction clear_rules() {\n raf(() => {\n if (active)\n return;\n active_docs.forEach(doc => {\n const stylesheet = doc.__svelte_stylesheet;\n let i = stylesheet.cssRules.length;\n while (i--)\n stylesheet.deleteRule(i);\n doc.__svelte_rules = {};\n });\n active_docs.clear();\n });\n}\n\nfunction create_animation(node, from, fn, params) {\n if (!from)\n return noop;\n const to = node.getBoundingClientRect();\n if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom)\n return noop;\n const { delay = 0, duration = 300, easing = identity, \n // @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation?\n start: start_time = now() + delay, \n // @ts-ignore todo:\n end = start_time + duration, tick = noop, css } = fn(node, { from, to }, params);\n let running = true;\n let started = false;\n let name;\n function start() {\n if (css) {\n name = create_rule(node, 0, 1, duration, delay, easing, css);\n }\n if (!delay) {\n started = true;\n }\n }\n function stop() {\n if (css)\n delete_rule(node, name);\n running = false;\n }\n loop(now => {\n if (!started && now >= start_time) {\n started = true;\n }\n if (started && now >= end) {\n tick(1, 0);\n stop();\n }\n if (!running) {\n return false;\n }\n if (started) {\n const p = now - start_time;\n const t = 0 + 1 * easing(p / duration);\n tick(t, 1 - t);\n }\n return true;\n });\n start();\n tick(0, 1);\n return stop;\n}\nfunction fix_position(node) {\n const style = getComputedStyle(node);\n if (style.position !== 'absolute' && style.position !== 'fixed') {\n const { width, height } = style;\n const a = node.getBoundingClientRect();\n node.style.position = 'absolute';\n node.style.width = width;\n node.style.height = height;\n add_transform(node, a);\n }\n}\nfunction add_transform(node, a) {\n const b = node.getBoundingClientRect();\n if (a.left !== b.left || a.top !== b.top) {\n const style = getComputedStyle(node);\n const transform = style.transform === 'none' ? '' : style.transform;\n node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;\n }\n}\n\nlet current_component;\nfunction set_current_component(component) {\n current_component = component;\n}\nfunction get_current_component() {\n if (!current_component)\n throw new Error('Function called outside component initialization');\n return current_component;\n}\nfunction beforeUpdate(fn) {\n get_current_component().$$.before_update.push(fn);\n}\nfunction onMount(fn) {\n get_current_component().$$.on_mount.push(fn);\n}\nfunction afterUpdate(fn) {\n get_current_component().$$.after_update.push(fn);\n}\nfunction onDestroy(fn) {\n get_current_component().$$.on_destroy.push(fn);\n}\nfunction createEventDispatcher() {\n const component = get_current_component();\n return (type, detail) => {\n const callbacks = component.$$.callbacks[type];\n if (callbacks) {\n // TODO are there situations where events could be dispatched\n // in a server (non-DOM) environment?\n const event = custom_event(type, detail);\n callbacks.slice().forEach(fn => {\n fn.call(component, event);\n });\n }\n };\n}\nfunction setContext(key, context) {\n get_current_component().$$.context.set(key, context);\n}\nfunction getContext(key) {\n return get_current_component().$$.context.get(key);\n}\nfunction getAllContexts() {\n return get_current_component().$$.context;\n}\nfunction hasContext(key) {\n return get_current_component().$$.context.has(key);\n}\n// TODO figure out if we still want to support\n// shorthand events, or if we want to implement\n// a real bubbling mechanism\nfunction bubble(component, event) {\n const callbacks = component.$$.callbacks[event.type];\n if (callbacks) {\n // @ts-ignore\n callbacks.slice().forEach(fn => fn.call(this, event));\n }\n}\n\nconst dirty_components = [];\nconst intros = { enabled: false };\nconst binding_callbacks = [];\nconst render_callbacks = [];\nconst flush_callbacks = [];\nconst resolved_promise = Promise.resolve();\nlet update_scheduled = false;\nfunction schedule_update() {\n if (!update_scheduled) {\n update_scheduled = true;\n resolved_promise.then(flush);\n }\n}\nfunction tick() {\n schedule_update();\n return resolved_promise;\n}\nfunction add_render_callback(fn) {\n render_callbacks.push(fn);\n}\nfunction add_flush_callback(fn) {\n flush_callbacks.push(fn);\n}\nlet flushing = false;\nconst seen_callbacks = new Set();\nfunction flush() {\n if (flushing)\n return;\n flushing = true;\n do {\n // first, call beforeUpdate functions\n // and update components\n for (let i = 0; i < dirty_components.length; i += 1) {\n const component = dirty_components[i];\n set_current_component(component);\n update(component.$$);\n }\n set_current_component(null);\n dirty_components.length = 0;\n while (binding_callbacks.length)\n binding_callbacks.pop()();\n // then, once components are updated, call\n // afterUpdate functions. This may cause\n // subsequent updates...\n for (let i = 0; i < render_callbacks.length; i += 1) {\n const callback = render_callbacks[i];\n if (!seen_callbacks.has(callback)) {\n // ...so guard against infinite loops\n seen_callbacks.add(callback);\n callback();\n }\n }\n render_callbacks.length = 0;\n } while (dirty_components.length);\n while (flush_callbacks.length) {\n flush_callbacks.pop()();\n }\n update_scheduled = false;\n flushing = false;\n seen_callbacks.clear();\n}\nfunction update($$) {\n if ($$.fragment !== null) {\n $$.update();\n run_all($$.before_update);\n const dirty = $$.dirty;\n $$.dirty = [-1];\n $$.fragment && $$.fragment.p($$.ctx, dirty);\n $$.after_update.forEach(add_render_callback);\n }\n}\n\nlet promise;\nfunction wait() {\n if (!promise) {\n promise = Promise.resolve();\n promise.then(() => {\n promise = null;\n });\n }\n return promise;\n}\nfunction dispatch(node, direction, kind) {\n node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));\n}\nconst outroing = new Set();\nlet outros;\nfunction group_outros() {\n outros = {\n r: 0,\n c: [],\n p: outros // parent group\n };\n}\nfunction check_outros() {\n if (!outros.r) {\n run_all(outros.c);\n }\n outros = outros.p;\n}\nfunction transition_in(block, local) {\n if (block && block.i) {\n outroing.delete(block);\n block.i(local);\n }\n}\nfunction transition_out(block, local, detach, callback) {\n if (block && block.o) {\n if (outroing.has(block))\n return;\n outroing.add(block);\n outros.c.push(() => {\n outroing.delete(block);\n if (callback) {\n if (detach)\n block.d(1);\n callback();\n }\n });\n block.o(local);\n }\n}\nconst null_transition = { duration: 0 };\nfunction create_in_transition(node, fn, params) {\n let config = fn(node, params);\n let running = false;\n let animation_name;\n let task;\n let uid = 0;\n function cleanup() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++);\n tick(0, 1);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n if (task)\n task.abort();\n running = true;\n add_render_callback(() => dispatch(node, true, 'start'));\n task = loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(1, 0);\n dispatch(node, true, 'end');\n cleanup();\n return running = false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(t, 1 - t);\n }\n }\n return running;\n });\n }\n let started = false;\n return {\n start() {\n if (started)\n return;\n started = true;\n delete_rule(node);\n if (is_function(config)) {\n config = config();\n wait().then(go);\n }\n else {\n go();\n }\n },\n invalidate() {\n started = false;\n },\n end() {\n if (running) {\n cleanup();\n running = false;\n }\n }\n };\n}\nfunction create_out_transition(node, fn, params) {\n let config = fn(node, params);\n let running = true;\n let animation_name;\n const group = outros;\n group.r += 1;\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 1, 0, duration, delay, easing, css);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n add_render_callback(() => dispatch(node, false, 'start'));\n loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(0, 1);\n dispatch(node, false, 'end');\n if (!--group.r) {\n // this will result in `end()` being called,\n // so we don't need to clean up here\n run_all(group.c);\n }\n return false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(1 - t, t);\n }\n }\n return running;\n });\n }\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go();\n });\n }\n else {\n go();\n }\n return {\n end(reset) {\n if (reset && config.tick) {\n config.tick(1, 0);\n }\n if (running) {\n if (animation_name)\n delete_rule(node, animation_name);\n running = false;\n }\n }\n };\n}\nfunction create_bidirectional_transition(node, fn, params, intro) {\n let config = fn(node, params);\n let t = intro ? 0 : 1;\n let running_program = null;\n let pending_program = null;\n let animation_name = null;\n function clear_animation() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function init(program, duration) {\n const d = (program.b - t);\n duration *= Math.abs(d);\n return {\n a: t,\n b: program.b,\n d,\n duration,\n start: program.start,\n end: program.start + duration,\n group: program.group\n };\n }\n function go(b) {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n const program = {\n start: now() + delay,\n b\n };\n if (!b) {\n // @ts-ignore todo: improve typings\n program.group = outros;\n outros.r += 1;\n }\n if (running_program || pending_program) {\n pending_program = program;\n }\n else {\n // if this is an intro, and there's a delay, we need to do\n // an initial tick and/or apply CSS animation immediately\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, b, duration, delay, easing, css);\n }\n if (b)\n tick(0, 1);\n running_program = init(program, duration);\n add_render_callback(() => dispatch(node, b, 'start'));\n loop(now => {\n if (pending_program && now > pending_program.start) {\n running_program = init(pending_program, duration);\n pending_program = null;\n dispatch(node, running_program.b, 'start');\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);\n }\n }\n if (running_program) {\n if (now >= running_program.end) {\n tick(t = running_program.b, 1 - t);\n dispatch(node, running_program.b, 'end');\n if (!pending_program) {\n // we're done\n if (running_program.b) {\n // intro — we can tidy up immediately\n clear_animation();\n }\n else {\n // outro — needs to be coordinated\n if (!--running_program.group.r)\n run_all(running_program.group.c);\n }\n }\n running_program = null;\n }\n else if (now >= running_program.start) {\n const p = now - running_program.start;\n t = running_program.a + running_program.d * easing(p / running_program.duration);\n tick(t, 1 - t);\n }\n }\n return !!(running_program || pending_program);\n });\n }\n }\n return {\n run(b) {\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go(b);\n });\n }\n else {\n go(b);\n }\n },\n end() {\n clear_animation();\n running_program = pending_program = null;\n }\n };\n}\n\nfunction handle_promise(promise, info) {\n const token = info.token = {};\n function update(type, index, key, value) {\n if (info.token !== token)\n return;\n info.resolved = value;\n let child_ctx = info.ctx;\n if (key !== undefined) {\n child_ctx = child_ctx.slice();\n child_ctx[key] = value;\n }\n const block = type && (info.current = type)(child_ctx);\n let needs_flush = false;\n if (info.block) {\n if (info.blocks) {\n info.blocks.forEach((block, i) => {\n if (i !== index && block) {\n group_outros();\n transition_out(block, 1, 1, () => {\n if (info.blocks[i] === block) {\n info.blocks[i] = null;\n }\n });\n check_outros();\n }\n });\n }\n else {\n info.block.d(1);\n }\n block.c();\n transition_in(block, 1);\n block.m(info.mount(), info.anchor);\n needs_flush = true;\n }\n info.block = block;\n if (info.blocks)\n info.blocks[index] = block;\n if (needs_flush) {\n flush();\n }\n }\n if (is_promise(promise)) {\n const current_component = get_current_component();\n promise.then(value => {\n set_current_component(current_component);\n update(info.then, 1, info.value, value);\n set_current_component(null);\n }, error => {\n set_current_component(current_component);\n update(info.catch, 2, info.error, error);\n set_current_component(null);\n if (!info.hasCatch) {\n throw error;\n }\n });\n // if we previously had a then/catch block, destroy it\n if (info.current !== info.pending) {\n update(info.pending, 0);\n return true;\n }\n }\n else {\n if (info.current !== info.then) {\n update(info.then, 1, info.value, promise);\n return true;\n }\n info.resolved = promise;\n }\n}\nfunction update_await_block_branch(info, ctx, dirty) {\n const child_ctx = ctx.slice();\n const { resolved } = info;\n if (info.current === info.then) {\n child_ctx[info.value] = resolved;\n }\n if (info.current === info.catch) {\n child_ctx[info.error] = resolved;\n }\n info.block.p(child_ctx, dirty);\n}\n\nconst globals = (typeof window !== 'undefined'\n ? window\n : typeof globalThis !== 'undefined'\n ? globalThis\n : global);\n\nfunction destroy_block(block, lookup) {\n block.d(1);\n lookup.delete(block.key);\n}\nfunction outro_and_destroy_block(block, lookup) {\n transition_out(block, 1, 1, () => {\n lookup.delete(block.key);\n });\n}\nfunction fix_and_destroy_block(block, lookup) {\n block.f();\n destroy_block(block, lookup);\n}\nfunction fix_and_outro_and_destroy_block(block, lookup) {\n block.f();\n outro_and_destroy_block(block, lookup);\n}\nfunction update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {\n let o = old_blocks.length;\n let n = list.length;\n let i = o;\n const old_indexes = {};\n while (i--)\n old_indexes[old_blocks[i].key] = i;\n const new_blocks = [];\n const new_lookup = new Map();\n const deltas = new Map();\n i = n;\n while (i--) {\n const child_ctx = get_context(ctx, list, i);\n const key = get_key(child_ctx);\n let block = lookup.get(key);\n if (!block) {\n block = create_each_block(key, child_ctx);\n block.c();\n }\n else if (dynamic) {\n block.p(child_ctx, dirty);\n }\n new_lookup.set(key, new_blocks[i] = block);\n if (key in old_indexes)\n deltas.set(key, Math.abs(i - old_indexes[key]));\n }\n const will_move = new Set();\n const did_move = new Set();\n function insert(block) {\n transition_in(block, 1);\n block.m(node, next);\n lookup.set(block.key, block);\n next = block.first;\n n--;\n }\n while (o && n) {\n const new_block = new_blocks[n - 1];\n const old_block = old_blocks[o - 1];\n const new_key = new_block.key;\n const old_key = old_block.key;\n if (new_block === old_block) {\n // do nothing\n next = new_block.first;\n o--;\n n--;\n }\n else if (!new_lookup.has(old_key)) {\n // remove old block\n destroy(old_block, lookup);\n o--;\n }\n else if (!lookup.has(new_key) || will_move.has(new_key)) {\n insert(new_block);\n }\n else if (did_move.has(old_key)) {\n o--;\n }\n else if (deltas.get(new_key) > deltas.get(old_key)) {\n did_move.add(new_key);\n insert(new_block);\n }\n else {\n will_move.add(old_key);\n o--;\n }\n }\n while (o--) {\n const old_block = old_blocks[o];\n if (!new_lookup.has(old_block.key))\n destroy(old_block, lookup);\n }\n while (n)\n insert(new_blocks[n - 1]);\n return new_blocks;\n}\nfunction validate_each_keys(ctx, list, get_context, get_key) {\n const keys = new Set();\n for (let i = 0; i < list.length; i++) {\n const key = get_key(get_context(ctx, list, i));\n if (keys.has(key)) {\n throw new Error('Cannot have duplicate keys in a keyed each');\n }\n keys.add(key);\n }\n}\n\nfunction get_spread_update(levels, updates) {\n const update = {};\n const to_null_out = {};\n const accounted_for = { $$scope: 1 };\n let i = levels.length;\n while (i--) {\n const o = levels[i];\n const n = updates[i];\n if (n) {\n for (const key in o) {\n if (!(key in n))\n to_null_out[key] = 1;\n }\n for (const key in n) {\n if (!accounted_for[key]) {\n update[key] = n[key];\n accounted_for[key] = 1;\n }\n }\n levels[i] = n;\n }\n else {\n for (const key in o) {\n accounted_for[key] = 1;\n }\n }\n }\n for (const key in to_null_out) {\n if (!(key in update))\n update[key] = undefined;\n }\n return update;\n}\nfunction get_spread_object(spread_props) {\n return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};\n}\n\n// source: https://html.spec.whatwg.org/multipage/indices.html\nconst boolean_attributes = new Set([\n 'allowfullscreen',\n 'allowpaymentrequest',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'ismap',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected'\n]);\n\nconst invalid_attribute_name_character = /[\\s'\">/=\\u{FDD0}-\\u{FDEF}\\u{FFFE}\\u{FFFF}\\u{1FFFE}\\u{1FFFF}\\u{2FFFE}\\u{2FFFF}\\u{3FFFE}\\u{3FFFF}\\u{4FFFE}\\u{4FFFF}\\u{5FFFE}\\u{5FFFF}\\u{6FFFE}\\u{6FFFF}\\u{7FFFE}\\u{7FFFF}\\u{8FFFE}\\u{8FFFF}\\u{9FFFE}\\u{9FFFF}\\u{AFFFE}\\u{AFFFF}\\u{BFFFE}\\u{BFFFF}\\u{CFFFE}\\u{CFFFF}\\u{DFFFE}\\u{DFFFF}\\u{EFFFE}\\u{EFFFF}\\u{FFFFE}\\u{FFFFF}\\u{10FFFE}\\u{10FFFF}]/u;\n// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n// https://infra.spec.whatwg.org/#noncharacter\nfunction spread(args, classes_to_add) {\n const attributes = Object.assign({}, ...args);\n if (classes_to_add) {\n if (attributes.class == null) {\n attributes.class = classes_to_add;\n }\n else {\n attributes.class += ' ' + classes_to_add;\n }\n }\n let str = '';\n Object.keys(attributes).forEach(name => {\n if (invalid_attribute_name_character.test(name))\n return;\n const value = attributes[name];\n if (value === true)\n str += ' ' + name;\n else if (boolean_attributes.has(name.toLowerCase())) {\n if (value)\n str += ' ' + name;\n }\n else if (value != null) {\n str += ` ${name}=\"${value}\"`;\n }\n });\n return str;\n}\nconst escaped = {\n '\"': '&quot;',\n \"'\": '&#39;',\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;'\n};\nfunction escape(html) {\n return String(html).replace(/[\"'&<>]/g, match => escaped[match]);\n}\nfunction escape_attribute_value(value) {\n return typeof value === 'string' ? escape(value) : value;\n}\nfunction escape_object(obj) {\n const result = {};\n for (const key in obj) {\n result[key] = escape_attribute_value(obj[key]);\n }\n return result;\n}\nfunction each(items, fn) {\n let str = '';\n for (let i = 0; i < items.length; i += 1) {\n str += fn(items[i], i);\n }\n return str;\n}\nconst missing_component = {\n $$render: () => ''\n};\nfunction validate_component(component, name) {\n if (!component || !component.$$render) {\n if (name === 'svelte:component')\n name += ' this={...}';\n throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`);\n }\n return component;\n}\nfunction debug(file, line, column, values) {\n console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console\n console.log(values); // eslint-disable-line no-console\n return '';\n}\nlet on_destroy;\nfunction create_ssr_component(fn) {\n function $$render(result, props, bindings, slots, context) {\n const parent_component = current_component;\n const $$ = {\n on_destroy,\n context: new Map(parent_component ? parent_component.$$.context : context || []),\n // these will be immediately discarded\n on_mount: [],\n before_update: [],\n after_update: [],\n callbacks: blank_object()\n };\n set_current_component({ $$ });\n const html = fn(result, props, bindings, slots);\n set_current_component(parent_component);\n return html;\n }\n return {\n render: (props = {}, { $$slots = {}, context = new Map() } = {}) => {\n on_destroy = [];\n const result = { title: '', head: '', css: new Set() };\n const html = $$render(result, props, {}, $$slots, context);\n run_all(on_destroy);\n return {\n html,\n css: {\n code: Array.from(result.css).map(css => css.code).join('\\n'),\n map: null // TODO\n },\n head: result.title + result.head\n };\n },\n $$render\n };\n}\nfunction add_attribute(name, value, boolean) {\n if (value == null || (boolean && !value))\n return '';\n return ` ${name}${value === true ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `\"${value}\"`}`}`;\n}\nfunction add_classes(classes) {\n return classes ? ` class=\"${classes}\"` : '';\n}\n\nfunction bind(component, name, callback) {\n const index = component.$$.props[name];\n if (index !== undefined) {\n component.$$.bound[index] = callback;\n callback(component.$$.ctx[index]);\n }\n}\nfunction create_component(block) {\n block && block.c();\n}\nfunction claim_component(block, parent_nodes) {\n block && block.l(parent_nodes);\n}\nfunction mount_component(component, target, anchor, customElement) {\n const { fragment, on_mount, on_destroy, after_update } = component.$$;\n fragment && fragment.m(target, anchor);\n if (!customElement) {\n // onMount happens before the initial afterUpdate\n add_render_callback(() => {\n const new_on_destroy = on_mount.map(run).filter(is_function);\n if (on_destroy) {\n on_destroy.push(...new_on_destroy);\n }\n else {\n // Edge case - component was destroyed immediately,\n // most likely as a result of a binding initialising\n run_all(new_on_destroy);\n }\n component.$$.on_mount = [];\n });\n }\n after_update.forEach(add_render_callback);\n}\nfunction destroy_component(component, detaching) {\n const $$ = component.$$;\n if ($$.fragment !== null) {\n run_all($$.on_destroy);\n $$.fragment && $$.fragment.d(detaching);\n // TODO null out other refs, including component.$$ (but need to\n // preserve final state?)\n $$.on_destroy = $$.fragment = null;\n $$.ctx = [];\n }\n}\nfunction make_dirty(component, i) {\n if (component.$$.dirty[0] === -1) {\n dirty_components.push(component);\n schedule_update();\n component.$$.dirty.fill(0);\n }\n component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));\n}\nfunction init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) {\n const parent_component = current_component;\n set_current_component(component);\n const $$ = component.$$ = {\n fragment: null,\n ctx: null,\n // state\n props,\n update: noop,\n not_equal,\n bound: blank_object(),\n // lifecycle\n on_mount: [],\n on_destroy: [],\n on_disconnect: [],\n before_update: [],\n after_update: [],\n context: new Map(parent_component ? parent_component.$$.context : options.context || []),\n // everything else\n callbacks: blank_object(),\n dirty,\n skip_bound: false,\n root: options.target || parent_component.$$.root\n };\n append_styles && append_styles($$.root);\n let ready = false;\n $$.ctx = instance\n ? instance(component, options.props || {}, (i, ret, ...rest) => {\n const value = rest.length ? rest[0] : ret;\n if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {\n if (!$$.skip_bound && $$.bound[i])\n $$.bound[i](value);\n if (ready)\n make_dirty(component, i);\n }\n return ret;\n })\n : [];\n $$.update();\n ready = true;\n run_all($$.before_update);\n // `false` as a special case of no DOM component\n $$.fragment = create_fragment ? create_fragment($$.ctx) : false;\n if (options.target) {\n if (options.hydrate) {\n start_hydrating();\n const nodes = children(options.target);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.l(nodes);\n nodes.forEach(detach);\n }\n else {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.c();\n }\n if (options.intro)\n transition_in(component.$$.fragment);\n mount_component(component, options.target, options.anchor, options.customElement);\n end_hydrating();\n flush();\n }\n set_current_component(parent_component);\n}\nlet SvelteElement;\nif (typeof HTMLElement === 'function') {\n SvelteElement = class extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n }\n connectedCallback() {\n const { on_mount } = this.$$;\n this.$$.on_disconnect = on_mount.map(run).filter(is_function);\n // @ts-ignore todo: improve typings\n for (const key in this.$$.slotted) {\n // @ts-ignore todo: improve typings\n this.appendChild(this.$$.slotted[key]);\n }\n }\n attributeChangedCallback(attr, _oldValue, newValue) {\n this[attr] = newValue;\n }\n disconnectedCallback() {\n run_all(this.$$.on_disconnect);\n }\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n // TODO should this delegate to addEventListener?\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n };\n}\n/**\n * Base class for Svelte components. Used when dev=false.\n */\nclass SvelteComponent {\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n}\n\nfunction dispatch_dev(type, detail) {\n document.dispatchEvent(custom_event(type, Object.assign({ version: '3.42.4' }, detail), true));\n}\nfunction append_dev(target, node) {\n dispatch_dev('SvelteDOMInsert', { target, node });\n append(target, node);\n}\nfunction append_hydration_dev(target, node) {\n dispatch_dev('SvelteDOMInsert', { target, node });\n append_hydration(target, node);\n}\nfunction insert_dev(target, node, anchor) {\n dispatch_dev('SvelteDOMInsert', { target, node, anchor });\n insert(target, node, anchor);\n}\nfunction insert_hydration_dev(target, node, anchor) {\n dispatch_dev('SvelteDOMInsert', { target, node, anchor });\n insert_hydration(target, node, anchor);\n}\nfunction detach_dev(node) {\n dispatch_dev('SvelteDOMRemove', { node });\n detach(node);\n}\nfunction detach_between_dev(before, after) {\n while (before.nextSibling && before.nextSibling !== after) {\n detach_dev(before.nextSibling);\n }\n}\nfunction detach_before_dev(after) {\n while (after.previousSibling) {\n detach_dev(after.previousSibling);\n }\n}\nfunction detach_after_dev(before) {\n while (before.nextSibling) {\n detach_dev(before.nextSibling);\n }\n}\nfunction listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) {\n const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : [];\n if (has_prevent_default)\n modifiers.push('preventDefault');\n if (has_stop_propagation)\n modifiers.push('stopPropagation');\n dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers });\n const dispose = listen(node, event, handler, options);\n return () => {\n dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers });\n dispose();\n };\n}\nfunction attr_dev(node, attribute, value) {\n attr(node, attribute, value);\n if (value == null)\n dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute });\n else\n dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value });\n}\nfunction prop_dev(node, property, value) {\n node[property] = value;\n dispatch_dev('SvelteDOMSetProperty', { node, property, value });\n}\nfunction dataset_dev(node, property, value) {\n node.dataset[property] = value;\n dispatch_dev('SvelteDOMSetDataset', { node, property, value });\n}\nfunction set_data_dev(text, data) {\n data = '' + data;\n if (text.wholeText === data)\n return;\n dispatch_dev('SvelteDOMSetData', { node: text, data });\n text.data = data;\n}\nfunction validate_each_argument(arg) {\n if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {\n let msg = '{#each} only iterates over array-like objects.';\n if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {\n msg += ' You can use a spread to convert this iterable into an array.';\n }\n throw new Error(msg);\n }\n}\nfunction validate_slots(name, slot, keys) {\n for (const slot_key of Object.keys(slot)) {\n if (!~keys.indexOf(slot_key)) {\n console.warn(`<${name}> received an unexpected slot \"${slot_key}\".`);\n }\n }\n}\n/**\n * Base class for Svelte components with some minor dev-enhancements. Used when dev=true.\n */\nclass SvelteComponentDev extends SvelteComponent {\n constructor(options) {\n if (!options || (!options.target && !options.$$inline)) {\n throw new Error(\"'target' is a required option\");\n }\n super();\n }\n $destroy() {\n super.$destroy();\n this.$destroy = () => {\n console.warn('Component was already destroyed'); // eslint-disable-line no-console\n };\n }\n $capture_state() { }\n $inject_state() { }\n}\n/**\n * Base class to create strongly typed Svelte components.\n * This only exists for typing purposes and should be used in `.d.ts` files.\n *\n * ### Example:\n *\n * You have component library on npm called `component-library`, from which\n * you export a component called `MyComponent`. For Svelte+TypeScript users,\n * you want to provide typings. Therefore you create a `index.d.ts`:\n * ```ts\n * import { SvelteComponentTyped } from \"svelte\";\n * export class MyComponent extends SvelteComponentTyped<{foo: string}> {}\n * ```\n * Typing this makes it possible for IDEs like VS Code with the Svelte extension\n * to provide intellisense and to use the component like this in a Svelte file\n * with TypeScript:\n * ```svelte\n * <script lang=\"ts\">\n * \timport { MyComponent } from \"component-library\";\n * </script>\n * <MyComponent foo={'bar'} />\n * ```\n *\n * #### Why not make this part of `SvelteComponent(Dev)`?\n * Because\n * ```ts\n * class ASubclassOfSvelteComponent extends SvelteComponent<{foo: string}> {}\n * const component: typeof SvelteComponent = ASubclassOfSvelteComponent;\n * ```\n * will throw a type error, so we need to separate the more strictly typed class.\n */\nclass SvelteComponentTyped extends SvelteComponentDev {\n constructor(options) {\n super(options);\n }\n}\nfunction loop_guard(timeout) {\n const start = Date.now();\n return () => {\n if (Date.now() - start > timeout) {\n throw new Error('Infinite loop detected');\n }\n };\n}\n\nexport { HtmlTag, HtmlTagHydration, SvelteComponent, SvelteComponentDev, SvelteComponentTyped, SvelteElement, action_destroyer, add_attribute, add_classes, add_flush_callback, add_location, add_render_callback, add_resize_listener, add_transform, afterUpdate, append, append_dev, append_empty_stylesheet, append_hydration, append_hydration_dev, append_styles, assign, attr, attr_dev, attribute_to_object, beforeUpdate, bind, binding_callbacks, blank_object, bubble, check_outros, children, claim_component, claim_element, claim_html_tag, claim_space, claim_svg_element, claim_text, clear_loops, component_subscribe, compute_rest_props, compute_slots, createEventDispatcher, create_animation, create_bidirectional_transition, create_component, create_in_transition, create_out_transition, create_slot, create_ssr_component, current_component, custom_event, dataset_dev, debug, destroy_block, destroy_component, destroy_each, detach, detach_after_dev, detach_before_dev, detach_between_dev, detach_dev, dirty_components, dispatch_dev, each, element, element_is, empty, end_hydrating, escape, escape_attribute_value, escape_object, escaped, exclude_internal_props, fix_and_destroy_block, fix_and_outro_and_destroy_block, fix_position, flush, getAllContexts, getContext, get_all_dirty_from_scope, get_binding_group_value, get_current_component, get_custom_elements_slots, get_root_for_style, get_slot_changes, get_spread_object, get_spread_update, get_store_value, globals, group_outros, handle_promise, hasContext, has_prop, identity, init, insert, insert_dev, insert_hydration, insert_hydration_dev, intros, invalid_attribute_name_character, is_client, is_crossorigin, is_empty, is_function, is_promise, listen, listen_dev, loop, loop_guard, missing_component, mount_component, noop, not_equal, now, null_to_empty, object_without_properties, onDestroy, onMount, once, outro_and_destroy_block, prevent_default, prop_dev, query_selector_all, raf, run, run_all, safe_not_equal, schedule_update, select_multiple_value, select_option, select_options, select_value, self, setContext, set_attributes, set_current_component, set_custom_element_data, set_data, set_data_dev, set_input_type, set_input_value, set_now, set_raf, set_store_value, set_style, set_svg_attributes, space, spread, src_url_equal, start_hydrating, stop_propagation, subscribe, svg_element, text, tick, time_ranges_to_array, to_number, toggle_class, transition_in, transition_out, trusted, update_await_block_branch, update_keyed_each, update_slot, update_slot_base, validate_component, validate_each_argument, validate_each_keys, validate_slots, validate_store, xlink_attr };\n","<script lang=\"ts\">\n import { isEmpty } from \"lodash\";\n\n export let cursorName: string;\n export let tagName: string;\n export let backgroundColor: string;\n export let appliance: string;\n export let x: number;\n export let y: number;\n export let src: string;\n export let visible: boolean;\n export let avatar: string;\n export let theme: string;\n export let color: string;\n export let cursorTagBackgroundColor: string;\n export let opacity: number;\n\n $: hasName = !isEmpty(cursorName);\n $: hasTagName = !isEmpty(tagName);\n $: hasAvatar = !isEmpty(avatar);\n $: display = visible ? \"initial\" : \"none\";\n\n const computedAvatarStyle = () => {\n return Object.entries({\n width: (hasName ? 19 : 28) + \"px\",\n height: (hasName ? 19 : 28) + \"px\",\n position: hasName ? \"initial\" : \"absolute\",\n \"border-color\": hasName ? \"white\" : backgroundColor,\n \"margin-right\": (hasName ? 4 : 0) + \"px\",\n })\n .map(([key, v]) => `${key}: ${v}`)\n .join(\";\");\n };\n</script>\n\n<div\n class=\"netless-window-manager-cursor-mid\"\n style=\"transform: translateX({x}px) translateY({y}px);display: {display}\"\n>\n <div class=\"netless-window-manager-cursor-name\">\n <div\n class={theme}\n style=\"background-color: {backgroundColor};color: {color};opacity: {opacity}\"\n >\n {#if hasAvatar}\n <img\n class=\"netless-window-manager-cursor-selector-avatar\"\n style={computedAvatarStyle()}\n src={avatar}\n alt=\"avatar\"\n />\n {/if}\n <span style=\"overflow: hidden;white-space: nowrap;text-overflow: ellipsis;max-width: 80px\">{cursorName}</span>\n {#if hasTagName}\n <span class=\"netless-window-manager-cursor-tag-name\" style=\"background-color: {cursorTagBackgroundColor}\">\n {tagName}\n </span>\n {/if}\n </div>\n </div>\n <div class=\"cursor-image-wrapper\">\n <img class=\"netless-window-manager-cursor-{appliance}-image\" {src} alt={appliance} />\n </div>\n</div>\n","import { ApplianceNames } from \"white-web-sdk\";\nimport pencil from \"../image/pencil-cursor.png\";\nimport selector from \"../image/selector-cursor.png\";\nimport eraser from \"../image/eraser-cursor.png\";\nimport shape from \"../image/shape-cursor.svg\";\nimport text from \"../image/text-cursor.svg\";\n\nexport const ApplianceMap: {\n [key: string]: string;\n} = {\n [ApplianceNames.pencil]: pencil,\n [ApplianceNames.selector]: selector,\n [ApplianceNames.eraser]: eraser,\n [ApplianceNames.shape]: shape,\n [ApplianceNames.text]: text,\n};\n","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNDBweCIgaGVpZ2h0PSI0MHB4IiB2aWV3Qm94PSIwIDAgNDAgNDAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDYwLjEgKDg4MTMzKSAtIGh0dHBzOi8vc2tldGNoLmNvbSAtLT4KICAgIDx0aXRsZT5zaGFwZS1jdXJzb3I8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz4KICAgICAgICA8cGF0aCBkPSJNMjAsMjEuNSBDMjAuMjQ1NDU5OSwyMS41IDIwLjQ0OTYwODQsMjEuNjc2ODc1MiAyMC40OTE5NDQzLDIxLjkxMDEyNDQgTDIwLjUsMjIgTDIwLjUsMjcgQzIwLjUsMjcuMjc2MTQyNCAyMC4yNzYxNDI0LDI3LjUgMjAsMjcuNSBDMTkuNzU0NTQwMSwyNy41IDE5LjU1MDM5MTYsMjcuMzIzMTI0OCAxOS41MDgwNTU3LDI3LjA4OTg3NTYgTDE5LjUsMjcgTDE5LjUsMjIgQzE5LjUsMjEuNzIzODU3NiAxOS43MjM4NTc2LDIxLjUgMjAsMjEuNSBaIE0yNywxOS41IEMyNy4yNzYxNDI0LDE5LjUgMjcuNSwxOS43MjM4NTc2IDI3LjUsMjAgQzI3LjUsMjAuMjQ1NDU5OSAyNy4zMjMxMjQ4LDIwLjQ0OTYwODQgMjcuMDg5ODc1NiwyMC40OTE5NDQzIEwyNywyMC41IEwyMiwyMC41IEMyMS43MjM4NTc2LDIwLjUgMjEuNSwyMC4yNzYxNDI0IDIxLjUsMjAgQzIxLjUsMTkuNzU0NTQwMSAyMS42NzY4NzUyLDE5LjU1MDM5MTYgMjEuOTEwMTI0NCwxOS41MDgwNTU3IEwyMiwxOS41IEwyNywxOS41IFogTTE4LDE5LjUgQzE4LjI3NjE0MjQsMTkuNSAxOC41LDE5LjcyMzg1NzYgMTguNSwyMCBDMTguNSwyMC4yNDU0NTk5IDE4LjMyMzEyNDgsMjAuNDQ5NjA4NCAxOC4wODk4NzU2LDIwLjQ5MTk0NDMgTDE4LDIwLjUgTDEzLDIwLjUgQzEyLjcyMzg1NzYsMjAuNSAxMi41LDIwLjI3NjE0MjQgMTIuNSwyMCBDMTIuNSwxOS43NTQ1NDAxIDEyLjY3Njg3NTIsMTkuNTUwMzkxNiAxMi45MTAxMjQ0LDE5LjUwODA1NTcgTDEzLDE5LjUgTDE4LDE5LjUgWiBNMjAsMTIuNSBDMjAuMjQ1NDU5OSwxMi41IDIwLjQ0OTYwODQsMTIuNjc2ODc1MiAyMC40OTE5NDQzLDEyLjkxMDEyNDQgTDIwLjUsMTMgTDIwLjUsMTggQzIwLjUsMTguMjc2MTQyNCAyMC4yNzYxNDI0LDE4LjUgMjAsMTguNSBDMTkuNzU0NTQwMSwxOC41IDE5LjU1MDM5MTYsMTguMzIzMTI0OCAxOS41MDgwNTU3LDE4LjA4OTg3NTYgTDE5LjUsMTggTDE5LjUsMTMgQzE5LjUsMTIuNzIzODU3NiAxOS43MjM4NTc2LDEyLjUgMjAsMTIuNSBaIiBpZD0icGF0aC0xIj48L3BhdGg+CiAgICAgICAgPGZpbHRlciB4PSItNjQuNiUiIHk9Ii01OS41JSIgd2lkdGg9IjIyOS4zJSIgaGVpZ2h0PSIyNDYuMSUiIGZpbHRlclVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgaWQ9ImZpbHRlci0yIj4KICAgICAgICAgICAgPGZlTW9ycGhvbG9neSByYWRpdXM9IjEiIG9wZXJhdG9yPSJkaWxhdGUiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dTcHJlYWRPdXRlcjEiPjwvZmVNb3JwaG9sb2d5PgogICAgICAgICAgICA8ZmVPZmZzZXQgZHg9IjAiIGR5PSIyIiBpbj0ic2hhZG93U3ByZWFkT3V0ZXIxIiByZXN1bHQ9InNoYWRvd09mZnNldE91dGVyMSI+PC9mZU9mZnNldD4KICAgICAgICAgICAgPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMyIgaW49InNoYWRvd09mZnNldE91dGVyMSIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIj48L2ZlR2F1c3NpYW5CbHVyPgogICAgICAgICAgICA8ZmVDb21wb3NpdGUgaW49InNoYWRvd0JsdXJPdXRlcjEiIGluMj0iU291cmNlQWxwaGEiIG9wZXJhdG9yPSJvdXQiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUNvbXBvc2l0ZT4KICAgICAgICAgICAgPGZlQ29sb3JNYXRyaXggdmFsdWVzPSIwIDAgMCAwIDAgICAwIDAgMCAwIDAgICAwIDAgMCAwIDAgIDAgMCAwIDAuMTYgMCIgdHlwZT0ibWF0cml4IiBpbj0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUNvbG9yTWF0cml4PgogICAgICAgIDwvZmlsdGVyPgogICAgPC9kZWZzPgogICAgPGcgaWQ9Iumhtemdoi00IiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iV2hpdGVib2FyZC1HdWlkZWxpbmVzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzQ0LjAwMDAwMCwgLTc1MS4wMDAwMDApIj4KICAgICAgICAgICAgPGcgaWQ9InNoYXBlLWN1cnNvciIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzQ0LjAwMDAwMCwgNzUxLjAwMDAwMCkiPgogICAgICAgICAgICAgICAgPHJlY3QgaWQ9IuefqeW9ouWkh+S7vS00NCIgZmlsbD0iI0ZGRkZGRiIgb3BhY2l0eT0iMC4wMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIiByeD0iMiI+PC9yZWN0PgogICAgICAgICAgICAgICAgPGcgaWQ9IuW9oueKtue7k+WQiCIgZmlsbC1ydWxlPSJub256ZXJvIj4KICAgICAgICAgICAgICAgICAgICA8dXNlIGZpbGw9ImJsYWNrIiBmaWxsLW9wYWNpdHk9IjEiIGZpbHRlcj0idXJsKCNmaWx0ZXItMikiIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIxIiBkPSJNMjAsMjEgQzIwLjQ4NTQxMDMsMjEgMjAuODk4MDg1LDIxLjM0Nzk5OTMgMjAuOTg5OTQ3OSwyMS44NjU0ODc3IEwyMSwyMiBMMjEsMjcgQzIxLDI3LjU1MjI4NDcgMjAuNTUyMjg0NywyOCAyMCwyOCBDMTkuNTE0NTg5NywyOCAxOS4xMDE5MTUsMjcuNjUyMDAwNyAxOS4wMTAwNTIxLDI3LjEzNDUxMjMgTDE5LDI3IEwxOSwyMiBDMTksMjEuNDQ3NzE1MyAxOS40NDc3MTUzLDIxIDIwLDIxIFogTTI3LDE5IEMyNy41NTIyODQ3LDE5IDI4LDE5LjQ0NzcxNTMgMjgsMjAgQzI4LDIwLjQ4NTQxMDMgMjcuNjUyMDAwNywyMC44OTgwODUgMjcuMTM0NTEyMywyMC45ODk5NDc5IEwyNywyMSBMMjIsMjEgQzIxLjQ0NzcxNTMsMjEgMjEsMjAuNTUyMjg0NyAyMSwyMCBDMjEsMTkuNTE0NTg5NyAyMS4zNDc5OTkzLDE5LjEwMTkxNSAyMS44NjU0ODc3LDE5LjAxMDA1MjEgTDIyLDE5IEwyNywxOSBaIE0xOCwxOSBDMTguNTUyMjg0NywxOSAxOSwxOS40NDc3MTUzIDE5LDIwIEMxOSwyMC40ODU0MTAzIDE4LjY1MjAwMDcsMjAuODk4MDg1IDE4LjEzNDUxMjMsMjAuOTg5OTQ3OSBMMTgsMjEgTDEzLDIxIEMxMi40NDc3MTUzLDIxIDEyLDIwLjU1MjI4NDcgMTIsMjAgQzEyLDE5LjUxNDU4OTcgMTIuMzQ3OTk5MywxOS4xMDE5MTUgMTIuODY1NDg3NywxOS4wMTAwNTIxIEwxMywxOSBMMTgsMTkgWiBNMjAsMTIgQzIwLjQ4NTQxMDMsMTIgMjAuODk4MDg1LDEyLjM0Nzk5OTMgMjAuOTg5OTQ3OSwxMi44NjU0ODc3IEwyMSwxMyBMMjEsMTggQzIxLDE4LjU1MjI4NDcgMjAuNTUyMjg0NywxOSAyMCwxOSBDMTkuNTE0NTg5NywxOSAxOS4xMDE5MTUsMTguNjUyMDAwNyAxOS4wMTAwNTIxLDE4LjEzNDUxMjMgTDE5LDE4IEwxOSwxMyBDMTksMTIuNDQ3NzE1MyAxOS40NDc3MTUzLDEyIDIwLDEyIFoiIGZpbGw9IiMyMTIzMjQiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PC9wYXRoPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPHJlY3QgaWQ9IuefqeW9oiIgZmlsbD0iI0ZGRkZGRiIgeD0iMTguNSIgeT0iMTciIHdpZHRoPSIzIiBoZWlnaHQ9IjYiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDxyZWN0IGlkPSLnn6nlvaIiIGZpbGw9IiNGRkZGRkYiIHg9IjE3IiB5PSIxOC41IiB3aWR0aD0iNiIgaGVpZ2h0PSIzIj48L3JlY3Q+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjAsMjEuNSBDMjAuMjQ1NDU5OSwyMS41IDIwLjQ0OTYwODQsMjEuNjc2ODc1MiAyMC40OTE5NDQzLDIxLjkxMDEyNDQgTDIwLjUsMjIgTDIwLjUsMjcgQzIwLjUsMjcuMjc2MTQyNCAyMC4yNzYxNDI0LDI3LjUgMjAsMjcuNSBDMTkuNzU0NTQwMSwyNy41IDE5LjU1MDM5MTYsMjcuMzIzMTI0OCAxOS41MDgwNTU3LDI3LjA4OTg3NTYgTDE5LjUsMjcgTDE5LjUsMjIgQzE5LjUsMjEuNzIzODU3NiAxOS43MjM4NTc2LDIxLjUgMjAsMjEuNSBaIE0yNywxOS41IEMyNy4yNzYxNDI0LDE5LjUgMjcuNSwxOS43MjM4NTc2IDI3LjUsMjAgQzI3LjUsMjAuMjQ1NDU5OSAyNy4zMjMxMjQ4LDIwLjQ0OTYwODQgMjcuMDg5ODc1NiwyMC40OTE5NDQzIEwyNywyMC41IEwyMiwyMC41IEMyMS43MjM4NTc2LDIwLjUgMjEuNSwyMC4yNzYxNDI0IDIxLjUsMjAgQzIxLjUsMTkuNzU0NTQwMSAyMS42NzY4NzUyLDE5LjU1MDM5MTYgMjEuOTEwMTI0NCwxOS41MDgwNTU3IEwyMiwxOS41IEwyNywxOS41IFogTTE4LDE5LjUgQzE4LjI3NjE0MjQsMTkuNSAxOC41LDE5LjcyMzg1NzYgMTguNSwyMCBDMTguNSwyMC4yNDU0NTk5IDE4LjMyMzEyNDgsMjAuNDQ5NjA4NCAxOC4wODk4NzU2LDIwLjQ5MTk0NDMgTDE4LDIwLjUgTDEzLDIwLjUgQzEyLjcyMzg1NzYsMjAuNSAxMi41LDIwLjI3NjE0MjQgMTIuNSwyMCBDMTIuNSwxOS43NTQ1NDAxIDEyLjY3Njg3NTIsMTkuNTUwMzkxNiAxMi45MTAxMjQ0LDE5LjUwODA1NTcgTDEzLDE5LjUgTDE4LDE5LjUgWiBNMjAsMTIuNSBDMjAuMjQ1NDU5OSwxMi41IDIwLjQ0OTYwODQsMTIuNjc2ODc1MiAyMC40OTE5NDQzLDEyLjkxMDEyNDQgTDIwLjUsMTMgTDIwLjUsMTggQzIwLjUsMTguMjc2MTQyNCAyMC4yNzYxNDI0LDE4LjUgMjAsMTguNSBDMTkuNzU0NTQwMSwxOC41IDE5LjU1MDM5MTYsMTguMzIzMTI0OCAxOS41MDgwNTU3LDE4LjA4OTg3NTYgTDE5LjUsMTggTDE5LjUsMTMgQzE5LjUsMTIuNzIzODU3NiAxOS43MjM4NTc2LDEyLjUgMjAsMTIuNSBaIiBpZD0i5b2i54q257uT5ZCIIiBmaWxsPSIjMjEyMzI0IiBmaWxsLXJ1bGU9Im5vbnplcm8iPjwvcGF0aD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+\"","export default \"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNDdweCIgaGVpZ2h0PSI0MHB4IiB2aWV3Qm94PSIwIDAgNDcgNDAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDYwLjEgKDg4MTMzKSAtIGh0dHBzOi8vc2tldGNoLmNvbSAtLT4KICAgIDx0aXRsZT50ZXh0LWN1cnNvcjwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPgogICAgICAgIDxwYXRoIGQ9Ik0xNiwyNi41IEMxNS43MjM4NTc2LDI2LjUgMTUuNSwyNi4yNzYxNDI0IDE1LjUsMjYgQzE1LjUsMjUuNzU0NTQwMSAxNS42NzY4NzUyLDI1LjU1MDM5MTYgMTUuOTEwMTI0NCwyNS41MDgwNTU3IEwxNiwyNS41IEwxOS41LDI1LjUgTDE5LjUsMTQuNSBMMTYsMTQuNSBDMTUuNzIzODU3NiwxNC41IDE1LjUsMTQuMjc2MTQyNCAxNS41LDE0IEMxNS41LDEzLjc1NDU0MDEgMTUuNjc2ODc1MiwxMy41NTAzOTE2IDE1LjkxMDEyNDQsMTMuNTA4MDU1NyBMMTYsMTMuNSBMMjQsMTMuNSBDMjQuMjc2MTQyNCwxMy41IDI0LjUsMTMuNzIzODU3NiAyNC41LDE0IEMyNC41LDE0LjI0NTQ1OTkgMjQuMzIzMTI0OCwxNC40NDk2MDg0IDI0LjA4OTg3NTYsMTQuNDkxOTQ0MyBMMjQsMTQuNSBMMjAuNSwxNC41IEwyMC41LDI1LjUgTDI0LDI1LjUgQzI0LjI3NjE0MjQsMjUuNSAyNC41LDI1LjcyMzg1NzYgMjQuNSwyNiBDMjQuNSwyNi4yNDU0NTk5IDI0LjMyMzEyNDgsMjYuNDQ5NjA4NCAyNC4wODk4NzU2LDI2LjQ5MTk0NDMgTDI0LDI2LjUgTDE2LDI2LjUgWiIgaWQ9InBhdGgtMSI+PC9wYXRoPgogICAgICAgIDxmaWx0ZXIgeD0iLTI4NC4wJSIgeT0iLTgxLjUlIiB3aWR0aD0iNjY4LjElIiBoZWlnaHQ9IjI5My45JSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0iZmlsdGVyLTIiPgogICAgICAgICAgICA8ZmVNb3JwaG9sb2d5IHJhZGl1cz0iMSIgb3BlcmF0b3I9ImRpbGF0ZSIgaW49IlNvdXJjZUFscGhhIiByZXN1bHQ9InNoYWRvd1NwcmVhZE91dGVyMSI+PC9mZU1vcnBob2xvZ3k+CiAgICAgICAgICAgIDxmZU9mZnNldCBkeD0iMCIgZHk9IjIiIGluPSJzaGFkb3dTcHJlYWRPdXRlcjEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIj48L2ZlT2Zmc2V0PgogICAgICAgICAgICA8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIzIiBpbj0ic2hhZG93T2Zmc2V0T3V0ZXIxIiByZXN1bHQ9InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVHYXVzc2lhbkJsdXI+CiAgICAgICAgICAgIDxmZUNvbXBvc2l0ZSBpbj0ic2hhZG93Qmx1ck91dGVyMSIgaW4yPSJTb3VyY2VBbHBoYSIgb3BlcmF0b3I9Im91dCIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIj48L2ZlQ29tcG9zaXRlPgogICAgICAgICAgICA8ZmVDb2xvck1hdHJpeCB2YWx1ZXM9IjAgMCAwIDAgMCAgIDAgMCAwIDAgMCAgIDAgMCAwIDAgMCAgMCAwIDAgMC4xNiAwIiB0eXBlPSJtYXRyaXgiIGluPSJzaGFkb3dCbHVyT3V0ZXIxIj48L2ZlQ29sb3JNYXRyaXg+CiAgICAgICAgPC9maWx0ZXI+CiAgICA8L2RlZnM+CiAgICA8ZyBpZD0i6aG16Z2iLTQiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXaGl0ZWJvYXJkLUd1aWRlbGluZXMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zODguMDAwMDAwLCAtNjcyLjAwMDAwMCkiPgogICAgICAgICAgICA8ZyBpZD0idGV4dC1jdXJzb3IiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM5Mi4wMDAwMDAsIDY3Mi4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxyZWN0IGlkPSLnn6nlvaLlpIfku70tNDAiIGZpbGw9IiNGRkZGRkYiIG9wYWNpdHk9IjAuMDEiIHg9IjAiIHk9IjAiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcng9IjIiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDxnIGlkPSLlvaLnirbnu5PlkIgiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgICAgICAgICAgPHVzZSBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIxIiBmaWx0ZXI9InVybCgjZmlsdGVyLTIpIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMSIgZD0iTTE5LDI1IEwxOSwxNSBMMTYsMTUgQzE1LjQ0NzcxNTMsMTUgMTUsMTQuNTUyMjg0NyAxNSwxNCBDMTUsMTMuNTE0NTg5NyAxNS4zNDc5OTkzLDEzLjEwMTkxNSAxNS44NjU0ODc3LDEzLjAxMDA1MjEgTDE2LDEzIEwyNCwxMyBDMjQuNTUyMjg0NywxMyAyNSwxMy40NDc3MTUzIDI1LDE0IEMyNSwxNC40ODU0MTAzIDI0LjY1MjAwMDcsMTQuODk4MDg1IDI0LjEzNDUxMjMsMTQuOTg5OTQ3OSBMMjQsMTUgTDIxLDE1IEwyMSwyNSBMMjQsMjUgQzI0LjU1MjI4NDcsMjUgMjUsMjUuNDQ3NzE1MyAyNSwyNiBDMjUsMjYuNDg1NDEwMyAyNC42NTIwMDA3LDI2Ljg5ODA4NSAyNC4xMzQ1MTIzLDI2Ljk4OTk0NzkgTDI0LDI3IEwxNiwyNyBDMTUuNDQ3NzE1MywyNyAxNSwyNi41NTIyODQ3IDE1LDI2IEMxNSwyNS41MTQ1ODk3IDE1LjM0Nzk5OTMsMjUuMTAxOTE1IDE1Ljg2NTQ4NzcsMjUuMDEwMDUyMSBMMTYsMjUgTDE5LDI1IFoiIGZpbGw9IiMyMTIzMjQiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PC9wYXRoPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=\"","import App from './Cursor.svelte';\nimport { ApplianceMap } from './icons';\nimport { ApplianceNames } from 'white-web-sdk';\nimport { CursorState } from '../constants';\nimport { Fields } from '../AttributesDelegate';\nimport { get, omit } from 'lodash';\nimport type { Position } from '../AttributesDelegate';\nimport type { RoomMember } from \"white-web-sdk\";\nimport type { CursorManager } from \"./index\";\nimport type { SvelteComponent } from \"svelte\";\nimport { Base } from '../Base';\nimport type { AppManager } from '../AppManager';\n\nexport type Payload = {\n [key: string]: any\n}\n\n\nexport class Cursor extends Base {\n private member?: RoomMember;\n private timer?: number;\n private component?: SvelteComponent;\n\n constructor(\n manager: AppManager,\n addCursorChangeListener: (uid: string, callback: (position: Position, state: CursorState) => void) => void,\n private cursors: any,\n private memberId: string,\n private cursorManager: CursorManager,\n private wrapper?: HTMLElement,\n ) {\n super(manager);\n this.setMember();\n this.createCursor();\n addCursorChangeListener(this.memberId, this.onCursorChange);\n this.autoHidden();\n }\n\n private onCursorChange = (position: Position, state: CursorState) => {\n if (position.type === \"main\") {\n const rect = this.cursorManager.wrapperRect;\n if (this.component && rect) {\n this.autoHidden();\n this.moveCursor(position, rect, this.manager.mainView);\n }\n } else {\n const focusView = this.cursorManager.focusView;\n // TODO 可以存一个当前 focusView 的 Rect 这样只有 focus 切换的时候才调用 getBoundingClientRect\n const viewRect = focusView?.divElement?.getBoundingClientRect();\n const viewCamera = focusView?.camera;\n if (focusView && viewRect && viewCamera && this.component) {\n this.autoHidden();\n this.moveCursor(position, viewRect, focusView);\n }\n }\n if (state && state === CursorState.Leave) {\n this.hide();\n }\n }\n\n private moveCursor(cursor: Position, rect: DOMRect, view: any) {\n const { x, y, type } = cursor;\n const point = view?.screen.convertPointToScreen(x, y);\n if (point) {\n let translateX = point.x - 2;\n let translateY = point.y - 18;\n if (type === \"app\") {\n const wrapperRect = this.cursorManager.wrapperRect;\n if (wrapperRect) {\n translateX = translateX + rect.x - wrapperRect.x;\n translateY = translateY + rect.y - wrapperRect.y;\n }\n }\n if (point.x < 0 || point.x > rect.width || point.y < 0 || point.y > rect.height) {\n this.component?.$set({ visible: false, x: translateX, y: translateY });\n } else {\n this.component?.$set({ visible: true, x: translateX, y: translateY });\n }\n }\n }\n\n public get memberApplianceName() {\n return this.member?.memberState?.currentApplianceName;\n }\n\n public get memberColor() {\n const rgb = this.member?.memberState?.strokeColor.join(\",\");\n return `rgb(${rgb})`;\n }\n\n private get payload(): Payload | undefined {\n return this.member?.payload;\n }\n\n public get memberCursorName() {\n return this.payload?.nickName || this.payload?.cursorName || this.memberId;\n }\n\n private get memberTheme() {\n if (this.payload?.theme) {\n return \"netless-window-manager-cursor-inner-mellow\";\n } else {\n return \"netless-window-manager-cursor-inner\";\n }\n }\n\n private get memberCursorTextColor() {\n return this.payload?.cursorTextColor || \"#FFFFFF\";\n }\n\n private get memberCursorTagBackgroundColor() {\n return this.payload?.cursorTagBackgroundColor || this.memberColor;\n }\n\n private get memberAvatar() {\n return this.payload?.avatar;\n }\n\n private get memberOpacity() {\n if (!this.memberCursorName && !this.memberAvatar) {\n return 0;\n } else {\n return 1;\n }\n }\n\n public get cursorState(): CursorState | undefined {\n return get(this.cursors, [this.memberId, Fields.CursorState]);\n }\n\n public get cursorPosition(): Position | undefined {\n return get(this.cursors, [this.memberId, Fields.Position]);\n }\n\n private autoHidden() {\n if (this.timer) {\n clearTimeout(this.timer);\n }\n this.timer = window.setTimeout(() => {\n this.hide();\n this.store.updateCursorState(this.memberId, CursorState.Leave);\n }, 1000 * 10); // 10 秒钟自动隐藏\n }\n\n private async createCursor() {\n if (this.member && this.wrapper) {\n this.component = new App({\n target: this.wrapper,\n props: this.initProps(),\n });\n }\n }\n\n private initProps() {\n return {\n x: 0,\n y: 0,\n appliance: this.memberApplianceName,\n avatar: this.memberAvatar,\n src: this.getIcon(),\n visible: false,\n backgroundColor: this.memberColor,\n cursorName: this.memberCursorName,\n theme: this.memberTheme,\n color: this.memberCursorTextColor,\n cursorTagBackgroundColor: this.memberCursorTagBackgroundColor,\n opacity: this.memberOpacity,\n };\n }\n\n private getIcon() {\n if (this.member) {\n const applianceSrc = ApplianceMap[this.memberApplianceName || ApplianceNames.shape];\n return applianceSrc || ApplianceMap[ApplianceNames.shape];\n }\n }\n\n public setMember() {\n this.member = this.context.findMemberByUid(this.memberId);\n this.updateComponent();\n }\n\n private updateComponent() {\n this.component?.$set(omit(this.initProps(), [\"x\", \"y\"]));\n }\n\n public destroy() {\n if (this.component) {\n this.component.$destroy();\n }\n this.manager.refresher?.remove(this.memberId);\n this.cursorManager.cursorInstances.delete(this.memberId);\n }\n\n public hide() {\n if (this.component) {\n this.component.$set({ visible: false });\n }\n }\n}\n","import { autorun } from \"white-web-sdk\";\nimport { Base } from \"../Base\";\nimport { compact, debounce, get, uniq } from \"lodash\";\nimport { Cursor } from \"./Cursor\";\nimport { CursorState } from \"../constants\";\nimport { emitter, WindowManager } from \"../index\";\nimport { Fields } from \"../AttributesDelegate\";\nimport { onObjectInserted } from \"../Utils/Reactive\";\nimport { SideEffectManager } from \"side-effect-manager\";\nimport type { PositionType, Position } from \"../AttributesDelegate\";\nimport type { Point, RoomMember, View } from \"white-web-sdk\";\nimport type { AppManager } from \"../AppManager\";\n\nexport type EventType = {\n type: PositionType;\n id?: string;\n};\n\nexport type MoveCursorParams = {\n uid: string;\n x: number;\n y: number;\n};\nexport class CursorManager extends Base {\n public containerRect?: DOMRect;\n public wrapperRect?: DOMRect;\n public cursorInstances: Map<string, Cursor> = new Map();\n public roomMembers?: readonly RoomMember[];\n private mainViewElement?: HTMLDivElement;\n private sideEffectManager = new SideEffectManager();\n\n constructor(private appManager: AppManager) {\n super(appManager);\n this.roomMembers = this.appManager.room?.state.roomMembers;\n const wrapper = WindowManager.wrapper;\n if (wrapper) {\n this.setupWrapper(wrapper);\n }\n emitter.on(\"onReconnected\", () => {\n this.onReconnect();\n });\n }\n\n public setupWrapper(wrapper: HTMLElement) {\n if (this.manager.refresher?.hasReactor(\"cursors\")) {\n this.destroy();\n }\n this.sideEffectManager.add(() => {\n wrapper.addEventListener(\"pointerenter\", this.mouseMoveListener);\n wrapper.addEventListener(\"pointermove\", this.mouseMoveListener);\n wrapper.addEventListener(\"pointerleave\", this.mouseLeaveListener);\n return () => {\n wrapper.removeEventListener(\"pointerenter\", this.mouseMoveListener);\n wrapper.removeEventListener(\"pointermove\", this.mouseMoveListener);\n wrapper.removeEventListener(\"pointerleave\", this.mouseLeaveListener);\n };\n });\n\n this.initCursorAttributes();\n this.wrapperRect = wrapper.getBoundingClientRect();\n this.startReaction(wrapper);\n }\n\n public setMainViewDivElement(div: HTMLDivElement) {\n this.mainViewElement = div;\n }\n\n private startReaction(wrapper: HTMLElement) {\n this.manager.refresher?.add(\"cursors\", () => {\n return onObjectInserted(this.cursors, () => {\n this.handleRoomMembersChange(wrapper);\n });\n });\n }\n\n private getUids = (members: readonly RoomMember[] | undefined) => {\n return compact(uniq(members?.map(member => member.payload?.uid)));\n };\n\n private handleRoomMembersChange = debounce((wrapper: HTMLElement) => {\n const uids = this.getUids(this.roomMembers);\n const cursors = Object.keys(this.cursors);\n if (uids?.length) {\n cursors.map(uid => {\n if (uids.includes(uid) && !this.cursorInstances.has(uid)) {\n if (uid === this.context.uid) {\n return;\n }\n const component = new Cursor(\n this.appManager,\n this.addCursorChangeListener,\n this.cursors,\n uid,\n this,\n wrapper\n );\n this.cursorInstances.set(uid, component);\n }\n });\n }\n }, 100);\n\n public get cursors() {\n return this.manager.attributes?.[Fields.Cursors];\n }\n\n public get boxState() {\n return this.store.getBoxState();\n }\n\n public get focusView() {\n return this.appManager.focusApp?.view;\n }\n\n private mouseMoveListener = debounce((event: MouseEvent) => {\n this.updateCursor(this.getType(event), event.clientX, event.clientY);\n }, 5);\n\n private updateCursor(event: EventType, clientX: number, clientY: number) {\n if (this.wrapperRect && this.manager.canOperate) {\n const view = event.type === \"main\" ? this.appManager.mainView : this.focusView;\n const point = this.getPoint(view, clientX, clientY);\n if (point) {\n this.setNormalCursorState();\n this.store.updateCursor(this.context.uid, {\n x: point.x,\n y: point.y,\n ...event,\n });\n }\n }\n }\n\n private getPoint = (\n view: View | undefined,\n clientX: number,\n clientY: number\n ): Point | undefined => {\n const rect = view?.divElement?.getBoundingClientRect();\n if (rect) {\n const point = view?.convertToPointInWorld({\n x: clientX - rect.x,\n y: clientY - rect.y,\n });\n return point;\n }\n };\n\n /**\n * 因为窗口内框在不同分辨率下的大小不一样,所以这里通过来鼠标事件的 target 来判断是在主白板还是在 APP 中\n */\n private getType = (event: MouseEvent | Touch): EventType => {\n const target = event.target as HTMLElement;\n const focusApp = this.appManager.focusApp;\n switch (target.parentElement) {\n case this.mainViewElement: {\n return { type: \"main\" };\n }\n case focusApp?.view?.divElement: {\n return { type: \"app\" };\n }\n default: {\n return { type: \"main\" };\n }\n }\n };\n\n private initCursorAttributes() {\n this.store.updateCursor(this.context.uid, {\n x: 0,\n y: 0,\n type: \"main\",\n });\n this.store.updateCursorState(this.context.uid, CursorState.Leave);\n }\n\n private setNormalCursorState() {\n const cursorState = this.store.getCursorState(this.context.uid);\n if (cursorState !== CursorState.Normal) {\n this.store.updateCursorState(this.context.uid, CursorState.Normal);\n }\n }\n\n private mouseLeaveListener = () => {\n this.hideCursor(this.context.uid);\n this.store.updateCursorState(this.context.uid, CursorState.Leave);\n };\n\n public updateContainerRect() {\n this.containerRect = WindowManager.container?.getBoundingClientRect();\n this.wrapperRect = WindowManager.wrapper?.getBoundingClientRect();\n }\n\n public setRoomMembers(members: readonly RoomMember[]) {\n this.roomMembers = members;\n this.cursorInstances.forEach(cursor => {\n cursor.setMember();\n });\n if (WindowManager.wrapper) {\n this.handleRoomMembersChange(WindowManager.wrapper);\n }\n }\n\n public deleteCursor(uid: string) {\n this.store.cleanCursor(uid);\n const cursor = this.cursorInstances.get(uid);\n if (cursor) {\n cursor.destroy();\n }\n }\n\n public hideCursor(uid: string) {\n const cursor = this.cursorInstances.get(uid);\n if (cursor) {\n cursor.hide();\n }\n }\n\n public cleanMemberAttributes(members: readonly RoomMember[]) {\n const uids = this.getUids(members);\n const needDeleteIds: string[] = [];\n const cursors = Object.keys(this.cursors);\n cursors.map(cursorId => {\n const index = uids.findIndex(id => id === cursorId);\n if (index === -1) {\n needDeleteIds.push(cursorId);\n }\n });\n needDeleteIds.forEach(uid => {\n this.deleteCursor(uid);\n });\n }\n\n public onReconnect() {\n if (this.cursorInstances.size) {\n this.cursorInstances.forEach(cursor => cursor.destroy());\n this.cursorInstances.clear();\n }\n this.roomMembers = this.appManager.room?.state.roomMembers;\n if (WindowManager.wrapper) {\n this.handleRoomMembersChange(WindowManager.wrapper);\n }\n }\n\n public addCursorChangeListener = (\n uid: string,\n callback: (position: Position, state: CursorState) => void\n ) => {\n this.manager.refresher?.add(uid, () => {\n const disposer = autorun(() => {\n const position = get(this.cursors, [uid, Fields.Position]);\n const state = get(this.cursors, [uid, Fields.CursorState]);\n if (position) {\n callback(position, state);\n }\n });\n return disposer;\n });\n };\n\n public destroy() {\n this.sideEffectManager.flushAll();\n if (this.cursorInstances.size) {\n this.cursorInstances.forEach(cursor => {\n cursor.destroy();\n });\n this.cursorInstances.clear();\n }\n this.manager.refresher?.remove(\"cursors\");\n }\n}\n","import AppDocsViewer from \"@netless/app-docs-viewer\";\nimport AppMediaPlayer, { setOptions } from \"@netless/app-media-player\";\nimport { WindowManager } from \"./index\";\nimport \"@netless/app-docs-viewer/dist/style.css\";\n\nexport const setupBuiltin = () => {\n if (WindowManager.debug) {\n setOptions({ verbose: true });\n }\n\n WindowManager.register({\n kind: AppDocsViewer.kind,\n src: AppDocsViewer,\n });\n WindowManager.register({\n kind: AppMediaPlayer.kind,\n src: AppMediaPlayer,\n });\n};\n\nexport const BuiltinApps = {\n DocsViewer: AppDocsViewer.kind as string,\n MediaPlayer: AppMediaPlayer.kind as string,\n};\n","import Emittery from \"emittery\";\nimport pRetry from \"p-retry\";\nimport { AppManager } from \"./AppManager\";\nimport { appRegister } from \"./Register\";\nimport { ContainerResizeObserver } from \"./ContainerResizeObserver\";\nimport { createBoxManager } from \"./BoxManager\";\nimport { CursorManager } from \"./Cursor\";\nimport { DEFAULT_CONTAINER_RATIO, Events, REQUIRE_VERSION } from \"./constants\";\nimport { Fields } from \"./AttributesDelegate\";\nimport { initDb } from \"./Register/storage\";\nimport { isNull, isObject } from \"lodash\";\nimport { log } from \"./Utils/log\";\nimport { ReconnectRefresher } from \"./ReconnectRefresher\";\nimport { replaceRoomFunction } from \"./Utils/RoomHacker\";\nimport { setupBuiltin } from \"./BuiltinApps\";\nimport { setupWrapper } from \"./Helper\";\nimport \"./style.css\";\nimport \"@netless/telebox-insider/dist/style.css\";\nimport {\n addEmitterOnceListener,\n ensureValidScenePath,\n getVersionNumber,\n isValidScenePath,\n wait,\n} from \"./Utils/Common\";\nimport type { TELE_BOX_STATE, BoxManager } from \"./BoxManager\";\nimport {\n AppCreateError,\n AppManagerNotInitError,\n InvalidScenePath,\n ParamsInvalidError,\n WhiteWebSDKInvalidError,\n} from \"./Utils/error\";\nimport type { Apps } from \"./AttributesDelegate\";\nimport {\n InvisiblePlugin,\n isPlayer,\n isRoom,\n RoomPhase,\n ViewMode,\n WhiteVersion,\n} from \"white-web-sdk\";\nimport type {\n Displayer,\n SceneDefinition,\n View,\n Room,\n InvisiblePluginContext,\n Camera,\n AnimationMode,\n CameraBound,\n Point,\n Rectangle,\n ViewVisionMode,\n CameraState,\n} from \"white-web-sdk\";\nimport type { AppListeners } from \"./AppListener\";\nimport type { NetlessApp, RegisterParams } from \"./typings\";\nimport type { TeleBoxColorScheme, TeleBoxState } from \"@netless/telebox-insider\";\nimport type { AppProxy } from \"./AppProxy\";\n\nexport type WindowMangerAttributes = {\n modelValue?: string;\n boxState: TELE_BOX_STATE;\n maximized?: boolean;\n minimized?: boolean;\n [key: string]: any;\n};\n\nexport type apps = {\n [key: string]: NetlessApp;\n};\n\nexport type AddAppOptions = {\n scenePath?: string;\n title?: string;\n scenes?: SceneDefinition[];\n};\n\nexport type setAppOptions = AddAppOptions & { appOptions?: any };\n\nexport type AddAppParams<TAttributes = any> = {\n kind: string;\n // app 地址(本地 app 不需要传)\n src?: string;\n // 窗口配置\n options?: AddAppOptions;\n // 初始化 attributes\n attributes?: TAttributes;\n};\n\nexport type BaseInsertParams = {\n kind: string;\n // app 地址(本地 app 不需要传)\n src?: string;\n // 窗口配置\n options?: AddAppOptions;\n // 初始化 attributes\n attributes?: any;\n isDynamicPPT?: boolean;\n};\n\nexport type AppSyncAttributes = {\n kind: string;\n src?: string;\n options: any;\n state?: any;\n isDynamicPPT?: boolean;\n fullPath?: string;\n createdAt?: number;\n};\n\nexport type AppInitState = {\n id: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n focus?: boolean;\n maximized?: boolean;\n minimized?: boolean;\n sceneIndex?: number;\n boxState?: TeleBoxState; // 兼容旧版 telebox\n zIndex?: number;\n};\n\nexport type EmitterEvent = {\n onCreated: undefined;\n InitReplay: AppInitState;\n move: { appId: string; x: number; y: number };\n focus: { appId: string };\n close: { appId: string };\n resize: { appId: string; width: number; height: number; x?: number; y?: number };\n error: Error;\n seek: number;\n mainViewMounted: undefined;\n observerIdChange: number;\n boxStateChange: string;\n playgroundSizeChange: DOMRect;\n onReconnected: void;\n};\n\nexport type EmitterType = Emittery<EmitterEvent>;\nexport const emitter: EmitterType = new Emittery();\n\nexport type PublicEvent = {\n mainViewModeChange: ViewVisionMode;\n boxStateChange: `${TELE_BOX_STATE}`;\n darkModeChange: boolean;\n prefersColorSchemeChange: TeleBoxColorScheme;\n cameraStateChange: CameraState;\n mainViewScenePathChange: string;\n mainViewSceneIndexChange: number;\n focusedChange: string | undefined;\n};\n\nexport type MountParams = {\n room: Room;\n container?: HTMLElement;\n /** 白板高宽比例, 默认为 9 / 16 */\n containerSizeRatio?: number;\n /** 显示 PS 透明背景,默认 true */\n chessboard?: boolean;\n collectorContainer?: HTMLElement;\n collectorStyles?: Partial<CSSStyleDeclaration>;\n overwriteStyles?: string;\n cursor?: boolean;\n debug?: boolean;\n disableCameraTransform?: boolean;\n prefersColorScheme?: TeleBoxColorScheme;\n};\n\nexport type CallbacksType = Emittery<PublicEvent>;\nexport const callbacks: CallbacksType = new Emittery();\n\nexport const reconnectRefresher = new ReconnectRefresher({ emitter });\n\nexport class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {\n public static kind = \"WindowManager\";\n public static displayer: Displayer;\n public static wrapper?: HTMLElement;\n public static playground?: HTMLElement;\n public static container?: HTMLElement;\n public static debug = false;\n public static containerSizeRatio = DEFAULT_CONTAINER_RATIO;\n private static isCreated = false;\n\n public version = __APP_VERSION__;\n\n public appListeners?: AppListeners;\n\n public readonly?: boolean;\n public emitter: Emittery<PublicEvent> = callbacks;\n public appManager?: AppManager;\n public cursorManager?: CursorManager;\n public viewMode = ViewMode.Broadcaster;\n public isReplay = isPlayer(this.displayer);\n\n private boxManager?: BoxManager;\n private static params?: MountParams;\n\n private containerResizeObserver?: ContainerResizeObserver;\n\n constructor(context: InvisiblePluginContext) {\n super(context);\n WindowManager.displayer = context.displayer;\n }\n\n public static async mount(params: MountParams): Promise<WindowManager> {\n const room = params.room;\n WindowManager.container = params.container;\n const containerSizeRatio = params.containerSizeRatio;\n const debug = params.debug;\n\n const cursor = params.cursor;\n WindowManager.params = params;\n\n this.checkVersion();\n if (isRoom(room)) {\n if (room.phase !== RoomPhase.Connected) {\n throw new Error(\"[WindowManager]: Room only Connected can be mount\");\n }\n if (room.phase === RoomPhase.Connected) {\n // redo undo 需要设置这个属性\n room.disableSerialization = false;\n }\n }\n if (WindowManager.isCreated) {\n throw new Error(\"[WindowManager]: Already created cannot be created again\");\n }\n let manager = await this.initManager(room);\n this.debug = Boolean(debug);\n log(\"Already insert room\", manager);\n\n if (isRoom(this.displayer)) {\n if (!manager) {\n throw new Error(\"[WindowManager]: init InvisiblePlugin failed\");\n }\n } else {\n await pRetry(\n async count => {\n manager = await this.initManager(room);\n if (!manager) {\n log(`manager is empty. retrying ${count}`);\n throw new Error();\n }\n },\n { retries: 10 }\n );\n }\n\n if (containerSizeRatio) {\n WindowManager.containerSizeRatio = containerSizeRatio;\n }\n await manager.ensureAttributes();\n\n manager.appManager = new AppManager(manager);\n\n if (cursor) {\n manager.cursorManager = new CursorManager(manager.appManager);\n }\n\n if (params.container) {\n manager.bindContainer(params.container);\n }\n\n replaceRoomFunction(room, manager);\n emitter.emit(\"onCreated\");\n WindowManager.isCreated = true;\n try {\n await initDb();\n } catch (error) {\n console.warn(\"[WindowManager]: indexedDB open failed\");\n console.log(error);\n }\n return manager;\n }\n\n private static async initManager(room: Room): Promise<WindowManager> {\n let manager = room.getInvisiblePlugin(WindowManager.kind) as WindowManager;\n if (!manager) {\n if (isRoom(room)) {\n if (room.isWritable === false) {\n try {\n await room.setWritable(true);\n } catch (error) {\n throw new Error(\"[WindowManger]: room must be switched to be writable\");\n }\n manager = (await room.createInvisiblePlugin(\n WindowManager,\n {}\n )) as WindowManager;\n manager.ensureAttributes();\n await wait(500);\n await room.setWritable(false);\n } else {\n manager = (await room.createInvisiblePlugin(\n WindowManager,\n {}\n )) as WindowManager;\n }\n }\n }\n return manager;\n }\n\n private static initContainer(\n manager: WindowManager,\n container: HTMLElement,\n chessboard: boolean | undefined,\n overwriteStyles: string | undefined\n ) {\n if (!WindowManager.container) {\n WindowManager.container = container;\n }\n const { playground, wrapper, sizer, mainViewElement } = setupWrapper(container);\n WindowManager.playground = playground;\n if (chessboard) {\n sizer.classList.add(\"netless-window-manager-chess-sizer\");\n }\n if (overwriteStyles) {\n const style = document.createElement(\"style\");\n style.textContent = overwriteStyles;\n playground.appendChild(style);\n }\n manager.containerResizeObserver = ContainerResizeObserver.create(\n playground,\n sizer,\n wrapper,\n emitter\n );\n WindowManager.wrapper = wrapper;\n return mainViewElement;\n }\n\n public bindContainer(container: HTMLElement) {\n if (WindowManager.isCreated && WindowManager.container) {\n if (WindowManager.container.firstChild) {\n container.appendChild(WindowManager.container.firstChild);\n }\n } else {\n if (WindowManager.params) {\n const params = WindowManager.params;\n const mainViewElement = WindowManager.initContainer(\n this,\n container,\n params.chessboard,\n params.overwriteStyles\n );\n const boxManager = createBoxManager(this, callbacks, emitter, {\n collectorContainer: params.collectorContainer,\n collectorStyles: params.collectorStyles,\n prefersColorScheme: params.prefersColorScheme,\n });\n this.boxManager = boxManager;\n this.appManager?.setBoxManager(boxManager);\n this.bindMainView(mainViewElement, params.disableCameraTransform);\n if (WindowManager.wrapper) {\n this.cursorManager?.setupWrapper(WindowManager.wrapper);\n }\n }\n }\n this.boxManager?.updateManagerRect();\n this.appManager?.refresh();\n this.appManager?.resetMaximized();\n this.appManager?.resetMinimized();\n WindowManager.container = container;\n }\n\n public bindCollectorContainer(container: HTMLElement) {\n if (WindowManager.isCreated && this.boxManager) {\n this.boxManager.setCollectorContainer(container);\n } else {\n if (WindowManager.params) {\n WindowManager.params.collectorContainer = container;\n }\n }\n }\n\n /**\n * 注册插件\n */\n public static register<AppOptions = any, SetupResult = any, Attributes = any>(\n params: RegisterParams<AppOptions, SetupResult, Attributes>\n ): Promise<void> {\n return appRegister.register(params);\n }\n\n /**\n * 创建一个 app 至白板\n */\n public async addApp<T = any>(params: AddAppParams<T>): Promise<string | undefined> {\n if (this.appManager) {\n if (!params.kind || typeof params.kind !== \"string\") {\n throw new ParamsInvalidError();\n }\n const appImpl = await appRegister.appClasses.get(params.kind)?.();\n if (appImpl && appImpl.config?.singleton) {\n if (this.appManager.appProxies.has(params.kind)) {\n throw new AppCreateError();\n }\n }\n const isDynamicPPT = this.setupScenePath(params, this.appManager);\n if (isDynamicPPT === undefined) {\n return;\n }\n if (params?.options?.scenePath) {\n params.options.scenePath = ensureValidScenePath(params.options.scenePath);\n }\n const appId = await this.appManager.addApp(params, Boolean(isDynamicPPT));\n return appId;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n private setupScenePath(params: AddAppParams, appManager: AppManager): boolean | undefined {\n let isDynamicPPT = false;\n if (params.options) {\n const { scenePath, scenes } = params.options;\n if (scenePath) {\n if (!isValidScenePath(scenePath)) {\n throw new InvalidScenePath();\n }\n const apps = Object.keys(this.apps || {});\n for (const appId of apps) {\n const appScenePath = appManager.store.getAppScenePath(appId);\n if (appScenePath && appScenePath === scenePath) {\n console.warn(`[WindowManager]: ScenePath ${scenePath} Already opened`);\n return;\n }\n }\n }\n if (scenePath && scenes && scenes.length > 0) {\n if (this.isDynamicPPT(scenes)) {\n isDynamicPPT = true;\n if (!this.displayer.entireScenes()[scenePath]) {\n this.room?.putScenes(scenePath, scenes);\n }\n } else {\n if (!this.displayer.entireScenes()[scenePath]) {\n this.room?.putScenes(scenePath, [{ name: scenes[0].name }]);\n }\n }\n }\n if (scenePath && scenes === undefined) {\n this.room?.putScenes(scenePath, [{}]);\n }\n }\n return isDynamicPPT;\n }\n\n /**\n * 设置 mainView 的 ScenePath, 并且切换白板为可写状态\n */\n public async setMainViewScenePath(scenePath: string): Promise<void> {\n if (this.appManager) {\n await this.appManager.setMainViewScenePath(scenePath);\n }\n }\n\n /**\n * 设置 mainView 的 SceneIndex, 并且切换白板为可写状态\n */\n public async setMainViewSceneIndex(index: number): Promise<void> {\n if (this.appManager) {\n await this.appManager.setMainViewSceneIndex(index);\n }\n }\n\n /**\n * 返回 mainView 的 ScenePath\n */\n public getMainViewScenePath(): string {\n return this.appManager?.store.getMainViewScenePath();\n }\n\n /**\n * 返回 mainView 的 SceneIndex\n */\n public getMainViewSceneIndex(): number {\n return this.appManager?.store.getMainViewSceneIndex();\n }\n\n /**\n * 设置所有 app 的 readonly 模式\n */\n public setReadonly(readonly: boolean): void {\n this.readonly = readonly;\n this.boxManager?.setReadonly(readonly);\n }\n\n /**\n * 切换 mainView 为可写\n */\n public switchMainViewToWriter(): Promise<void> | undefined {\n return this.appManager?.mainViewProxy.mainViewClickHandler();\n }\n\n /**\n * app destroy 回调\n */\n public onAppDestroy(kind: string, listener: (error: Error) => void): void {\n addEmitterOnceListener(`destroy-${kind}`, listener);\n }\n\n /**\n * 设置 ViewMode\n */\n public setViewMode(mode: ViewMode): void {\n if (!this.canOperate) return;\n if (mode === ViewMode.Broadcaster) {\n this.appManager?.mainViewProxy.setCameraAndSize();\n this.appManager?.mainViewProxy.start();\n }\n if (mode === ViewMode.Freedom) {\n this.appManager?.mainViewProxy.stop();\n }\n this.viewMode = mode;\n }\n\n public get mainView(): View {\n if (this.appManager) {\n return this.appManager.mainViewProxy.view;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n public get camera(): Camera {\n if (this.appManager) {\n return this.appManager.mainViewProxy.view.camera;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n public get cameraState(): CameraState {\n if (this.appManager) {\n return this.appManager.mainViewProxy.cameraState;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n public get apps(): Apps | undefined {\n return this.appManager?.store.apps();\n }\n\n public get boxState(): TeleBoxState | undefined {\n if (this.appManager) {\n return this.appManager.boxManager?.boxState;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n public get darkMode(): boolean {\n return Boolean(this.appManager?.boxManager?.darkMode);\n }\n\n public get prefersColorScheme(): TeleBoxColorScheme | undefined {\n if (this.appManager) {\n return this.appManager.boxManager?.prefersColorScheme;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n public get focused(): string | undefined {\n return this.attributes.focus;\n }\n\n /**\n * 查询所有的 App\n */\n public queryAll(): AppProxy[] {\n return Array.from(this.appManager?.appProxies.values() || []);\n }\n\n /**\n * 查询单个 App\n */\n public queryOne(appId: string): AppProxy | undefined {\n return this.appManager?.appProxies.get(appId);\n }\n\n /**\n * 关闭 APP\n */\n public async closeApp(appId: string): Promise<void> {\n return this.appManager?.closeApp(appId);\n }\n\n public moveCamera(\n camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }\n ): void {\n this.mainView.moveCamera(camera);\n }\n\n public moveCameraToContain(\n rectangle: Rectangle &\n Readonly<{\n animationMode?: AnimationMode;\n }>\n ): void {\n this.mainView.moveCameraToContain(rectangle);\n this.appManager?.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);\n setTimeout(() => {\n this.appManager?.mainViewProxy.setCameraAndSize();\n }, 1000);\n }\n\n public convertToPointInWorld(point: Point): Point {\n return this.mainView.convertToPointInWorld(point);\n }\n\n public setCameraBound(cameraBound: CameraBound): void {\n this.mainView.setCameraBound(cameraBound);\n }\n\n public override onDestroy(): void {\n this._destroy();\n }\n\n public override destroy(): void {\n this._destroy();\n }\n\n private _destroy() {\n this.containerResizeObserver?.disconnect();\n this.appManager?.destroy();\n this.cursorManager?.destroy();\n WindowManager.container = undefined;\n WindowManager.wrapper = undefined;\n WindowManager.isCreated = false;\n if (WindowManager.playground) {\n WindowManager.playground.parentNode?.removeChild(WindowManager.playground);\n }\n WindowManager.params = undefined;\n log(\"Destroyed\");\n }\n\n private bindMainView(divElement: HTMLDivElement, disableCameraTransform: boolean | undefined) {\n if (this.appManager) {\n this.appManager.bindMainView(divElement, Boolean(disableCameraTransform));\n this.cursorManager?.setMainViewDivElement(divElement);\n }\n }\n\n public get canOperate(): boolean {\n if (isRoom(this.displayer)) {\n return (\n (this.displayer as Room).isWritable &&\n (this.displayer as Room).phase === RoomPhase.Connected\n );\n } else {\n return false;\n }\n }\n\n public get room(): Room {\n return this.displayer as Room;\n }\n\n public safeSetAttributes(attributes: any): void {\n if (this.canOperate) {\n this.setAttributes(attributes);\n }\n }\n\n public safeUpdateAttributes(keys: string[], value: any): void {\n if (this.canOperate) {\n this.updateAttributes(keys, value);\n }\n }\n\n public setPrefersColorScheme(scheme: TeleBoxColorScheme): void {\n this.appManager?.boxManager?.setPrefersColorScheme(scheme);\n }\n\n private isDynamicPPT(scenes: SceneDefinition[]) {\n const sceneSrc = scenes[0]?.ppt?.src;\n return sceneSrc?.startsWith(\"pptx://\");\n }\n\n private static checkVersion() {\n const version = getVersionNumber(WhiteVersion);\n if (version < getVersionNumber(REQUIRE_VERSION)) {\n throw new WhiteWebSDKInvalidError(REQUIRE_VERSION);\n }\n }\n\n private async ensureAttributes() {\n if (isNull(this.attributes)) {\n await wait(50);\n }\n if (isObject(this.attributes)) {\n if (!this.attributes[Fields.Apps]) {\n this.safeSetAttributes({ [Fields.Apps]: {} });\n }\n if (!this.attributes[Fields.Cursors]) {\n this.safeSetAttributes({ [Fields.Cursors]: {} });\n }\n const sceneState = this.displayer.state.sceneState;\n if (!this.attributes[\"_mainScenePath\"]) {\n this.safeSetAttributes({ _mainScenePath: sceneState.scenePath });\n }\n if (!this.attributes[\"_mainSceneIndex\"]) {\n this.safeSetAttributes({ _mainSceneIndex: sceneState.index });\n }\n }\n }\n}\n\nsetupBuiltin();\n\nexport * from \"./typings\";\n\nexport { BuiltinApps } from \"./BuiltinApps\";\n","import { debounce, isFunction } from \"lodash\";\nimport { log } from \"./Utils/log\";\nimport { RoomPhase } from \"white-web-sdk\";\nimport type { Room } from \"white-web-sdk\";\nimport type { EmitterType } from \"./index\";\n\nexport type ReconnectRefresherContext = {\n emitter: EmitterType;\n};\n\n// 白板重连之后会刷新所有的对象,导致 listener 失效, 所以这里在重连之后重新对所有对象进行监听\nexport class ReconnectRefresher {\n private phase?: RoomPhase;\n private room: Room | undefined;\n private reactors: Map<string, any> = new Map();\n private disposers: Map<string, any> = new Map();\n\n constructor(private ctx: ReconnectRefresherContext) {}\n\n public setRoom(room: Room | undefined) {\n this.room = room;\n this.phase = room?.phase;\n room?.callbacks.off(\"onPhaseChanged\", this.onPhaseChanged);\n room?.callbacks.on(\"onPhaseChanged\", this.onPhaseChanged);\n }\n\n public setContext(ctx: ReconnectRefresherContext) {\n this.ctx = ctx;\n }\n\n private onPhaseChanged = (phase: RoomPhase) => {\n if (phase === RoomPhase.Connected && this.phase === RoomPhase.Reconnecting) {\n this.onReconnected();\n }\n this.phase = phase;\n };\n\n private onReconnected = debounce(() => {\n log(\"onReconnected refresh reactors\");\n this.releaseDisposers();\n this.reactors.forEach((func, id) => {\n if (isFunction(func)) {\n this.disposers.set(id, func());\n }\n });\n this.ctx.emitter.emit(\"onReconnected\", undefined);\n }, 3000);\n\n private releaseDisposers() {\n this.disposers.forEach(disposer => {\n if (isFunction(disposer)) {\n disposer();\n }\n });\n this.disposers.clear();\n }\n\n public add(id: string, func: any) {\n if (isFunction(func)) {\n this.reactors.set(id, func);\n this.disposers.set(id, func());\n }\n }\n\n public remove(id: string) {\n if (this.reactors.has(id)) {\n this.reactors.delete(id);\n }\n const disposer = this.disposers.get(id);\n if (disposer) {\n if (isFunction(disposer)) {\n disposer();\n }\n this.disposers.delete(id);\n }\n }\n\n public hasReactor(id: string) {\n return this.reactors.has(id);\n }\n\n public destroy() {\n this.room?.callbacks.off(\"onPhaseChanged\", this.onPhaseChanged);\n this.releaseDisposers();\n }\n}\n","import { emitter } from \"../index\";\nimport { isPlayer } from \"white-web-sdk\";\nimport type { WindowManager } from '../index';\nimport type { Camera, Room , Player , PlayerSeekingResult } from \"white-web-sdk\";\n\n// 修改多窗口状态下一些失效的方法实现到 manager 的 mainview 上, 降低迁移成本\nexport const replaceRoomFunction = (room: Room, manager: WindowManager) => {\n if (isPlayer(room)) {\n const player = room as unknown as Player;\n const originSeek = player.seekToProgressTime;\n // eslint-disable-next-line no-inner-declarations\n async function newSeek(time: number): Promise<PlayerSeekingResult> {\n const seekResult = await originSeek.call(player, time);\n if (seekResult === \"success\") {\n emitter.emit(\"seek\", time);\n }\n return seekResult;\n }\n player.seekToProgressTime = newSeek;\n } else {\n const descriptor = Object.getOwnPropertyDescriptor(room, \"disableCameraTransform\");\n if (descriptor) return;\n Object.defineProperty(room, \"disableCameraTransform\", {\n get() {\n return manager.mainView.disableCameraTransform;\n },\n set(disable: boolean) {\n manager.mainView.disableCameraTransform = disable;\n },\n });\n\n Object.defineProperty(room, \"canUndoSteps\", {\n get() {\n return manager.mainView.canUndoSteps;\n }\n });\n\n Object.defineProperty(room, \"canRedoSteps\", {\n get() {\n return manager.mainView.canRedoSteps;\n }\n });\n\n room.moveCamera = (camera: Camera) => manager.mainView.moveCamera(camera);\n room.moveCameraToContain = (...args) => manager.moveCameraToContain(...args);\n room.convertToPointInWorld = (...args) => manager.mainView.convertToPointInWorld(...args);\n room.setCameraBound = (...args) => manager.mainView.setCameraBound(...args);\n room.scenePreview = (...args) => manager.mainView.scenePreview(...args);\n room.fillSceneSnapshot = (...args) => manager.mainView.fillSceneSnapshot(...args);\n room.generateScreenshot = (...args) => manager.mainView.generateScreenshot(...args);\n room.setMemberState = (...args) => manager.mainView.setMemberState(...args);\n room.redo = () => manager.mainView.redo();\n room.undo = () => manager.mainView.undo();\n }\n\n};","import { WindowManager } from \"./index\";\n\nexport const setupWrapper = (\n root: HTMLElement\n): {\n playground: HTMLDivElement;\n wrapper: HTMLDivElement;\n sizer: HTMLDivElement;\n mainViewElement: HTMLDivElement;\n} => {\n const playground = document.createElement(\"div\");\n playground.className = \"netless-window-manager-playground\";\n\n const sizer = document.createElement(\"div\");\n sizer.className = \"netless-window-manager-sizer\";\n\n const wrapper = document.createElement(\"div\");\n wrapper.className = \"netless-window-manager-wrapper\";\n\n const mainViewElement = document.createElement(\"div\");\n mainViewElement.className = \"netless-window-manager-main-view\";\n\n playground.appendChild(sizer);\n sizer.appendChild(wrapper);\n wrapper.appendChild(mainViewElement);\n root.appendChild(playground);\n WindowManager.wrapper = wrapper;\n\n return { playground, wrapper, sizer, mainViewElement };\n};"],"names":["Events","Events2","AppAttributes","AppAttributes2","AppEvents","AppEvents2","AppStatus","CursorState","CursorState2","MIN_WIDTH","MIN_HEIGHT","db","store","initDb","async","Promise","resolve","reject","request","indexedDB","open","onerror","e","onupgradeneeded","event","db2","target","result","objectStoreNames","contains","createObjectStore","keyPath","createIndex","unique","onsuccess","setItem","key","val","payload","kind","sourceCode","transaction","objectStore","add","getItem","index","get","getScript","url","item","resource","options","timeout","controller","AbortController","id","setTimeout","abort","response","fetch","__spreadProps","signal","headers","fetchWithTimeout","text2","text","executeScript","appName","Function","window","appRegister","constructor","Map","params","registered","set","srcOrAppOrFunction","src","downloadApp","appClass","name","error","message","includes","define","amd","loadApp","Error","appClasses","app","this","appClassesCache","addHooks","emitter2","createKindEmitter","kindEmitters","emit","has","Emittery","setViewFocusScenePath","view","focusScenePath","setScenePath","room","scenePath","isWritable","state","sceneState","debounce","callbacks2","mode","makeValidScenePath","displayer","scenes","entireScenes","firstSceneName","getVersionNumber","version","versionString","split","map","s","padStart","join","parseInt","wait","time","manager","authorId","observerId","data","eventName","AppMove","appMoveHandler","AppResize","appResizeHandler","AppBoxStateChange","boxStateChangeHandler","SetMainViewScenePath","setMainViewScenePathHandler","MoveCameraToContain","moveCameraToContainHandler","boxManager","moveBox","resizeBox","Object","assign","skipUpdate","refreshViewSize","nextScenePath","mainView","moveCameraToContain","addListeners","addMagixEventListener","mainMagixEventListener","removeListeners","removeMagixEventListener","onObjectByEvent","object","func","listenUpdated","listener","events","unlistenUpdated","reaction","fireImmediately","safeListenPropsUpdated","getProps","callback","onDestroyed","disposeListenUpdated","disposeReaction","props","isObject","onObjectRemoved","UpdateEventKind","Removed","onObjectInserted","Inserted","plainObjectKeys","keys","Boolean","Set","listeners","size","dispatch","forEach","addListener","removeListener","delete","STORAGE_NS","context2","defaultState","SideEffectManager","WeakMap","StorageEvent","_context","_state","rawState","_getRawState","getIsWritable","getAttributes","updateAttributes","setState","rawValue","JSON","parse","stringify","isRef","v","_refMap","_sideEffect","addDisposer","_updateProperties","bind","destroy","_destroyed","warn","ensureState","reduce","length","value","_lastValue","_setRawState","refValue","k","genUID","__isRef","emptyStorage","mapValues","noop","deleteStorage","flushAll","defaultValue","actions","diffs","i","action","oldValue","newValue","curValue","onStateChanged","appId","appProxy","appOptions","autorun","toJS","listenDisposed","unlistenDisposed","isReplay","attributes","appAttr","getAppAttributes","isDynamicPPT","appProxy2","appProxies","getAppInitPath","canOperate","box","getBox","BoxNotCreatedError","safeSetAttributes","safeUpdateAttributes","setFullPath","dom","getView","divElement","getRoom","storeId","storage","Storage","emitter","on","dispatchMagixEvent","appEmitter","isAddApp","_storage","Fields","Fields2","setContext","context","apps","Apps","Focus","getAppState","State","getMaximized","getMinimized","setupAppAttributes","attrNames","push","pick","attrs","createdAt","Date","now","Size","Position","SceneIndex","updateAppState","stateName","cleanAppAttributes","cleanFocus","getAppSceneIndex","getAppScenePath","getMainViewScenePath","getMainViewSceneIndex","getBoxState","BoxState","setMainViewScenePath","_mainScenePath","setMainViewSceneIndex","_mainSceneIndex","getMainViewCamera","MainViewCamera","getMainViewSize","MainViewSize","setMainViewCamera","camera","__spreadValues","setMainViewSize","size2","setAppFocus","focus","updateCursor","uid","position","Cursors","updateCursorState","cursorState","getCursorState","cleanCursor","setMainViewFocusPath","log","args","WindowManager","debug","memberId","roomMembers","find","member","updateManagerRect","blurFocusBox","blurAllBox","Context","createContext","Base","viewManager","sceneIndex","maximized","minimized","zIndex","x","y","width","height","appId2","refresher","stateKey","appState","appAttributes","setZIndex","appListener","makeAppEventListener","initScenes","createView","readonly","getFullScenePath","FullPath","getFullScenePathFromScenes","fullPath","dir","scene","getScenePath","path","appImpl","appParams","setupApp","focusApp","focusBox","BoxManagerNotFoundError","AppContext","appContext","once","WindowCreated","then","boxInitState","getAppInitState","updateBoxState","onAny","appAttributesUpdateListener","setup","appResult","notifyApp","afterSetupApp","fixMobileSize","createBox","smartPosition","intrinsicWidth","intrinsicHeight","setBoxInitState","onSeek","currentAppState","AppProxy","baseInsertApp","emitAppSceneStateChange","emitAppIsWritableChange","setBoxMinSize","minWidth","minwidth","minHeight","minheight","setBoxTitle","title","status","fullScenePath","needCloseBox","cleanAttrs","clearListeners","closeBox","destroyView","appStatus","remove","close","views","release","setViewScenePath","clear","setDefaultCameraBound","setCameraBound","maxContentMode","minContentMode","mainViewCamera","moveCameraToContian","mainViewSize","moveCamera","isEqual","mainViewClickHandler","cameraState","createMainView","moveCameraSizeByAttributes","addMainViewListener","start","setCameraAndSize","playgroundSizeChangeListener","sizeChangeHandler","sideEffectManager","off","started","addCameraListener","cameraReaction","mainViewScenePath","mainViewIsAddListener","addEventListener","mainViewClickListener","removeMainViewListener","removeEventListener","callbacks","onCameraUpdatedByDevice","onCameraOrSizeUpdated","removeCameraListener","isEmpty","originX","originY","animationMode","AnimationMode","Immediately","scale","centerX","centerY","needScale","stop","windowManger","ids","startsWith","cursorManager","setRoomMembers","cleanMemberAttributes","isReadonly","isManualWritable","setReadonly","disableCameraTransform","dispatchInternalEvent","mainViewProxy","MainViewProxy","ViewManager","appListeners","AppListeners","displayerStateListener","reconnectRefresher","setRoom","onCreated","onReconnected","isPlayer","attributesUpdateCallback","onAppDelete","boxEventListener","setMaximized","setMinimized","mainSceneIndex","_prevSceneIndex","focused","_prevFocused","mainScenePath","displayerWritableListener","container","appsWithCreatedAt","sortBy","StartCreate","focusByAttributes","retries","catch","err","refresh","setBoxManager","resetMaximized","resetMinimized","bindMainView","needFocus","beforeAddApp","afterAddApp","impl","config","singleton","v4","replace","slice","genAppId","intrinsicX","intrinsicY","ZIndex","isRoom","scenePathType","ScenePathType","None","Page","_setMainViewScenePath","Dir","validScenePath","sceneList","pop","sceneDir","safeDispatchMagixEvent","boxSize","focusAppId","reconnected","Array","from","values","all","notifyContainerRectUpdate","rect","offAny","ResizeObserver","ResizeObserverPolyfill","sizer","wrapper","containerResizeObserver","ContainerResizeObserver","observePlaygroundSize","updateSizer","getBoundingClientRect","containerRect","contentRect","observe","containerSizeRatio","classList","toggle","style","disconnect","createTeleBoxManagerConfig","teleBoxManager","setupBoxManager","TELE_BOX_MANAGER_EVENT","blurBox","darkMode","colorScheme","getMainView","prefersColorScheme","boxes","createBoxConfig","create","queryOne","TELE_BOX_STATE","Maximized","root","document","body","initManagerState","fence","TeleBoxManager","collectorContainer","setCollectorContainer","collector","TeleBoxCollector","styles","collectorStyles","mount","setCollector","boxIsFocus","getFocusBox","query","getTopBox","maxBy","update","setContainerRect","blurAll","updateAll","focusTopBox","setPrefersColorScheme","fn","fns","run","thing","a","b","src_url_equal_anchor","current_component","element_src","createElement","href","node","appendChild","anchor","insertBefore","parentNode","removeChild","createTextNode","attribute","removeAttribute","getAttribute","setAttribute","wholeText","important","setProperty","component","dirty_components","binding_callbacks","render_callbacks","flush_callbacks","resolved_promise","update_scheduled","flushing","seen_callbacks","$$","fragment","before_update","dirty","p","ctx","after_update","add_render_callback","outroing","flush","fill","instance2","create_fragment2","not_equal","append_styles","parent_component","bound","blank_object","on_mount","on_destroy","on_disconnect","skip_bound","ready","ret","rest","hydrate","nodes","element2","childNodes","l","detach","c","intro","block","local","customElement","m","new_on_destroy","filter","is_function","cursorName","tagName","backgroundColor","appliance","visible","avatar","theme","color","cursorTagBackgroundColor","opacity","hasTagName","hasAvatar","display","entries","hasName","$destroy","detaching","d","$on","type","indexOf","splice","$set","$$props","obj","$$set","ApplianceMap","ApplianceNames","pencil","selector","eraser","shape","addCursorChangeListener","cursors","wrapperRect","autoHidden","moveCursor","focusView","viewRect","viewCamera","Leave","hide","setMember","createCursor","onCursorChange","cursor","point","screen","convertPointToScreen","translateX","translateY","memberState","currentApplianceName","strokeColor","nickName","cursorTextColor","memberColor","memberCursorName","memberAvatar","timer","App","initProps","memberApplianceName","getIcon","memberTheme","memberCursorTextColor","memberCursorTagBackgroundColor","memberOpacity","findMemberByUid","updateComponent","omit","cursorInstances","appManager","members","compact","uniq","wrapper2","uids","getUids","Cursor","getType","clientX","clientY","convertToPointInWorld","parentElement","mainViewElement","hideCursor","setupWrapper","onReconnect","hasReactor","mouseMoveListener","mouseLeaveListener","initCursorAttributes","startReaction","setMainViewDivElement","div","handleRoomMembersChange","getPoint","setNormalCursorState","Normal","updateContainerRect","deleteCursor","needDeleteIds","findIndex","cursorId","BuiltinApps","DocsViewer","AppDocsViewer","MediaPlayer","AppMediaPlayer","phase","RoomPhase","Connected","Reconnecting","releaseDisposers","reactors","isFunction","disposers","onPhaseChanged","disposer","InvisiblePlugin","ViewMode","Broadcaster","checkVersion","disableSerialization","_WindowManager","isCreated","initManager","pRetry","count","ensureAttributes","AppManager","CursorManager","bindContainer","player","originSeek","seekToProgressTime","seekResult","call","getOwnPropertyDescriptor","defineProperty","disable","canUndoSteps","canRedoSteps","scenePreview","fillSceneSnapshot","generateScreenshot","setMemberState","redo","undo","getInvisiblePlugin","setWritable","createInvisiblePlugin","chessboard","overwriteStyles","playground","className","style2","textContent","firstChild","initContainer","BoxManager","bindCollectorContainer","register","ParamsInvalidError","AppCreateError","setupScenePath","endsWith","addApp","AppManagerNotInitError","isValidScenePath","InvalidScenePath","appScenePath","putScenes","switchMainViewToWriter","onAppDestroy","setViewMode","Freedom","viewMode","boxState","queryAll","closeApp","rectangle","cameraBound","onDestroy","_destroy","setAttributes","scheme","sceneSrc","ppt","WhiteVersion","WhiteWebSDKInvalidError","isNull","verbose"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/constants.ts","../src/Register/storage.ts","../src/Register/loader.ts","../src/Register/index.ts","../src/Utils/Common.ts","../src/AppListener.ts","../src/Utils/error.ts","../src/Utils/Reactive.ts","../src/App/Storage/utils.ts","../src/App/Storage/StorageEvent.ts","../src/App/Storage/index.ts","../src/AppContext.ts","../src/AttributesDelegate.ts","../src/Utils/log.ts","../src/Base/Context.ts","../src/Base/index.ts","../src/AppProxy.ts","../src/View/ViewManager.ts","../src/View/MainView.ts","../src/AppManager.ts","../src/ContainerResizeObserver.ts","../src/BoxManager.ts","../node_modules/svelte/internal/index.mjs","../src/Cursor/Cursor.svelte","../src/Cursor/icons.ts","../src/image/pencil-cursor.png","../src/image/selector-cursor.png","../src/image/eraser-cursor.png","../src/image/shape-cursor.svg","../src/image/text-cursor.svg","../src/Cursor/Cursor.ts","../src/Cursor/index.ts","../src/BuiltinApps.ts","../src/index.ts","../src/ReconnectRefresher.ts","../src/Utils/RoomHacker.ts","../src/Helper.ts"],"sourcesContent":["export enum Events {\n AppMove = \"AppMove\",\n AppFocus = \"AppFocus\",\n AppResize = \"AppResize\",\n AppBoxStateChange = \"AppBoxStateChange\",\n GetAttributes = \"GetAttributes\",\n UpdateWindowManagerWrapper = \"UpdateWindowManagerWrapper\",\n InitReplay = \"InitReplay\",\n WindowCreated = \"WindowCreated\",\n SetMainViewScenePath = \"SetMainViewScenePath\",\n SetMainViewSceneIndex = \"SetMainViewSceneIndex\",\n SwitchViewsToFreedom = \"SwitchViewsToFreedom\",\n MoveCameraToContain = \"MoveCameraToContain\"\n}\n\nexport const MagixEventName = \"__WindowManger\";\n\nexport enum AppAttributes {\n Size = \"size\",\n Position = \"position\",\n SceneIndex = \"SceneIndex\",\n ZIndex = \"zIndex\",\n}\n\nexport enum AppEvents {\n setBoxSize = \"setBoxSize\",\n setBoxMinSize = \"setBoxMinSize\",\n destroy = \"destroy\",\n}\n\nexport enum AppStatus {\n StartCreate = \"StartCreate\",\n}\n\nexport enum CursorState {\n Leave = \"leave\",\n Normal = \"normal\",\n}\n\nexport const REQUIRE_VERSION = \"2.16.0\";\n\nexport const MIN_WIDTH = 340 / 720;\nexport const MIN_HEIGHT = 340 / 720;\n\nexport const SET_SCENEPATH_DELAY = 100; // 设置 scenePath 的延迟事件\n\nexport const DEFAULT_CONTAINER_RATIO = 9 / 16;\n","const DatabaseName = \"__WindowManagerAppCache\";\n\nlet db: IDBDatabase;\nlet store: IDBObjectStore;\n\nexport const initDb = async () => {\n db = await createDb();\n}\n\nexport const setItem = (key: string, val: any) => {\n if (!db) return;\n return addRecord(db, { kind: key, sourceCode: val })\n};\n\nexport const getItem = async (key: string): Promise<string | null> => {\n if (!db) return null;\n return await query(db, key);\n};\n\nexport const removeItem = (key: string) => {\n if (!db) return;\n return deleteRecord(db, key);\n};\n\nfunction createDb(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DatabaseName, 2);\n request.onerror = (e) => {\n reject(e);\n }\n\n request.onupgradeneeded = (event: any) => {\n const db = event.target.result as IDBDatabase;\n if (!db.objectStoreNames.contains(\"apps\")) {\n store = db.createObjectStore(\"apps\", { keyPath: \"kind\" });\n store.createIndex(\"kind\", \"kind\", { unique: true });\n }\n }\n\n request.onsuccess = () => {\n const db = request.result;\n resolve(db);\n }\n })\n}\n\nfunction query<T>(db: IDBDatabase, val: string): Promise<T | null> {\n return new Promise((resolve, reject) => {\n const index = db.transaction([\"apps\"]).objectStore(\"apps\").index(\"kind\");\n const request = index.get(val);\n request.onerror = (e) => reject(e);\n request.onsuccess = () => {\n if (request.result) {\n resolve(request.result);\n } else {\n resolve(null);\n }\n }\n })\n}\n\nfunction addRecord(db: IDBDatabase, payload: any): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = db.transaction([\"apps\"], \"readwrite\").objectStore(\"apps\").add(payload);\n request.onsuccess = () => resolve();\n request.onerror = () => reject();\n })\n}\n\nfunction deleteRecord(db: IDBDatabase, key: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = db.transaction([\"apps\"], \"readwrite\").objectStore(\"apps\").delete(key);\n request.onsuccess = () => resolve();\n request.onerror = () => reject();\n })\n}\n","import { getItem, setItem } from \"./storage\";\nimport type { NetlessApp } from \"../typings\";\n\nconst Prefix = \"NetlessApp\";\n\nconst TIMEOUT = 10000; // 10 秒超时\n\nexport const getScript = async (url: string): Promise<string> => {\n const item = await getItem(url);\n if (item) {\n return item;\n } else {\n const result = await fetchWithTimeout(url, { timeout: TIMEOUT });\n const text = await result.text();\n await setItem(url, text);\n return text;\n }\n};\n\nexport const executeScript = (text: string, appName: string): NetlessApp => {\n let result = Function(text + `;return ${appName}`)();\n if (typeof result === \"undefined\") {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n result = window[appName];\n }\n return result;\n};\n\nexport const loadApp = async (\n url: string,\n key: string,\n name?: string\n): Promise<NetlessApp | undefined> => {\n const appName = name || Prefix + key;\n const text = await getScript(url);\n try {\n return executeScript(text, appName);\n } catch (error: any) {\n if (error.message.includes(\"Can only have one anonymous define call per script file\")) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const define = window.define;\n if (\"function\" == typeof define && define.amd) {\n delete define.amd;\n }\n return executeScript(text, appName);\n }\n }\n};\n\nasync function fetchWithTimeout(resource: string, options: RequestInit & { timeout: number }) {\n const { timeout = 10000 } = options;\n\n const controller = new AbortController();\n const id = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(resource, {\n ...options,\n signal: controller.signal,\n headers: {\n \"content-type\": \"text/plain\",\n },\n });\n clearTimeout(id);\n\n return response;\n}\n","import Emittery from \"emittery\";\nimport type { NetlessApp, RegisterEvents, RegisterParams } from \"../typings\";\nimport { loadApp } from \"./loader\";\n\nclass AppRegister {\n public kindEmitters: Map<string, Emittery<RegisterEvents>> = new Map();\n public registered: Map<string, RegisterParams> = new Map();\n public appClassesCache: Map<string, Promise<NetlessApp>> = new Map();\n public appClasses: Map<string, () => Promise<NetlessApp>> = new Map();\n\n public async register(params: RegisterParams): Promise<void> {\n this.registered.set(params.kind, params);\n \n const srcOrAppOrFunction = params.src\n let downloadApp: () => Promise<NetlessApp>\n \n if (typeof srcOrAppOrFunction === \"string\") {\n downloadApp = async () => {\n const appClass = await loadApp(srcOrAppOrFunction, params.kind);\n if (appClass) {\n return appClass\n } else {\n throw new Error(`[WindowManager]: load remote script failed, ${srcOrAppOrFunction}`);\n }\n }\n } else if (typeof srcOrAppOrFunction === \"function\") {\n downloadApp = srcOrAppOrFunction\n } else {\n downloadApp = async () => srcOrAppOrFunction\n }\n\n this.appClasses.set(params.kind, async () => {\n let app = this.appClassesCache.get(params.kind)\n if (!app) {\n app = downloadApp()\n this.appClassesCache.set(params.kind, app)\n }\n return app\n });\n \n if (params.addHooks) {\n const emitter = this.createKindEmitter(params.kind);\n if (emitter) {\n params.addHooks(emitter);\n }\n }\n }\n\n public async notifyApp<T extends keyof RegisterEvents>(kind: string, event: T, payload: RegisterEvents[T]) {\n const emitter = this.kindEmitters.get(kind);\n await emitter?.emit(event, payload);\n }\n\n private createKindEmitter(kind: string) {\n if (!this.kindEmitters.has(kind)) {\n const emitter = new Emittery<RegisterEvents>();\n this.kindEmitters.set(kind, emitter);\n }\n return this.kindEmitters.get(kind);\n }\n}\n\nexport const appRegister = new AppRegister();\n","import { appRegister } from \"../Register\";\nimport { debounce } from \"lodash\";\nimport { emitter } from \"../index\";\nimport { v4 } from \"uuid\";\nimport type { PublicEvent } from \"../index\";\nimport type { Displayer, ViewVisionMode, Room, View } from \"white-web-sdk\";\nimport type Emittery from \"emittery\";\n\nexport const genAppId = async (kind: string) => {\n const impl = await appRegister.appClasses.get(kind)?.();\n if (impl && impl.config?.singleton) {\n return kind;\n }\n return `${kind}-${v4().replace(\"-\", \"\").slice(0, 8)}`;\n};\n\nexport const setViewFocusScenePath = (view: View, focusScenePath: string) => {\n if (view.focusScenePath !== focusScenePath) {\n view.focusScenePath = focusScenePath;\n }\n};\n\nexport const setScenePath = (room: Room | undefined, scenePath: string) => {\n if (room && room.isWritable) {\n if (room.state.sceneState.scenePath !== scenePath) {\n room.setScenePath(scenePath);\n }\n }\n};\n\nexport const getScenePath = (\n room: Room | undefined,\n dir: string | undefined,\n index: number\n): string | undefined => {\n if (room && dir) {\n const scenes = entireScenes(room);\n const scene = scenes[dir]?.[index];\n if (scene) {\n return `${dir}/${scene.name}`;\n }\n }\n};\n\nexport const setViewMode = (view: View, mode: ViewVisionMode) => {\n if (!(view as any).didRelease && view.mode !== mode) {\n view.mode = mode;\n }\n};\n\nexport const emitError = (error: Error) => {\n if (emitter.listenerCount(\"error\") > 0) {\n emitter.emit(\"error\", error);\n } else {\n console.log(\"[WindowManager]:\", error);\n }\n};\n\nexport const addEmitterOnceListener = (event: any, listener: any) => {\n emitter.once(event).then(listener);\n};\n\nexport const notifyMainViewModeChange = debounce(\n (callbacks: Emittery<PublicEvent>, mode: ViewVisionMode) => {\n callbacks.emit(\"mainViewModeChange\", mode);\n },\n 200\n);\n\nexport const makeValidScenePath = (displayer: Displayer, scenePath: string, index = 0) => {\n const scenes = entireScenes(displayer)[scenePath];\n if (!scenes) return;\n const firstSceneName = scenes[index].name;\n if (scenePath === \"/\") {\n return `/${firstSceneName}`;\n } else {\n return `${scenePath}/${firstSceneName}`;\n }\n};\n\nexport const entireScenes = (displayer: Displayer) => {\n return displayer.entireScenes();\n};\n\nexport const isValidScenePath = (scenePath: string) => {\n return scenePath.startsWith(\"/\");\n};\n\nexport const ensureValidScenePath = (scenePath: string) => {\n if (scenePath.endsWith(\"/\")) {\n return scenePath.slice(0, -1);\n } else {\n return scenePath;\n }\n};\n\nexport const getVersionNumber = (version: string) => {\n const versionString = version\n .split(\".\")\n .map(s => s.padStart(2, \"0\"))\n .join(\"\");\n return parseInt(versionString);\n};\n\nexport const wait = (time: number) => new Promise(resolve => setTimeout(resolve, time));\n","import { callbacks } from './index';\nimport { Events, MagixEventName } from './constants';\nimport type { Event } from \"white-web-sdk\";\nimport type { AppManager } from \"./AppManager\";\nimport type { TeleBoxState } from \"@netless/telebox-insider\";\nimport { setViewFocusScenePath } from './Utils/Common';\n\nexport class AppListeners {\n private displayer = this.manager.displayer;\n\n constructor(private manager: AppManager) {}\n\n private get boxManager() {\n return this.manager.boxManager;\n }\n\n public addListeners() {\n this.displayer.addMagixEventListener(MagixEventName, this.mainMagixEventListener);\n }\n\n public removeListeners() {\n this.displayer.removeMagixEventListener(MagixEventName, this.mainMagixEventListener);\n }\n\n private mainMagixEventListener = (event: Event) => {\n if (event.authorId !== this.displayer.observerId) {\n const data = event.payload;\n switch (data.eventName) {\n case Events.AppMove: {\n this.appMoveHandler(data.payload);\n break;\n }\n case Events.AppResize: {\n this.appResizeHandler(data.payload);\n break;\n }\n case Events.AppBoxStateChange: {\n this.boxStateChangeHandler(data.payload);\n break;\n }\n case Events.SetMainViewScenePath: {\n this.setMainViewScenePathHandler(data.payload);\n break;\n }\n case Events.MoveCameraToContain: {\n this.moveCameraToContainHandler(data.payload);\n break;\n }\n default:\n break;\n }\n }\n };\n\n private appMoveHandler = (payload: any) => {\n this.boxManager?.moveBox(payload);\n };\n\n private appResizeHandler = (payload: any) => {\n this.boxManager?.resizeBox(Object.assign(payload, { skipUpdate: true }));\n this.manager.room?.refreshViewSize();\n };\n\n private boxStateChangeHandler = (state: TeleBoxState) => {\n callbacks.emit(\"boxStateChange\", state);\n }\n\n private setMainViewScenePathHandler = ({ nextScenePath }: { nextScenePath: string }) => {\n setViewFocusScenePath(this.manager.mainView, nextScenePath);\n callbacks.emit(\"mainViewScenePathChange\", nextScenePath);\n }\n\n private moveCameraToContainHandler = (payload: any) => {\n this.manager.mainView.moveCameraToContain(payload);\n }\n}\n","\nexport class AppCreateError extends Error {\n override message = \"[WindowManager]: app duplicate exists and cannot be created again\";\n}\n\nexport class AppNotRegisterError extends Error {\n constructor(kind: string) {\n super(`[WindowManager]: app ${kind} need register or provide src`);\n }\n}\n\nexport class AppManagerNotInitError extends Error {\n override message = \"[WindowManager]: AppManager must be initialized\";\n}\n\nexport class WhiteWebSDKInvalidError extends Error {\n constructor(version: string) {\n super(`[WindowManager]: white-web-sdk version must large than ${version}`);\n }\n}\n\nexport class ParamsInvalidError extends Error {\n override message = \"[WindowManager]: kind must be a valid string\";\n}\n\nexport class BoxNotCreatedError extends Error {\n override message = \"[WindowManager]: box need created\";\n}\n\nexport class InvalidScenePath extends Error {\n override message = `[WindowManager]: ScenePath should start with \"/\"`;\n}\n\nexport class BoxManagerNotFoundError extends Error {\n override message = \"[WindowManager]: boxManager not found\";\n}\n","import { listenUpdated, unlistenUpdated, reaction, UpdateEventKind } from \"white-web-sdk\";\nimport type { AkkoObjectUpdatedProperty , AkkoObjectUpdatedListener } from \"white-web-sdk\";\nimport { isObject } from \"lodash\";\n\n// 兼容 13 和 14 版本 SDK\nexport const onObjectByEvent = (event: UpdateEventKind) => {\n return (object: any, func: () => void) => {\n if (object === undefined) return;\n if (listenUpdated) {\n const listener = (events: readonly AkkoObjectUpdatedProperty<any>[]) => {\n const kinds = events.map(e => e.kind);\n if (kinds.includes(event)) {\n func();\n }\n }\n listenUpdated(object, listener);\n func();\n return () => unlistenUpdated(object, listener);\n } else {\n return reaction(\n () => object,\n () => {\n func();\n }, {\n fireImmediately: true,\n }\n )\n }\n }\n}\n\nexport const safeListenPropsUpdated = <T>(\n getProps: () => T,\n callback: AkkoObjectUpdatedListener<T>,\n onDestroyed?: (props: unknown) => void\n ) => {\n let disposeListenUpdated: (() => void) | null = null;\n const disposeReaction = reaction(\n getProps,\n () => {\n if (disposeListenUpdated) {\n disposeListenUpdated();\n disposeListenUpdated = null;\n }\n const props = getProps();\n if (isObject(props)) {\n disposeListenUpdated = () => unlistenUpdated(props, callback);\n listenUpdated(props, callback);\n } else {\n onDestroyed?.(props);\n }\n },\n { fireImmediately: true }\n );\n\n return () => {\n disposeListenUpdated?.();\n disposeReaction();\n };\n}\n\nexport const onObjectRemoved = onObjectByEvent(UpdateEventKind.Removed);\nexport const onObjectInserted = onObjectByEvent(UpdateEventKind.Inserted);\n","import { has } from \"lodash\";\nimport { genUID } from \"side-effect-manager\";\nimport type { AutoRefValue, ExtractRawValue, RefValue } from \"./typings\";\n\nexport const plainObjectKeys = Object.keys as <T>(o: T) => Array<Extract<keyof T, string>>;\n\nexport function isRef<TValue = unknown>(e: unknown): e is RefValue<TValue> {\n return Boolean(has(e, '__isRef'));\n}\n\nexport function makeRef<TValue>(v: TValue): RefValue<TValue> {\n return { k: genUID(), v, __isRef: true };\n}\n\nexport function makeAutoRef<TValue>(v: TValue): AutoRefValue<TValue> {\n return isRef<ExtractRawValue<TValue>>(v) ? v : makeRef(v as ExtractRawValue<TValue>);\n}\n","export type StorageEventListener<T> = (event: T) => void;\n\nexport class StorageEvent<TMessage> {\n listeners = new Set<StorageEventListener<TMessage>>();\n\n get length(): number {\n return this.listeners.size;\n }\n\n dispatch(message: TMessage): void {\n this.listeners.forEach(callback => callback(message));\n }\n\n addListener(listener: StorageEventListener<TMessage>): void {\n this.listeners.add(listener);\n }\n\n removeListener(listener: StorageEventListener<TMessage>): void {\n this.listeners.delete(listener);\n }\n}\n","import type { AkkoObjectUpdatedProperty } from \"white-web-sdk\";\nimport { get, has, mapValues, isObject, size, noop } from \"lodash\";\nimport { SideEffectManager } from \"side-effect-manager\";\nimport type { AppContext } from \"../../AppContext\";\nimport { safeListenPropsUpdated } from \"../../Utils/Reactive\";\nimport { isRef, makeRef, plainObjectKeys } from \"./utils\";\nimport type { Diff, MaybeRefValue, RefValue, StorageStateChangedEvent } from \"./typings\";\nimport { StorageEvent } from \"./StorageEvent\";\n\nexport * from './typings';\n\nexport const STORAGE_NS = \"_WM-STORAGE_\";\n\nexport class Storage<TState extends Record<string, any> = any> implements Storage<TState> {\n readonly id: string | null;\n\n private readonly _context: AppContext;\n private readonly _sideEffect = new SideEffectManager();\n private _state: TState;\n private _destroyed = false;\n\n private _refMap = new WeakMap<any, RefValue>();\n\n /**\n * `setState` alters local state immediately before sending to server. This will cache the old value for onStateChanged diffing.\n */\n private _lastValue = new Map<string | number | symbol, TState[Extract<keyof TState, string>]>();\n\n constructor(context: AppContext, id?: string, defaultState?: TState) {\n if (defaultState && !isObject(defaultState)) {\n throw new Error(`Default state for Storage ${id} is not an object.`);\n }\n\n this._context = context;\n this.id = id || null;\n\n this._state = {} as TState;\n const rawState = this._getRawState(this._state);\n\n if (this.id !== null && this._context.getIsWritable()) {\n if (rawState === this._state || !isObject(rawState)) {\n if (!get(this._context.getAttributes(), [STORAGE_NS])) {\n this._context.updateAttributes([STORAGE_NS], {});\n }\n this._context.updateAttributes([STORAGE_NS, this.id], this._state);\n }\n if (defaultState) {\n this.setState(defaultState);\n }\n }\n\n // strip mobx\n plainObjectKeys(rawState).forEach(key => {\n if (this.id === null && key === STORAGE_NS) {\n return;\n }\n try {\n const rawValue = isObject(rawState[key]) ? JSON.parse(JSON.stringify(rawState[key])) : rawState[key];\n if (isRef<TState[Extract<keyof TState, string>]>(rawValue)) {\n this._state[key] = rawValue.v;\n if (isObject(rawValue.v)) {\n this._refMap.set(rawValue.v, rawValue);\n }\n } else {\n this._state[key] = rawValue;\n }\n } catch (e) {\n console.error(e);\n }\n });\n\n this._sideEffect.addDisposer(\n safeListenPropsUpdated(\n () => this.id === null ? context.getAttributes() : get(context.getAttributes(), [STORAGE_NS, this.id]),\n this._updateProperties.bind(this),\n this.destroy.bind(this)\n )\n );\n }\n\n get state(): Readonly<TState> {\n if (this._destroyed) {\n console.warn(`Accessing state on destroyed Storage \"${this.id}\"`)\n }\n return this._state;\n }\n\n readonly onStateChanged = new StorageEvent<StorageStateChangedEvent<TState>>();\n\n ensureState(state: Partial<TState>): void {\n return this.setState(\n plainObjectKeys(state).reduce((payload, key) => {\n if (!has(this._state, key)) {\n payload[key] = state[key];\n }\n return payload;\n }, {} as Partial<TState>)\n );\n }\n\n setState(state: Partial<TState>): void {\n if (this._destroyed) {\n console.error(new Error(`Cannot call setState on destroyed Storage \"${this.id}\".`));\n return;\n }\n\n if (!this._context.getIsWritable()) {\n console.error(new Error(`Cannot setState on Storage \"${this.id}\" without writable access`), state);\n return;\n }\n\n const keys = plainObjectKeys(state);\n if (keys.length > 0) {\n keys.forEach(key => {\n const value = state[key];\n if (value === this._state[key]) {\n return;\n }\n\n if (value === void 0) {\n this._lastValue.set(key, this._state[key]);\n delete this._state[key];\n this._setRawState(key, value);\n } else {\n this._lastValue.set(key, this._state[key]);\n this._state[key] = value as TState[Extract<keyof TState, string>];\n\n let payload: MaybeRefValue<typeof value> = value;\n if (isObject(value)) {\n let refValue = this._refMap.get(value);\n if (!refValue) {\n refValue = makeRef(value);\n this._refMap.set(value, refValue);\n }\n payload = refValue;\n }\n\n this._setRawState(key, payload)\n }\n });\n }\n }\n\n /**\n * Empty storage data.\n */\n emptyStorage(): void {\n if (size(this._state) <= 0) {\n return;\n }\n\n if (this._destroyed) {\n console.error(new Error(`Cannot empty destroyed Storage \"${this.id}\".`));\n return;\n }\n\n if (!this._context.getIsWritable()) {\n console.error(new Error(`Cannot empty Storage \"${this.id}\" without writable access.`));\n return;\n }\n\n this.setState(mapValues(this._state, noop as () => undefined));\n }\n\n /**\n * Delete storage index with all of its data and destroy the Storage instance.\n */\n deleteStorage(): void {\n if (this.id === null) {\n throw new Error(`Cannot delete main Storage`);\n }\n\n if (!this._context.getIsWritable()) {\n console.error(new Error(`Cannot delete Storage \"${this.id}\" without writable access.`));\n return;\n }\n\n this.destroy();\n\n this._context.updateAttributes([STORAGE_NS, this.id], void 0);\n }\n\n get destroyed(): boolean {\n return this._destroyed;\n }\n\n /**\n * Destroy the Storage instance. The data will be kept.\n */\n destroy() {\n this._destroyed = true;\n this._sideEffect.flushAll();\n }\n\n private _getRawState(): TState | undefined\n private _getRawState(defaultValue: TState): TState\n private _getRawState(defaultValue?: TState): TState | undefined {\n if (this.id === null) {\n return get(this._context.getAttributes(), [], defaultValue);\n } else {\n return get(this._context.getAttributes(), [STORAGE_NS, this.id], defaultValue);\n }\n }\n\n private _setRawState(key: string, value: any): void {\n if (this.id === null) {\n if (key === STORAGE_NS) {\n throw new Error(`Cannot set attribute internal filed \"${STORAGE_NS}\"`)\n }\n return this._context.updateAttributes([key], value);\n } else {\n return this._context.updateAttributes([STORAGE_NS, this.id, key], value);\n }\n }\n\n private _updateProperties(actions: ReadonlyArray<AkkoObjectUpdatedProperty<TState, string>>): void {\n if (this._destroyed) {\n console.error(new Error(`Cannot call _updateProperties on destroyed Storage \"${this.id}\".`));\n return;\n }\n\n if (actions.length > 0) {\n const diffs: Diff<TState> = {};\n\n for (let i = 0; i < actions.length; i++) {\n try {\n const action = actions[i]\n const key = action.key as Extract<keyof TState, string>;\n\n if (this.id === null && key === STORAGE_NS) {\n continue\n }\n\n const value = isObject(action.value) ? JSON.parse(JSON.stringify(action.value)) : action.value;\n let oldValue: TState[Extract<keyof TState, string>] | undefined;\n if (this._lastValue.has(key)) {\n oldValue = this._lastValue.get(key);\n this._lastValue.delete(key);\n }\n\n switch (action.kind) {\n case 2: {\n // Removed\n if (has(this._state, key)) {\n oldValue = this._state[key];\n delete this._state[key];\n }\n diffs[key] = { oldValue };\n break;\n }\n default: {\n let newValue = value;\n\n if (isRef<TState[Extract<keyof TState, string>]>(value)) {\n const { k, v } = value;\n const curValue = this._state[key];\n if (isObject(curValue) && this._refMap.get(curValue)?.k === k) {\n newValue = curValue;\n } else {\n newValue = v;\n if (isObject(v)) {\n this._refMap.set(v, value);\n }\n }\n }\n\n if (newValue !== this._state[key]) {\n oldValue = this._state[key];\n this._state[key] = newValue;\n }\n\n diffs[key] = { newValue, oldValue };\n break;\n }\n }\n } catch (e) {\n console.error(e)\n }\n }\n\n this.onStateChanged.dispatch(diffs);\n }\n }\n}\n","import {\n autorun,\n listenDisposed,\n listenUpdated,\n reaction,\n unlistenDisposed,\n unlistenUpdated,\n toJS\n} from 'white-web-sdk';\nimport { BoxNotCreatedError } from './Utils/error';\nimport type { Room, SceneDefinition, View } from \"white-web-sdk\";\nimport type { ReadonlyTeleBox } from \"@netless/telebox-insider\";\nimport type Emittery from \"emittery\";\nimport type { BoxManager } from \"./BoxManager\";\nimport type { AppEmitterEvent } from \"./index\";\nimport type { AppManager } from \"./AppManager\";\nimport type { AppProxy } from \"./AppProxy\";\nimport { Storage } from './App/Storage';\nimport type { MagixEventAddListener, MagixEventDispatcher, MagixEventRemoveListener } from './App/MagixEvent';\n\nexport class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOptions = any> {\n public readonly emitter: Emittery<AppEmitterEvent<TAttributes>>;\n public readonly mobxUtils = {\n autorun,\n reaction,\n toJS\n };\n public readonly objectUtils = {\n listenUpdated,\n unlistenUpdated,\n listenDisposed,\n unlistenDisposed\n };\n\n private store = this.manager.store;\n public readonly isAddApp: boolean;\n public readonly isReplay = this.manager.isReplay;\n\n constructor(\n private manager: AppManager,\n private boxManager: BoxManager,\n public appId: string,\n private appProxy: AppProxy,\n private appOptions?: TAppOptions | (() => TAppOptions),\n ) {\n this.emitter = appProxy.appEmitter;\n this.isAddApp = appProxy.isAddApp;\n }\n\n public getDisplayer = () => {\n return this.manager.displayer;\n }\n\n /** @deprecated Use context.storage.state instead. */\n public getAttributes = (): TAttributes | undefined => {\n return this.appProxy.attributes;\n }\n\n public getScenes = (): SceneDefinition[] | undefined => {\n const appAttr = this.store.getAppAttributes(this.appId);\n if (appAttr?.isDynamicPPT) {\n const appProxy = this.manager.appProxies.get(this.appId);\n if (appProxy) {\n return appProxy.scenes;\n }\n } else {\n return appAttr?.options[\"scenes\"];\n }\n }\n\n public getView = (): View | undefined => {\n return this.appProxy.view;\n }\n\n public getInitScenePath = () => {\n return this.manager.getAppInitPath(this.appId);\n }\n\n /** Get App writable status. */\n public getIsWritable = (): boolean => {\n return this.manager.canOperate;\n }\n\n /** Get the App Window UI box. */\n public getBox = (): ReadonlyTeleBox => {\n const box = this.boxManager.getBox(this.appId);\n if (box) {\n return box;\n } else {\n throw new BoxNotCreatedError();\n }\n }\n\n public getRoom = (): Room | undefined => {\n return this.manager.room;\n }\n\n /** @deprecated Use context.storage.setState instead. */\n public setAttributes = (attributes: TAttributes) => {\n this.manager.safeSetAttributes({ [this.appId]: attributes });\n }\n\n /** @deprecated Use context.storage.setState instead. */\n public updateAttributes = (keys: string[], value: any) => {\n if (this.manager.attributes[this.appId]) {\n this.manager.safeUpdateAttributes([this.appId, ...keys], value);\n }\n }\n\n public setScenePath = async (scenePath: string): Promise<void> => {\n if (!this.appProxy.box) return;\n this.appProxy.setFullPath(scenePath);\n // 兼容 15 版本 SDK 的切页\n this.getRoom()?.setScenePath(scenePath);\n }\n\n public mountView = (dom: HTMLDivElement): void => {\n const view = this.getView();\n if (view) {\n view.divElement = dom;\n setTimeout(() => {\n // 渲染需要时间,延迟 refresh\n this.getRoom()?.refreshViewSize();\n }, 1000);\n }\n }\n\n /** Get the local App options. */\n public getAppOptions = (): TAppOptions | undefined => {\n return typeof this.appOptions === 'function' ? (this.appOptions as () => TAppOptions)() : this.appOptions\n }\n\n private _storage?: Storage<TAttributes>\n\n /** Main Storage for attributes. */\n public get storage(): Storage<TAttributes> {\n if (!this._storage) {\n this._storage = new Storage(this);\n }\n return this._storage;\n }\n\n /**\n * Create separated storages for flexible state management.\n * @param storeId Namespace for the storage. Storages of the same namespace share the same data.\n * @param defaultState Default state for initial storage creation.\n * @returns \n */\n public createStorage = <TState>(storeId: string, defaultState?: TState): Storage<TState> => {\n const storage = new Storage(this, storeId, defaultState);\n this.emitter.on(\"destroy\", () => {\n storage.destroy();\n });\n return storage;\n }\n\n /** Dispatch events to other clients (and self). */\n public dispatchMagixEvent: MagixEventDispatcher<TMagixEventPayloads> = (this.manager.displayer as Room).dispatchMagixEvent.bind(this.manager.displayer)\n\n /** Listen to events from others clients (and self messages). */\n public addMagixEventListener: MagixEventAddListener<TMagixEventPayloads> = this.manager.displayer.addMagixEventListener.bind(this.manager.displayer)\n\n /** Remove a Magix event listener. */\n public removeMagixEventListener = this.manager.displayer.removeMagixEventListener.bind(this.manager.displayer) as MagixEventRemoveListener<TMagixEventPayloads>\n}\n","import { AppAttributes } from \"./constants\";\nimport { get, pick } from \"lodash\";\nimport { setViewFocusScenePath } from \"./Utils/Common\";\nimport type { AddAppParams, AppSyncAttributes } from \"./index\";\nimport type { Camera, Size, View } from \"white-web-sdk\";\nimport type { Cursor } from \"./Cursor/Cursor\";\n\nexport enum Fields {\n Apps = \"apps\",\n Focus = \"focus\",\n State = \"state\",\n BoxState = \"boxState\",\n MainViewCamera = \"mainViewCamera\",\n MainViewSize = \"mainViewSize\",\n Broadcaster = \"broadcaster\",\n Cursors = \"cursors\",\n Position = \"position\",\n CursorState = \"cursorState\",\n FullPath = \"fullPath\",\n}\n\nexport type Apps = {\n [key: string]: AppSyncAttributes;\n};\n\nexport type Position = {\n x: number;\n y: number;\n type: PositionType;\n id?: string;\n};\n\nexport type PositionType = \"main\" | \"app\";\n\nexport type StoreContext = {\n getAttributes: () => any;\n safeUpdateAttributes: (keys: string[], value: any) => void;\n safeSetAttributes: (attributes: any) => void;\n}\nexport class AttributesDelegate {\n\n constructor(private context: StoreContext) {}\n\n public setContext(context: StoreContext) {\n this.context = context;\n }\n\n public get attributes() {\n return this.context.getAttributes();\n }\n\n public apps(): Apps {\n return get(this.attributes, [Fields.Apps]);\n }\n\n public get focus(): string | undefined {\n return get(this.attributes, [Fields.Focus]);\n }\n\n public getAppAttributes(id: string): AppSyncAttributes {\n return get(this.apps(), [id]);\n }\n\n public getAppState(id: string) {\n return get(this.apps(), [id, Fields.State]);\n }\n\n public getMaximized() {\n return get(this.attributes, [\"maximized\"]);\n }\n\n public getMinimized() {\n return get(this.attributes, [\"minimized\"]);\n }\n\n public setupAppAttributes(params: AddAppParams, id: string, isDynamicPPT: boolean) {\n const attributes = this.attributes;\n if (!attributes.apps) {\n this.context.safeSetAttributes({ apps: {} });\n }\n const attrNames = [\"scenePath\", \"title\"];\n if (!isDynamicPPT) {\n attrNames.push(\"scenes\");\n }\n const options = pick(params.options, attrNames);\n const attrs: AppSyncAttributes = { kind: params.kind, options, isDynamicPPT };\n if (typeof params.src === \"string\") {\n attrs.src = params.src;\n }\n attrs.createdAt = Date.now();\n this.context.safeUpdateAttributes([Fields.Apps, id], attrs);\n this.context.safeUpdateAttributes([Fields.Apps, id, Fields.State], {\n [AppAttributes.Size]: {},\n [AppAttributes.Position]: {},\n [AppAttributes.SceneIndex]: 0,\n });\n }\n\n public updateAppState(appId: string, stateName: AppAttributes, state: any) {\n if (get(this.attributes, [Fields.Apps, appId, Fields.State])) {\n this.context.safeUpdateAttributes([Fields.Apps, appId, Fields.State, stateName], state);\n }\n }\n\n public cleanAppAttributes(id: string) {\n this.context.safeUpdateAttributes([Fields.Apps, id], undefined);\n this.context.safeSetAttributes({ [id]: undefined });\n const focus = this.attributes[Fields.Focus];\n if (focus === id) {\n this.cleanFocus();\n }\n }\n\n public cleanFocus() {\n this.context.safeSetAttributes({ [Fields.Focus]: undefined });\n }\n\n public getAppSceneIndex(id: string) {\n return this.getAppState(id)?.[AppAttributes.SceneIndex];\n }\n\n public getAppScenePath(id: string) {\n return this.getAppAttributes(id)?.options?.scenePath;\n }\n\n public getMainViewScenePath() {\n return this.attributes[\"_mainScenePath\"];\n }\n\n public getMainViewSceneIndex() {\n return this.attributes[\"_mainSceneIndex\"];\n }\n\n public getBoxState() {\n return this.attributes[Fields.BoxState];\n }\n\n public setMainViewScenePath(scenePath: string) {\n this.context.safeSetAttributes({ _mainScenePath: scenePath });\n }\n\n public setMainViewSceneIndex(index: number) {\n this.context.safeSetAttributes({ _mainSceneIndex: index });\n }\n\n public getMainViewCamera(): MainViewCamera {\n return get(this.attributes, [Fields.MainViewCamera]);\n }\n\n public getMainViewSize(): MainViewSize {\n return get(this.attributes, [Fields.MainViewSize]);\n }\n\n public setMainViewCamera(camera: (Camera & { id: string }) | undefined) {\n this.context.safeSetAttributes({ [Fields.MainViewCamera]: { ...camera } });\n }\n\n public setMainViewSize(size: (Size & { id: string }) | undefined) {\n this.context.safeSetAttributes({ [Fields.MainViewSize]: { ...size } });\n }\n\n public setAppFocus(appId: string, focus: boolean) {\n if (focus) {\n this.context.safeSetAttributes({ [Fields.Focus]: appId });\n } else {\n this.context.safeSetAttributes({ [Fields.Focus]: undefined });\n }\n }\n\n public updateCursor(uid: string, position: Position) {\n if (!get(this.attributes, [Fields.Cursors])) {\n this.context.safeUpdateAttributes([Fields.Cursors], {});\n }\n if (!get(this.attributes, [Fields.Cursors, uid])) {\n this.context.safeUpdateAttributes([Fields.Cursors, uid], {});\n }\n this.context.safeUpdateAttributes([Fields.Cursors, uid, Fields.Position], position);\n }\n\n public updateCursorState(uid: string, cursorState: string | undefined) {\n if (!get(this.attributes, [Fields.Cursors, uid])) {\n this.context.safeUpdateAttributes([Fields.Cursors, uid], {});\n }\n this.context.safeUpdateAttributes([Fields.Cursors, uid, Fields.CursorState], cursorState);\n }\n\n public getCursorState(uid: string) {\n return get(this.attributes, [Fields.Cursors, uid, Fields.CursorState]);\n }\n\n public cleanCursor(uid: string) {\n this.context.safeUpdateAttributes([Fields.Cursors, uid], undefined);\n }\n\n // TODO 状态中保存一个 SceneName 优化性能\n public setMainViewFocusPath(mainView: View) {\n const scenePath = this.getMainViewScenePath();\n if (scenePath) {\n setViewFocusScenePath(mainView, scenePath);\n }\n }\n}\n\nexport type MainViewSize = {\n id: string;\n width: number;\n height: number;\n};\n\nexport type MainViewCamera = {\n id: string;\n centerX: number;\n centerY: number;\n scale: number;\n};\n\nexport type Cursors = {\n [key: string]: Cursor;\n};\n\n\nexport const store = new AttributesDelegate({\n getAttributes: () => {\n throw new Error(\"getAttributes not implemented\")\n },\n safeSetAttributes: () => {\n throw new Error(\"safeSetAttributes not implemented\")\n },\n safeUpdateAttributes: () => {\n throw new Error(\"safeUpdateAttributes not implemented\")\n },\n});\n","import { WindowManager } from \"../index\";\n\nexport const log = (...args: any[]): void => {\n if (WindowManager.debug) {\n console.log(`[WindowManager]:`, ...args);\n }\n};\n","import { emitter } from \"../index\";\nimport type { AppManager } from \"../AppManager\";\n\nexport class Context {\n public observerId: number;\n\n constructor(private manager: AppManager) {\n this.observerId = manager.displayer.observerId;\n\n emitter.on(\"observerIdChange\", id => {\n this.observerId = id;\n });\n };\n\n public get uid() {\n return this.manager.room?.uid || \"\";\n }\n\n public findMember = (memberId: number) => {\n const roomMembers = this.manager.room?.state.roomMembers;\n return roomMembers?.find(member => member.memberId === memberId);\n }\n\n public findMemberByUid = (uid: string) => {\n const roomMembers = this.manager.room?.state.roomMembers;\n return roomMembers?.find(member => member.payload?.uid === uid);\n }\n\n public updateManagerRect() {\n this.manager.boxManager?.updateManagerRect();\n }\n\n public blurFocusBox() {\n this.manager.boxManager?.blurAllBox();\n }\n}\n\nlet context: Context;\n\nexport const createContext = (manager: AppManager) => {\n if (!context) {\n context = new Context(manager);\n }\n return context;\n};\n","import type { AppManager } from \"../AppManager\";\nimport { store } from \"../AttributesDelegate\";\nimport { createContext } from \"./Context\";\n\nexport class Base {\n public store = store;\n public context = createContext(this.manager);\n\n constructor(public manager: AppManager) {}\n}\n","import Emittery from \"emittery\";\nimport { AppAttributes, AppEvents, Events } from \"./constants\";\nimport { AppContext } from \"./AppContext\";\nimport { appRegister } from \"./Register\";\nimport { autorun } from \"white-web-sdk\";\nimport { emitter } from \"./index\";\nimport { Fields } from \"./AttributesDelegate\";\nimport { debounce, get } from \"lodash\";\nimport { log } from \"./Utils/log\";\nimport { setScenePath, setViewFocusScenePath, getScenePath } from \"./Utils/Common\";\nimport type {\n AppEmitterEvent,\n AppInitState,\n BaseInsertParams,\n setAppOptions,\n AppListenerKeys,\n} from \"./index\";\nimport type { SceneState, View, SceneDefinition } from \"white-web-sdk\";\nimport type { AppManager } from \"./AppManager\";\nimport type { NetlessApp } from \"./typings\";\nimport type { ReadonlyTeleBox } from \"@netless/telebox-insider\";\nimport { Base } from \"./Base\";\nimport { BoxManagerNotFoundError } from \"./Utils/error\";\n\nexport class AppProxy extends Base {\n public id: string;\n public scenePath?: string;\n public appEmitter: Emittery<AppEmitterEvent>;\n public scenes?: SceneDefinition[];\n\n private appListener: any;\n private boxManager = this.manager.boxManager;\n private appProxies = this.manager.appProxies;\n private viewManager = this.manager.viewManager;\n private kind: string;\n public isAddApp: boolean;\n private status: \"normal\" | \"destroyed\" = \"normal\";\n private stateKey: string;\n private appResult?: NetlessApp<any>;\n private appContext?: AppContext<any, any>;\n\n constructor(\n private params: BaseInsertParams,\n manager: AppManager,\n appId: string,\n isAddApp: boolean\n ) {\n super(manager);\n this.kind = params.kind;\n this.id = appId;\n this.stateKey = `${this.id}_state`;\n this.appProxies.set(this.id, this);\n this.appEmitter = new Emittery();\n this.appListener = this.makeAppEventListener(this.id);\n this.isAddApp = isAddApp;\n\n this.initScenes();\n\n if (this.params.options?.scenePath) {\n // 只有传入了 scenePath 的 App 才会创建 View\n this.createView();\n }\n }\n\n private initScenes() {\n const options = this.params.options;\n if (options) {\n this.scenePath = options.scenePath;\n if (this.appAttributes?.isDynamicPPT && this.scenePath) {\n this.scenes = this.manager.displayer.entireScenes()[this.scenePath];\n } else {\n this.scenes = options.scenes;\n }\n }\n }\n\n public get view(): View | undefined {\n return this.manager.viewManager.getView(this.id);\n }\n\n public get isWritable(): boolean {\n return this.manager.canOperate && !this.box?.readonly;\n }\n\n public get attributes() {\n return this.manager.attributes[this.id];\n }\n\n public get appAttributes() {\n return this.store.getAppAttributes(this.id);\n }\n\n public getFullScenePath(): string | undefined {\n if (this.scenePath) {\n return get(this.appAttributes, [Fields.FullPath], this.getFullScenePathFromScenes());\n }\n }\n\n private getFullScenePathFromScenes() {\n const sceneIndex = get(this.appAttributes, [\"state\", \"SceneIndex\"], 0);\n const fullPath = getScenePath(this.manager.room, this.scenePath, sceneIndex);\n if (fullPath) {\n this.setFullPath(fullPath);\n }\n return fullPath;\n }\n\n public setFullPath(path: string) {\n this.manager.safeUpdateAttributes([\"apps\", this.id, Fields.FullPath], path);\n }\n\n public async baseInsertApp(skipUpdate = false): Promise<{ appId: string; app: NetlessApp }> {\n const params = this.params;\n if (!params.kind) {\n throw new Error(\"[WindowManager]: kind require\");\n }\n const appImpl = await appRegister.appClasses.get(params.kind)?.();\n const appParams = appRegister.registered.get(params.kind);\n if (appImpl) {\n await this.setupApp(\n this.id,\n skipUpdate,\n appImpl,\n params.options,\n appParams?.appOptions\n );\n } else {\n throw new Error(`[WindowManager]: app load failed ${params.kind} ${params.src}`);\n }\n this.context.updateManagerRect();\n return {\n appId: this.id,\n app: appImpl,\n };\n }\n\n private focusApp() {\n this.focusBox();\n this.store.setMainViewFocusPath(this.manager.mainView);\n }\n\n public get box(): ReadonlyTeleBox | undefined {\n return this.boxManager?.getBox(this.id);\n }\n\n public focusBox() {\n this.boxManager?.focusBox({ appId: this.id });\n }\n\n private async setupApp(\n appId: string,\n skipUpdate: boolean,\n app: NetlessApp,\n options?: setAppOptions,\n appOptions?: any\n ) {\n log(\"setupApp\", appId, app, options);\n if (!this.boxManager) {\n throw new BoxManagerNotFoundError();\n }\n const context = new AppContext(this.manager, this.boxManager, appId, this, appOptions);\n this.appContext = context;\n try {\n emitter.once(`${appId}${Events.WindowCreated}` as any).then(async () => {\n let boxInitState: AppInitState | undefined;\n if (!skipUpdate) {\n boxInitState = this.getAppInitState(appId);\n this.boxManager?.updateBoxState(boxInitState);\n }\n this.appEmitter.onAny(this.appListener);\n this.appAttributesUpdateListener(appId);\n this.setViewFocusScenePath();\n setTimeout(async () => {\n // 延迟执行 setup, 防止初始化的属性没有更新成功\n const result = await app.setup(context);\n this.appResult = result;\n appRegister.notifyApp(app.kind, \"created\", { appId, result });\n this.afterSetupApp(boxInitState);\n this.fixMobileSize();\n }, 50);\n });\n this.boxManager?.createBox({\n appId: appId,\n app,\n options,\n canOperate: this.manager.canOperate,\n smartPosition: this.isAddApp,\n });\n } catch (error: any) {\n console.error(error);\n throw new Error(`[WindowManager]: app setup error: ${error.message}`);\n }\n }\n\n // 兼容移动端创建时会出现 PPT 不适配的问题\n private fixMobileSize() {\n const box = this.boxManager?.getBox(this.id);\n if (box) {\n this.boxManager?.resizeBox({\n appId: this.id,\n width: box.intrinsicWidth + 0.001,\n height: box.intrinsicHeight + 0.001,\n skipUpdate: true,\n });\n }\n }\n\n private afterSetupApp(boxInitState: AppInitState | undefined): void {\n if (boxInitState) {\n if (!boxInitState?.x || !boxInitState.y) {\n this.boxManager?.setBoxInitState(this.id);\n }\n }\n }\n\n public onSeek(time: number) {\n this.appEmitter.emit(\"seek\", time);\n const boxInitState = this.getAppInitState(this.id);\n this.boxManager?.updateBoxState(boxInitState);\n }\n\n public async onReconnected() {\n this.appEmitter.emit(\"reconnected\", undefined);\n const currentAppState = this.getAppInitState(this.id);\n await this.destroy(true, false, true);\n const params = this.params;\n const appProxy = new AppProxy(params, this.manager, this.id, this.isAddApp);\n await appProxy.baseInsertApp(true);\n this.boxManager?.updateBoxState(currentAppState);\n }\n\n public getAppInitState = (id: string) => {\n const attrs = this.store.getAppState(id);\n if (!attrs) return;\n const position = attrs?.[AppAttributes.Position];\n const focus = this.store.focus;\n const size = attrs?.[AppAttributes.Size];\n const sceneIndex = attrs?.[AppAttributes.SceneIndex];\n const maximized = this.attributes?.[\"maximized\"];\n const minimized = this.attributes?.[\"minimized\"];\n const zIndex = attrs?.zIndex;\n let payload = { maximized, minimized, zIndex } as AppInitState;\n if (position) {\n payload = { ...payload, id: id, x: position.x, y: position.y };\n }\n if (focus === id) {\n payload = { ...payload, focus: true };\n }\n if (size) {\n payload = { ...payload, width: size.width, height: size.height };\n }\n if (sceneIndex) {\n payload = { ...payload, sceneIndex };\n }\n return payload;\n };\n\n public emitAppSceneStateChange(sceneState: SceneState) {\n this.appEmitter.emit(\"sceneStateChange\", sceneState);\n }\n\n public emitAppIsWritableChange() {\n this.appEmitter.emit(\"writableChange\", this.isWritable);\n }\n\n private makeAppEventListener(appId: string) {\n return (eventName: AppListenerKeys, data: any) => {\n if (!this.manager.canOperate) return;\n switch (eventName) {\n case \"setBoxSize\": {\n this.boxManager?.resizeBox({\n appId,\n width: data.width,\n height: data.height,\n skipUpdate: false,\n });\n break;\n }\n case \"setBoxMinSize\": {\n this.boxManager?.setBoxMinSize({\n appId,\n minWidth: data.minwidth,\n minHeight: data.minheight,\n });\n break;\n }\n case \"setBoxTitle\": {\n this.boxManager?.setBoxTitle({ appId, title: data.title });\n break;\n }\n case AppEvents.destroy: {\n if (this.status === \"destroyed\") return;\n this.destroy(true, false, true, data?.error);\n if (data?.error) {\n console.error(data?.error);\n }\n break;\n }\n case \"focus\": {\n this.boxManager?.focusBox({ appId: this.id });\n emitter.emit(\"focus\", { appId: this.id });\n break;\n }\n default: {\n break;\n }\n }\n };\n }\n\n private appAttributesUpdateListener = (appId: string) => {\n this.manager.refresher?.add(appId, () => {\n return autorun(() => {\n const attrs = this.manager.attributes[appId];\n if (attrs) {\n this.appEmitter.emit(\"attributesUpdate\", attrs);\n }\n });\n });\n this.manager.refresher?.add(this.stateKey, () => {\n return autorun(() => {\n const appState = this.appAttributes?.state;\n if (appState?.zIndex > 0 && appState.zIndex !== this.box?.zIndex) {\n this.boxManager?.setZIndex(appId, appState.zIndex);\n }\n });\n });\n this.manager.refresher?.add(`${appId}-fullPath`, () => {\n return autorun(() => {\n const fullPath = this.appAttributes.fullPath;\n this.setFocusScenePathHandler(fullPath);\n });\n });\n };\n\n private setFocusScenePathHandler = debounce((fullPath: string | undefined) => {\n if (this.view && fullPath && fullPath !== this.view?.focusScenePath) {\n setViewFocusScenePath(this.view, fullPath);\n }\n }, 50);\n\n public setScenePath(): void {\n if (!this.manager.canOperate) return;\n const fullScenePath = this.getFullScenePath();\n if (this.manager.room && fullScenePath && this.view) {\n setScenePath(this.manager.room, fullScenePath);\n }\n }\n\n public setViewFocusScenePath() {\n const fullPath = this.getFullScenePath();\n if (fullPath && this.view) {\n setViewFocusScenePath(this.view, fullPath);\n }\n }\n\n private async createView(): Promise<View> {\n const view = await this.viewManager.createView(this.id);\n this.setViewFocusScenePath();\n return view;\n }\n\n public async destroy(\n needCloseBox: boolean,\n cleanAttrs: boolean,\n skipUpdate: boolean,\n error?: Error\n ) {\n if (this.status === \"destroyed\") return;\n this.status = \"destroyed\";\n await appRegister.notifyApp(this.kind, \"destroy\", { appId: this.id });\n await this.appEmitter.emit(\"destroy\", { error });\n this.appEmitter.clearListeners();\n emitter.emit(`destroy-${this.id}` as any, { error });\n if (needCloseBox) {\n this.boxManager?.closeBox(this.id, skipUpdate);\n }\n if (cleanAttrs) {\n this.store.cleanAppAttributes(this.id);\n }\n this.appProxies.delete(this.id);\n\n this.viewManager.destroyView(this.id);\n this.manager.appStatus.delete(this.id);\n this.manager.refresher?.remove(this.id);\n this.manager.refresher?.remove(this.stateKey);\n this.manager.refresher?.remove(`${this.id}-fullPath`);\n }\n\n public close(): Promise<void> {\n return this.destroy(true, true, false);\n }\n}\n","import type { View , Displayer} from \"white-web-sdk\";\n\nexport class ViewManager {\n public views: Map<string, View> = new Map();\n\n constructor(private displayer: Displayer) {}\n\n public createView(id: string): View {\n const view = createView(this.displayer);\n this.views.set(id, view);\n return view;\n }\n\n public getView(id: string): View | undefined {\n return this.views.get(id);\n }\n\n public destroyView(id: string): void {\n const view = this.views.get(id);\n if (view) {\n view.release();\n this.views.delete(id);\n }\n }\n\n public setViewScenePath(id: string, scenePath: string): void {\n const view = this.views.get(id);\n if (view) {\n view.focusScenePath = scenePath;\n }\n }\n\n public destroy() {\n this.views.forEach(view => {\n view.release();\n });\n this.views.clear();\n }\n}\n\n\nexport const createView = (displayer: Displayer): View => {\n const view = displayer.views.createView();\n setDefaultCameraBound(view);\n return view;\n};\n\nexport const setDefaultCameraBound = (view: View) => {\n view.setCameraBound({\n maxContentMode: () => 10,\n minContentMode: () => 0.1,\n });\n};\n","import { AnimationMode, reaction } from \"white-web-sdk\";\nimport { Base } from \"../Base\";\nimport { callbacks, emitter } from \"../index\";\nimport { createView } from \"./ViewManager\";\nimport { debounce, isEmpty, isEqual } from \"lodash\";\nimport { Fields } from \"../AttributesDelegate\";\nimport { setViewFocusScenePath } from \"../Utils/Common\";\nimport { SideEffectManager } from \"side-effect-manager\";\nimport type { Camera, Size, View } from \"white-web-sdk\";\nimport type { AppManager } from \"../AppManager\";\n\nexport class MainViewProxy extends Base {\n private scale?: number;\n private started = false;\n private mainViewIsAddListener = false;\n private mainView: View;\n private viewId = \"mainView\";\n\n private sideEffectManager = new SideEffectManager();\n\n constructor(manager: AppManager) {\n super(manager);\n this.mainView = this.createMainView();\n this.moveCameraSizeByAttributes();\n emitter.once(\"mainViewMounted\").then(() => {\n this.addMainViewListener();\n setTimeout(() => {\n this.start();\n if (!this.mainViewCamera || !this.mainViewSize) {\n this.setCameraAndSize();\n }\n }, 200); // 等待 mainView 挂载完毕再进行监听,否则会触发不必要的 onSizeUpdated\n });\n const playgroundSizeChangeListener = () => {\n this.sizeChangeHandler(this.mainViewSize);\n };\n this.sideEffectManager.add(() => {\n emitter.on(\"playgroundSizeChange\", playgroundSizeChangeListener);\n return () => emitter.off(\"playgroundSizeChange\", playgroundSizeChangeListener);\n });\n }\n\n private get mainViewCamera() {\n return this.store.getMainViewCamera();\n }\n\n private get mainViewSize() {\n return this.store.getMainViewSize();\n }\n\n private moveCameraSizeByAttributes() {\n this.moveCameraToContian(this.mainViewSize);\n this.moveCamera(this.mainViewCamera);\n }\n\n public start() {\n if (this.started) return;\n this.sizeChangeHandler(this.mainViewSize);\n this.addCameraListener();\n this.manager.refresher?.add(Fields.MainViewCamera, this.cameraReaction);\n this.started = true;\n }\n\n public setCameraAndSize(): void {\n this.store.setMainViewCamera({ ...this.mainView.camera, id: this.context.uid });\n this.store.setMainViewSize({ ...this.mainView.size, id: this.context.uid });\n }\n\n private cameraReaction = () => {\n return reaction(\n () => this.mainViewCamera,\n camera => {\n if (camera && camera.id !== this.context.uid) {\n this.moveCameraToContian(this.mainViewSize);\n this.moveCamera(camera);\n }\n },\n {\n fireImmediately: true,\n }\n );\n };\n\n private sizeChangeHandler = debounce((size: Size) => {\n if (size) {\n this.moveCameraToContian(size);\n this.moveCamera(this.mainViewCamera);\n }\n }, 30);\n\n public get view(): View {\n return this.mainView;\n }\n\n public get cameraState() {\n return { ...this.view.camera, ...this.view.size };\n }\n\n public createMainView(): View {\n const mainView = createView(this.manager.displayer);\n const mainViewScenePath = this.store.getMainViewScenePath();\n if (mainViewScenePath) {\n setViewFocusScenePath(mainView, mainViewScenePath);\n }\n return mainView;\n }\n\n private onCameraUpdatedByDevice = (camera: Camera) => {\n this.store.setMainViewCamera({ ...camera, id: this.context.uid });\n if (!isEqual(this.mainViewSize, { ...this.mainView.size, id: this.context.uid })) {\n this.setMainViewSize(this.view.size);\n }\n };\n\n public addMainViewListener(): void {\n if (this.mainViewIsAddListener) return;\n if (this.view.divElement) {\n this.view.divElement.addEventListener(\"click\", this.mainViewClickListener);\n this.view.divElement.addEventListener(\"touchend\", this.mainViewClickListener);\n this.mainViewIsAddListener = true;\n }\n }\n\n public removeMainViewListener(): void {\n if (this.view.divElement) {\n this.view.divElement.removeEventListener(\"click\", this.mainViewClickListener);\n this.view.divElement.removeEventListener(\"touchend\", this.mainViewClickListener);\n }\n }\n\n private mainViewClickListener = () => {\n this.mainViewClickHandler();\n };\n\n public async mainViewClickHandler(): Promise<void> {\n if (!this.manager.canOperate) return;\n this.store.cleanFocus();\n this.context.blurFocusBox();\n }\n\n public setMainViewSize = debounce(size => {\n this.store.setMainViewSize({ ...size, id: this.context.uid });\n }, 50);\n\n private addCameraListener() {\n this.view.callbacks.on(\"onCameraUpdatedByDevice\", this.onCameraUpdatedByDevice);\n this.view.callbacks.on(\"onCameraUpdated\", this.onCameraOrSizeUpdated);\n this.view.callbacks.on(\"onSizeUpdated\", this.onCameraOrSizeUpdated);\n }\n\n private removeCameraListener() {\n this.view.callbacks.off(\"onCameraUpdatedByDevice\", this.onCameraUpdatedByDevice);\n this.view.callbacks.off(\"onCameraUpdated\", this.onCameraOrSizeUpdated);\n this.view.callbacks.off(\"onSizeUpdated\", this.onCameraOrSizeUpdated);\n }\n\n private onCameraOrSizeUpdated = () => {\n callbacks.emit(\"cameraStateChange\", this.cameraState);\n };\n\n public moveCameraToContian(size: Size): void {\n if (!isEmpty(size)) {\n this.view.moveCameraToContain({\n width: size.width,\n height: size.height,\n originX: -size.width / 2,\n originY: -size.height / 2,\n animationMode: AnimationMode.Immediately,\n });\n this.scale = this.view.camera.scale;\n }\n }\n\n public moveCamera(camera: Camera): void {\n if (!isEmpty(camera)) {\n if (isEqual(camera, this.view.camera)) return;\n const { centerX, centerY, scale } = camera;\n const needScale = scale * (this.scale || 1);\n this.view.moveCamera({\n centerX: centerX,\n centerY: centerY,\n scale: needScale,\n animationMode: AnimationMode.Immediately,\n });\n }\n }\n\n public stop() {\n this.removeMainViewListener();\n this.removeCameraListener();\n this.manager.refresher?.remove(Fields.MainViewCamera);\n this.manager.refresher?.remove(Fields.MainViewSize);\n this.started = false;\n }\n\n public destroy() {\n this.stop();\n this.sideEffectManager.flushAll();\n }\n}\n","import pRetry from \"p-retry\";\nimport { AppAttributes, AppStatus, Events, MagixEventName } from \"./constants\";\nimport { AppListeners } from \"./AppListener\";\nimport { AppProxy } from \"./AppProxy\";\nimport { autorun, isPlayer, isRoom, ScenePathType } from \"white-web-sdk\";\nimport { callbacks, emitter, WindowManager, reconnectRefresher } from \"./index\";\nimport { genAppId, makeValidScenePath, setScenePath, setViewFocusScenePath } from \"./Utils/Common\";\nimport { log } from \"./Utils/log\";\nimport { MainViewProxy } from \"./View/MainView\";\nimport { onObjectRemoved, safeListenPropsUpdated } from \"./Utils/Reactive\";\nimport { get, sortBy } from \"lodash\";\nimport { store } from \"./AttributesDelegate\";\nimport { ViewManager } from \"./View/ViewManager\";\nimport type { ReconnectRefresher } from \"./ReconnectRefresher\";\nimport type { BoxManager } from \"./BoxManager\";\nimport type { Displayer, DisplayerState, Room } from \"white-web-sdk\";\nimport type { AddAppParams, BaseInsertParams, TeleBoxRect, EmitterEvent } from \"./index\";\n\nexport class AppManager {\n public displayer: Displayer;\n public viewManager: ViewManager;\n public appProxies: Map<string, AppProxy> = new Map();\n public appStatus: Map<string, AppStatus> = new Map();\n public store = store;\n public mainViewProxy: MainViewProxy;\n public refresher?: ReconnectRefresher;\n public isReplay = this.windowManger.isReplay;\n\n private appListeners: AppListeners;\n public boxManager?: BoxManager;\n\n private _prevSceneIndex: number | undefined;\n private _prevFocused: string | undefined;\n\n constructor(public windowManger: WindowManager) {\n this.displayer = windowManger.displayer;\n this.store.setContext({\n getAttributes: () => this.attributes,\n safeSetAttributes: attributes => this.safeSetAttributes(attributes),\n safeUpdateAttributes: (keys, val) => this.safeUpdateAttributes(keys, val),\n });\n this.mainViewProxy = new MainViewProxy(this);\n this.viewManager = new ViewManager(this.displayer);\n this.appListeners = new AppListeners(this);\n this.displayer.callbacks.on(this.eventName, this.displayerStateListener);\n this.appListeners.addListeners();\n\n this.refresher = reconnectRefresher;\n this.refresher.setRoom(this.room);\n this.refresher.setContext({ emitter });\n\n emitter.once(\"onCreated\").then(() => this.onCreated());\n emitter.on(\"onReconnected\", () => this.onReconnected());\n if (isPlayer(this.displayer)) {\n emitter.on(\"seek\", time => {\n this.appProxies.forEach(appProxy => {\n appProxy.onSeek(time);\n });\n this.attributesUpdateCallback(this.attributes.apps);\n this.onAppDelete(this.attributes.apps);\n });\n }\n }\n\n private async onCreated() {\n await this.attributesUpdateCallback(this.attributes.apps);\n this.boxManager?.updateManagerRect();\n emitter.onAny(this.boxEventListener);\n this.refresher?.add(\"apps\", () => {\n return safeListenPropsUpdated(\n () => this.attributes.apps,\n () => {\n this.attributesUpdateCallback(this.attributes.apps);\n }\n );\n });\n this.refresher?.add(\"appsClose\", () => {\n return onObjectRemoved(this.attributes.apps, () => {\n this.onAppDelete(this.attributes.apps);\n });\n });\n this.refresher?.add(\"maximized\", () => {\n return autorun(() => {\n const maximized = this.attributes.maximized;\n this.boxManager?.setMaximized(Boolean(maximized));\n });\n });\n this.refresher?.add(\"minimized\", () => {\n return autorun(() => {\n const minimized = this.attributes.minimized;\n if (this.boxManager?.minimized !== minimized) {\n if (minimized === true) {\n this.boxManager?.blurAllBox();\n }\n setTimeout(() => {\n this.boxManager?.setMinimized(Boolean(minimized));\n }, 0);\n }\n });\n });\n this.refresher?.add(\"mainViewIndex\", () => {\n return autorun(() => {\n const mainSceneIndex = get(this.attributes, \"_mainSceneIndex\");\n if (mainSceneIndex !== undefined && this._prevSceneIndex !== mainSceneIndex) {\n callbacks.emit(\"mainViewSceneIndexChange\", mainSceneIndex);\n this._prevSceneIndex = mainSceneIndex;\n }\n });\n });\n this.refresher?.add(\"focusedChange\", () => {\n return autorun(() => {\n const focused = get(this.attributes, \"focus\");\n if (this._prevFocused !== focused) {\n callbacks.emit(\"focusedChange\", focused);\n this._prevFocused = focused;\n }\n });\n })\n if (!this.attributes.apps || Object.keys(this.attributes.apps).length === 0) {\n const mainScenePath = this.store.getMainViewScenePath();\n if (!mainScenePath) return;\n const sceneState = this.displayer.state.sceneState;\n if (sceneState.scenePath !== mainScenePath) {\n setScenePath(this.room, mainScenePath);\n }\n }\n this.displayerWritableListener(!this.room?.isWritable);\n this.displayer.callbacks.on(\"onEnableWriteNowChanged\", this.displayerWritableListener);\n this._prevFocused = this.attributes.focus;\n }\n\n /**\n * 插件更新 attributes 时的回调\n *\n * @param {*} attributes\n * @memberof WindowManager\n */\n public async attributesUpdateCallback(apps: any) {\n if (apps && WindowManager.container) {\n const appIds = Object.keys(apps);\n const appsWithCreatedAt = appIds.map(appId => {\n return {\n id: appId,\n createdAt: apps[appId].createdAt,\n };\n });\n for (const { id } of sortBy(appsWithCreatedAt, \"createdAt\")) {\n if (!this.appProxies.has(id) && !this.appStatus.has(id)) {\n const app = apps[id];\n\n pRetry(\n async () => {\n this.appStatus.set(id, AppStatus.StartCreate);\n // 防御 appAttributes 有可能为 undefined 的情况,这里做一个重试\n const appAttributes = this.attributes[id];\n if (!appAttributes) {\n throw new Error(\"appAttributes is undefined\");\n }\n await this.baseInsertApp(\n {\n kind: app.kind,\n options: app.options,\n isDynamicPPT: app.isDynamicPPT,\n },\n id,\n false\n );\n this.focusByAttributes(apps);\n },\n { retries: 3 }\n ).catch(err => {\n console.warn(`[WindowManager]: Insert App Error`, err);\n this.appStatus.delete(id);\n });\n }\n }\n }\n }\n\n public refresh() {\n this.attributesUpdateCallback(this.attributes.apps);\n }\n\n public setBoxManager(boxManager: BoxManager) {\n this.boxManager = boxManager;\n }\n\n public resetMaximized() {\n this.boxManager?.setMaximized(Boolean(this.store.getMaximized()));\n }\n\n public resetMinimized() {\n this.boxManager?.setMinimized(Boolean(this.store.getMinimized()));\n }\n\n private onAppDelete = (apps: any) => {\n const ids = Object.keys(apps);\n this.appProxies.forEach((appProxy, id) => {\n if (!ids.includes(id)) {\n appProxy.destroy(true, false, true);\n }\n });\n };\n\n public bindMainView(divElement: HTMLDivElement, disableCameraTransform: boolean) {\n const mainView = this.mainViewProxy.view;\n mainView.disableCameraTransform = disableCameraTransform;\n mainView.divElement = divElement;\n if (!mainView.focusScenePath) {\n this.setMainViewFocusPath();\n }\n emitter.emit(\"mainViewMounted\");\n }\n\n public setMainViewFocusPath() {\n const scenePath = this.store.getMainViewScenePath();\n if (scenePath) {\n setViewFocusScenePath(this.mainView, scenePath);\n }\n }\n\n public async addApp(params: AddAppParams, isDynamicPPT: boolean): Promise<string | undefined> {\n log(\"addApp\", params);\n const { appId, needFocus } = await this.beforeAddApp(params, isDynamicPPT);\n const appProxy = await this.baseInsertApp(params, appId, true, needFocus);\n this.afterAddApp(appProxy);\n return appProxy?.id;\n }\n\n private async beforeAddApp(params: AddAppParams, isDynamicPPT: boolean) {\n const appId = await genAppId(params.kind);\n this.appStatus.set(appId, AppStatus.StartCreate);\n const attrs = params.attributes ?? {};\n this.safeUpdateAttributes([appId], attrs);\n this.store.setupAppAttributes(params, appId, isDynamicPPT);\n const needFocus = !this.boxManager?.minimized;\n if (needFocus) {\n this.store.setAppFocus(appId, true);\n }\n return { appId, needFocus };\n }\n\n private afterAddApp(appProxy: AppProxy | undefined) {\n if (appProxy && appProxy.box) {\n const box = appProxy.box;\n emitter.emit(\"move\", {\n appId: appProxy.id,\n x: box?.intrinsicX,\n y: box?.intrinsicY,\n });\n this.store.updateAppState(appProxy.id, AppAttributes.ZIndex, box.zIndex);\n }\n if (this.boxManager?.minimized) {\n this.boxManager?.setMinimized(false, false);\n }\n }\n\n public async closeApp(appId: string) {\n const appProxy = this.appProxies.get(appId);\n if (appProxy) {\n appProxy.destroy(true, true, false);\n }\n }\n\n private async baseInsertApp(\n params: BaseInsertParams,\n appId: string,\n isAddApp: boolean,\n focus?: boolean\n ) {\n if (this.appProxies.has(appId)) {\n console.warn(\"[WindowManager]: app duplicate exists and cannot be created again\");\n return;\n }\n const appProxy = new AppProxy(params, this, appId, isAddApp);\n if (appProxy) {\n await appProxy.baseInsertApp(focus);\n this.appStatus.delete(appId);\n return appProxy;\n } else {\n this.appStatus.delete(appId);\n throw new Error(\"[WindowManger]: initialize AppProxy failed\");\n }\n }\n\n private displayerStateListener = (state: Partial<DisplayerState>) => {\n const sceneState = state.sceneState;\n if (sceneState) {\n const scenePath = sceneState.scenePath;\n this.appProxies.forEach(appProxy => {\n if (appProxy.scenePath && scenePath.startsWith(appProxy.scenePath)) {\n appProxy.emitAppSceneStateChange(sceneState);\n appProxy.setFullPath(scenePath);\n }\n });\n }\n if (state.roomMembers) {\n this.windowManger.cursorManager?.setRoomMembers(state.roomMembers);\n this.windowManger.cursorManager?.cleanMemberAttributes(state.roomMembers);\n }\n this.appProxies.forEach(appProxy => {\n appProxy.appEmitter.emit(\"roomStateChange\", state);\n });\n emitter.emit(\"observerIdChange\", this.displayer.observerId);\n };\n\n public displayerWritableListener = (isReadonly: boolean) => {\n const isWritable = !isReadonly;\n const isManualWritable =\n this.windowManger.readonly === undefined || this.windowManger.readonly === false;\n if (this.windowManger.readonly === undefined) {\n this.boxManager?.setReadonly(isReadonly);\n } else {\n this.boxManager?.setReadonly(!(isWritable && isManualWritable));\n }\n this.appProxies.forEach(appProxy => {\n appProxy.emitAppIsWritableChange();\n });\n if (isWritable === true) {\n this.mainView.disableCameraTransform = false;\n if (this.room && this.room.disableSerialization === true) {\n this.room.disableSerialization = false;\n }\n } else {\n this.mainView.disableCameraTransform = true;\n }\n };\n\n private get eventName() {\n return isRoom(this.displayer) ? \"onRoomStateChanged\" : \"onPlayerStateChanged\";\n }\n\n public get attributes() {\n return this.windowManger.attributes;\n }\n\n public get canOperate() {\n return this.windowManger.canOperate;\n }\n\n public get room() {\n return isRoom(this.displayer) ? (this.displayer as Room) : undefined;\n }\n\n public get mainView() {\n return this.mainViewProxy.view;\n }\n\n public get focusApp() {\n if (this.store.focus) {\n return this.appProxies.get(this.store.focus);\n }\n }\n\n public safeSetAttributes(attributes: any) {\n this.windowManger.safeSetAttributes(attributes);\n }\n\n public safeUpdateAttributes(keys: string[], value: any) {\n this.windowManger.safeUpdateAttributes(keys, value);\n }\n\n public async setMainViewScenePath(scenePath: string) {\n if (this.room) {\n const scenePathType = this.displayer.scenePathType(scenePath);\n if (scenePathType === ScenePathType.None) {\n throw new Error(`[WindowManager]: ${scenePath} not valid scene`);\n } else if (scenePathType === ScenePathType.Page) {\n await this._setMainViewScenePath(scenePath);\n } else if (scenePathType === ScenePathType.Dir) {\n const validScenePath = makeValidScenePath(this.displayer, scenePath);\n if (validScenePath) {\n await this._setMainViewScenePath(validScenePath);\n }\n }\n }\n }\n\n private async _setMainViewScenePath(scenePath: string) {\n this.safeSetAttributes({ _mainScenePath: scenePath });\n this.setMainViewFocusPath();\n this.store.setMainViewFocusPath(this.mainView);\n this.dispatchInternalEvent(Events.SetMainViewScenePath, { nextScenePath: scenePath });\n }\n\n public async setMainViewSceneIndex(index: number) {\n if (this.room) {\n this.safeSetAttributes({ _mainSceneIndex: index });\n const mainViewScenePath = this.store.getMainViewScenePath() as string;\n if (mainViewScenePath) {\n const sceneList = mainViewScenePath.split(\"/\");\n sceneList.pop();\n let sceneDir = sceneList.join(\"/\");\n if (sceneDir === \"\") {\n sceneDir = \"/\";\n }\n const scenePath = makeValidScenePath(this.displayer, sceneDir, index);\n if (scenePath) {\n this.store.setMainViewScenePath(scenePath);\n this.setMainViewFocusPath();\n }\n }\n }\n }\n\n public getAppInitPath(appId: string): string | undefined {\n const attrs = this.store.getAppAttributes(appId);\n if (attrs) {\n return attrs?.options?.scenePath;\n }\n }\n\n public safeDispatchMagixEvent(event: string, payload: any) {\n if (this.canOperate) {\n (this.displayer as Room).dispatchMagixEvent(event, payload);\n }\n }\n\n private boxEventListener = (eventName: keyof EmitterEvent, payload: any) => {\n switch (eventName) {\n case \"move\": {\n this.dispatchInternalEvent(Events.AppMove, payload);\n this.store.updateAppState(payload.appId, AppAttributes.Position, {\n x: payload.x,\n y: payload.y,\n });\n break;\n }\n case \"focus\": {\n this.windowManger.safeSetAttributes({ focus: payload.appId });\n break;\n }\n case \"resize\": {\n if (payload.width && payload.height) {\n this.dispatchInternalEvent(Events.AppResize, payload);\n this.store.updateAppState(payload.appId, AppAttributes.Size, {\n width: payload.width,\n height: payload.height,\n });\n }\n break;\n }\n case \"close\": {\n const appProxy = this.appProxies.get(payload.appId);\n if (appProxy) {\n appProxy.destroy(false, true, payload.error);\n }\n break;\n }\n case \"boxStateChange\": {\n this.dispatchInternalEvent(Events.AppBoxStateChange, payload);\n break;\n }\n default:\n break;\n }\n };\n\n public focusByAttributes(apps: any) {\n if (apps && Object.keys(apps).length === this.boxManager?.boxSize) {\n const focusAppId = this.store.focus;\n if (focusAppId) {\n this.boxManager.focusBox({ appId: focusAppId });\n }\n }\n }\n\n public async onReconnected() {\n const appProxies = Array.from(this.appProxies.values());\n const reconnected = appProxies.map(appProxy => {\n return appProxy.onReconnected();\n });\n await Promise.all(reconnected);\n }\n\n public notifyContainerRectUpdate(rect: TeleBoxRect) {\n this.appProxies.forEach(appProxy => {\n appProxy.appEmitter.emit(\"containerRectUpdate\", rect);\n });\n }\n\n public dispatchInternalEvent(event: Events, payload: any) {\n this.safeDispatchMagixEvent(MagixEventName, {\n eventName: event,\n payload: payload,\n });\n }\n\n public destroy() {\n this.displayer.callbacks.off(this.eventName, this.displayerStateListener);\n this.displayer.callbacks.off(\"onEnableWriteNowChanged\", this.displayerWritableListener);\n this.appListeners.removeListeners();\n emitter.offAny(this.boxEventListener);\n emitter.clearListeners();\n if (this.appProxies.size) {\n this.appProxies.forEach(appProxy => {\n appProxy.destroy(true, false, true);\n });\n }\n this.viewManager.destroy();\n this.boxManager?.destroy();\n this.refresher?.destroy();\n this.mainViewProxy.destroy();\n callbacks.clearListeners();\n this._prevSceneIndex = undefined;\n }\n}\n","import { ResizeObserver as ResizeObserverPolyfill } from \"@juggle/resize-observer\";\nimport { WindowManager } from \"./index\";\nimport type { EmitterType} from \"./index\";\n\nconst ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;\n\nexport class ContainerResizeObserver {\n private containerResizeObserver?: ResizeObserver;\n\n constructor(private emitter: EmitterType) {}\n\n public static create(\n container: HTMLElement,\n sizer: HTMLElement,\n wrapper: HTMLDivElement,\n emitter: EmitterType,\n ) {\n const containerResizeObserver = new ContainerResizeObserver(emitter);\n containerResizeObserver.observePlaygroundSize(container, sizer, wrapper);\n return containerResizeObserver;\n }\n\n public observePlaygroundSize(\n container: HTMLElement,\n sizer: HTMLElement,\n wrapper: HTMLDivElement\n ) {\n this.updateSizer(container.getBoundingClientRect(), sizer, wrapper);\n\n this.containerResizeObserver = new ResizeObserver(entries => {\n const containerRect = entries[0]?.contentRect;\n if (containerRect) {\n this.updateSizer(containerRect, sizer, wrapper);\n this.emitter.emit(\"playgroundSizeChange\", containerRect)\n }\n });\n\n this.containerResizeObserver.observe(container);\n }\n\n private updateSizer(\n { width, height }: DOMRectReadOnly,\n sizer: HTMLElement,\n wrapper: HTMLDivElement\n ) {\n if (width && height) {\n if (height / width > WindowManager.containerSizeRatio) {\n height = width * WindowManager.containerSizeRatio;\n sizer.classList.toggle(\"netless-window-manager-sizer-horizontal\", true);\n } else {\n width = height / WindowManager.containerSizeRatio;\n sizer.classList.toggle(\"netless-window-manager-sizer-horizontal\", false);\n }\n wrapper.style.width = `${width}px`;\n wrapper.style.height = `${height}px`;\n }\n }\n\n public disconnect() {\n this.containerResizeObserver?.disconnect();\n }\n}\n","import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from \"./constants\";\nimport { debounce, maxBy } from \"lodash\";\nimport {\n TELE_BOX_MANAGER_EVENT,\n TELE_BOX_STATE,\n TeleBoxCollector,\n TeleBoxManager,\n} from \"@netless/telebox-insider\";\nimport { emitter, WindowManager } from \"./index\";\nimport type { AddAppOptions, AppInitState, EmitterType, CallbacksType } from \"./index\";\nimport type {\n TeleBoxManagerUpdateConfig,\n TeleBoxManagerCreateConfig,\n ReadonlyTeleBox,\n TeleBoxManagerConfig,\n TeleBoxColorScheme,\n TeleBoxRect,\n} from \"@netless/telebox-insider\";\nimport type Emittery from \"emittery\";\nimport type { NetlessApp } from \"./typings\";\nimport type { View } from \"white-web-sdk\";\n\nexport { TELE_BOX_STATE };\n\nexport type CreateBoxParams = {\n appId: string;\n app: NetlessApp;\n view?: View;\n emitter?: Emittery;\n options?: AddAppOptions;\n canOperate?: boolean;\n smartPosition?: boolean;\n};\n\ntype AppId = { appId: string };\n\ntype MoveBoxParams = AppId & { x: number; y: number };\n\ntype ResizeBoxParams = AppId & { width: number; height: number; skipUpdate: boolean };\n\ntype SetBoxMinSizeParams = AppId & { minWidth: number; minHeight: number };\n\ntype SetBoxTitleParams = AppId & { title: string };\n\nexport type CreateTeleBoxManagerConfig = {\n collectorContainer?: HTMLElement;\n collectorStyles?: Partial<CSSStyleDeclaration>;\n prefersColorScheme?: TeleBoxColorScheme;\n};\n\nexport type BoxManagerContext = {\n safeSetAttributes: (attributes: any) => void;\n getMainView: () => View;\n updateAppState: (appId: string, field: AppAttributes, value: any) => void;\n emitter: EmitterType;\n callbacks: CallbacksType;\n canOperate: () => boolean;\n notifyContainerRectUpdate: (rect: TeleBoxRect) => void;\n cleanFocus: () => void;\n};\n\nexport const createBoxManager = (\n manager: WindowManager,\n callbacks: CallbacksType,\n emitter: EmitterType,\n options: CreateTeleBoxManagerConfig\n) => {\n return new BoxManager(\n {\n safeSetAttributes: (attributes: any) => manager.safeSetAttributes(attributes),\n getMainView: () => manager.mainView,\n updateAppState: (...args) => manager.appManager?.store.updateAppState(...args),\n canOperate: () => manager.canOperate,\n notifyContainerRectUpdate: (rect: TeleBoxRect) =>\n manager.appManager?.notifyContainerRectUpdate(rect),\n cleanFocus: () => manager.appManager?.store.cleanFocus(),\n callbacks,\n emitter,\n },\n options\n );\n};\n\nexport class BoxManager {\n public teleBoxManager: TeleBoxManager;\n\n constructor(\n private context: BoxManagerContext,\n private createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig\n ) {\n const { emitter, callbacks } = context;\n this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);\n this.teleBoxManager.events.on(TELE_BOX_MANAGER_EVENT.State, state => {\n if (state) {\n this.context.callbacks.emit(\"boxStateChange\", state);\n this.context.emitter.emit(\"boxStateChange\", state);\n }\n });\n this.teleBoxManager.events.on(\"minimized\", minimized => {\n this.context.safeSetAttributes({ minimized });\n if (minimized) {\n this.context.cleanFocus();\n this.blurAllBox();\n }\n });\n this.teleBoxManager.events.on(\"maximized\", maximized => {\n this.context.safeSetAttributes({ maximized });\n });\n this.teleBoxManager.events.on(\"removed\", boxes => {\n boxes.forEach(box => {\n emitter.emit(\"close\", { appId: box.id });\n });\n });\n this.teleBoxManager.events.on(\n \"intrinsic_move\",\n debounce((box: ReadonlyTeleBox): void => {\n emitter.emit(\"move\", { appId: box.id, x: box.intrinsicX, y: box.intrinsicY });\n }, 50)\n );\n this.teleBoxManager.events.on(\n \"intrinsic_resize\",\n debounce((box: ReadonlyTeleBox): void => {\n emitter.emit(\"resize\", {\n appId: box.id,\n width: box.intrinsicWidth,\n height: box.intrinsicHeight,\n });\n }, 200)\n );\n this.teleBoxManager.events.on(\"focused\", box => {\n if (box) {\n if (this.canOperate) {\n emitter.emit(\"focus\", { appId: box.id });\n } else {\n this.teleBoxManager.blurBox(box.id);\n }\n }\n });\n this.teleBoxManager.events.on(\"dark_mode\", darkMode => {\n callbacks.emit(\"darkModeChange\", darkMode);\n });\n this.teleBoxManager.events.on(\"prefers_color_scheme\", colorScheme => {\n callbacks.emit(\"prefersColorSchemeChange\", colorScheme);\n });\n this.teleBoxManager.events.on(\"z_index\", box => {\n this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);\n });\n emitter.on(\"playgroundSizeChange\", this.playgroundSizeChangeListener);\n }\n\n private playgroundSizeChangeListener = () => {\n this.updateManagerRect();\n }\n\n private get mainView() {\n return this.context.getMainView();\n }\n\n private get canOperate() {\n return this.context.canOperate();\n }\n\n public get boxState() {\n return this.teleBoxManager.state;\n }\n\n public get maximized() {\n return this.teleBoxManager.maximized;\n }\n\n public get minimized() {\n return this.teleBoxManager.minimized;\n }\n\n public get darkMode() {\n return this.teleBoxManager.darkMode;\n }\n\n public get prefersColorScheme(): TeleBoxColorScheme {\n return this.teleBoxManager.prefersColorScheme;\n }\n\n public get boxSize() {\n return this.teleBoxManager.boxes.length;\n }\n\n public createBox(params: CreateBoxParams): void {\n if (!this.teleBoxManager) return;\n let { minwidth = MIN_WIDTH, minheight = MIN_HEIGHT } = params.app.config ?? {};\n const { width, height } = params.app.config ?? {};\n const title = params.options?.title || params.appId;\n const rect = this.teleBoxManager.containerRect;\n\n if (minwidth > 1) {\n minwidth = minwidth / rect.width;\n }\n\n if (minheight > 1) {\n minheight = minheight / rect.height;\n }\n\n const createBoxConfig: TeleBoxManagerCreateConfig = {\n title,\n minWidth: minwidth,\n minHeight: minheight,\n width,\n height,\n id: params.appId,\n };\n this.teleBoxManager.create(createBoxConfig, params.smartPosition);\n this.context.emitter.emit(`${params.appId}${Events.WindowCreated}` as any);\n }\n\n public setBoxInitState(appId: string): void {\n const box = this.teleBoxManager.queryOne({ id: appId });\n if (box) {\n if (box.state === TELE_BOX_STATE.Maximized) {\n this.context.emitter.emit(\"resize\", {\n appId: appId,\n x: box.x,\n y: box.y,\n width: box.intrinsicWidth,\n height: box.intrinsicHeight,\n });\n }\n }\n }\n\n public setupBoxManager(\n createTeleBoxManagerConfig?: CreateTeleBoxManagerConfig\n ): TeleBoxManager {\n const root = WindowManager.wrapper ? WindowManager.wrapper : document.body;\n const rect = root.getBoundingClientRect();\n const initManagerState: TeleBoxManagerConfig = {\n root: root,\n containerRect: {\n x: 0,\n y: 0,\n width: rect.width,\n height: rect.height,\n },\n fence: false,\n prefersColorScheme: createTeleBoxManagerConfig?.prefersColorScheme,\n };\n\n const manager = new TeleBoxManager(initManagerState);\n if (this.teleBoxManager) {\n this.teleBoxManager.destroy();\n }\n this.teleBoxManager = manager;\n const container = createTeleBoxManagerConfig?.collectorContainer || WindowManager.wrapper;\n if (container) {\n this.setCollectorContainer(container);\n }\n return manager;\n }\n\n public setCollectorContainer(container: HTMLElement) {\n const collector = new TeleBoxCollector({\n styles: this.createTeleBoxManagerConfig?.collectorStyles,\n }).mount(container);\n this.teleBoxManager.setCollector(collector);\n }\n\n public getBox(appId: string): ReadonlyTeleBox | undefined {\n return this.teleBoxManager.queryOne({ id: appId });\n }\n\n public closeBox(appId: string, skipUpdate = false): ReadonlyTeleBox | undefined {\n return this.teleBoxManager.remove(appId, skipUpdate);\n }\n\n public boxIsFocus(appId: string): boolean | undefined {\n const box = this.getBox(appId);\n return box?.focus;\n }\n\n public getFocusBox(): ReadonlyTeleBox | undefined {\n const boxes = this.teleBoxManager.query({ focus: true });\n return boxes[0];\n }\n\n public getTopBox(): ReadonlyTeleBox | undefined {\n const boxes = this.teleBoxManager.query();\n return maxBy(boxes, \"zIndex\");\n }\n\n public updateBoxState(state?: AppInitState): void {\n if (!state) return;\n const box = this.getBox(state.id);\n if (box) {\n this.teleBoxManager.update(\n box.id,\n {\n x: state.x,\n y: state.y,\n width: state.width || 0.5,\n height: state.height || 0.5,\n zIndex: state.zIndex,\n },\n true\n );\n setTimeout(() => {\n if (state.focus) {\n this.teleBoxManager.focusBox(box.id, true);\n }\n if (state.maximized != null) {\n this.teleBoxManager.setMaximized(Boolean(state.maximized), true);\n }\n if (state.minimized != null) {\n this.teleBoxManager.setMinimized(Boolean(state.minimized), true);\n }\n }, 50);\n this.context.callbacks.emit(\"boxStateChange\", this.teleBoxManager.state);\n }\n }\n\n public updateManagerRect(): void {\n const rect = this.mainView.divElement?.getBoundingClientRect();\n if (rect && rect.width > 0 && rect.height > 0) {\n const containerRect = { x: 0, y: 0, width: rect.width, height: rect.height };\n this.teleBoxManager.setContainerRect(containerRect);\n this.context.notifyContainerRectUpdate(this.teleBoxManager.containerRect);\n }\n }\n\n public moveBox({ appId, x, y }: MoveBoxParams): void {\n this.teleBoxManager.update(appId, { x, y }, true);\n }\n\n public focusBox({ appId }: AppId, skipUpdate = true): void {\n this.teleBoxManager.focusBox(appId, skipUpdate);\n }\n\n public resizeBox({ appId, width, height, skipUpdate }: ResizeBoxParams): void {\n this.teleBoxManager.update(appId, { width, height }, skipUpdate);\n }\n\n public setBoxMinSize(params: SetBoxMinSizeParams): void {\n this.teleBoxManager.update(\n params.appId,\n {\n minWidth: params.minWidth,\n minHeight: params.minHeight,\n },\n true\n );\n }\n\n public setBoxTitle(params: SetBoxTitleParams): void {\n this.teleBoxManager.update(params.appId, { title: params.title }, true);\n }\n\n public blurAllBox(): void {\n this.teleBoxManager.blurAll();\n }\n\n public updateAll(config: TeleBoxManagerUpdateConfig): void {\n this.teleBoxManager.updateAll(config);\n }\n\n public setMaximized(maximized: boolean) {\n if (maximized !== this.maximized) {\n this.teleBoxManager.setMaximized(maximized, true);\n }\n }\n\n public setMinimized(minimized: boolean, skipUpdate = true) {\n this.teleBoxManager.setMinimized(minimized, skipUpdate);\n }\n\n public focusTopBox(): void {\n const boxes = this.teleBoxManager.query();\n if (boxes.length >= 1) {\n const box = this.getTopBox();\n if (box) {\n this.focusBox({ appId: box.id }, false);\n }\n }\n }\n\n public setReadonly(readonly: boolean) {\n this.teleBoxManager.setReadonly(readonly);\n }\n\n public setPrefersColorScheme(colorScheme: TeleBoxColorScheme) {\n this.teleBoxManager.setPrefersColorScheme(colorScheme);\n }\n\n public setZIndex(id: string, zIndex: number, skipUpdate = true) {\n this.teleBoxManager.update(id, { zIndex }, skipUpdate);\n }\n\n public destroy() {\n emitter.off(\"playgroundSizeChange\", this.playgroundSizeChangeListener);\n this.teleBoxManager.destroy();\n }\n}\n","function noop() { }\nconst identity = x => x;\nfunction assign(tar, src) {\n // @ts-ignore\n for (const k in src)\n tar[k] = src[k];\n return tar;\n}\nfunction is_promise(value) {\n return value && typeof value === 'object' && typeof value.then === 'function';\n}\nfunction add_location(element, file, line, column, char) {\n element.__svelte_meta = {\n loc: { file, line, column, char }\n };\n}\nfunction run(fn) {\n return fn();\n}\nfunction blank_object() {\n return Object.create(null);\n}\nfunction run_all(fns) {\n fns.forEach(run);\n}\nfunction is_function(thing) {\n return typeof thing === 'function';\n}\nfunction safe_not_equal(a, b) {\n return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');\n}\nlet src_url_equal_anchor;\nfunction src_url_equal(element_src, url) {\n if (!src_url_equal_anchor) {\n src_url_equal_anchor = document.createElement('a');\n }\n src_url_equal_anchor.href = url;\n return element_src === src_url_equal_anchor.href;\n}\nfunction not_equal(a, b) {\n return a != a ? b == b : a !== b;\n}\nfunction is_empty(obj) {\n return Object.keys(obj).length === 0;\n}\nfunction validate_store(store, name) {\n if (store != null && typeof store.subscribe !== 'function') {\n throw new Error(`'${name}' is not a store with a 'subscribe' method`);\n }\n}\nfunction subscribe(store, ...callbacks) {\n if (store == null) {\n return noop;\n }\n const unsub = store.subscribe(...callbacks);\n return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;\n}\nfunction get_store_value(store) {\n let value;\n subscribe(store, _ => value = _)();\n return value;\n}\nfunction component_subscribe(component, store, callback) {\n component.$$.on_destroy.push(subscribe(store, callback));\n}\nfunction create_slot(definition, ctx, $$scope, fn) {\n if (definition) {\n const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);\n return definition[0](slot_ctx);\n }\n}\nfunction get_slot_context(definition, ctx, $$scope, fn) {\n return definition[1] && fn\n ? assign($$scope.ctx.slice(), definition[1](fn(ctx)))\n : $$scope.ctx;\n}\nfunction get_slot_changes(definition, $$scope, dirty, fn) {\n if (definition[2] && fn) {\n const lets = definition[2](fn(dirty));\n if ($$scope.dirty === undefined) {\n return lets;\n }\n if (typeof lets === 'object') {\n const merged = [];\n const len = Math.max($$scope.dirty.length, lets.length);\n for (let i = 0; i < len; i += 1) {\n merged[i] = $$scope.dirty[i] | lets[i];\n }\n return merged;\n }\n return $$scope.dirty | lets;\n }\n return $$scope.dirty;\n}\nfunction update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn) {\n if (slot_changes) {\n const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n slot.p(slot_context, slot_changes);\n }\n}\nfunction update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) {\n const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn);\n update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn);\n}\nfunction get_all_dirty_from_scope($$scope) {\n if ($$scope.ctx.length > 32) {\n const dirty = [];\n const length = $$scope.ctx.length / 32;\n for (let i = 0; i < length; i++) {\n dirty[i] = -1;\n }\n return dirty;\n }\n return -1;\n}\nfunction exclude_internal_props(props) {\n const result = {};\n for (const k in props)\n if (k[0] !== '$')\n result[k] = props[k];\n return result;\n}\nfunction compute_rest_props(props, keys) {\n const rest = {};\n keys = new Set(keys);\n for (const k in props)\n if (!keys.has(k) && k[0] !== '$')\n rest[k] = props[k];\n return rest;\n}\nfunction compute_slots(slots) {\n const result = {};\n for (const key in slots) {\n result[key] = true;\n }\n return result;\n}\nfunction once(fn) {\n let ran = false;\n return function (...args) {\n if (ran)\n return;\n ran = true;\n fn.call(this, ...args);\n };\n}\nfunction null_to_empty(value) {\n return value == null ? '' : value;\n}\nfunction set_store_value(store, ret, value) {\n store.set(value);\n return ret;\n}\nconst has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);\nfunction action_destroyer(action_result) {\n return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;\n}\n\nconst is_client = typeof window !== 'undefined';\nlet now = is_client\n ? () => window.performance.now()\n : () => Date.now();\nlet raf = is_client ? cb => requestAnimationFrame(cb) : noop;\n// used internally for testing\nfunction set_now(fn) {\n now = fn;\n}\nfunction set_raf(fn) {\n raf = fn;\n}\n\nconst tasks = new Set();\nfunction run_tasks(now) {\n tasks.forEach(task => {\n if (!task.c(now)) {\n tasks.delete(task);\n task.f();\n }\n });\n if (tasks.size !== 0)\n raf(run_tasks);\n}\n/**\n * For testing purposes only!\n */\nfunction clear_loops() {\n tasks.clear();\n}\n/**\n * Creates a new task that runs on each raf frame\n * until it returns a falsy value or is aborted\n */\nfunction loop(callback) {\n let task;\n if (tasks.size === 0)\n raf(run_tasks);\n return {\n promise: new Promise(fulfill => {\n tasks.add(task = { c: callback, f: fulfill });\n }),\n abort() {\n tasks.delete(task);\n }\n };\n}\n\n// Track which nodes are claimed during hydration. Unclaimed nodes can then be removed from the DOM\n// at the end of hydration without touching the remaining nodes.\nlet is_hydrating = false;\nfunction start_hydrating() {\n is_hydrating = true;\n}\nfunction end_hydrating() {\n is_hydrating = false;\n}\nfunction upper_bound(low, high, key, value) {\n // Return first index of value larger than input value in the range [low, high)\n while (low < high) {\n const mid = low + ((high - low) >> 1);\n if (key(mid) <= value) {\n low = mid + 1;\n }\n else {\n high = mid;\n }\n }\n return low;\n}\nfunction init_hydrate(target) {\n if (target.hydrate_init)\n return;\n target.hydrate_init = true;\n // We know that all children have claim_order values since the unclaimed have been detached if target is not <head>\n let children = target.childNodes;\n // If target is <head>, there may be children without claim_order\n if (target.nodeName === 'HEAD') {\n const myChildren = [];\n for (let i = 0; i < children.length; i++) {\n const node = children[i];\n if (node.claim_order !== undefined) {\n myChildren.push(node);\n }\n }\n children = myChildren;\n }\n /*\n * Reorder claimed children optimally.\n * We can reorder claimed children optimally by finding the longest subsequence of\n * nodes that are already claimed in order and only moving the rest. The longest\n * subsequence subsequence of nodes that are claimed in order can be found by\n * computing the longest increasing subsequence of .claim_order values.\n *\n * This algorithm is optimal in generating the least amount of reorder operations\n * possible.\n *\n * Proof:\n * We know that, given a set of reordering operations, the nodes that do not move\n * always form an increasing subsequence, since they do not move among each other\n * meaning that they must be already ordered among each other. Thus, the maximal\n * set of nodes that do not move form a longest increasing subsequence.\n */\n // Compute longest increasing subsequence\n // m: subsequence length j => index k of smallest value that ends an increasing subsequence of length j\n const m = new Int32Array(children.length + 1);\n // Predecessor indices + 1\n const p = new Int32Array(children.length);\n m[0] = -1;\n let longest = 0;\n for (let i = 0; i < children.length; i++) {\n const current = children[i].claim_order;\n // Find the largest subsequence length such that it ends in a value less than our current value\n // upper_bound returns first greater value, so we subtract one\n // with fast path for when we are on the current longest subsequence\n const seqLen = ((longest > 0 && children[m[longest]].claim_order <= current) ? longest + 1 : upper_bound(1, longest, idx => children[m[idx]].claim_order, current)) - 1;\n p[i] = m[seqLen] + 1;\n const newLen = seqLen + 1;\n // We can guarantee that current is the smallest value. Otherwise, we would have generated a longer sequence.\n m[newLen] = i;\n longest = Math.max(newLen, longest);\n }\n // The longest increasing subsequence of nodes (initially reversed)\n const lis = [];\n // The rest of the nodes, nodes that will be moved\n const toMove = [];\n let last = children.length - 1;\n for (let cur = m[longest] + 1; cur != 0; cur = p[cur - 1]) {\n lis.push(children[cur - 1]);\n for (; last >= cur; last--) {\n toMove.push(children[last]);\n }\n last--;\n }\n for (; last >= 0; last--) {\n toMove.push(children[last]);\n }\n lis.reverse();\n // We sort the nodes being moved to guarantee that their insertion order matches the claim order\n toMove.sort((a, b) => a.claim_order - b.claim_order);\n // Finally, we move the nodes\n for (let i = 0, j = 0; i < toMove.length; i++) {\n while (j < lis.length && toMove[i].claim_order >= lis[j].claim_order) {\n j++;\n }\n const anchor = j < lis.length ? lis[j] : null;\n target.insertBefore(toMove[i], anchor);\n }\n}\nfunction append(target, node) {\n target.appendChild(node);\n}\nfunction append_styles(target, style_sheet_id, styles) {\n const append_styles_to = get_root_for_style(target);\n if (!append_styles_to.getElementById(style_sheet_id)) {\n const style = element('style');\n style.id = style_sheet_id;\n style.textContent = styles;\n append_stylesheet(append_styles_to, style);\n }\n}\nfunction get_root_for_style(node) {\n if (!node)\n return document;\n const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;\n if (root && root.host) {\n return root;\n }\n return node.ownerDocument;\n}\nfunction append_empty_stylesheet(node) {\n const style_element = element('style');\n append_stylesheet(get_root_for_style(node), style_element);\n return style_element;\n}\nfunction append_stylesheet(node, style) {\n append(node.head || node, style);\n}\nfunction append_hydration(target, node) {\n if (is_hydrating) {\n init_hydrate(target);\n if ((target.actual_end_child === undefined) || ((target.actual_end_child !== null) && (target.actual_end_child.parentElement !== target))) {\n target.actual_end_child = target.firstChild;\n }\n // Skip nodes of undefined ordering\n while ((target.actual_end_child !== null) && (target.actual_end_child.claim_order === undefined)) {\n target.actual_end_child = target.actual_end_child.nextSibling;\n }\n if (node !== target.actual_end_child) {\n // We only insert if the ordering of this node should be modified or the parent node is not target\n if (node.claim_order !== undefined || node.parentNode !== target) {\n target.insertBefore(node, target.actual_end_child);\n }\n }\n else {\n target.actual_end_child = node.nextSibling;\n }\n }\n else if (node.parentNode !== target || node.nextSibling !== null) {\n target.appendChild(node);\n }\n}\nfunction insert(target, node, anchor) {\n target.insertBefore(node, anchor || null);\n}\nfunction insert_hydration(target, node, anchor) {\n if (is_hydrating && !anchor) {\n append_hydration(target, node);\n }\n else if (node.parentNode !== target || node.nextSibling != anchor) {\n target.insertBefore(node, anchor || null);\n }\n}\nfunction detach(node) {\n node.parentNode.removeChild(node);\n}\nfunction destroy_each(iterations, detaching) {\n for (let i = 0; i < iterations.length; i += 1) {\n if (iterations[i])\n iterations[i].d(detaching);\n }\n}\nfunction element(name) {\n return document.createElement(name);\n}\nfunction element_is(name, is) {\n return document.createElement(name, { is });\n}\nfunction object_without_properties(obj, exclude) {\n const target = {};\n for (const k in obj) {\n if (has_prop(obj, k)\n // @ts-ignore\n && exclude.indexOf(k) === -1) {\n // @ts-ignore\n target[k] = obj[k];\n }\n }\n return target;\n}\nfunction svg_element(name) {\n return document.createElementNS('http://www.w3.org/2000/svg', name);\n}\nfunction text(data) {\n return document.createTextNode(data);\n}\nfunction space() {\n return text(' ');\n}\nfunction empty() {\n return text('');\n}\nfunction listen(node, event, handler, options) {\n node.addEventListener(event, handler, options);\n return () => node.removeEventListener(event, handler, options);\n}\nfunction prevent_default(fn) {\n return function (event) {\n event.preventDefault();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction stop_propagation(fn) {\n return function (event) {\n event.stopPropagation();\n // @ts-ignore\n return fn.call(this, event);\n };\n}\nfunction self(fn) {\n return function (event) {\n // @ts-ignore\n if (event.target === this)\n fn.call(this, event);\n };\n}\nfunction trusted(fn) {\n return function (event) {\n // @ts-ignore\n if (event.isTrusted)\n fn.call(this, event);\n };\n}\nfunction attr(node, attribute, value) {\n if (value == null)\n node.removeAttribute(attribute);\n else if (node.getAttribute(attribute) !== value)\n node.setAttribute(attribute, value);\n}\nfunction set_attributes(node, attributes) {\n // @ts-ignore\n const descriptors = Object.getOwnPropertyDescriptors(node.__proto__);\n for (const key in attributes) {\n if (attributes[key] == null) {\n node.removeAttribute(key);\n }\n else if (key === 'style') {\n node.style.cssText = attributes[key];\n }\n else if (key === '__value') {\n node.value = node[key] = attributes[key];\n }\n else if (descriptors[key] && descriptors[key].set) {\n node[key] = attributes[key];\n }\n else {\n attr(node, key, attributes[key]);\n }\n }\n}\nfunction set_svg_attributes(node, attributes) {\n for (const key in attributes) {\n attr(node, key, attributes[key]);\n }\n}\nfunction set_custom_element_data(node, prop, value) {\n if (prop in node) {\n node[prop] = typeof node[prop] === 'boolean' && value === '' ? true : value;\n }\n else {\n attr(node, prop, value);\n }\n}\nfunction xlink_attr(node, attribute, value) {\n node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);\n}\nfunction get_binding_group_value(group, __value, checked) {\n const value = new Set();\n for (let i = 0; i < group.length; i += 1) {\n if (group[i].checked)\n value.add(group[i].__value);\n }\n if (!checked) {\n value.delete(__value);\n }\n return Array.from(value);\n}\nfunction to_number(value) {\n return value === '' ? null : +value;\n}\nfunction time_ranges_to_array(ranges) {\n const array = [];\n for (let i = 0; i < ranges.length; i += 1) {\n array.push({ start: ranges.start(i), end: ranges.end(i) });\n }\n return array;\n}\nfunction children(element) {\n return Array.from(element.childNodes);\n}\nfunction init_claim_info(nodes) {\n if (nodes.claim_info === undefined) {\n nodes.claim_info = { last_index: 0, total_claimed: 0 };\n }\n}\nfunction claim_node(nodes, predicate, processNode, createNode, dontUpdateLastIndex = false) {\n // Try to find nodes in an order such that we lengthen the longest increasing subsequence\n init_claim_info(nodes);\n const resultNode = (() => {\n // We first try to find an element after the previous one\n for (let i = nodes.claim_info.last_index; i < nodes.length; i++) {\n const node = nodes[i];\n if (predicate(node)) {\n const replacement = processNode(node);\n if (replacement === undefined) {\n nodes.splice(i, 1);\n }\n else {\n nodes[i] = replacement;\n }\n if (!dontUpdateLastIndex) {\n nodes.claim_info.last_index = i;\n }\n return node;\n }\n }\n // Otherwise, we try to find one before\n // We iterate in reverse so that we don't go too far back\n for (let i = nodes.claim_info.last_index - 1; i >= 0; i--) {\n const node = nodes[i];\n if (predicate(node)) {\n const replacement = processNode(node);\n if (replacement === undefined) {\n nodes.splice(i, 1);\n }\n else {\n nodes[i] = replacement;\n }\n if (!dontUpdateLastIndex) {\n nodes.claim_info.last_index = i;\n }\n else if (replacement === undefined) {\n // Since we spliced before the last_index, we decrease it\n nodes.claim_info.last_index--;\n }\n return node;\n }\n }\n // If we can't find any matching node, we create a new one\n return createNode();\n })();\n resultNode.claim_order = nodes.claim_info.total_claimed;\n nodes.claim_info.total_claimed += 1;\n return resultNode;\n}\nfunction claim_element_base(nodes, name, attributes, create_element) {\n return claim_node(nodes, (node) => node.nodeName === name, (node) => {\n const remove = [];\n for (let j = 0; j < node.attributes.length; j++) {\n const attribute = node.attributes[j];\n if (!attributes[attribute.name]) {\n remove.push(attribute.name);\n }\n }\n remove.forEach(v => node.removeAttribute(v));\n return undefined;\n }, () => create_element(name));\n}\nfunction claim_element(nodes, name, attributes) {\n return claim_element_base(nodes, name, attributes, element);\n}\nfunction claim_svg_element(nodes, name, attributes) {\n return claim_element_base(nodes, name, attributes, svg_element);\n}\nfunction claim_text(nodes, data) {\n return claim_node(nodes, (node) => node.nodeType === 3, (node) => {\n const dataStr = '' + data;\n if (node.data.startsWith(dataStr)) {\n if (node.data.length !== dataStr.length) {\n return node.splitText(dataStr.length);\n }\n }\n else {\n node.data = dataStr;\n }\n }, () => text(data), true // Text nodes should not update last index since it is likely not worth it to eliminate an increasing subsequence of actual elements\n );\n}\nfunction claim_space(nodes) {\n return claim_text(nodes, ' ');\n}\nfunction find_comment(nodes, text, start) {\n for (let i = start; i < nodes.length; i += 1) {\n const node = nodes[i];\n if (node.nodeType === 8 /* comment node */ && node.textContent.trim() === text) {\n return i;\n }\n }\n return nodes.length;\n}\nfunction claim_html_tag(nodes) {\n // find html opening tag\n const start_index = find_comment(nodes, 'HTML_TAG_START', 0);\n const end_index = find_comment(nodes, 'HTML_TAG_END', start_index);\n if (start_index === end_index) {\n return new HtmlTagHydration();\n }\n init_claim_info(nodes);\n const html_tag_nodes = nodes.splice(start_index, end_index + 1);\n detach(html_tag_nodes[0]);\n detach(html_tag_nodes[html_tag_nodes.length - 1]);\n const claimed_nodes = html_tag_nodes.slice(1, html_tag_nodes.length - 1);\n for (const n of claimed_nodes) {\n n.claim_order = nodes.claim_info.total_claimed;\n nodes.claim_info.total_claimed += 1;\n }\n return new HtmlTagHydration(claimed_nodes);\n}\nfunction set_data(text, data) {\n data = '' + data;\n if (text.wholeText !== data)\n text.data = data;\n}\nfunction set_input_value(input, value) {\n input.value = value == null ? '' : value;\n}\nfunction set_input_type(input, type) {\n try {\n input.type = type;\n }\n catch (e) {\n // do nothing\n }\n}\nfunction set_style(node, key, value, important) {\n node.style.setProperty(key, value, important ? 'important' : '');\n}\nfunction select_option(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n if (option.__value === value) {\n option.selected = true;\n return;\n }\n }\n select.selectedIndex = -1; // no option should be selected\n}\nfunction select_options(select, value) {\n for (let i = 0; i < select.options.length; i += 1) {\n const option = select.options[i];\n option.selected = ~value.indexOf(option.__value);\n }\n}\nfunction select_value(select) {\n const selected_option = select.querySelector(':checked') || select.options[0];\n return selected_option && selected_option.__value;\n}\nfunction select_multiple_value(select) {\n return [].map.call(select.querySelectorAll(':checked'), option => option.__value);\n}\n// unfortunately this can't be a constant as that wouldn't be tree-shakeable\n// so we cache the result instead\nlet crossorigin;\nfunction is_crossorigin() {\n if (crossorigin === undefined) {\n crossorigin = false;\n try {\n if (typeof window !== 'undefined' && window.parent) {\n void window.parent.document;\n }\n }\n catch (error) {\n crossorigin = true;\n }\n }\n return crossorigin;\n}\nfunction add_resize_listener(node, fn) {\n const computed_style = getComputedStyle(node);\n if (computed_style.position === 'static') {\n node.style.position = 'relative';\n }\n const iframe = element('iframe');\n iframe.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ' +\n 'overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: -1;');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.tabIndex = -1;\n const crossorigin = is_crossorigin();\n let unsubscribe;\n if (crossorigin) {\n iframe.src = \"data:text/html,<script>onresize=function(){parent.postMessage(0,'*')}</script>\";\n unsubscribe = listen(window, 'message', (event) => {\n if (event.source === iframe.contentWindow)\n fn();\n });\n }\n else {\n iframe.src = 'about:blank';\n iframe.onload = () => {\n unsubscribe = listen(iframe.contentWindow, 'resize', fn);\n };\n }\n append(node, iframe);\n return () => {\n if (crossorigin) {\n unsubscribe();\n }\n else if (unsubscribe && iframe.contentWindow) {\n unsubscribe();\n }\n detach(iframe);\n };\n}\nfunction toggle_class(element, name, toggle) {\n element.classList[toggle ? 'add' : 'remove'](name);\n}\nfunction custom_event(type, detail, bubbles = false) {\n const e = document.createEvent('CustomEvent');\n e.initCustomEvent(type, bubbles, false, detail);\n return e;\n}\nfunction query_selector_all(selector, parent = document.body) {\n return Array.from(parent.querySelectorAll(selector));\n}\nclass HtmlTag {\n constructor() {\n this.e = this.n = null;\n }\n c(html) {\n this.h(html);\n }\n m(html, target, anchor = null) {\n if (!this.e) {\n this.e = element(target.nodeName);\n this.t = target;\n this.c(html);\n }\n this.i(anchor);\n }\n h(html) {\n this.e.innerHTML = html;\n this.n = Array.from(this.e.childNodes);\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert(this.t, this.n[i], anchor);\n }\n }\n p(html) {\n this.d();\n this.h(html);\n this.i(this.a);\n }\n d() {\n this.n.forEach(detach);\n }\n}\nclass HtmlTagHydration extends HtmlTag {\n constructor(claimed_nodes) {\n super();\n this.e = this.n = null;\n this.l = claimed_nodes;\n }\n c(html) {\n if (this.l) {\n this.n = this.l;\n }\n else {\n super.c(html);\n }\n }\n i(anchor) {\n for (let i = 0; i < this.n.length; i += 1) {\n insert_hydration(this.t, this.n[i], anchor);\n }\n }\n}\nfunction attribute_to_object(attributes) {\n const result = {};\n for (const attribute of attributes) {\n result[attribute.name] = attribute.value;\n }\n return result;\n}\nfunction get_custom_elements_slots(element) {\n const result = {};\n element.childNodes.forEach((node) => {\n result[node.slot || 'default'] = true;\n });\n return result;\n}\n\nconst active_docs = new Set();\nlet active = 0;\n// https://github.com/darkskyapp/string-hash/blob/master/index.js\nfunction hash(str) {\n let hash = 5381;\n let i = str.length;\n while (i--)\n hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n return hash >>> 0;\n}\nfunction create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {\n const step = 16.666 / duration;\n let keyframes = '{\\n';\n for (let p = 0; p <= 1; p += step) {\n const t = a + (b - a) * ease(p);\n keyframes += p * 100 + `%{${fn(t, 1 - t)}}\\n`;\n }\n const rule = keyframes + `100% {${fn(b, 1 - b)}}\\n}`;\n const name = `__svelte_${hash(rule)}_${uid}`;\n const doc = get_root_for_style(node);\n active_docs.add(doc);\n const stylesheet = doc.__svelte_stylesheet || (doc.__svelte_stylesheet = append_empty_stylesheet(node).sheet);\n const current_rules = doc.__svelte_rules || (doc.__svelte_rules = {});\n if (!current_rules[name]) {\n current_rules[name] = true;\n stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);\n }\n const animation = node.style.animation || '';\n node.style.animation = `${animation ? `${animation}, ` : ''}${name} ${duration}ms linear ${delay}ms 1 both`;\n active += 1;\n return name;\n}\nfunction delete_rule(node, name) {\n const previous = (node.style.animation || '').split(', ');\n const next = previous.filter(name\n ? anim => anim.indexOf(name) < 0 // remove specific animation\n : anim => anim.indexOf('__svelte') === -1 // remove all Svelte animations\n );\n const deleted = previous.length - next.length;\n if (deleted) {\n node.style.animation = next.join(', ');\n active -= deleted;\n if (!active)\n clear_rules();\n }\n}\nfunction clear_rules() {\n raf(() => {\n if (active)\n return;\n active_docs.forEach(doc => {\n const stylesheet = doc.__svelte_stylesheet;\n let i = stylesheet.cssRules.length;\n while (i--)\n stylesheet.deleteRule(i);\n doc.__svelte_rules = {};\n });\n active_docs.clear();\n });\n}\n\nfunction create_animation(node, from, fn, params) {\n if (!from)\n return noop;\n const to = node.getBoundingClientRect();\n if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom)\n return noop;\n const { delay = 0, duration = 300, easing = identity, \n // @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation?\n start: start_time = now() + delay, \n // @ts-ignore todo:\n end = start_time + duration, tick = noop, css } = fn(node, { from, to }, params);\n let running = true;\n let started = false;\n let name;\n function start() {\n if (css) {\n name = create_rule(node, 0, 1, duration, delay, easing, css);\n }\n if (!delay) {\n started = true;\n }\n }\n function stop() {\n if (css)\n delete_rule(node, name);\n running = false;\n }\n loop(now => {\n if (!started && now >= start_time) {\n started = true;\n }\n if (started && now >= end) {\n tick(1, 0);\n stop();\n }\n if (!running) {\n return false;\n }\n if (started) {\n const p = now - start_time;\n const t = 0 + 1 * easing(p / duration);\n tick(t, 1 - t);\n }\n return true;\n });\n start();\n tick(0, 1);\n return stop;\n}\nfunction fix_position(node) {\n const style = getComputedStyle(node);\n if (style.position !== 'absolute' && style.position !== 'fixed') {\n const { width, height } = style;\n const a = node.getBoundingClientRect();\n node.style.position = 'absolute';\n node.style.width = width;\n node.style.height = height;\n add_transform(node, a);\n }\n}\nfunction add_transform(node, a) {\n const b = node.getBoundingClientRect();\n if (a.left !== b.left || a.top !== b.top) {\n const style = getComputedStyle(node);\n const transform = style.transform === 'none' ? '' : style.transform;\n node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;\n }\n}\n\nlet current_component;\nfunction set_current_component(component) {\n current_component = component;\n}\nfunction get_current_component() {\n if (!current_component)\n throw new Error('Function called outside component initialization');\n return current_component;\n}\nfunction beforeUpdate(fn) {\n get_current_component().$$.before_update.push(fn);\n}\nfunction onMount(fn) {\n get_current_component().$$.on_mount.push(fn);\n}\nfunction afterUpdate(fn) {\n get_current_component().$$.after_update.push(fn);\n}\nfunction onDestroy(fn) {\n get_current_component().$$.on_destroy.push(fn);\n}\nfunction createEventDispatcher() {\n const component = get_current_component();\n return (type, detail) => {\n const callbacks = component.$$.callbacks[type];\n if (callbacks) {\n // TODO are there situations where events could be dispatched\n // in a server (non-DOM) environment?\n const event = custom_event(type, detail);\n callbacks.slice().forEach(fn => {\n fn.call(component, event);\n });\n }\n };\n}\nfunction setContext(key, context) {\n get_current_component().$$.context.set(key, context);\n}\nfunction getContext(key) {\n return get_current_component().$$.context.get(key);\n}\nfunction getAllContexts() {\n return get_current_component().$$.context;\n}\nfunction hasContext(key) {\n return get_current_component().$$.context.has(key);\n}\n// TODO figure out if we still want to support\n// shorthand events, or if we want to implement\n// a real bubbling mechanism\nfunction bubble(component, event) {\n const callbacks = component.$$.callbacks[event.type];\n if (callbacks) {\n // @ts-ignore\n callbacks.slice().forEach(fn => fn.call(this, event));\n }\n}\n\nconst dirty_components = [];\nconst intros = { enabled: false };\nconst binding_callbacks = [];\nconst render_callbacks = [];\nconst flush_callbacks = [];\nconst resolved_promise = Promise.resolve();\nlet update_scheduled = false;\nfunction schedule_update() {\n if (!update_scheduled) {\n update_scheduled = true;\n resolved_promise.then(flush);\n }\n}\nfunction tick() {\n schedule_update();\n return resolved_promise;\n}\nfunction add_render_callback(fn) {\n render_callbacks.push(fn);\n}\nfunction add_flush_callback(fn) {\n flush_callbacks.push(fn);\n}\nlet flushing = false;\nconst seen_callbacks = new Set();\nfunction flush() {\n if (flushing)\n return;\n flushing = true;\n do {\n // first, call beforeUpdate functions\n // and update components\n for (let i = 0; i < dirty_components.length; i += 1) {\n const component = dirty_components[i];\n set_current_component(component);\n update(component.$$);\n }\n set_current_component(null);\n dirty_components.length = 0;\n while (binding_callbacks.length)\n binding_callbacks.pop()();\n // then, once components are updated, call\n // afterUpdate functions. This may cause\n // subsequent updates...\n for (let i = 0; i < render_callbacks.length; i += 1) {\n const callback = render_callbacks[i];\n if (!seen_callbacks.has(callback)) {\n // ...so guard against infinite loops\n seen_callbacks.add(callback);\n callback();\n }\n }\n render_callbacks.length = 0;\n } while (dirty_components.length);\n while (flush_callbacks.length) {\n flush_callbacks.pop()();\n }\n update_scheduled = false;\n flushing = false;\n seen_callbacks.clear();\n}\nfunction update($$) {\n if ($$.fragment !== null) {\n $$.update();\n run_all($$.before_update);\n const dirty = $$.dirty;\n $$.dirty = [-1];\n $$.fragment && $$.fragment.p($$.ctx, dirty);\n $$.after_update.forEach(add_render_callback);\n }\n}\n\nlet promise;\nfunction wait() {\n if (!promise) {\n promise = Promise.resolve();\n promise.then(() => {\n promise = null;\n });\n }\n return promise;\n}\nfunction dispatch(node, direction, kind) {\n node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));\n}\nconst outroing = new Set();\nlet outros;\nfunction group_outros() {\n outros = {\n r: 0,\n c: [],\n p: outros // parent group\n };\n}\nfunction check_outros() {\n if (!outros.r) {\n run_all(outros.c);\n }\n outros = outros.p;\n}\nfunction transition_in(block, local) {\n if (block && block.i) {\n outroing.delete(block);\n block.i(local);\n }\n}\nfunction transition_out(block, local, detach, callback) {\n if (block && block.o) {\n if (outroing.has(block))\n return;\n outroing.add(block);\n outros.c.push(() => {\n outroing.delete(block);\n if (callback) {\n if (detach)\n block.d(1);\n callback();\n }\n });\n block.o(local);\n }\n}\nconst null_transition = { duration: 0 };\nfunction create_in_transition(node, fn, params) {\n let config = fn(node, params);\n let running = false;\n let animation_name;\n let task;\n let uid = 0;\n function cleanup() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++);\n tick(0, 1);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n if (task)\n task.abort();\n running = true;\n add_render_callback(() => dispatch(node, true, 'start'));\n task = loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(1, 0);\n dispatch(node, true, 'end');\n cleanup();\n return running = false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(t, 1 - t);\n }\n }\n return running;\n });\n }\n let started = false;\n return {\n start() {\n if (started)\n return;\n started = true;\n delete_rule(node);\n if (is_function(config)) {\n config = config();\n wait().then(go);\n }\n else {\n go();\n }\n },\n invalidate() {\n started = false;\n },\n end() {\n if (running) {\n cleanup();\n running = false;\n }\n }\n };\n}\nfunction create_out_transition(node, fn, params) {\n let config = fn(node, params);\n let running = true;\n let animation_name;\n const group = outros;\n group.r += 1;\n function go() {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n if (css)\n animation_name = create_rule(node, 1, 0, duration, delay, easing, css);\n const start_time = now() + delay;\n const end_time = start_time + duration;\n add_render_callback(() => dispatch(node, false, 'start'));\n loop(now => {\n if (running) {\n if (now >= end_time) {\n tick(0, 1);\n dispatch(node, false, 'end');\n if (!--group.r) {\n // this will result in `end()` being called,\n // so we don't need to clean up here\n run_all(group.c);\n }\n return false;\n }\n if (now >= start_time) {\n const t = easing((now - start_time) / duration);\n tick(1 - t, t);\n }\n }\n return running;\n });\n }\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go();\n });\n }\n else {\n go();\n }\n return {\n end(reset) {\n if (reset && config.tick) {\n config.tick(1, 0);\n }\n if (running) {\n if (animation_name)\n delete_rule(node, animation_name);\n running = false;\n }\n }\n };\n}\nfunction create_bidirectional_transition(node, fn, params, intro) {\n let config = fn(node, params);\n let t = intro ? 0 : 1;\n let running_program = null;\n let pending_program = null;\n let animation_name = null;\n function clear_animation() {\n if (animation_name)\n delete_rule(node, animation_name);\n }\n function init(program, duration) {\n const d = (program.b - t);\n duration *= Math.abs(d);\n return {\n a: t,\n b: program.b,\n d,\n duration,\n start: program.start,\n end: program.start + duration,\n group: program.group\n };\n }\n function go(b) {\n const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition;\n const program = {\n start: now() + delay,\n b\n };\n if (!b) {\n // @ts-ignore todo: improve typings\n program.group = outros;\n outros.r += 1;\n }\n if (running_program || pending_program) {\n pending_program = program;\n }\n else {\n // if this is an intro, and there's a delay, we need to do\n // an initial tick and/or apply CSS animation immediately\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, b, duration, delay, easing, css);\n }\n if (b)\n tick(0, 1);\n running_program = init(program, duration);\n add_render_callback(() => dispatch(node, b, 'start'));\n loop(now => {\n if (pending_program && now > pending_program.start) {\n running_program = init(pending_program, duration);\n pending_program = null;\n dispatch(node, running_program.b, 'start');\n if (css) {\n clear_animation();\n animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);\n }\n }\n if (running_program) {\n if (now >= running_program.end) {\n tick(t = running_program.b, 1 - t);\n dispatch(node, running_program.b, 'end');\n if (!pending_program) {\n // we're done\n if (running_program.b) {\n // intro — we can tidy up immediately\n clear_animation();\n }\n else {\n // outro — needs to be coordinated\n if (!--running_program.group.r)\n run_all(running_program.group.c);\n }\n }\n running_program = null;\n }\n else if (now >= running_program.start) {\n const p = now - running_program.start;\n t = running_program.a + running_program.d * easing(p / running_program.duration);\n tick(t, 1 - t);\n }\n }\n return !!(running_program || pending_program);\n });\n }\n }\n return {\n run(b) {\n if (is_function(config)) {\n wait().then(() => {\n // @ts-ignore\n config = config();\n go(b);\n });\n }\n else {\n go(b);\n }\n },\n end() {\n clear_animation();\n running_program = pending_program = null;\n }\n };\n}\n\nfunction handle_promise(promise, info) {\n const token = info.token = {};\n function update(type, index, key, value) {\n if (info.token !== token)\n return;\n info.resolved = value;\n let child_ctx = info.ctx;\n if (key !== undefined) {\n child_ctx = child_ctx.slice();\n child_ctx[key] = value;\n }\n const block = type && (info.current = type)(child_ctx);\n let needs_flush = false;\n if (info.block) {\n if (info.blocks) {\n info.blocks.forEach((block, i) => {\n if (i !== index && block) {\n group_outros();\n transition_out(block, 1, 1, () => {\n if (info.blocks[i] === block) {\n info.blocks[i] = null;\n }\n });\n check_outros();\n }\n });\n }\n else {\n info.block.d(1);\n }\n block.c();\n transition_in(block, 1);\n block.m(info.mount(), info.anchor);\n needs_flush = true;\n }\n info.block = block;\n if (info.blocks)\n info.blocks[index] = block;\n if (needs_flush) {\n flush();\n }\n }\n if (is_promise(promise)) {\n const current_component = get_current_component();\n promise.then(value => {\n set_current_component(current_component);\n update(info.then, 1, info.value, value);\n set_current_component(null);\n }, error => {\n set_current_component(current_component);\n update(info.catch, 2, info.error, error);\n set_current_component(null);\n if (!info.hasCatch) {\n throw error;\n }\n });\n // if we previously had a then/catch block, destroy it\n if (info.current !== info.pending) {\n update(info.pending, 0);\n return true;\n }\n }\n else {\n if (info.current !== info.then) {\n update(info.then, 1, info.value, promise);\n return true;\n }\n info.resolved = promise;\n }\n}\nfunction update_await_block_branch(info, ctx, dirty) {\n const child_ctx = ctx.slice();\n const { resolved } = info;\n if (info.current === info.then) {\n child_ctx[info.value] = resolved;\n }\n if (info.current === info.catch) {\n child_ctx[info.error] = resolved;\n }\n info.block.p(child_ctx, dirty);\n}\n\nconst globals = (typeof window !== 'undefined'\n ? window\n : typeof globalThis !== 'undefined'\n ? globalThis\n : global);\n\nfunction destroy_block(block, lookup) {\n block.d(1);\n lookup.delete(block.key);\n}\nfunction outro_and_destroy_block(block, lookup) {\n transition_out(block, 1, 1, () => {\n lookup.delete(block.key);\n });\n}\nfunction fix_and_destroy_block(block, lookup) {\n block.f();\n destroy_block(block, lookup);\n}\nfunction fix_and_outro_and_destroy_block(block, lookup) {\n block.f();\n outro_and_destroy_block(block, lookup);\n}\nfunction update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) {\n let o = old_blocks.length;\n let n = list.length;\n let i = o;\n const old_indexes = {};\n while (i--)\n old_indexes[old_blocks[i].key] = i;\n const new_blocks = [];\n const new_lookup = new Map();\n const deltas = new Map();\n i = n;\n while (i--) {\n const child_ctx = get_context(ctx, list, i);\n const key = get_key(child_ctx);\n let block = lookup.get(key);\n if (!block) {\n block = create_each_block(key, child_ctx);\n block.c();\n }\n else if (dynamic) {\n block.p(child_ctx, dirty);\n }\n new_lookup.set(key, new_blocks[i] = block);\n if (key in old_indexes)\n deltas.set(key, Math.abs(i - old_indexes[key]));\n }\n const will_move = new Set();\n const did_move = new Set();\n function insert(block) {\n transition_in(block, 1);\n block.m(node, next);\n lookup.set(block.key, block);\n next = block.first;\n n--;\n }\n while (o && n) {\n const new_block = new_blocks[n - 1];\n const old_block = old_blocks[o - 1];\n const new_key = new_block.key;\n const old_key = old_block.key;\n if (new_block === old_block) {\n // do nothing\n next = new_block.first;\n o--;\n n--;\n }\n else if (!new_lookup.has(old_key)) {\n // remove old block\n destroy(old_block, lookup);\n o--;\n }\n else if (!lookup.has(new_key) || will_move.has(new_key)) {\n insert(new_block);\n }\n else if (did_move.has(old_key)) {\n o--;\n }\n else if (deltas.get(new_key) > deltas.get(old_key)) {\n did_move.add(new_key);\n insert(new_block);\n }\n else {\n will_move.add(old_key);\n o--;\n }\n }\n while (o--) {\n const old_block = old_blocks[o];\n if (!new_lookup.has(old_block.key))\n destroy(old_block, lookup);\n }\n while (n)\n insert(new_blocks[n - 1]);\n return new_blocks;\n}\nfunction validate_each_keys(ctx, list, get_context, get_key) {\n const keys = new Set();\n for (let i = 0; i < list.length; i++) {\n const key = get_key(get_context(ctx, list, i));\n if (keys.has(key)) {\n throw new Error('Cannot have duplicate keys in a keyed each');\n }\n keys.add(key);\n }\n}\n\nfunction get_spread_update(levels, updates) {\n const update = {};\n const to_null_out = {};\n const accounted_for = { $$scope: 1 };\n let i = levels.length;\n while (i--) {\n const o = levels[i];\n const n = updates[i];\n if (n) {\n for (const key in o) {\n if (!(key in n))\n to_null_out[key] = 1;\n }\n for (const key in n) {\n if (!accounted_for[key]) {\n update[key] = n[key];\n accounted_for[key] = 1;\n }\n }\n levels[i] = n;\n }\n else {\n for (const key in o) {\n accounted_for[key] = 1;\n }\n }\n }\n for (const key in to_null_out) {\n if (!(key in update))\n update[key] = undefined;\n }\n return update;\n}\nfunction get_spread_object(spread_props) {\n return typeof spread_props === 'object' && spread_props !== null ? spread_props : {};\n}\n\n// source: https://html.spec.whatwg.org/multipage/indices.html\nconst boolean_attributes = new Set([\n 'allowfullscreen',\n 'allowpaymentrequest',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'ismap',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected'\n]);\n\nconst invalid_attribute_name_character = /[\\s'\">/=\\u{FDD0}-\\u{FDEF}\\u{FFFE}\\u{FFFF}\\u{1FFFE}\\u{1FFFF}\\u{2FFFE}\\u{2FFFF}\\u{3FFFE}\\u{3FFFF}\\u{4FFFE}\\u{4FFFF}\\u{5FFFE}\\u{5FFFF}\\u{6FFFE}\\u{6FFFF}\\u{7FFFE}\\u{7FFFF}\\u{8FFFE}\\u{8FFFF}\\u{9FFFE}\\u{9FFFF}\\u{AFFFE}\\u{AFFFF}\\u{BFFFE}\\u{BFFFF}\\u{CFFFE}\\u{CFFFF}\\u{DFFFE}\\u{DFFFF}\\u{EFFFE}\\u{EFFFF}\\u{FFFFE}\\u{FFFFF}\\u{10FFFE}\\u{10FFFF}]/u;\n// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n// https://infra.spec.whatwg.org/#noncharacter\nfunction spread(args, classes_to_add) {\n const attributes = Object.assign({}, ...args);\n if (classes_to_add) {\n if (attributes.class == null) {\n attributes.class = classes_to_add;\n }\n else {\n attributes.class += ' ' + classes_to_add;\n }\n }\n let str = '';\n Object.keys(attributes).forEach(name => {\n if (invalid_attribute_name_character.test(name))\n return;\n const value = attributes[name];\n if (value === true)\n str += ' ' + name;\n else if (boolean_attributes.has(name.toLowerCase())) {\n if (value)\n str += ' ' + name;\n }\n else if (value != null) {\n str += ` ${name}=\"${value}\"`;\n }\n });\n return str;\n}\nconst escaped = {\n '\"': '&quot;',\n \"'\": '&#39;',\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;'\n};\nfunction escape(html) {\n return String(html).replace(/[\"'&<>]/g, match => escaped[match]);\n}\nfunction escape_attribute_value(value) {\n return typeof value === 'string' ? escape(value) : value;\n}\nfunction escape_object(obj) {\n const result = {};\n for (const key in obj) {\n result[key] = escape_attribute_value(obj[key]);\n }\n return result;\n}\nfunction each(items, fn) {\n let str = '';\n for (let i = 0; i < items.length; i += 1) {\n str += fn(items[i], i);\n }\n return str;\n}\nconst missing_component = {\n $$render: () => ''\n};\nfunction validate_component(component, name) {\n if (!component || !component.$$render) {\n if (name === 'svelte:component')\n name += ' this={...}';\n throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`);\n }\n return component;\n}\nfunction debug(file, line, column, values) {\n console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console\n console.log(values); // eslint-disable-line no-console\n return '';\n}\nlet on_destroy;\nfunction create_ssr_component(fn) {\n function $$render(result, props, bindings, slots, context) {\n const parent_component = current_component;\n const $$ = {\n on_destroy,\n context: new Map(parent_component ? parent_component.$$.context : context || []),\n // these will be immediately discarded\n on_mount: [],\n before_update: [],\n after_update: [],\n callbacks: blank_object()\n };\n set_current_component({ $$ });\n const html = fn(result, props, bindings, slots);\n set_current_component(parent_component);\n return html;\n }\n return {\n render: (props = {}, { $$slots = {}, context = new Map() } = {}) => {\n on_destroy = [];\n const result = { title: '', head: '', css: new Set() };\n const html = $$render(result, props, {}, $$slots, context);\n run_all(on_destroy);\n return {\n html,\n css: {\n code: Array.from(result.css).map(css => css.code).join('\\n'),\n map: null // TODO\n },\n head: result.title + result.head\n };\n },\n $$render\n };\n}\nfunction add_attribute(name, value, boolean) {\n if (value == null || (boolean && !value))\n return '';\n return ` ${name}${value === true ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `\"${value}\"`}`}`;\n}\nfunction add_classes(classes) {\n return classes ? ` class=\"${classes}\"` : '';\n}\n\nfunction bind(component, name, callback) {\n const index = component.$$.props[name];\n if (index !== undefined) {\n component.$$.bound[index] = callback;\n callback(component.$$.ctx[index]);\n }\n}\nfunction create_component(block) {\n block && block.c();\n}\nfunction claim_component(block, parent_nodes) {\n block && block.l(parent_nodes);\n}\nfunction mount_component(component, target, anchor, customElement) {\n const { fragment, on_mount, on_destroy, after_update } = component.$$;\n fragment && fragment.m(target, anchor);\n if (!customElement) {\n // onMount happens before the initial afterUpdate\n add_render_callback(() => {\n const new_on_destroy = on_mount.map(run).filter(is_function);\n if (on_destroy) {\n on_destroy.push(...new_on_destroy);\n }\n else {\n // Edge case - component was destroyed immediately,\n // most likely as a result of a binding initialising\n run_all(new_on_destroy);\n }\n component.$$.on_mount = [];\n });\n }\n after_update.forEach(add_render_callback);\n}\nfunction destroy_component(component, detaching) {\n const $$ = component.$$;\n if ($$.fragment !== null) {\n run_all($$.on_destroy);\n $$.fragment && $$.fragment.d(detaching);\n // TODO null out other refs, including component.$$ (but need to\n // preserve final state?)\n $$.on_destroy = $$.fragment = null;\n $$.ctx = [];\n }\n}\nfunction make_dirty(component, i) {\n if (component.$$.dirty[0] === -1) {\n dirty_components.push(component);\n schedule_update();\n component.$$.dirty.fill(0);\n }\n component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));\n}\nfunction init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) {\n const parent_component = current_component;\n set_current_component(component);\n const $$ = component.$$ = {\n fragment: null,\n ctx: null,\n // state\n props,\n update: noop,\n not_equal,\n bound: blank_object(),\n // lifecycle\n on_mount: [],\n on_destroy: [],\n on_disconnect: [],\n before_update: [],\n after_update: [],\n context: new Map(parent_component ? parent_component.$$.context : options.context || []),\n // everything else\n callbacks: blank_object(),\n dirty,\n skip_bound: false,\n root: options.target || parent_component.$$.root\n };\n append_styles && append_styles($$.root);\n let ready = false;\n $$.ctx = instance\n ? instance(component, options.props || {}, (i, ret, ...rest) => {\n const value = rest.length ? rest[0] : ret;\n if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {\n if (!$$.skip_bound && $$.bound[i])\n $$.bound[i](value);\n if (ready)\n make_dirty(component, i);\n }\n return ret;\n })\n : [];\n $$.update();\n ready = true;\n run_all($$.before_update);\n // `false` as a special case of no DOM component\n $$.fragment = create_fragment ? create_fragment($$.ctx) : false;\n if (options.target) {\n if (options.hydrate) {\n start_hydrating();\n const nodes = children(options.target);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.l(nodes);\n nodes.forEach(detach);\n }\n else {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n $$.fragment && $$.fragment.c();\n }\n if (options.intro)\n transition_in(component.$$.fragment);\n mount_component(component, options.target, options.anchor, options.customElement);\n end_hydrating();\n flush();\n }\n set_current_component(parent_component);\n}\nlet SvelteElement;\nif (typeof HTMLElement === 'function') {\n SvelteElement = class extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n }\n connectedCallback() {\n const { on_mount } = this.$$;\n this.$$.on_disconnect = on_mount.map(run).filter(is_function);\n // @ts-ignore todo: improve typings\n for (const key in this.$$.slotted) {\n // @ts-ignore todo: improve typings\n this.appendChild(this.$$.slotted[key]);\n }\n }\n attributeChangedCallback(attr, _oldValue, newValue) {\n this[attr] = newValue;\n }\n disconnectedCallback() {\n run_all(this.$$.on_disconnect);\n }\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n // TODO should this delegate to addEventListener?\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n };\n}\n/**\n * Base class for Svelte components. Used when dev=false.\n */\nclass SvelteComponent {\n $destroy() {\n destroy_component(this, 1);\n this.$destroy = noop;\n }\n $on(type, callback) {\n const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));\n callbacks.push(callback);\n return () => {\n const index = callbacks.indexOf(callback);\n if (index !== -1)\n callbacks.splice(index, 1);\n };\n }\n $set($$props) {\n if (this.$$set && !is_empty($$props)) {\n this.$$.skip_bound = true;\n this.$$set($$props);\n this.$$.skip_bound = false;\n }\n }\n}\n\nfunction dispatch_dev(type, detail) {\n document.dispatchEvent(custom_event(type, Object.assign({ version: '3.42.4' }, detail), true));\n}\nfunction append_dev(target, node) {\n dispatch_dev('SvelteDOMInsert', { target, node });\n append(target, node);\n}\nfunction append_hydration_dev(target, node) {\n dispatch_dev('SvelteDOMInsert', { target, node });\n append_hydration(target, node);\n}\nfunction insert_dev(target, node, anchor) {\n dispatch_dev('SvelteDOMInsert', { target, node, anchor });\n insert(target, node, anchor);\n}\nfunction insert_hydration_dev(target, node, anchor) {\n dispatch_dev('SvelteDOMInsert', { target, node, anchor });\n insert_hydration(target, node, anchor);\n}\nfunction detach_dev(node) {\n dispatch_dev('SvelteDOMRemove', { node });\n detach(node);\n}\nfunction detach_between_dev(before, after) {\n while (before.nextSibling && before.nextSibling !== after) {\n detach_dev(before.nextSibling);\n }\n}\nfunction detach_before_dev(after) {\n while (after.previousSibling) {\n detach_dev(after.previousSibling);\n }\n}\nfunction detach_after_dev(before) {\n while (before.nextSibling) {\n detach_dev(before.nextSibling);\n }\n}\nfunction listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) {\n const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : [];\n if (has_prevent_default)\n modifiers.push('preventDefault');\n if (has_stop_propagation)\n modifiers.push('stopPropagation');\n dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers });\n const dispose = listen(node, event, handler, options);\n return () => {\n dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers });\n dispose();\n };\n}\nfunction attr_dev(node, attribute, value) {\n attr(node, attribute, value);\n if (value == null)\n dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute });\n else\n dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value });\n}\nfunction prop_dev(node, property, value) {\n node[property] = value;\n dispatch_dev('SvelteDOMSetProperty', { node, property, value });\n}\nfunction dataset_dev(node, property, value) {\n node.dataset[property] = value;\n dispatch_dev('SvelteDOMSetDataset', { node, property, value });\n}\nfunction set_data_dev(text, data) {\n data = '' + data;\n if (text.wholeText === data)\n return;\n dispatch_dev('SvelteDOMSetData', { node: text, data });\n text.data = data;\n}\nfunction validate_each_argument(arg) {\n if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {\n let msg = '{#each} only iterates over array-like objects.';\n if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {\n msg += ' You can use a spread to convert this iterable into an array.';\n }\n throw new Error(msg);\n }\n}\nfunction validate_slots(name, slot, keys) {\n for (const slot_key of Object.keys(slot)) {\n if (!~keys.indexOf(slot_key)) {\n console.warn(`<${name}> received an unexpected slot \"${slot_key}\".`);\n }\n }\n}\n/**\n * Base class for Svelte components with some minor dev-enhancements. Used when dev=true.\n */\nclass SvelteComponentDev extends SvelteComponent {\n constructor(options) {\n if (!options || (!options.target && !options.$$inline)) {\n throw new Error(\"'target' is a required option\");\n }\n super();\n }\n $destroy() {\n super.$destroy();\n this.$destroy = () => {\n console.warn('Component was already destroyed'); // eslint-disable-line no-console\n };\n }\n $capture_state() { }\n $inject_state() { }\n}\n/**\n * Base class to create strongly typed Svelte components.\n * This only exists for typing purposes and should be used in `.d.ts` files.\n *\n * ### Example:\n *\n * You have component library on npm called `component-library`, from which\n * you export a component called `MyComponent`. For Svelte+TypeScript users,\n * you want to provide typings. Therefore you create a `index.d.ts`:\n * ```ts\n * import { SvelteComponentTyped } from \"svelte\";\n * export class MyComponent extends SvelteComponentTyped<{foo: string}> {}\n * ```\n * Typing this makes it possible for IDEs like VS Code with the Svelte extension\n * to provide intellisense and to use the component like this in a Svelte file\n * with TypeScript:\n * ```svelte\n * <script lang=\"ts\">\n * \timport { MyComponent } from \"component-library\";\n * </script>\n * <MyComponent foo={'bar'} />\n * ```\n *\n * #### Why not make this part of `SvelteComponent(Dev)`?\n * Because\n * ```ts\n * class ASubclassOfSvelteComponent extends SvelteComponent<{foo: string}> {}\n * const component: typeof SvelteComponent = ASubclassOfSvelteComponent;\n * ```\n * will throw a type error, so we need to separate the more strictly typed class.\n */\nclass SvelteComponentTyped extends SvelteComponentDev {\n constructor(options) {\n super(options);\n }\n}\nfunction loop_guard(timeout) {\n const start = Date.now();\n return () => {\n if (Date.now() - start > timeout) {\n throw new Error('Infinite loop detected');\n }\n };\n}\n\nexport { HtmlTag, HtmlTagHydration, SvelteComponent, SvelteComponentDev, SvelteComponentTyped, SvelteElement, action_destroyer, add_attribute, add_classes, add_flush_callback, add_location, add_render_callback, add_resize_listener, add_transform, afterUpdate, append, append_dev, append_empty_stylesheet, append_hydration, append_hydration_dev, append_styles, assign, attr, attr_dev, attribute_to_object, beforeUpdate, bind, binding_callbacks, blank_object, bubble, check_outros, children, claim_component, claim_element, claim_html_tag, claim_space, claim_svg_element, claim_text, clear_loops, component_subscribe, compute_rest_props, compute_slots, createEventDispatcher, create_animation, create_bidirectional_transition, create_component, create_in_transition, create_out_transition, create_slot, create_ssr_component, current_component, custom_event, dataset_dev, debug, destroy_block, destroy_component, destroy_each, detach, detach_after_dev, detach_before_dev, detach_between_dev, detach_dev, dirty_components, dispatch_dev, each, element, element_is, empty, end_hydrating, escape, escape_attribute_value, escape_object, escaped, exclude_internal_props, fix_and_destroy_block, fix_and_outro_and_destroy_block, fix_position, flush, getAllContexts, getContext, get_all_dirty_from_scope, get_binding_group_value, get_current_component, get_custom_elements_slots, get_root_for_style, get_slot_changes, get_spread_object, get_spread_update, get_store_value, globals, group_outros, handle_promise, hasContext, has_prop, identity, init, insert, insert_dev, insert_hydration, insert_hydration_dev, intros, invalid_attribute_name_character, is_client, is_crossorigin, is_empty, is_function, is_promise, listen, listen_dev, loop, loop_guard, missing_component, mount_component, noop, not_equal, now, null_to_empty, object_without_properties, onDestroy, onMount, once, outro_and_destroy_block, prevent_default, prop_dev, query_selector_all, raf, run, run_all, safe_not_equal, schedule_update, select_multiple_value, select_option, select_options, select_value, self, setContext, set_attributes, set_current_component, set_custom_element_data, set_data, set_data_dev, set_input_type, set_input_value, set_now, set_raf, set_store_value, set_style, set_svg_attributes, space, spread, src_url_equal, start_hydrating, stop_propagation, subscribe, svg_element, text, tick, time_ranges_to_array, to_number, toggle_class, transition_in, transition_out, trusted, update_await_block_branch, update_keyed_each, update_slot, update_slot_base, validate_component, validate_each_argument, validate_each_keys, validate_slots, validate_store, xlink_attr };\n","<script lang=\"ts\">\n import { isEmpty } from \"lodash\";\n\n export let cursorName: string;\n export let tagName: string;\n export let backgroundColor: string;\n export let appliance: string;\n export let x: number;\n export let y: number;\n export let src: string;\n export let visible: boolean;\n export let avatar: string;\n export let theme: string;\n export let color: string;\n export let cursorTagBackgroundColor: string;\n export let opacity: number;\n\n $: hasName = !isEmpty(cursorName);\n $: hasTagName = !isEmpty(tagName);\n $: hasAvatar = !isEmpty(avatar);\n $: display = visible ? \"initial\" : \"none\";\n\n const computedAvatarStyle = () => {\n return Object.entries({\n width: (hasName ? 19 : 28) + \"px\",\n height: (hasName ? 19 : 28) + \"px\",\n position: hasName ? \"initial\" : \"absolute\",\n \"border-color\": hasName ? \"white\" : backgroundColor,\n \"margin-right\": (hasName ? 4 : 0) + \"px\",\n })\n .map(([key, v]) => `${key}: ${v}`)\n .join(\";\");\n };\n</script>\n\n<div\n class=\"netless-window-manager-cursor-mid\"\n style=\"transform: translateX({x}px) translateY({y}px);display: {display}\"\n>\n <div class=\"netless-window-manager-cursor-name\">\n <div\n class={theme}\n style=\"background-color: {backgroundColor};color: {color};opacity: {opacity}\"\n >\n {#if hasAvatar}\n <img\n class=\"netless-window-manager-cursor-selector-avatar\"\n style={computedAvatarStyle()}\n src={avatar}\n alt=\"avatar\"\n />\n {/if}\n <span style=\"overflow: hidden;white-space: nowrap;text-overflow: ellipsis;max-width: 80px\">{cursorName}</span>\n {#if hasTagName}\n <span class=\"netless-window-manager-cursor-tag-name\" style=\"background-color: {cursorTagBackgroundColor}\">\n {tagName}\n </span>\n {/if}\n </div>\n </div>\n <div class=\"cursor-image-wrapper\">\n <img class=\"netless-window-manager-cursor-{appliance}-image\" {src} alt={appliance} />\n </div>\n</div>\n","import { ApplianceNames } from \"white-web-sdk\";\nimport pencil from \"../image/pencil-cursor.png\";\nimport selector from \"../image/selector-cursor.png\";\nimport eraser from \"../image/eraser-cursor.png\";\nimport shape from \"../image/shape-cursor.svg\";\nimport text from \"../image/text-cursor.svg\";\n\nexport const ApplianceMap: {\n [key: string]: string;\n} = {\n [ApplianceNames.pencil]: pencil,\n [ApplianceNames.selector]: selector,\n [ApplianceNames.eraser]: eraser,\n [ApplianceNames.shape]: shape,\n [ApplianceNames.text]: text,\n};\n","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNDBweCIgaGVpZ2h0PSI0MHB4IiB2aWV3Qm94PSIwIDAgNDAgNDAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDYwLjEgKDg4MTMzKSAtIGh0dHBzOi8vc2tldGNoLmNvbSAtLT4KICAgIDx0aXRsZT5zaGFwZS1jdXJzb3I8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz4KICAgICAgICA8cGF0aCBkPSJNMjAsMjEuNSBDMjAuMjQ1NDU5OSwyMS41IDIwLjQ0OTYwODQsMjEuNjc2ODc1MiAyMC40OTE5NDQzLDIxLjkxMDEyNDQgTDIwLjUsMjIgTDIwLjUsMjcgQzIwLjUsMjcuMjc2MTQyNCAyMC4yNzYxNDI0LDI3LjUgMjAsMjcuNSBDMTkuNzU0NTQwMSwyNy41IDE5LjU1MDM5MTYsMjcuMzIzMTI0OCAxOS41MDgwNTU3LDI3LjA4OTg3NTYgTDE5LjUsMjcgTDE5LjUsMjIgQzE5LjUsMjEuNzIzODU3NiAxOS43MjM4NTc2LDIxLjUgMjAsMjEuNSBaIE0yNywxOS41IEMyNy4yNzYxNDI0LDE5LjUgMjcuNSwxOS43MjM4NTc2IDI3LjUsMjAgQzI3LjUsMjAuMjQ1NDU5OSAyNy4zMjMxMjQ4LDIwLjQ0OTYwODQgMjcuMDg5ODc1NiwyMC40OTE5NDQzIEwyNywyMC41IEwyMiwyMC41IEMyMS43MjM4NTc2LDIwLjUgMjEuNSwyMC4yNzYxNDI0IDIxLjUsMjAgQzIxLjUsMTkuNzU0NTQwMSAyMS42NzY4NzUyLDE5LjU1MDM5MTYgMjEuOTEwMTI0NCwxOS41MDgwNTU3IEwyMiwxOS41IEwyNywxOS41IFogTTE4LDE5LjUgQzE4LjI3NjE0MjQsMTkuNSAxOC41LDE5LjcyMzg1NzYgMTguNSwyMCBDMTguNSwyMC4yNDU0NTk5IDE4LjMyMzEyNDgsMjAuNDQ5NjA4NCAxOC4wODk4NzU2LDIwLjQ5MTk0NDMgTDE4LDIwLjUgTDEzLDIwLjUgQzEyLjcyMzg1NzYsMjAuNSAxMi41LDIwLjI3NjE0MjQgMTIuNSwyMCBDMTIuNSwxOS43NTQ1NDAxIDEyLjY3Njg3NTIsMTkuNTUwMzkxNiAxMi45MTAxMjQ0LDE5LjUwODA1NTcgTDEzLDE5LjUgTDE4LDE5LjUgWiBNMjAsMTIuNSBDMjAuMjQ1NDU5OSwxMi41IDIwLjQ0OTYwODQsMTIuNjc2ODc1MiAyMC40OTE5NDQzLDEyLjkxMDEyNDQgTDIwLjUsMTMgTDIwLjUsMTggQzIwLjUsMTguMjc2MTQyNCAyMC4yNzYxNDI0LDE4LjUgMjAsMTguNSBDMTkuNzU0NTQwMSwxOC41IDE5LjU1MDM5MTYsMTguMzIzMTI0OCAxOS41MDgwNTU3LDE4LjA4OTg3NTYgTDE5LjUsMTggTDE5LjUsMTMgQzE5LjUsMTIuNzIzODU3NiAxOS43MjM4NTc2LDEyLjUgMjAsMTIuNSBaIiBpZD0icGF0aC0xIj48L3BhdGg+CiAgICAgICAgPGZpbHRlciB4PSItNjQuNiUiIHk9Ii01OS41JSIgd2lkdGg9IjIyOS4zJSIgaGVpZ2h0PSIyNDYuMSUiIGZpbHRlclVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgaWQ9ImZpbHRlci0yIj4KICAgICAgICAgICAgPGZlTW9ycGhvbG9neSByYWRpdXM9IjEiIG9wZXJhdG9yPSJkaWxhdGUiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dTcHJlYWRPdXRlcjEiPjwvZmVNb3JwaG9sb2d5PgogICAgICAgICAgICA8ZmVPZmZzZXQgZHg9IjAiIGR5PSIyIiBpbj0ic2hhZG93U3ByZWFkT3V0ZXIxIiByZXN1bHQ9InNoYWRvd09mZnNldE91dGVyMSI+PC9mZU9mZnNldD4KICAgICAgICAgICAgPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMyIgaW49InNoYWRvd09mZnNldE91dGVyMSIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIj48L2ZlR2F1c3NpYW5CbHVyPgogICAgICAgICAgICA8ZmVDb21wb3NpdGUgaW49InNoYWRvd0JsdXJPdXRlcjEiIGluMj0iU291cmNlQWxwaGEiIG9wZXJhdG9yPSJvdXQiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUNvbXBvc2l0ZT4KICAgICAgICAgICAgPGZlQ29sb3JNYXRyaXggdmFsdWVzPSIwIDAgMCAwIDAgICAwIDAgMCAwIDAgICAwIDAgMCAwIDAgIDAgMCAwIDAuMTYgMCIgdHlwZT0ibWF0cml4IiBpbj0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUNvbG9yTWF0cml4PgogICAgICAgIDwvZmlsdGVyPgogICAgPC9kZWZzPgogICAgPGcgaWQ9Iumhtemdoi00IiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iV2hpdGVib2FyZC1HdWlkZWxpbmVzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzQ0LjAwMDAwMCwgLTc1MS4wMDAwMDApIj4KICAgICAgICAgICAgPGcgaWQ9InNoYXBlLWN1cnNvciIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzQ0LjAwMDAwMCwgNzUxLjAwMDAwMCkiPgogICAgICAgICAgICAgICAgPHJlY3QgaWQ9IuefqeW9ouWkh+S7vS00NCIgZmlsbD0iI0ZGRkZGRiIgb3BhY2l0eT0iMC4wMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIiByeD0iMiI+PC9yZWN0PgogICAgICAgICAgICAgICAgPGcgaWQ9IuW9oueKtue7k+WQiCIgZmlsbC1ydWxlPSJub256ZXJvIj4KICAgICAgICAgICAgICAgICAgICA8dXNlIGZpbGw9ImJsYWNrIiBmaWxsLW9wYWNpdHk9IjEiIGZpbHRlcj0idXJsKCNmaWx0ZXItMikiIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZT0iI0ZGRkZGRiIgc3Ryb2tlLXdpZHRoPSIxIiBkPSJNMjAsMjEgQzIwLjQ4NTQxMDMsMjEgMjAuODk4MDg1LDIxLjM0Nzk5OTMgMjAuOTg5OTQ3OSwyMS44NjU0ODc3IEwyMSwyMiBMMjEsMjcgQzIxLDI3LjU1MjI4NDcgMjAuNTUyMjg0NywyOCAyMCwyOCBDMTkuNTE0NTg5NywyOCAxOS4xMDE5MTUsMjcuNjUyMDAwNyAxOS4wMTAwNTIxLDI3LjEzNDUxMjMgTDE5LDI3IEwxOSwyMiBDMTksMjEuNDQ3NzE1MyAxOS40NDc3MTUzLDIxIDIwLDIxIFogTTI3LDE5IEMyNy41NTIyODQ3LDE5IDI4LDE5LjQ0NzcxNTMgMjgsMjAgQzI4LDIwLjQ4NTQxMDMgMjcuNjUyMDAwNywyMC44OTgwODUgMjcuMTM0NTEyMywyMC45ODk5NDc5IEwyNywyMSBMMjIsMjEgQzIxLjQ0NzcxNTMsMjEgMjEsMjAuNTUyMjg0NyAyMSwyMCBDMjEsMTkuNTE0NTg5NyAyMS4zNDc5OTkzLDE5LjEwMTkxNSAyMS44NjU0ODc3LDE5LjAxMDA1MjEgTDIyLDE5IEwyNywxOSBaIE0xOCwxOSBDMTguNTUyMjg0NywxOSAxOSwxOS40NDc3MTUzIDE5LDIwIEMxOSwyMC40ODU0MTAzIDE4LjY1MjAwMDcsMjAuODk4MDg1IDE4LjEzNDUxMjMsMjAuOTg5OTQ3OSBMMTgsMjEgTDEzLDIxIEMxMi40NDc3MTUzLDIxIDEyLDIwLjU1MjI4NDcgMTIsMjAgQzEyLDE5LjUxNDU4OTcgMTIuMzQ3OTk5MywxOS4xMDE5MTUgMTIuODY1NDg3NywxOS4wMTAwNTIxIEwxMywxOSBMMTgsMTkgWiBNMjAsMTIgQzIwLjQ4NTQxMDMsMTIgMjAuODk4MDg1LDEyLjM0Nzk5OTMgMjAuOTg5OTQ3OSwxMi44NjU0ODc3IEwyMSwxMyBMMjEsMTggQzIxLDE4LjU1MjI4NDcgMjAuNTUyMjg0NywxOSAyMCwxOSBDMTkuNTE0NTg5NywxOSAxOS4xMDE5MTUsMTguNjUyMDAwNyAxOS4wMTAwNTIxLDE4LjEzNDUxMjMgTDE5LDE4IEwxOSwxMyBDMTksMTIuNDQ3NzE1MyAxOS40NDc3MTUzLDEyIDIwLDEyIFoiIGZpbGw9IiMyMTIzMjQiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PC9wYXRoPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPHJlY3QgaWQ9IuefqeW9oiIgZmlsbD0iI0ZGRkZGRiIgeD0iMTguNSIgeT0iMTciIHdpZHRoPSIzIiBoZWlnaHQ9IjYiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDxyZWN0IGlkPSLnn6nlvaIiIGZpbGw9IiNGRkZGRkYiIHg9IjE3IiB5PSIxOC41IiB3aWR0aD0iNiIgaGVpZ2h0PSIzIj48L3JlY3Q+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjAsMjEuNSBDMjAuMjQ1NDU5OSwyMS41IDIwLjQ0OTYwODQsMjEuNjc2ODc1MiAyMC40OTE5NDQzLDIxLjkxMDEyNDQgTDIwLjUsMjIgTDIwLjUsMjcgQzIwLjUsMjcuMjc2MTQyNCAyMC4yNzYxNDI0LDI3LjUgMjAsMjcuNSBDMTkuNzU0NTQwMSwyNy41IDE5LjU1MDM5MTYsMjcuMzIzMTI0OCAxOS41MDgwNTU3LDI3LjA4OTg3NTYgTDE5LjUsMjcgTDE5LjUsMjIgQzE5LjUsMjEuNzIzODU3NiAxOS43MjM4NTc2LDIxLjUgMjAsMjEuNSBaIE0yNywxOS41IEMyNy4yNzYxNDI0LDE5LjUgMjcuNSwxOS43MjM4NTc2IDI3LjUsMjAgQzI3LjUsMjAuMjQ1NDU5OSAyNy4zMjMxMjQ4LDIwLjQ0OTYwODQgMjcuMDg5ODc1NiwyMC40OTE5NDQzIEwyNywyMC41IEwyMiwyMC41IEMyMS43MjM4NTc2LDIwLjUgMjEuNSwyMC4yNzYxNDI0IDIxLjUsMjAgQzIxLjUsMTkuNzU0NTQwMSAyMS42NzY4NzUyLDE5LjU1MDM5MTYgMjEuOTEwMTI0NCwxOS41MDgwNTU3IEwyMiwxOS41IEwyNywxOS41IFogTTE4LDE5LjUgQzE4LjI3NjE0MjQsMTkuNSAxOC41LDE5LjcyMzg1NzYgMTguNSwyMCBDMTguNSwyMC4yNDU0NTk5IDE4LjMyMzEyNDgsMjAuNDQ5NjA4NCAxOC4wODk4NzU2LDIwLjQ5MTk0NDMgTDE4LDIwLjUgTDEzLDIwLjUgQzEyLjcyMzg1NzYsMjAuNSAxMi41LDIwLjI3NjE0MjQgMTIuNSwyMCBDMTIuNSwxOS43NTQ1NDAxIDEyLjY3Njg3NTIsMTkuNTUwMzkxNiAxMi45MTAxMjQ0LDE5LjUwODA1NTcgTDEzLDE5LjUgTDE4LDE5LjUgWiBNMjAsMTIuNSBDMjAuMjQ1NDU5OSwxMi41IDIwLjQ0OTYwODQsMTIuNjc2ODc1MiAyMC40OTE5NDQzLDEyLjkxMDEyNDQgTDIwLjUsMTMgTDIwLjUsMTggQzIwLjUsMTguMjc2MTQyNCAyMC4yNzYxNDI0LDE4LjUgMjAsMTguNSBDMTkuNzU0NTQwMSwxOC41IDE5LjU1MDM5MTYsMTguMzIzMTI0OCAxOS41MDgwNTU3LDE4LjA4OTg3NTYgTDE5LjUsMTggTDE5LjUsMTMgQzE5LjUsMTIuNzIzODU3NiAxOS43MjM4NTc2LDEyLjUgMjAsMTIuNSBaIiBpZD0i5b2i54q257uT5ZCIIiBmaWxsPSIjMjEyMzI0IiBmaWxsLXJ1bGU9Im5vbnplcm8iPjwvcGF0aD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+\"","export default \"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNDdweCIgaGVpZ2h0PSI0MHB4IiB2aWV3Qm94PSIwIDAgNDcgNDAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDYwLjEgKDg4MTMzKSAtIGh0dHBzOi8vc2tldGNoLmNvbSAtLT4KICAgIDx0aXRsZT50ZXh0LWN1cnNvcjwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPgogICAgICAgIDxwYXRoIGQ9Ik0xNiwyNi41IEMxNS43MjM4NTc2LDI2LjUgMTUuNSwyNi4yNzYxNDI0IDE1LjUsMjYgQzE1LjUsMjUuNzU0NTQwMSAxNS42NzY4NzUyLDI1LjU1MDM5MTYgMTUuOTEwMTI0NCwyNS41MDgwNTU3IEwxNiwyNS41IEwxOS41LDI1LjUgTDE5LjUsMTQuNSBMMTYsMTQuNSBDMTUuNzIzODU3NiwxNC41IDE1LjUsMTQuMjc2MTQyNCAxNS41LDE0IEMxNS41LDEzLjc1NDU0MDEgMTUuNjc2ODc1MiwxMy41NTAzOTE2IDE1LjkxMDEyNDQsMTMuNTA4MDU1NyBMMTYsMTMuNSBMMjQsMTMuNSBDMjQuMjc2MTQyNCwxMy41IDI0LjUsMTMuNzIzODU3NiAyNC41LDE0IEMyNC41LDE0LjI0NTQ1OTkgMjQuMzIzMTI0OCwxNC40NDk2MDg0IDI0LjA4OTg3NTYsMTQuNDkxOTQ0MyBMMjQsMTQuNSBMMjAuNSwxNC41IEwyMC41LDI1LjUgTDI0LDI1LjUgQzI0LjI3NjE0MjQsMjUuNSAyNC41LDI1LjcyMzg1NzYgMjQuNSwyNiBDMjQuNSwyNi4yNDU0NTk5IDI0LjMyMzEyNDgsMjYuNDQ5NjA4NCAyNC4wODk4NzU2LDI2LjQ5MTk0NDMgTDI0LDI2LjUgTDE2LDI2LjUgWiIgaWQ9InBhdGgtMSI+PC9wYXRoPgogICAgICAgIDxmaWx0ZXIgeD0iLTI4NC4wJSIgeT0iLTgxLjUlIiB3aWR0aD0iNjY4LjElIiBoZWlnaHQ9IjI5My45JSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0iZmlsdGVyLTIiPgogICAgICAgICAgICA8ZmVNb3JwaG9sb2d5IHJhZGl1cz0iMSIgb3BlcmF0b3I9ImRpbGF0ZSIgaW49IlNvdXJjZUFscGhhIiByZXN1bHQ9InNoYWRvd1NwcmVhZE91dGVyMSI+PC9mZU1vcnBob2xvZ3k+CiAgICAgICAgICAgIDxmZU9mZnNldCBkeD0iMCIgZHk9IjIiIGluPSJzaGFkb3dTcHJlYWRPdXRlcjEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIj48L2ZlT2Zmc2V0PgogICAgICAgICAgICA8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIzIiBpbj0ic2hhZG93T2Zmc2V0T3V0ZXIxIiByZXN1bHQ9InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVHYXVzc2lhbkJsdXI+CiAgICAgICAgICAgIDxmZUNvbXBvc2l0ZSBpbj0ic2hhZG93Qmx1ck91dGVyMSIgaW4yPSJTb3VyY2VBbHBoYSIgb3BlcmF0b3I9Im91dCIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIj48L2ZlQ29tcG9zaXRlPgogICAgICAgICAgICA8ZmVDb2xvck1hdHJpeCB2YWx1ZXM9IjAgMCAwIDAgMCAgIDAgMCAwIDAgMCAgIDAgMCAwIDAgMCAgMCAwIDAgMC4xNiAwIiB0eXBlPSJtYXRyaXgiIGluPSJzaGFkb3dCbHVyT3V0ZXIxIj48L2ZlQ29sb3JNYXRyaXg+CiAgICAgICAgPC9maWx0ZXI+CiAgICA8L2RlZnM+CiAgICA8ZyBpZD0i6aG16Z2iLTQiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJXaGl0ZWJvYXJkLUd1aWRlbGluZXMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zODguMDAwMDAwLCAtNjcyLjAwMDAwMCkiPgogICAgICAgICAgICA8ZyBpZD0idGV4dC1jdXJzb3IiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM5Mi4wMDAwMDAsIDY3Mi4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxyZWN0IGlkPSLnn6nlvaLlpIfku70tNDAiIGZpbGw9IiNGRkZGRkYiIG9wYWNpdHk9IjAuMDEiIHg9IjAiIHk9IjAiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcng9IjIiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDxnIGlkPSLlvaLnirbnu5PlkIgiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgICAgICAgICAgPHVzZSBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIxIiBmaWx0ZXI9InVybCgjZmlsdGVyLTIpIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBzdHJva2U9IiNGRkZGRkYiIHN0cm9rZS13aWR0aD0iMSIgZD0iTTE5LDI1IEwxOSwxNSBMMTYsMTUgQzE1LjQ0NzcxNTMsMTUgMTUsMTQuNTUyMjg0NyAxNSwxNCBDMTUsMTMuNTE0NTg5NyAxNS4zNDc5OTkzLDEzLjEwMTkxNSAxNS44NjU0ODc3LDEzLjAxMDA1MjEgTDE2LDEzIEwyNCwxMyBDMjQuNTUyMjg0NywxMyAyNSwxMy40NDc3MTUzIDI1LDE0IEMyNSwxNC40ODU0MTAzIDI0LjY1MjAwMDcsMTQuODk4MDg1IDI0LjEzNDUxMjMsMTQuOTg5OTQ3OSBMMjQsMTUgTDIxLDE1IEwyMSwyNSBMMjQsMjUgQzI0LjU1MjI4NDcsMjUgMjUsMjUuNDQ3NzE1MyAyNSwyNiBDMjUsMjYuNDg1NDEwMyAyNC42NTIwMDA3LDI2Ljg5ODA4NSAyNC4xMzQ1MTIzLDI2Ljk4OTk0NzkgTDI0LDI3IEwxNiwyNyBDMTUuNDQ3NzE1MywyNyAxNSwyNi41NTIyODQ3IDE1LDI2IEMxNSwyNS41MTQ1ODk3IDE1LjM0Nzk5OTMsMjUuMTAxOTE1IDE1Ljg2NTQ4NzcsMjUuMDEwMDUyMSBMMTYsMjUgTDE5LDI1IFoiIGZpbGw9IiMyMTIzMjQiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PC9wYXRoPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=\"","import App from './Cursor.svelte';\nimport { ApplianceMap } from './icons';\nimport { ApplianceNames } from 'white-web-sdk';\nimport { CursorState } from '../constants';\nimport { Fields } from '../AttributesDelegate';\nimport { get, omit } from 'lodash';\nimport type { Position } from '../AttributesDelegate';\nimport type { RoomMember } from \"white-web-sdk\";\nimport type { CursorManager } from \"./index\";\nimport type { SvelteComponent } from \"svelte\";\nimport { Base } from '../Base';\nimport type { AppManager } from '../AppManager';\n\nexport type Payload = {\n [key: string]: any\n}\n\n\nexport class Cursor extends Base {\n private member?: RoomMember;\n private timer?: number;\n private component?: SvelteComponent;\n\n constructor(\n manager: AppManager,\n addCursorChangeListener: (uid: string, callback: (position: Position, state: CursorState) => void) => void,\n private cursors: any,\n private memberId: string,\n private cursorManager: CursorManager,\n private wrapper?: HTMLElement,\n ) {\n super(manager);\n this.setMember();\n this.createCursor();\n addCursorChangeListener(this.memberId, this.onCursorChange);\n this.autoHidden();\n }\n\n private onCursorChange = (position: Position, state: CursorState) => {\n if (position.type === \"main\") {\n const rect = this.cursorManager.wrapperRect;\n if (this.component && rect) {\n this.autoHidden();\n this.moveCursor(position, rect, this.manager.mainView);\n }\n } else {\n const focusView = this.cursorManager.focusView;\n // TODO 可以存一个当前 focusView 的 Rect 这样只有 focus 切换的时候才调用 getBoundingClientRect\n const viewRect = focusView?.divElement?.getBoundingClientRect();\n const viewCamera = focusView?.camera;\n if (focusView && viewRect && viewCamera && this.component) {\n this.autoHidden();\n this.moveCursor(position, viewRect, focusView);\n }\n }\n if (state && state === CursorState.Leave) {\n this.hide();\n }\n }\n\n private moveCursor(cursor: Position, rect: DOMRect, view: any) {\n const { x, y, type } = cursor;\n const point = view?.screen.convertPointToScreen(x, y);\n if (point) {\n let translateX = point.x - 2;\n let translateY = point.y - 18;\n if (type === \"app\") {\n const wrapperRect = this.cursorManager.wrapperRect;\n if (wrapperRect) {\n translateX = translateX + rect.x - wrapperRect.x;\n translateY = translateY + rect.y - wrapperRect.y;\n }\n }\n if (point.x < 0 || point.x > rect.width || point.y < 0 || point.y > rect.height) {\n this.component?.$set({ visible: false, x: translateX, y: translateY });\n } else {\n this.component?.$set({ visible: true, x: translateX, y: translateY });\n }\n }\n }\n\n public get memberApplianceName() {\n return this.member?.memberState?.currentApplianceName;\n }\n\n public get memberColor() {\n const rgb = this.member?.memberState?.strokeColor.join(\",\");\n return `rgb(${rgb})`;\n }\n\n private get payload(): Payload | undefined {\n return this.member?.payload;\n }\n\n public get memberCursorName() {\n return this.payload?.nickName || this.payload?.cursorName || this.memberId;\n }\n\n private get memberTheme() {\n if (this.payload?.theme) {\n return \"netless-window-manager-cursor-inner-mellow\";\n } else {\n return \"netless-window-manager-cursor-inner\";\n }\n }\n\n private get memberCursorTextColor() {\n return this.payload?.cursorTextColor || \"#FFFFFF\";\n }\n\n private get memberCursorTagBackgroundColor() {\n return this.payload?.cursorTagBackgroundColor || this.memberColor;\n }\n\n private get memberAvatar() {\n return this.payload?.avatar;\n }\n\n private get memberOpacity() {\n if (!this.memberCursorName && !this.memberAvatar) {\n return 0;\n } else {\n return 1;\n }\n }\n\n public get cursorState(): CursorState | undefined {\n return get(this.cursors, [this.memberId, Fields.CursorState]);\n }\n\n public get cursorPosition(): Position | undefined {\n return get(this.cursors, [this.memberId, Fields.Position]);\n }\n\n private autoHidden() {\n if (this.timer) {\n clearTimeout(this.timer);\n }\n this.timer = window.setTimeout(() => {\n this.hide();\n this.store.updateCursorState(this.memberId, CursorState.Leave);\n }, 1000 * 10); // 10 秒钟自动隐藏\n }\n\n private async createCursor() {\n if (this.member && this.wrapper) {\n this.component = new App({\n target: this.wrapper,\n props: this.initProps(),\n });\n }\n }\n\n private initProps() {\n return {\n x: 0,\n y: 0,\n appliance: this.memberApplianceName,\n avatar: this.memberAvatar,\n src: this.getIcon(),\n visible: false,\n backgroundColor: this.memberColor,\n cursorName: this.memberCursorName,\n theme: this.memberTheme,\n color: this.memberCursorTextColor,\n cursorTagBackgroundColor: this.memberCursorTagBackgroundColor,\n opacity: this.memberOpacity,\n };\n }\n\n private getIcon() {\n if (this.member) {\n const applianceSrc = ApplianceMap[this.memberApplianceName || ApplianceNames.shape];\n return applianceSrc || ApplianceMap[ApplianceNames.shape];\n }\n }\n\n public setMember() {\n this.member = this.context.findMemberByUid(this.memberId);\n this.updateComponent();\n }\n\n private updateComponent() {\n this.component?.$set(omit(this.initProps(), [\"x\", \"y\"]));\n }\n\n public destroy() {\n if (this.component) {\n this.component.$destroy();\n }\n this.manager.refresher?.remove(this.memberId);\n this.cursorManager.cursorInstances.delete(this.memberId);\n }\n\n public hide() {\n if (this.component) {\n this.component.$set({ visible: false });\n }\n }\n}\n","import { autorun } from \"white-web-sdk\";\nimport { Base } from \"../Base\";\nimport { compact, debounce, get, uniq } from \"lodash\";\nimport { Cursor } from \"./Cursor\";\nimport { CursorState } from \"../constants\";\nimport { emitter, WindowManager } from \"../index\";\nimport { Fields } from \"../AttributesDelegate\";\nimport { onObjectInserted } from \"../Utils/Reactive\";\nimport { SideEffectManager } from \"side-effect-manager\";\nimport type { PositionType, Position } from \"../AttributesDelegate\";\nimport type { Point, RoomMember, View } from \"white-web-sdk\";\nimport type { AppManager } from \"../AppManager\";\n\nexport type EventType = {\n type: PositionType;\n id?: string;\n};\n\nexport type MoveCursorParams = {\n uid: string;\n x: number;\n y: number;\n};\nexport class CursorManager extends Base {\n public containerRect?: DOMRect;\n public wrapperRect?: DOMRect;\n public cursorInstances: Map<string, Cursor> = new Map();\n public roomMembers?: readonly RoomMember[];\n private mainViewElement?: HTMLDivElement;\n private sideEffectManager = new SideEffectManager();\n\n constructor(private appManager: AppManager) {\n super(appManager);\n this.roomMembers = this.appManager.room?.state.roomMembers;\n const wrapper = WindowManager.wrapper;\n if (wrapper) {\n this.setupWrapper(wrapper);\n }\n emitter.on(\"onReconnected\", () => {\n this.onReconnect();\n });\n }\n\n public setupWrapper(wrapper: HTMLElement) {\n if (this.manager.refresher?.hasReactor(\"cursors\")) {\n this.destroy();\n }\n this.sideEffectManager.add(() => {\n wrapper.addEventListener(\"pointerenter\", this.mouseMoveListener);\n wrapper.addEventListener(\"pointermove\", this.mouseMoveListener);\n wrapper.addEventListener(\"pointerleave\", this.mouseLeaveListener);\n return () => {\n wrapper.removeEventListener(\"pointerenter\", this.mouseMoveListener);\n wrapper.removeEventListener(\"pointermove\", this.mouseMoveListener);\n wrapper.removeEventListener(\"pointerleave\", this.mouseLeaveListener);\n };\n });\n\n this.initCursorAttributes();\n this.wrapperRect = wrapper.getBoundingClientRect();\n this.startReaction(wrapper);\n }\n\n public setMainViewDivElement(div: HTMLDivElement) {\n this.mainViewElement = div;\n }\n\n private startReaction(wrapper: HTMLElement) {\n this.manager.refresher?.add(\"cursors\", () => {\n return onObjectInserted(this.cursors, () => {\n this.handleRoomMembersChange(wrapper);\n });\n });\n }\n\n private getUids = (members: readonly RoomMember[] | undefined) => {\n return compact(uniq(members?.map(member => member.payload?.uid)));\n };\n\n private handleRoomMembersChange = debounce((wrapper: HTMLElement) => {\n const uids = this.getUids(this.roomMembers);\n const cursors = Object.keys(this.cursors);\n if (uids?.length) {\n cursors.map(uid => {\n if (uids.includes(uid) && !this.cursorInstances.has(uid)) {\n if (uid === this.context.uid) {\n return;\n }\n const component = new Cursor(\n this.appManager,\n this.addCursorChangeListener,\n this.cursors,\n uid,\n this,\n wrapper\n );\n this.cursorInstances.set(uid, component);\n }\n });\n }\n }, 100);\n\n public get cursors() {\n return this.manager.attributes?.[Fields.Cursors];\n }\n\n public get boxState() {\n return this.store.getBoxState();\n }\n\n public get focusView() {\n return this.appManager.focusApp?.view;\n }\n\n private mouseMoveListener = debounce((event: MouseEvent) => {\n this.updateCursor(this.getType(event), event.clientX, event.clientY);\n }, 5);\n\n private updateCursor(event: EventType, clientX: number, clientY: number) {\n if (this.wrapperRect && this.manager.canOperate) {\n const view = event.type === \"main\" ? this.appManager.mainView : this.focusView;\n const point = this.getPoint(view, clientX, clientY);\n if (point) {\n this.setNormalCursorState();\n this.store.updateCursor(this.context.uid, {\n x: point.x,\n y: point.y,\n ...event,\n });\n }\n }\n }\n\n private getPoint = (\n view: View | undefined,\n clientX: number,\n clientY: number\n ): Point | undefined => {\n const rect = view?.divElement?.getBoundingClientRect();\n if (rect) {\n const point = view?.convertToPointInWorld({\n x: clientX - rect.x,\n y: clientY - rect.y,\n });\n return point;\n }\n };\n\n /**\n * 因为窗口内框在不同分辨率下的大小不一样,所以这里通过来鼠标事件的 target 来判断是在主白板还是在 APP 中\n */\n private getType = (event: MouseEvent | Touch): EventType => {\n const target = event.target as HTMLElement;\n const focusApp = this.appManager.focusApp;\n switch (target.parentElement) {\n case this.mainViewElement: {\n return { type: \"main\" };\n }\n case focusApp?.view?.divElement: {\n return { type: \"app\" };\n }\n default: {\n return { type: \"main\" };\n }\n }\n };\n\n private initCursorAttributes() {\n this.store.updateCursor(this.context.uid, {\n x: 0,\n y: 0,\n type: \"main\",\n });\n this.store.updateCursorState(this.context.uid, CursorState.Leave);\n }\n\n private setNormalCursorState() {\n const cursorState = this.store.getCursorState(this.context.uid);\n if (cursorState !== CursorState.Normal) {\n this.store.updateCursorState(this.context.uid, CursorState.Normal);\n }\n }\n\n private mouseLeaveListener = () => {\n this.hideCursor(this.context.uid);\n this.store.updateCursorState(this.context.uid, CursorState.Leave);\n };\n\n public updateContainerRect() {\n this.containerRect = WindowManager.container?.getBoundingClientRect();\n this.wrapperRect = WindowManager.wrapper?.getBoundingClientRect();\n }\n\n public setRoomMembers(members: readonly RoomMember[]) {\n this.roomMembers = members;\n this.cursorInstances.forEach(cursor => {\n cursor.setMember();\n });\n if (WindowManager.wrapper) {\n this.handleRoomMembersChange(WindowManager.wrapper);\n }\n }\n\n public deleteCursor(uid: string) {\n this.store.cleanCursor(uid);\n const cursor = this.cursorInstances.get(uid);\n if (cursor) {\n cursor.destroy();\n }\n }\n\n public hideCursor(uid: string) {\n const cursor = this.cursorInstances.get(uid);\n if (cursor) {\n cursor.hide();\n }\n }\n\n public cleanMemberAttributes(members: readonly RoomMember[]) {\n const uids = this.getUids(members);\n const needDeleteIds: string[] = [];\n const cursors = Object.keys(this.cursors);\n cursors.map(cursorId => {\n const index = uids.findIndex(id => id === cursorId);\n if (index === -1) {\n needDeleteIds.push(cursorId);\n }\n });\n needDeleteIds.forEach(uid => {\n this.deleteCursor(uid);\n });\n }\n\n public onReconnect() {\n if (this.cursorInstances.size) {\n this.cursorInstances.forEach(cursor => cursor.destroy());\n this.cursorInstances.clear();\n }\n this.roomMembers = this.appManager.room?.state.roomMembers;\n if (WindowManager.wrapper) {\n this.handleRoomMembersChange(WindowManager.wrapper);\n }\n }\n\n public addCursorChangeListener = (\n uid: string,\n callback: (position: Position, state: CursorState) => void\n ) => {\n this.manager.refresher?.add(uid, () => {\n const disposer = autorun(() => {\n const position = get(this.cursors, [uid, Fields.Position]);\n const state = get(this.cursors, [uid, Fields.CursorState]);\n if (position) {\n callback(position, state);\n }\n });\n return disposer;\n });\n };\n\n public destroy() {\n this.sideEffectManager.flushAll();\n if (this.cursorInstances.size) {\n this.cursorInstances.forEach(cursor => {\n cursor.destroy();\n });\n this.cursorInstances.clear();\n }\n this.manager.refresher?.remove(\"cursors\");\n }\n}\n","import AppDocsViewer from \"@netless/app-docs-viewer\";\nimport AppMediaPlayer, { setOptions } from \"@netless/app-media-player\";\nimport { WindowManager } from \"./index\";\nimport \"@netless/app-docs-viewer/dist/style.css\";\n\nexport const setupBuiltin = () => {\n if (WindowManager.debug) {\n setOptions({ verbose: true });\n }\n\n WindowManager.register({\n kind: AppDocsViewer.kind,\n src: AppDocsViewer,\n });\n WindowManager.register({\n kind: AppMediaPlayer.kind,\n src: AppMediaPlayer,\n });\n};\n\nexport const BuiltinApps = {\n DocsViewer: AppDocsViewer.kind as string,\n MediaPlayer: AppMediaPlayer.kind as string,\n};\n","import Emittery from \"emittery\";\nimport pRetry from \"p-retry\";\nimport { AppManager } from \"./AppManager\";\nimport { appRegister } from \"./Register\";\nimport { ContainerResizeObserver } from \"./ContainerResizeObserver\";\nimport { createBoxManager } from \"./BoxManager\";\nimport { CursorManager } from \"./Cursor\";\nimport { DEFAULT_CONTAINER_RATIO, Events, REQUIRE_VERSION } from \"./constants\";\nimport { Fields } from \"./AttributesDelegate\";\nimport { initDb } from \"./Register/storage\";\nimport { isNull, isObject } from \"lodash\";\nimport { log } from \"./Utils/log\";\nimport { ReconnectRefresher } from \"./ReconnectRefresher\";\nimport { replaceRoomFunction } from \"./Utils/RoomHacker\";\nimport { setupBuiltin } from \"./BuiltinApps\";\nimport { setupWrapper } from \"./Helper\";\nimport \"./style.css\";\nimport \"@netless/telebox-insider/dist/style.css\";\nimport {\n addEmitterOnceListener,\n ensureValidScenePath,\n getVersionNumber,\n isValidScenePath,\n wait,\n} from \"./Utils/Common\";\nimport type { TELE_BOX_STATE, BoxManager } from \"./BoxManager\";\nimport {\n AppCreateError,\n AppManagerNotInitError,\n InvalidScenePath,\n ParamsInvalidError,\n WhiteWebSDKInvalidError,\n} from \"./Utils/error\";\nimport type { Apps } from \"./AttributesDelegate\";\nimport {\n InvisiblePlugin,\n isPlayer,\n isRoom,\n RoomPhase,\n ViewMode,\n WhiteVersion,\n} from \"white-web-sdk\";\nimport type {\n Displayer,\n SceneDefinition,\n View,\n Room,\n InvisiblePluginContext,\n Camera,\n AnimationMode,\n CameraBound,\n Point,\n Rectangle,\n ViewVisionMode,\n CameraState,\n} from \"white-web-sdk\";\nimport type { AppListeners } from \"./AppListener\";\nimport type { NetlessApp, RegisterParams } from \"./typings\";\nimport type { TeleBoxColorScheme, TeleBoxState } from \"@netless/telebox-insider\";\nimport type { AppProxy } from \"./AppProxy\";\n\nexport type WindowMangerAttributes = {\n modelValue?: string;\n boxState: TELE_BOX_STATE;\n maximized?: boolean;\n minimized?: boolean;\n [key: string]: any;\n};\n\nexport type apps = {\n [key: string]: NetlessApp;\n};\n\nexport type AddAppOptions = {\n scenePath?: string;\n title?: string;\n scenes?: SceneDefinition[];\n};\n\nexport type setAppOptions = AddAppOptions & { appOptions?: any };\n\nexport type AddAppParams<TAttributes = any> = {\n kind: string;\n // app 地址(本地 app 不需要传)\n src?: string;\n // 窗口配置\n options?: AddAppOptions;\n // 初始化 attributes\n attributes?: TAttributes;\n};\n\nexport type BaseInsertParams = {\n kind: string;\n // app 地址(本地 app 不需要传)\n src?: string;\n // 窗口配置\n options?: AddAppOptions;\n // 初始化 attributes\n attributes?: any;\n isDynamicPPT?: boolean;\n};\n\nexport type AppSyncAttributes = {\n kind: string;\n src?: string;\n options: any;\n state?: any;\n isDynamicPPT?: boolean;\n fullPath?: string;\n createdAt?: number;\n};\n\nexport type AppInitState = {\n id: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n focus?: boolean;\n maximized?: boolean;\n minimized?: boolean;\n sceneIndex?: number;\n boxState?: TeleBoxState; // 兼容旧版 telebox\n zIndex?: number;\n};\n\nexport type EmitterEvent = {\n onCreated: undefined;\n InitReplay: AppInitState;\n move: { appId: string; x: number; y: number };\n focus: { appId: string };\n close: { appId: string };\n resize: { appId: string; width: number; height: number; x?: number; y?: number };\n error: Error;\n seek: number;\n mainViewMounted: undefined;\n observerIdChange: number;\n boxStateChange: string;\n playgroundSizeChange: DOMRect;\n onReconnected: void;\n};\n\nexport type EmitterType = Emittery<EmitterEvent>;\nexport const emitter: EmitterType = new Emittery();\n\nexport type PublicEvent = {\n mainViewModeChange: ViewVisionMode;\n boxStateChange: `${TELE_BOX_STATE}`;\n darkModeChange: boolean;\n prefersColorSchemeChange: TeleBoxColorScheme;\n cameraStateChange: CameraState;\n mainViewScenePathChange: string;\n mainViewSceneIndexChange: number;\n focusedChange: string | undefined;\n};\n\nexport type MountParams = {\n room: Room;\n container?: HTMLElement;\n /** 白板高宽比例, 默认为 9 / 16 */\n containerSizeRatio?: number;\n /** 显示 PS 透明背景,默认 true */\n chessboard?: boolean;\n collectorContainer?: HTMLElement;\n collectorStyles?: Partial<CSSStyleDeclaration>;\n overwriteStyles?: string;\n cursor?: boolean;\n debug?: boolean;\n disableCameraTransform?: boolean;\n prefersColorScheme?: TeleBoxColorScheme;\n};\n\nexport type CallbacksType = Emittery<PublicEvent>;\nexport const callbacks: CallbacksType = new Emittery();\n\nexport const reconnectRefresher = new ReconnectRefresher({ emitter });\n\nexport class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {\n public static kind = \"WindowManager\";\n public static displayer: Displayer;\n public static wrapper?: HTMLElement;\n public static playground?: HTMLElement;\n public static container?: HTMLElement;\n public static debug = false;\n public static containerSizeRatio = DEFAULT_CONTAINER_RATIO;\n private static isCreated = false;\n\n public version = __APP_VERSION__;\n\n public appListeners?: AppListeners;\n\n public readonly?: boolean;\n public emitter: Emittery<PublicEvent> = callbacks;\n public appManager?: AppManager;\n public cursorManager?: CursorManager;\n public viewMode = ViewMode.Broadcaster;\n public isReplay = isPlayer(this.displayer);\n\n private boxManager?: BoxManager;\n private static params?: MountParams;\n\n private containerResizeObserver?: ContainerResizeObserver;\n\n constructor(context: InvisiblePluginContext) {\n super(context);\n WindowManager.displayer = context.displayer;\n }\n\n public static async mount(params: MountParams): Promise<WindowManager> {\n const room = params.room;\n WindowManager.container = params.container;\n const containerSizeRatio = params.containerSizeRatio;\n const debug = params.debug;\n\n const cursor = params.cursor;\n WindowManager.params = params;\n\n this.checkVersion();\n if (isRoom(room)) {\n if (room.phase !== RoomPhase.Connected) {\n throw new Error(\"[WindowManager]: Room only Connected can be mount\");\n }\n if (room.phase === RoomPhase.Connected && room.isWritable) {\n // redo undo 需要设置这个属性\n room.disableSerialization = false;\n }\n }\n if (WindowManager.isCreated) {\n throw new Error(\"[WindowManager]: Already created cannot be created again\");\n }\n let manager = await this.initManager(room);\n this.debug = Boolean(debug);\n log(\"Already insert room\", manager);\n\n if (isRoom(this.displayer)) {\n if (!manager) {\n throw new Error(\"[WindowManager]: init InvisiblePlugin failed\");\n }\n } else {\n await pRetry(\n async count => {\n manager = await this.initManager(room);\n if (!manager) {\n log(`manager is empty. retrying ${count}`);\n throw new Error();\n }\n },\n { retries: 10 }\n );\n }\n\n if (containerSizeRatio) {\n WindowManager.containerSizeRatio = containerSizeRatio;\n }\n await manager.ensureAttributes();\n\n manager.appManager = new AppManager(manager);\n\n if (cursor) {\n manager.cursorManager = new CursorManager(manager.appManager);\n }\n\n if (params.container) {\n manager.bindContainer(params.container);\n }\n\n replaceRoomFunction(room, manager);\n emitter.emit(\"onCreated\");\n WindowManager.isCreated = true;\n try {\n await initDb();\n } catch (error) {\n console.warn(\"[WindowManager]: indexedDB open failed\");\n console.log(error);\n }\n return manager;\n }\n\n private static async initManager(room: Room): Promise<WindowManager> {\n let manager = room.getInvisiblePlugin(WindowManager.kind) as WindowManager;\n if (!manager) {\n if (isRoom(room)) {\n if (room.isWritable === false) {\n try {\n await room.setWritable(true);\n } catch (error) {\n throw new Error(\"[WindowManger]: room must be switched to be writable\");\n }\n manager = (await room.createInvisiblePlugin(\n WindowManager,\n {}\n )) as WindowManager;\n manager.ensureAttributes();\n await wait(500);\n await room.setWritable(false);\n } else {\n manager = (await room.createInvisiblePlugin(\n WindowManager,\n {}\n )) as WindowManager;\n }\n }\n }\n return manager;\n }\n\n private static initContainer(\n manager: WindowManager,\n container: HTMLElement,\n chessboard: boolean | undefined,\n overwriteStyles: string | undefined\n ) {\n if (!WindowManager.container) {\n WindowManager.container = container;\n }\n const { playground, wrapper, sizer, mainViewElement } = setupWrapper(container);\n WindowManager.playground = playground;\n if (chessboard) {\n sizer.classList.add(\"netless-window-manager-chess-sizer\");\n }\n if (overwriteStyles) {\n const style = document.createElement(\"style\");\n style.textContent = overwriteStyles;\n playground.appendChild(style);\n }\n manager.containerResizeObserver = ContainerResizeObserver.create(\n playground,\n sizer,\n wrapper,\n emitter\n );\n WindowManager.wrapper = wrapper;\n return mainViewElement;\n }\n\n public bindContainer(container: HTMLElement) {\n if (WindowManager.isCreated && WindowManager.container) {\n if (WindowManager.container.firstChild) {\n container.appendChild(WindowManager.container.firstChild);\n }\n } else {\n if (WindowManager.params) {\n const params = WindowManager.params;\n const mainViewElement = WindowManager.initContainer(\n this,\n container,\n params.chessboard,\n params.overwriteStyles\n );\n const boxManager = createBoxManager(this, callbacks, emitter, {\n collectorContainer: params.collectorContainer,\n collectorStyles: params.collectorStyles,\n prefersColorScheme: params.prefersColorScheme,\n });\n this.boxManager = boxManager;\n this.appManager?.setBoxManager(boxManager);\n this.bindMainView(mainViewElement, params.disableCameraTransform);\n if (WindowManager.wrapper) {\n this.cursorManager?.setupWrapper(WindowManager.wrapper);\n }\n }\n }\n this.boxManager?.updateManagerRect();\n this.appManager?.refresh();\n this.appManager?.resetMaximized();\n this.appManager?.resetMinimized();\n WindowManager.container = container;\n }\n\n public bindCollectorContainer(container: HTMLElement) {\n if (WindowManager.isCreated && this.boxManager) {\n this.boxManager.setCollectorContainer(container);\n } else {\n if (WindowManager.params) {\n WindowManager.params.collectorContainer = container;\n }\n }\n }\n\n /**\n * 注册插件\n */\n public static register<AppOptions = any, SetupResult = any, Attributes = any>(\n params: RegisterParams<AppOptions, SetupResult, Attributes>\n ): Promise<void> {\n return appRegister.register(params);\n }\n\n /**\n * 创建一个 app 至白板\n */\n public async addApp<T = any>(params: AddAppParams<T>): Promise<string | undefined> {\n if (this.appManager) {\n if (!params.kind || typeof params.kind !== \"string\") {\n throw new ParamsInvalidError();\n }\n const appImpl = await appRegister.appClasses.get(params.kind)?.();\n if (appImpl && appImpl.config?.singleton) {\n if (this.appManager.appProxies.has(params.kind)) {\n throw new AppCreateError();\n }\n }\n const isDynamicPPT = this.setupScenePath(params, this.appManager);\n if (isDynamicPPT === undefined) {\n return;\n }\n if (params?.options?.scenePath) {\n params.options.scenePath = ensureValidScenePath(params.options.scenePath);\n }\n const appId = await this.appManager.addApp(params, Boolean(isDynamicPPT));\n return appId;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n private setupScenePath(params: AddAppParams, appManager: AppManager): boolean | undefined {\n let isDynamicPPT = false;\n if (params.options) {\n const { scenePath, scenes } = params.options;\n if (scenePath) {\n if (!isValidScenePath(scenePath)) {\n throw new InvalidScenePath();\n }\n const apps = Object.keys(this.apps || {});\n for (const appId of apps) {\n const appScenePath = appManager.store.getAppScenePath(appId);\n if (appScenePath && appScenePath === scenePath) {\n console.warn(`[WindowManager]: ScenePath ${scenePath} Already opened`);\n return;\n }\n }\n }\n if (scenePath && scenes && scenes.length > 0) {\n if (this.isDynamicPPT(scenes)) {\n isDynamicPPT = true;\n if (!this.displayer.entireScenes()[scenePath]) {\n this.room?.putScenes(scenePath, scenes);\n }\n } else {\n if (!this.displayer.entireScenes()[scenePath]) {\n this.room?.putScenes(scenePath, [{ name: scenes[0].name }]);\n }\n }\n }\n if (scenePath && scenes === undefined) {\n this.room?.putScenes(scenePath, [{}]);\n }\n }\n return isDynamicPPT;\n }\n\n /**\n * 设置 mainView 的 ScenePath, 并且切换白板为可写状态\n */\n public async setMainViewScenePath(scenePath: string): Promise<void> {\n if (this.appManager) {\n await this.appManager.setMainViewScenePath(scenePath);\n }\n }\n\n /**\n * 设置 mainView 的 SceneIndex, 并且切换白板为可写状态\n */\n public async setMainViewSceneIndex(index: number): Promise<void> {\n if (this.appManager) {\n await this.appManager.setMainViewSceneIndex(index);\n }\n }\n\n /**\n * 返回 mainView 的 ScenePath\n */\n public getMainViewScenePath(): string {\n return this.appManager?.store.getMainViewScenePath();\n }\n\n /**\n * 返回 mainView 的 SceneIndex\n */\n public getMainViewSceneIndex(): number {\n return this.appManager?.store.getMainViewSceneIndex();\n }\n\n /**\n * 设置所有 app 的 readonly 模式\n */\n public setReadonly(readonly: boolean): void {\n this.readonly = readonly;\n this.boxManager?.setReadonly(readonly);\n }\n\n /**\n * 切换 mainView 为可写\n */\n public switchMainViewToWriter(): Promise<void> | undefined {\n return this.appManager?.mainViewProxy.mainViewClickHandler();\n }\n\n /**\n * app destroy 回调\n */\n public onAppDestroy(kind: string, listener: (error: Error) => void): void {\n addEmitterOnceListener(`destroy-${kind}`, listener);\n }\n\n /**\n * 设置 ViewMode\n */\n public setViewMode(mode: ViewMode): void {\n if (!this.canOperate) return;\n if (mode === ViewMode.Broadcaster) {\n this.appManager?.mainViewProxy.setCameraAndSize();\n this.appManager?.mainViewProxy.start();\n }\n if (mode === ViewMode.Freedom) {\n this.appManager?.mainViewProxy.stop();\n }\n this.viewMode = mode;\n }\n\n public get mainView(): View {\n if (this.appManager) {\n return this.appManager.mainViewProxy.view;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n public get camera(): Camera {\n if (this.appManager) {\n return this.appManager.mainViewProxy.view.camera;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n public get cameraState(): CameraState {\n if (this.appManager) {\n return this.appManager.mainViewProxy.cameraState;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n public get apps(): Apps | undefined {\n return this.appManager?.store.apps();\n }\n\n public get boxState(): TeleBoxState | undefined {\n if (this.appManager) {\n return this.appManager.boxManager?.boxState;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n public get darkMode(): boolean {\n return Boolean(this.appManager?.boxManager?.darkMode);\n }\n\n public get prefersColorScheme(): TeleBoxColorScheme | undefined {\n if (this.appManager) {\n return this.appManager.boxManager?.prefersColorScheme;\n } else {\n throw new AppManagerNotInitError();\n }\n }\n\n public get focused(): string | undefined {\n return this.attributes.focus;\n }\n\n /**\n * 查询所有的 App\n */\n public queryAll(): AppProxy[] {\n return Array.from(this.appManager?.appProxies.values() || []);\n }\n\n /**\n * 查询单个 App\n */\n public queryOne(appId: string): AppProxy | undefined {\n return this.appManager?.appProxies.get(appId);\n }\n\n /**\n * 关闭 APP\n */\n public async closeApp(appId: string): Promise<void> {\n return this.appManager?.closeApp(appId);\n }\n\n public moveCamera(\n camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }\n ): void {\n this.mainView.moveCamera(camera);\n }\n\n public moveCameraToContain(\n rectangle: Rectangle &\n Readonly<{\n animationMode?: AnimationMode;\n }>\n ): void {\n this.mainView.moveCameraToContain(rectangle);\n this.appManager?.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);\n setTimeout(() => {\n this.appManager?.mainViewProxy.setCameraAndSize();\n }, 1000);\n }\n\n public convertToPointInWorld(point: Point): Point {\n return this.mainView.convertToPointInWorld(point);\n }\n\n public setCameraBound(cameraBound: CameraBound): void {\n this.mainView.setCameraBound(cameraBound);\n }\n\n public override onDestroy(): void {\n this._destroy();\n }\n\n public override destroy(): void {\n this._destroy();\n }\n\n private _destroy() {\n this.containerResizeObserver?.disconnect();\n this.appManager?.destroy();\n this.cursorManager?.destroy();\n WindowManager.container = undefined;\n WindowManager.wrapper = undefined;\n WindowManager.isCreated = false;\n if (WindowManager.playground) {\n WindowManager.playground.parentNode?.removeChild(WindowManager.playground);\n }\n WindowManager.params = undefined;\n log(\"Destroyed\");\n }\n\n private bindMainView(divElement: HTMLDivElement, disableCameraTransform: boolean | undefined) {\n if (this.appManager) {\n this.appManager.bindMainView(divElement, Boolean(disableCameraTransform));\n this.cursorManager?.setMainViewDivElement(divElement);\n }\n }\n\n public get canOperate(): boolean {\n if (isRoom(this.displayer)) {\n return (\n (this.displayer as Room).isWritable &&\n (this.displayer as Room).phase === RoomPhase.Connected\n );\n } else {\n return false;\n }\n }\n\n public get room(): Room {\n return this.displayer as Room;\n }\n\n public safeSetAttributes(attributes: any): void {\n if (this.canOperate) {\n this.setAttributes(attributes);\n }\n }\n\n public safeUpdateAttributes(keys: string[], value: any): void {\n if (this.canOperate) {\n this.updateAttributes(keys, value);\n }\n }\n\n public setPrefersColorScheme(scheme: TeleBoxColorScheme): void {\n this.appManager?.boxManager?.setPrefersColorScheme(scheme);\n }\n\n private isDynamicPPT(scenes: SceneDefinition[]) {\n const sceneSrc = scenes[0]?.ppt?.src;\n return sceneSrc?.startsWith(\"pptx://\");\n }\n\n private static checkVersion() {\n const version = getVersionNumber(WhiteVersion);\n if (version < getVersionNumber(REQUIRE_VERSION)) {\n throw new WhiteWebSDKInvalidError(REQUIRE_VERSION);\n }\n }\n\n private async ensureAttributes() {\n if (isNull(this.attributes)) {\n await wait(50);\n }\n if (isObject(this.attributes)) {\n if (!this.attributes[Fields.Apps]) {\n this.safeSetAttributes({ [Fields.Apps]: {} });\n }\n if (!this.attributes[Fields.Cursors]) {\n this.safeSetAttributes({ [Fields.Cursors]: {} });\n }\n const sceneState = this.displayer.state.sceneState;\n if (!this.attributes[\"_mainScenePath\"]) {\n this.safeSetAttributes({ _mainScenePath: sceneState.scenePath });\n }\n if (!this.attributes[\"_mainSceneIndex\"]) {\n this.safeSetAttributes({ _mainSceneIndex: sceneState.index });\n }\n }\n }\n}\n\nsetupBuiltin();\n\nexport * from \"./typings\";\n\nexport { BuiltinApps } from \"./BuiltinApps\";\n","import { debounce, isFunction } from \"lodash\";\nimport { log } from \"./Utils/log\";\nimport { RoomPhase } from \"white-web-sdk\";\nimport type { Room } from \"white-web-sdk\";\nimport type { EmitterType } from \"./index\";\n\nexport type ReconnectRefresherContext = {\n emitter: EmitterType;\n};\n\n// 白板重连之后会刷新所有的对象,导致 listener 失效, 所以这里在重连之后重新对所有对象进行监听\nexport class ReconnectRefresher {\n private phase?: RoomPhase;\n private room: Room | undefined;\n private reactors: Map<string, any> = new Map();\n private disposers: Map<string, any> = new Map();\n\n constructor(private ctx: ReconnectRefresherContext) {}\n\n public setRoom(room: Room | undefined) {\n this.room = room;\n this.phase = room?.phase;\n room?.callbacks.off(\"onPhaseChanged\", this.onPhaseChanged);\n room?.callbacks.on(\"onPhaseChanged\", this.onPhaseChanged);\n }\n\n public setContext(ctx: ReconnectRefresherContext) {\n this.ctx = ctx;\n }\n\n private onPhaseChanged = (phase: RoomPhase) => {\n if (phase === RoomPhase.Connected && this.phase === RoomPhase.Reconnecting) {\n this.onReconnected();\n }\n this.phase = phase;\n };\n\n private onReconnected = debounce(() => {\n log(\"onReconnected refresh reactors\");\n this.releaseDisposers();\n this.reactors.forEach((func, id) => {\n if (isFunction(func)) {\n this.disposers.set(id, func());\n }\n });\n this.ctx.emitter.emit(\"onReconnected\", undefined);\n }, 3000);\n\n private releaseDisposers() {\n this.disposers.forEach(disposer => {\n if (isFunction(disposer)) {\n disposer();\n }\n });\n this.disposers.clear();\n }\n\n public add(id: string, func: any) {\n if (isFunction(func)) {\n this.reactors.set(id, func);\n this.disposers.set(id, func());\n }\n }\n\n public remove(id: string) {\n if (this.reactors.has(id)) {\n this.reactors.delete(id);\n }\n const disposer = this.disposers.get(id);\n if (disposer) {\n if (isFunction(disposer)) {\n disposer();\n }\n this.disposers.delete(id);\n }\n }\n\n public hasReactor(id: string) {\n return this.reactors.has(id);\n }\n\n public destroy() {\n this.room?.callbacks.off(\"onPhaseChanged\", this.onPhaseChanged);\n this.releaseDisposers();\n }\n}\n","import { emitter } from \"../index\";\nimport { isPlayer } from \"white-web-sdk\";\nimport type { WindowManager } from '../index';\nimport type { Camera, Room , Player , PlayerSeekingResult } from \"white-web-sdk\";\n\n// 修改多窗口状态下一些失效的方法实现到 manager 的 mainview 上, 降低迁移成本\nexport const replaceRoomFunction = (room: Room, manager: WindowManager) => {\n if (isPlayer(room)) {\n const player = room as unknown as Player;\n const originSeek = player.seekToProgressTime;\n // eslint-disable-next-line no-inner-declarations\n async function newSeek(time: number): Promise<PlayerSeekingResult> {\n const seekResult = await originSeek.call(player, time);\n if (seekResult === \"success\") {\n emitter.emit(\"seek\", time);\n }\n return seekResult;\n }\n player.seekToProgressTime = newSeek;\n } else {\n const descriptor = Object.getOwnPropertyDescriptor(room, \"disableCameraTransform\");\n if (descriptor) return;\n Object.defineProperty(room, \"disableCameraTransform\", {\n get() {\n return manager.mainView.disableCameraTransform;\n },\n set(disable: boolean) {\n manager.mainView.disableCameraTransform = disable;\n },\n });\n\n Object.defineProperty(room, \"canUndoSteps\", {\n get() {\n return manager.mainView.canUndoSteps;\n }\n });\n\n Object.defineProperty(room, \"canRedoSteps\", {\n get() {\n return manager.mainView.canRedoSteps;\n }\n });\n\n room.moveCamera = (camera: Camera) => manager.mainView.moveCamera(camera);\n room.moveCameraToContain = (...args) => manager.moveCameraToContain(...args);\n room.convertToPointInWorld = (...args) => manager.mainView.convertToPointInWorld(...args);\n room.setCameraBound = (...args) => manager.mainView.setCameraBound(...args);\n room.scenePreview = (...args) => manager.mainView.scenePreview(...args);\n room.fillSceneSnapshot = (...args) => manager.mainView.fillSceneSnapshot(...args);\n room.generateScreenshot = (...args) => manager.mainView.generateScreenshot(...args);\n room.setMemberState = (...args) => manager.mainView.setMemberState(...args);\n room.redo = () => manager.mainView.redo();\n room.undo = () => manager.mainView.undo();\n }\n\n};","import { WindowManager } from \"./index\";\n\nexport const setupWrapper = (\n root: HTMLElement\n): {\n playground: HTMLDivElement;\n wrapper: HTMLDivElement;\n sizer: HTMLDivElement;\n mainViewElement: HTMLDivElement;\n} => {\n const playground = document.createElement(\"div\");\n playground.className = \"netless-window-manager-playground\";\n\n const sizer = document.createElement(\"div\");\n sizer.className = \"netless-window-manager-sizer\";\n\n const wrapper = document.createElement(\"div\");\n wrapper.className = \"netless-window-manager-wrapper\";\n\n const mainViewElement = document.createElement(\"div\");\n mainViewElement.className = \"netless-window-manager-main-view\";\n\n playground.appendChild(sizer);\n sizer.appendChild(wrapper);\n wrapper.appendChild(mainViewElement);\n root.appendChild(playground);\n WindowManager.wrapper = wrapper;\n\n return { playground, wrapper, sizer, mainViewElement };\n};"],"names":["Events","Events2","AppAttributes","AppAttributes2","AppEvents","AppEvents2","AppStatus","CursorState","CursorState2","MIN_WIDTH","MIN_HEIGHT","db","store","initDb","async","Promise","resolve","reject","request","indexedDB","open","onerror","e","onupgradeneeded","event","db2","target","result","objectStoreNames","contains","createObjectStore","keyPath","createIndex","unique","onsuccess","setItem","key","val","payload","kind","sourceCode","transaction","objectStore","add","getItem","index","get","getScript","url","item","resource","options","timeout","controller","AbortController","id","setTimeout","abort","response","fetch","__spreadProps","signal","headers","fetchWithTimeout","text2","text","executeScript","appName","Function","window","appRegister","constructor","Map","params","registered","set","srcOrAppOrFunction","src","downloadApp","appClass","name","error","message","includes","define","amd","loadApp","Error","appClasses","app","this","appClassesCache","addHooks","emitter2","createKindEmitter","kindEmitters","emit","has","Emittery","setViewFocusScenePath","view","focusScenePath","setScenePath","room","scenePath","isWritable","state","sceneState","debounce","callbacks2","mode","makeValidScenePath","displayer","scenes","entireScenes","firstSceneName","getVersionNumber","version","versionString","split","map","s","padStart","join","parseInt","wait","time","manager","authorId","observerId","data","eventName","AppMove","appMoveHandler","AppResize","appResizeHandler","AppBoxStateChange","boxStateChangeHandler","SetMainViewScenePath","setMainViewScenePathHandler","MoveCameraToContain","moveCameraToContainHandler","boxManager","moveBox","resizeBox","Object","assign","skipUpdate","refreshViewSize","nextScenePath","mainView","moveCameraToContain","addListeners","addMagixEventListener","mainMagixEventListener","removeListeners","removeMagixEventListener","onObjectByEvent","object","func","listenUpdated","listener","events","unlistenUpdated","reaction","fireImmediately","safeListenPropsUpdated","getProps","callback","onDestroyed","disposeListenUpdated","disposeReaction","props","isObject","onObjectRemoved","UpdateEventKind","Removed","onObjectInserted","Inserted","plainObjectKeys","keys","Boolean","Set","listeners","size","dispatch","forEach","addListener","removeListener","delete","STORAGE_NS","context2","defaultState","SideEffectManager","WeakMap","StorageEvent","_context","_state","rawState","_getRawState","getIsWritable","getAttributes","updateAttributes","setState","rawValue","JSON","parse","stringify","isRef","v","_refMap","_sideEffect","addDisposer","_updateProperties","bind","destroy","_destroyed","warn","ensureState","reduce","length","value","_lastValue","_setRawState","refValue","k","genUID","__isRef","emptyStorage","mapValues","noop","deleteStorage","flushAll","defaultValue","actions","diffs","i","action","oldValue","newValue","curValue","onStateChanged","appId","appProxy","appOptions","autorun","toJS","listenDisposed","unlistenDisposed","isReplay","attributes","appAttr","getAppAttributes","isDynamicPPT","appProxy2","appProxies","getAppInitPath","canOperate","box","getBox","BoxNotCreatedError","safeSetAttributes","safeUpdateAttributes","setFullPath","getRoom","dom","getView","divElement","storeId","storage","Storage","emitter","on","dispatchMagixEvent","appEmitter","isAddApp","_storage","Fields","Fields2","setContext","context","apps","Apps","Focus","getAppState","State","getMaximized","getMinimized","setupAppAttributes","attrNames","push","pick","attrs","createdAt","Date","now","Size","Position","SceneIndex","updateAppState","stateName","cleanAppAttributes","cleanFocus","getAppSceneIndex","getAppScenePath","getMainViewScenePath","getMainViewSceneIndex","getBoxState","BoxState","setMainViewScenePath","_mainScenePath","setMainViewSceneIndex","_mainSceneIndex","getMainViewCamera","MainViewCamera","getMainViewSize","MainViewSize","setMainViewCamera","camera","__spreadValues","setMainViewSize","size2","setAppFocus","focus","updateCursor","uid","position","Cursors","updateCursorState","cursorState","getCursorState","cleanCursor","setMainViewFocusPath","log","args","WindowManager","debug","memberId","roomMembers","find","member","updateManagerRect","blurFocusBox","blurAllBox","Context","createContext","Base","viewManager","sceneIndex","maximized","minimized","zIndex","x","y","width","height","appId2","refresher","stateKey","appState","appAttributes","setZIndex","fullPath","setFocusScenePathHandler","appListener","makeAppEventListener","initScenes","createView","readonly","getFullScenePath","FullPath","getFullScenePathFromScenes","dir","scene","getScenePath","path","appImpl","appParams","setupApp","focusApp","focusBox","BoxManagerNotFoundError","AppContext","appContext","once","WindowCreated","then","boxInitState","getAppInitState","updateBoxState","onAny","appAttributesUpdateListener","setup","appResult","notifyApp","afterSetupApp","fixMobileSize","createBox","smartPosition","intrinsicWidth","intrinsicHeight","setBoxInitState","onSeek","currentAppState","AppProxy","baseInsertApp","emitAppSceneStateChange","emitAppIsWritableChange","setBoxMinSize","minWidth","minwidth","minHeight","minheight","setBoxTitle","title","status","fullScenePath","needCloseBox","cleanAttrs","clearListeners","closeBox","destroyView","appStatus","remove","close","views","release","setViewScenePath","clear","setDefaultCameraBound","setCameraBound","maxContentMode","minContentMode","mainViewCamera","moveCameraToContian","mainViewSize","moveCamera","isEqual","mainViewClickHandler","cameraState","createMainView","moveCameraSizeByAttributes","addMainViewListener","start","setCameraAndSize","playgroundSizeChangeListener","sizeChangeHandler","sideEffectManager","off","started","addCameraListener","cameraReaction","mainViewScenePath","mainViewIsAddListener","addEventListener","mainViewClickListener","removeMainViewListener","removeEventListener","callbacks","onCameraUpdatedByDevice","onCameraOrSizeUpdated","removeCameraListener","isEmpty","originX","originY","animationMode","AnimationMode","Immediately","scale","centerX","centerY","needScale","stop","windowManger","ids","startsWith","cursorManager","setRoomMembers","cleanMemberAttributes","isReadonly","isManualWritable","setReadonly","disableCameraTransform","disableSerialization","dispatchInternalEvent","mainViewProxy","MainViewProxy","ViewManager","appListeners","AppListeners","displayerStateListener","reconnectRefresher","setRoom","onCreated","onReconnected","isPlayer","attributesUpdateCallback","onAppDelete","boxEventListener","setMaximized","setMinimized","mainSceneIndex","_prevSceneIndex","focused","_prevFocused","mainScenePath","displayerWritableListener","container","appsWithCreatedAt","sortBy","StartCreate","focusByAttributes","retries","catch","err","refresh","setBoxManager","resetMaximized","resetMinimized","bindMainView","needFocus","beforeAddApp","afterAddApp","impl","config","singleton","v4","replace","slice","genAppId","intrinsicX","intrinsicY","ZIndex","isRoom","scenePathType","ScenePathType","None","Page","_setMainViewScenePath","Dir","validScenePath","sceneList","pop","sceneDir","safeDispatchMagixEvent","boxSize","focusAppId","reconnected","Array","from","values","all","notifyContainerRectUpdate","rect","offAny","ResizeObserver","ResizeObserverPolyfill","sizer","wrapper","containerResizeObserver","ContainerResizeObserver","observePlaygroundSize","updateSizer","getBoundingClientRect","containerRect","contentRect","observe","containerSizeRatio","classList","toggle","style","disconnect","createTeleBoxManagerConfig","teleBoxManager","setupBoxManager","TELE_BOX_MANAGER_EVENT","blurBox","darkMode","colorScheme","getMainView","prefersColorScheme","boxes","createBoxConfig","create","queryOne","TELE_BOX_STATE","Maximized","root","document","body","initManagerState","fence","TeleBoxManager","collectorContainer","setCollectorContainer","collector","TeleBoxCollector","styles","collectorStyles","mount","setCollector","boxIsFocus","getFocusBox","query","getTopBox","maxBy","update","setContainerRect","blurAll","updateAll","focusTopBox","setPrefersColorScheme","fn","fns","run","thing","a","b","src_url_equal_anchor","current_component","element_src","createElement","href","node","appendChild","anchor","insertBefore","parentNode","removeChild","createTextNode","attribute","removeAttribute","getAttribute","setAttribute","wholeText","important","setProperty","component","dirty_components","binding_callbacks","render_callbacks","flush_callbacks","resolved_promise","update_scheduled","flushing","seen_callbacks","$$","fragment","before_update","dirty","p","ctx","after_update","add_render_callback","outroing","flush","fill","instance2","create_fragment2","not_equal","append_styles","parent_component","bound","blank_object","on_mount","on_destroy","on_disconnect","skip_bound","ready","ret","rest","hydrate","nodes","element2","childNodes","l","detach","c","intro","block","local","customElement","m","new_on_destroy","filter","is_function","cursorName","tagName","backgroundColor","appliance","visible","avatar","theme","color","cursorTagBackgroundColor","opacity","hasTagName","hasAvatar","display","entries","hasName","$destroy","detaching","d","$on","type","indexOf","splice","$set","$$props","obj","$$set","ApplianceMap","ApplianceNames","pencil","selector","eraser","shape","addCursorChangeListener","cursors","wrapperRect","autoHidden","moveCursor","focusView","viewRect","viewCamera","Leave","hide","setMember","createCursor","onCursorChange","cursor","point","screen","convertPointToScreen","translateX","translateY","memberState","currentApplianceName","strokeColor","nickName","cursorTextColor","memberColor","memberCursorName","memberAvatar","timer","App","initProps","memberApplianceName","getIcon","memberTheme","memberCursorTextColor","memberCursorTagBackgroundColor","memberOpacity","findMemberByUid","updateComponent","omit","cursorInstances","appManager","members","compact","uniq","wrapper2","uids","getUids","Cursor","getType","clientX","clientY","convertToPointInWorld","parentElement","mainViewElement","hideCursor","setupWrapper","onReconnect","hasReactor","mouseMoveListener","mouseLeaveListener","initCursorAttributes","startReaction","setMainViewDivElement","div","handleRoomMembersChange","getPoint","setNormalCursorState","Normal","updateContainerRect","deleteCursor","needDeleteIds","findIndex","cursorId","BuiltinApps","DocsViewer","AppDocsViewer","MediaPlayer","AppMediaPlayer","phase","RoomPhase","Connected","Reconnecting","releaseDisposers","reactors","isFunction","disposers","onPhaseChanged","disposer","InvisiblePlugin","ViewMode","Broadcaster","checkVersion","_WindowManager","isCreated","initManager","pRetry","count","ensureAttributes","AppManager","CursorManager","bindContainer","player","originSeek","seekToProgressTime","seekResult","call","getOwnPropertyDescriptor","defineProperty","disable","canUndoSteps","canRedoSteps","scenePreview","fillSceneSnapshot","generateScreenshot","setMemberState","redo","undo","getInvisiblePlugin","setWritable","createInvisiblePlugin","chessboard","overwriteStyles","playground","className","style2","textContent","firstChild","initContainer","BoxManager","bindCollectorContainer","register","ParamsInvalidError","AppCreateError","setupScenePath","endsWith","addApp","AppManagerNotInitError","isValidScenePath","InvalidScenePath","appScenePath","putScenes","switchMainViewToWriter","onAppDestroy","setViewMode","Freedom","viewMode","boxState","queryAll","closeApp","rectangle","cameraBound","onDestroy","_destroy","setAttributes","scheme","sceneSrc","ppt","WhiteVersion","WhiteWebSDKInvalidError","isNull","verbose"],"mappings":"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"}