@ericchen1990/pano-view 3.4.1 → 3.5.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/data/errors.ts","../../../shared/viewer-config.ts","../src/tile/multires.ts","../src/data/viewer.ts","../src/data/hotspots.ts","../src/data/project.ts"],"sourcesContent":["export type PanoDataErrorCode =\n | \"INVALID_OPTIONS\"\n | \"FETCH_FAILED\"\n | \"HTTP_ERROR\"\n | \"INVALID_JSON\"\n | \"INVALID_CONFIG\"\n | \"UNSUPPORTED_SCHEMA_VERSION\"\n | \"UNSUPPORTED_PROJECTION\"\n | \"INVALID_PROJECT\"\n | \"INVALID_REFERENCE\"\n | \"ABORTED\";\n\nexport class PanoDataError extends Error {\n readonly code: PanoDataErrorCode;\n readonly status?: number;\n readonly sceneId?: string;\n readonly field?: string;\n readonly cause?: unknown;\n constructor(\n code: PanoDataErrorCode,\n message: string,\n details: {\n status?: number;\n sceneId?: string;\n field?: string;\n cause?: unknown;\n } = {}\n ) {\n super(message);\n this.name = \"PanoDataError\";\n this.code = code;\n Object.assign(this, details);\n }\n}\n\nexport function aborted(signal?: AbortSignal | null): void {\n if (signal?.aborted)\n throw new PanoDataError(\"ABORTED\", \"Loading was cancelled\");\n}\n","/** The portable rendering contract shared by the converter and browser viewer. */\nexport type ViewerCubeFace = \"f\" | \"r\" | \"b\" | \"l\" | \"u\" | \"d\";\nexport type CubemapViewerConfig = {\n type: \"tile\";\n multires: { tileSize: number; levels: number[] };\n urlTemplate: string;\n previewUrl: string;\n previewFaceOrder: ViewerCubeFace[];\n};\nexport type SphereViewerConfig = {\n type: \"sphereTile\";\n multires: { tileSize: number; levels: { width: number; height: number }[] };\n urlTemplate: string;\n previewUrl: string;\n indexBase: 0 | 1;\n};\nexport type ViewerConfig = CubemapViewerConfig | SphereViewerConfig;\nexport type ViewerDocument = ViewerConfig & { schemaVersion: 1 };\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function requiredString(value: unknown, field: string): string {\n if (typeof value !== \"string\" || !value.trim())\n throw new Error(`${field}: expected a nonempty string`);\n return value;\n}\n\nfunction positive(value: unknown, field: string): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0)\n throw new Error(`${field}: expected a positive safe integer`);\n return value;\n}\n\nexport function validateViewerConfig(value: unknown): ViewerConfig {\n if (!isRecord(value)) throw new Error(\"viewerConfig: expected an object\");\n if (value.type !== \"tile\" && value.type !== \"sphereTile\")\n throw new Error(\"type: expected tile or sphereTile\");\n if (!isRecord(value.multires))\n throw new Error(\"multires: expected an object\");\n const tileSize = positive(value.multires.tileSize, \"multires.tileSize\");\n if (tileSize > 8192) throw new Error(\"multires.tileSize: maximum is 8192\");\n const input = value.multires.levels;\n if (!Array.isArray(input) || input.length === 0 || input.length > 64)\n throw new Error(\"multires.levels: expected 1 to 64 levels\");\n const urlTemplate = requiredString(value.urlTemplate, \"urlTemplate\");\n const previewUrl = requiredString(value.previewUrl, \"previewUrl\");\n if (/%/.test(urlTemplate.replace(/%s|%l|%0*[hxucvywr]/g, \"\")))\n throw new Error(\"urlTemplate: unsupported placeholder\");\n if (value.type === \"tile\") {\n const levels = input.map((level, i) =>\n positive(level, `multires.levels[${i}]`)\n );\n if (levels.some((level, i) => i > 0 && level <= levels[i - 1]!))\n throw new Error(\"multires.levels: face sizes must increase\");\n const order = value.previewFaceOrder;\n if (\n !Array.isArray(order) ||\n order.length !== 6 ||\n ![\"f\", \"r\", \"b\", \"l\", \"u\", \"d\"].every((face) => order.includes(face))\n )\n throw new Error(\"previewFaceOrder: expected six unique cube faces\");\n return {\n type: \"tile\",\n multires: { tileSize, levels },\n urlTemplate,\n previewUrl,\n previewFaceOrder: [...order] as ViewerCubeFace[],\n };\n }\n if (urlTemplate.includes(\"%s\"))\n throw new Error(\"urlTemplate: sphere has no cube face\");\n if (value.indexBase !== 0 && value.indexBase !== 1)\n throw new Error(\"indexBase: expected 0 or 1\");\n const levels = input.map((level: unknown, i) => {\n if (!isRecord(level))\n throw new Error(`multires.levels[${i}]: expected dimensions`);\n const width = positive(level.width, `multires.levels[${i}].width`);\n const height = positive(level.height, `multires.levels[${i}].height`);\n if (Math.abs(width - 2 * height) > 2)\n throw new Error(`multires.levels[${i}]: expected a full 2:1 panorama`);\n return { width, height };\n });\n if (\n levels.some(\n (level, i) =>\n i > 0 &&\n (level.width <= levels[i - 1]!.width ||\n level.height <= levels[i - 1]!.height)\n )\n )\n throw new Error(\"multires.levels: dimensions must increase\");\n return {\n type: \"sphereTile\",\n multires: { tileSize, levels },\n urlTemplate,\n previewUrl,\n indexBase: value.indexBase,\n };\n}\n","import { resolveAssetUrl } from \"../asset-url\";\nimport type {\n TileAddress,\n TileMultiresConfig,\n} from \"./types\";\n\nfunction positiveInteger(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0 || !Number.isInteger(value)) {\n throw new Error(`${name} must be a positive integer, received ${String(value)}`);\n }\n return value;\n}\n\nfunction ascendingLevels(levels: number[]): number[] {\n for (let index = 1; index < levels.length; index += 1) {\n if (levels[index]! <= levels[index - 1]!) {\n throw new Error(\"multires face sizes must be strictly ascending\");\n }\n }\n return levels;\n}\n\nexport function parseMultires(\n multires: string | TileMultiresConfig,\n): TileMultiresConfig {\n if (typeof multires !== \"string\") {\n const tileSize = positiveInteger(multires.tileSize, \"multires.tileSize\");\n if (multires.levels.length === 0) {\n throw new Error(\"multires.levels must contain at least one face size\");\n }\n const levels = ascendingLevels(\n multires.levels.map((level, index) =>\n positiveInteger(level, `multires.levels[${index}]`),\n ),\n );\n return { tileSize, levels };\n }\n\n const values = multires.split(\",\").map((part) => Number(part.trim()));\n\n if (values.length < 2 || values.some((value) => !Number.isFinite(value))) {\n throw new Error(\n \"multires must contain a tile size followed by at least one face size\",\n );\n }\n\n const tileSize = positiveInteger(values[0]!, \"multires tile size\");\n const levels = ascendingLevels(\n values.slice(1).map((level, index) =>\n positiveInteger(level, `multires level ${index + 1}`),\n ),\n );\n return { tileSize, levels };\n}\n\nexport const DEFAULT_TILE_URL_TEMPLATE = \"tiles/%s/l%l/%v/l%l_%s_%h_%v.webp\";\n\nexport function buildDefaultTileUrlTemplate(): string {\n return DEFAULT_TILE_URL_TEMPLATE;\n}\n\nexport function resolveRelativeTileUrl(\n baseUrl: string,\n relativePath: string,\n): string {\n return resolveAssetUrl(baseUrl, relativePath);\n}\n\nexport function resolveTemplateUrl(\n template: string,\n address: Pick<TileAddress, \"face\" | \"level\" | \"row\" | \"col\">,\n): string {\n return template\n .replace(/%s/g, address.face)\n .replace(/%l/g, String(address.level))\n .replace(/%(0*)([hxucvywr])/g, (_match, zeroes: string, placeholder: string) => {\n const value = \"hxuc\".includes(placeholder)\n ? address.col\n : address.row;\n return String(value).padStart(zeroes.length + 1, \"0\");\n });\n}\n","import {\n isRecord,\n validateViewerConfig,\n type ViewerConfig,\n} from \"../../../../shared/viewer-config\";\nimport type { TileScene, SphereTileScene } from \"../scenes\";\nimport type { TileAddress } from \"../tile/types\";\nimport type { SphereTileAddress } from \"../sphere-tile/types\";\nimport { resolveTemplateUrl } from \"../tile/multires\";\nimport { PanoDataError, aborted } from \"./errors\";\n\nexport type AssetUrlContext = {\n defaultUrl: string;\n kind: \"tile\" | \"preview\" | \"hotspot\";\n sceneId: string;\n hotspotId?: string;\n};\nexport type AssetUrlResolver = (\n path: string,\n context: AssetUrlContext\n) => string;\nexport type JsonRequestOptions = {\n requestInit?: Pick<RequestInit, \"headers\" | \"credentials\" | \"signal\">;\n};\nexport type SceneFromViewerConfigOptions = {\n id: string;\n baseUrl: string;\n resolveAssetUrl?: AssetUrlResolver;\n};\nexport type LoadSceneFromJsonOptions = Omit<\n SceneFromViewerConfigOptions,\n \"baseUrl\"\n> &\n JsonRequestOptions & { baseUrl?: string };\n\n/** URL resolution is intentionally independent of React and browser globals on the server. */\nexport function documentUrl(input: string): string {\n try {\n const url = new URL(\n input,\n typeof document === \"undefined\" ? undefined : document.baseURI\n );\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\")\n throw new Error(\"Use HTTP(S)\");\n return url.href;\n } catch (cause) {\n throw new PanoDataError(\n \"INVALID_OPTIONS\",\n \"Expected an HTTP(S) URL; Node.js requires an absolute URL\",\n { cause }\n );\n }\n}\n\nexport function directoryUrl(input: string): string {\n const url = new URL(input);\n url.search = \"\";\n url.hash = \"\";\n if (!url.pathname.endsWith(\"/\")) url.pathname += \"/\";\n return url.href;\n}\n\nexport function resolveResource(baseUrl: string, path: string): string {\n try {\n const url = new URL(path, directoryUrl(baseUrl));\n if (![\"http:\", \"https:\", \"blob:\", \"data:\"].includes(url.protocol))\n throw new Error(\"Unsupported resource URL protocol\");\n return url.href;\n } catch (cause) {\n throw new PanoDataError(\n \"INVALID_CONFIG\",\n `Invalid resource path: ${path}`,\n { cause }\n );\n }\n}\n\nexport function mapResource(\n path: string,\n context: AssetUrlContext,\n resolver?: AssetUrlResolver\n): string {\n let result: string;\n try {\n result = resolver ? resolver(path, context) : context.defaultUrl;\n } catch (cause) {\n throw new PanoDataError(\"INVALID_CONFIG\", \"resolveAssetUrl failed\", {\n sceneId: context.sceneId,\n cause,\n });\n }\n if (typeof result !== \"string\" || !result.trim())\n throw new PanoDataError(\n \"INVALID_CONFIG\",\n \"resolveAssetUrl must return a nonempty final URL\",\n { sceneId: context.sceneId }\n );\n // A root path is already final; relative callback results are ambiguous and rejected.\n if (!result.startsWith(\"/\") && !/^(https?:|blob:|data:)/i.test(result))\n throw new PanoDataError(\n \"INVALID_CONFIG\",\n \"resolveAssetUrl must return an absolute URL or a site-root path\",\n { sceneId: context.sceneId }\n );\n return result;\n}\n\nexport function parseConfig(value: unknown): ViewerConfig {\n if (isRecord(value) && value.type !== \"tile\" && value.type !== \"sphereTile\")\n throw new PanoDataError(\n \"UNSUPPORTED_PROJECTION\",\n \"Expected a tile or sphereTile configuration\",\n { field: \"type\" }\n );\n try {\n return validateViewerConfig(value);\n } catch (cause) {\n const message =\n cause instanceof Error ? cause.message : \"Invalid viewer configuration\";\n throw new PanoDataError(\"INVALID_CONFIG\", message, {\n cause,\n field: message.split(\":\")[0],\n });\n }\n}\n\nexport function sceneFromViewerConfig(\n value: unknown,\n options: SceneFromViewerConfigOptions\n): TileScene | SphereTileScene {\n if (\n !options ||\n typeof options.id !== \"string\" ||\n !options.id.trim() ||\n typeof options.baseUrl !== \"string\" ||\n !options.baseUrl.trim()\n )\n throw new PanoDataError(\"INVALID_OPTIONS\", \"id and baseUrl are required\");\n const config = parseConfig(value);\n const baseUrl = directoryUrl(documentUrl(options.baseUrl));\n const resolve = (path: string, kind: \"tile\" | \"preview\") =>\n mapResource(\n path,\n {\n kind,\n sceneId: options.id,\n defaultUrl: resolveResource(baseUrl, path),\n },\n options.resolveAssetUrl\n );\n const previewUrl = resolve(config.previewUrl, \"preview\");\n if (config.type === \"tile\") {\n return {\n ...config,\n id: options.id,\n baseUrl,\n previewUrl,\n ...(options.resolveAssetUrl\n ? {\n resolveTileUrl: (address: TileAddress) =>\n resolve(resolveTemplateUrl(config.urlTemplate, address), \"tile\"),\n }\n : {}),\n };\n }\n return {\n ...config,\n id: options.id,\n baseUrl,\n previewUrl,\n ...(options.resolveAssetUrl\n ? {\n resolveTileUrl: (address: SphereTileAddress) => {\n // Sphere callbacks use logical zero-based addresses; the document controls storage indices.\n const path = resolveTemplateUrl(config.urlTemplate, {\n face: \"f\",\n level: address.level + config.indexBase,\n row: address.row + config.indexBase,\n col: address.col + config.indexBase,\n });\n return resolve(path, \"tile\");\n },\n }\n : {}),\n };\n}\n\nexport async function readJson(\n url: string,\n options: JsonRequestOptions\n): Promise<{ value: unknown; url: string }> {\n const signal = options.requestInit?.signal;\n aborted(signal);\n let response: Response;\n try {\n response = await fetch(url, { ...options.requestInit, method: \"GET\" });\n } catch (cause) {\n aborted(signal);\n throw new PanoDataError(\n \"FETCH_FAILED\",\n \"Could not fetch JSON; check the network and server CORS settings\",\n { cause }\n );\n }\n aborted(signal);\n if (!response.ok)\n throw new PanoDataError(\n \"HTTP_ERROR\",\n `JSON request returned HTTP ${response.status}`,\n { status: response.status }\n );\n try {\n const value: unknown = await response.json();\n aborted(signal);\n return { value, url: response.url || url };\n } catch (cause) {\n aborted(signal);\n throw new PanoDataError(\n \"INVALID_JSON\",\n \"Expected JSON; check for an HTML fallback or login page\",\n { cause }\n );\n }\n}\n\nexport async function loadSceneFromJson(\n url: string,\n options: LoadSceneFromJsonOptions\n): Promise<TileScene | SphereTileScene> {\n if (!options || typeof options.id !== \"string\" || !options.id.trim())\n throw new PanoDataError(\"INVALID_OPTIONS\", \"id is required\");\n const response = await readJson(documentUrl(url), options);\n if (!isRecord(response.value))\n throw new PanoDataError(\n \"INVALID_CONFIG\",\n \"viewer.json must contain an object\"\n );\n if (response.value.schemaVersion !== 1)\n throw new PanoDataError(\n \"UNSUPPORTED_SCHEMA_VERSION\",\n \"Unsupported viewer.json schemaVersion\",\n { field: \"schemaVersion\" }\n );\n return sceneFromViewerConfig(response.value, {\n ...options,\n baseUrl: options.baseUrl ?? new URL(\".\", response.url).href,\n });\n}\n","import { isRecord, requiredString } from \"../../../../shared/viewer-config\";\nimport type { HotspotDefinition } from \"../hotspot/definitions\";\nimport type { HotspotPosition } from \"../hotspot/types\";\nimport { PanoDataError } from \"./errors\";\nimport { mapResource, resolveResource, type AssetUrlResolver } from \"./viewer\";\n\nexport type ProjectHotspotDefinition = HotspotDefinition & {\n action?: { type: \"scene\"; sceneId: string };\n};\n\nconst common = [\n \"label\",\n \"visible\",\n \"interactive\",\n \"pointerEvents\",\n \"cursor\",\n \"renderOrder\",\n \"tooltip\",\n \"tooltipTrigger\",\n \"tooltipPlacement\",\n \"tooltipOffset\",\n \"tooltipAppearance\",\n];\nconst point = [\n \"position\",\n \"width\",\n \"height\",\n \"scale\",\n \"mode\",\n \"distance\",\n \"scaleMode\",\n \"referenceFov\",\n \"rotation\",\n \"opacity\",\n];\nconst fields = {\n image: [\"src\"],\n graphic: [\"graphic\"],\n sequence: [\"src\", \"frameCount\", \"frameDirection\", \"playing\", \"fps\", \"loop\"],\n video: [\n \"src\",\n \"poster\",\n \"playing\",\n \"loop\",\n \"muted\",\n \"volume\",\n \"playsInline\",\n \"preload\",\n \"crossOrigin\",\n ],\n audio: [\n \"src\",\n \"playing\",\n \"loop\",\n \"muted\",\n \"volume\",\n \"pauseWhenHidden\",\n \"range\",\n \"icon\",\n \"playingIcon\",\n \"marker\",\n \"crossOrigin\",\n ],\n text: [\n \"text\",\n \"fontFamily\",\n \"fontSize\",\n \"fontWeight\",\n \"fontStyle\",\n \"color\",\n \"background\",\n \"backgroundOpacity\",\n \"padding\",\n \"align\",\n \"verticalAlign\",\n \"whiteSpace\",\n \"lineHeight\",\n \"borderRadius\",\n \"stroke\",\n \"strokeWidth\",\n ],\n iframe: [\n \"src\",\n \"title\",\n \"sandbox\",\n \"allow\",\n \"referrerPolicy\",\n \"loading\",\n \"pointerPolicy\",\n \"background\",\n ],\n polygon: [\n \"vertices\",\n \"fill\",\n \"fillOpacity\",\n \"stroke\",\n \"strokeWidth\",\n \"strokeOpacity\",\n \"strokeDashSize\",\n \"strokeGapSize\",\n ],\n polyline: [\n \"vertices\",\n \"stroke\",\n \"strokeWidth\",\n \"strokeOpacity\",\n \"strokeDashSize\",\n \"strokeGapSize\",\n ],\n} satisfies Record<HotspotDefinition[\"type\"], string[]>;\nconst booleanFields = new Set([\n \"visible\",\n \"interactive\",\n \"playing\",\n \"loop\",\n \"muted\",\n \"playsInline\",\n \"pauseWhenHidden\",\n \"marker\",\n]);\nconst numberFields = new Set([\n \"renderOrder\",\n \"tooltipOffset\",\n \"width\",\n \"height\",\n \"scale\",\n \"distance\",\n \"referenceFov\",\n \"rotation\",\n \"opacity\",\n \"frameCount\",\n \"fps\",\n \"volume\",\n \"range\",\n \"fontSize\",\n \"backgroundOpacity\",\n \"padding\",\n \"lineHeight\",\n \"borderRadius\",\n \"strokeWidth\",\n \"fillOpacity\",\n \"strokeOpacity\",\n \"strokeDashSize\",\n \"strokeGapSize\",\n]);\nconst positiveFields = new Set([\n \"width\",\n \"height\",\n \"scale\",\n \"distance\",\n \"referenceFov\",\n \"frameCount\",\n \"fps\",\n \"fontSize\",\n \"lineHeight\",\n]);\nconst enums: Record<string, readonly string[]> = {\n pointerEvents: [\"auto\", \"none\"],\n tooltipTrigger: [\"always\", \"hover\", \"click\"],\n tooltipPlacement: [\"top\", \"bottom\", \"left\", \"right\"],\n mode: [\"surface\", \"billboard\"],\n scaleMode: [\"fov\", \"fixed\"],\n frameDirection: [\"horizontal\", \"vertical\"],\n preload: [\"none\", \"metadata\", \"auto\"],\n crossOrigin: [\"\", \"anonymous\", \"use-credentials\"],\n fontStyle: [\"normal\", \"italic\"],\n align: [\"left\", \"center\", \"right\"],\n verticalAlign: [\"top\", \"middle\", \"bottom\"],\n whiteSpace: [\"normal\", \"nowrap\"],\n loading: [\"eager\", \"lazy\"],\n pointerPolicy: [\"hotspot\", \"content\"],\n referrerPolicy: [\n \"\",\n \"no-referrer\",\n \"no-referrer-when-downgrade\",\n \"origin\",\n \"origin-when-cross-origin\",\n \"same-origin\",\n \"strict-origin\",\n \"strict-origin-when-cross-origin\",\n \"unsafe-url\",\n ],\n};\n\nfunction finite(value: unknown, field: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n throw new Error(`${field}: expected a finite number`);\n return value;\n}\n\nexport function parsePosition(value: unknown, field: string): HotspotPosition {\n if (!isRecord(value)) throw new Error(`${field}: expected yaw and pitch`);\n const yaw = finite(value.yaw, `${field}.yaw`);\n const pitch = finite(value.pitch, `${field}.pitch`);\n if (Math.abs(pitch) > 90)\n throw new Error(`${field}.pitch: expected -90 to 90`);\n return { yaw, pitch };\n}\n\nfunction parseGraphic(value: unknown): Record<string, unknown> {\n if (!isRecord(value)) throw new Error(\"graphic: expected an object\");\n const kind = requiredString(value.kind, \"graphic.kind\");\n if (\n ![\n \"circle\",\n \"triangle\",\n \"diamond\",\n \"star\",\n \"arrow\",\n \"rectangle\",\n \"ring\",\n \"svg\",\n \"path\",\n ].includes(kind)\n )\n throw new Error(\"graphic.kind: unsupported graphic\");\n const result: Record<string, unknown> = { kind };\n for (const key of [\"fill\", \"stroke\"]) {\n if (value[key] !== undefined)\n result[key] = requiredString(value[key], `graphic.${key}`);\n }\n for (const key of [\"strokeWidth\", \"cornerRadius\", \"innerRadius\"]) {\n if (value[key] !== undefined)\n result[key] = finite(value[key], `graphic.${key}`);\n }\n if (kind === \"svg\") result.src = requiredString(value.src, \"graphic.src\");\n if (kind === \"path\") {\n result.path = requiredString(value.path, \"graphic.path\");\n if (!Array.isArray(value.viewBox) || value.viewBox.length !== 4)\n throw new Error(\"graphic.viewBox: expected four numbers\");\n const viewBox = value.viewBox.map((n, i) =>\n finite(n, `graphic.viewBox[${i}]`)\n );\n if (viewBox[2]! <= 0 || viewBox[3]! <= 0)\n throw new Error(\"graphic.viewBox: width and height must be positive\");\n result.viewBox = viewBox;\n }\n return result;\n}\n\nfunction parseTooltip(value: unknown): unknown {\n if (typeof value === \"string\") return value;\n if (!isRecord(value)) throw new Error(\"tooltip: expected text or an object\");\n const result: Record<string, string> = {};\n for (const key of [\"text\", \"image\", \"imageAlt\"]) {\n if (value[key] !== undefined) {\n if (typeof value[key] !== \"string\")\n throw new Error(`tooltip.${key}: expected a string`);\n result[key] = value[key];\n }\n }\n return result;\n}\n\nfunction parseAppearance(value: unknown): Record<string, string | number> {\n if (!isRecord(value))\n throw new Error(\"tooltipAppearance: expected an object\");\n const result: Record<string, string | number> = {};\n for (const key of [\n \"background\",\n \"color\",\n \"border\",\n \"borderRadius\",\n \"shadow\",\n \"padding\",\n \"fontSize\",\n \"fontFamily\",\n \"lineHeight\",\n \"letterSpacing\",\n ]) {\n const item = value[key];\n if (item === undefined) continue;\n if (\n [\"background\", \"color\", \"border\", \"shadow\", \"fontFamily\"].includes(key) &&\n typeof item !== \"string\"\n )\n throw new Error(`tooltipAppearance.${key}: expected a string`);\n if (\n typeof item !== \"string\" &&\n (typeof item !== \"number\" || !Number.isFinite(item))\n )\n throw new Error(\n `tooltipAppearance.${key}: expected a string or finite number`\n );\n result[key] = item;\n }\n return result;\n}\n\nexport function parseHotspot(\n value: unknown,\n sceneId: string,\n field: string\n): ProjectHotspotDefinition {\n try {\n if (!isRecord(value)) throw new Error(\"expected a hotspot object\");\n const type = requiredString(value.type, \"type\");\n if (!Object.prototype.hasOwnProperty.call(fields, type))\n throw new Error(\"type: unsupported hotspot type\");\n const kind = type as HotspotDefinition[\"type\"];\n const result: Record<string, unknown> = {\n type,\n id: requiredString(value.id, \"id\"),\n };\n const isPath = kind === \"polygon\" || kind === \"polyline\";\n const allowed = [...common, ...(isPath ? [] : point), ...fields[kind]];\n for (const key of allowed) {\n const item = value[key];\n if (item === undefined) continue;\n if (key === \"position\") result[key] = parsePosition(item, key);\n else if (key === \"vertices\") {\n if (!Array.isArray(item) || item.length < (kind === \"polygon\" ? 3 : 2))\n throw new Error(\"vertices: not enough points\");\n result[key] = item.map((p, i) => parsePosition(p, `vertices[${i}]`));\n } else if (key === \"graphic\") result[key] = parseGraphic(item);\n else if (key === \"tooltip\") result[key] = parseTooltip(item);\n else if (key === \"tooltipAppearance\") result[key] = parseAppearance(item);\n else if (booleanFields.has(key)) {\n if (typeof item !== \"boolean\")\n throw new Error(`${key}: expected a boolean`);\n result[key] = item;\n } else if (numberFields.has(key)) {\n const n = finite(item, key);\n if (positiveFields.has(key) && n <= 0)\n throw new Error(`${key}: expected a positive number`);\n if (key === \"frameCount\" && !Number.isSafeInteger(n))\n throw new Error(\"frameCount: expected an integer\");\n if (\n [\n \"opacity\",\n \"fillOpacity\",\n \"strokeOpacity\",\n \"volume\",\n \"backgroundOpacity\",\n ].includes(key) &&\n (n < 0 || n > 1)\n )\n throw new Error(`${key}: expected 0 to 1`);\n result[key] = n;\n } else if (key === \"fontWeight\" && typeof item === \"number\")\n result[key] = finite(item, key);\n else if (key === \"src\" && kind === \"audio\" && Array.isArray(item)) {\n if (!item.length) throw new Error(\"src: expected audio sources\");\n result[key] = item.map((src, i) => requiredString(src, `src[${i}]`));\n } else {\n if (typeof item !== \"string\")\n throw new Error(`${key}: expected a string`);\n if (enums[key] && !enums[key].includes(item))\n throw new Error(`${key}: unsupported value`);\n result[key] = item;\n }\n }\n if (!isPath && !result.position) throw new Error(\"position: required\");\n if (isPath && !result.vertices) throw new Error(\"vertices: required\");\n if (\n [\"image\", \"sequence\", \"video\", \"audio\", \"iframe\"].includes(kind) &&\n !(typeof result.src === \"string\"\n ? result.src.trim()\n : Array.isArray(result.src))\n )\n throw new Error(\"src: required\");\n if (kind === \"graphic\" && !result.graphic)\n throw new Error(\"graphic: required\");\n if (kind === \"text\" && typeof result.text !== \"string\")\n throw new Error(\"text: required\");\n if (kind === \"sequence\" && !result.frameCount)\n throw new Error(\"frameCount: required\");\n if (value.action !== undefined) {\n if (!isRecord(value.action) || value.action.type !== \"scene\")\n throw new Error(\"action: expected a scene action\");\n result.action = {\n type: \"scene\",\n sceneId: requiredString(value.action.sceneId, \"action.sceneId\"),\n };\n }\n return result as ProjectHotspotDefinition;\n } catch (cause) {\n const detail = cause instanceof Error ? cause.message : \"Invalid hotspot\";\n throw new PanoDataError(\"INVALID_PROJECT\", `${field}.${detail}`, {\n sceneId,\n field: `${field}.${detail.split(\":\")[0]}`,\n cause,\n });\n }\n}\n\nexport function resolveHotspotAssets(\n hotspot: ProjectHotspotDefinition,\n baseUrl: string,\n sceneId: string,\n resolver?: AssetUrlResolver\n): ProjectHotspotDefinition {\n const resolve = (path: string) =>\n path\n ? mapResource(\n path,\n {\n kind: \"hotspot\",\n sceneId,\n hotspotId: hotspot.id,\n defaultUrl: resolveResource(baseUrl, path),\n },\n resolver\n )\n : path;\n const result = { ...hotspot };\n if (\"src\" in result)\n result.src = Array.isArray(result.src)\n ? result.src.map(resolve)\n : resolve(result.src);\n if (\"poster\" in result && result.poster)\n result.poster = resolve(result.poster);\n if (result.type === \"audio\") {\n if (result.icon) result.icon = resolve(result.icon);\n if (result.playingIcon) result.playingIcon = resolve(result.playingIcon);\n }\n if (result.type === \"graphic\" && result.graphic.kind === \"svg\")\n result.graphic = { ...result.graphic, src: resolve(result.graphic.src) };\n if (typeof result.tooltip === \"object\")\n result.tooltip = {\n ...result.tooltip,\n ...(result.tooltip.image ? { image: resolve(result.tooltip.image) } : {}),\n };\n return result;\n}\n","import {\n isRecord,\n requiredString,\n type ViewerConfig,\n} from \"../../../../shared/viewer-config\";\nimport type { TileScene, SphereTileScene } from \"../scenes\";\nimport type { PanoViewerState } from \"../types\";\nimport { PanoDataError, aborted } from \"./errors\";\nimport {\n parseHotspot,\n parsePosition,\n resolveHotspotAssets,\n type ProjectHotspotDefinition,\n} from \"./hotspots\";\nimport {\n documentUrl,\n directoryUrl,\n readJson,\n parseConfig,\n resolveResource,\n sceneFromViewerConfig,\n loadSceneFromJson,\n type AssetUrlResolver,\n type JsonRequestOptions,\n} from \"./viewer\";\n\nexport type PanoProjectSceneDefinition = {\n id: string;\n title?: string;\n source: (\n | { viewerUrl: string; viewerConfig?: never }\n | { viewerConfig: ViewerConfig; viewerUrl?: never }\n ) & { baseUrl?: string };\n initialView?: Partial<PanoViewerState>;\n hotspots?: ProjectHotspotDefinition[];\n};\nexport type PanoProjectDefinition = {\n schemaVersion: 1;\n title?: string;\n initialSceneId?: string;\n scenes: PanoProjectSceneDefinition[];\n};\nexport type LoadedProjectScene = {\n scene: TileScene | SphereTileScene;\n title?: string;\n initialView?: PanoViewerState;\n hotspots: ProjectHotspotDefinition[];\n};\nexport type LoadedPanoProject = {\n title?: string;\n initialSceneId: string;\n scenes: LoadedProjectScene[];\n};\nexport type LoadPanoProjectOptions = JsonRequestOptions & {\n /** Directory used for project-relative references. Required for object input. */\n baseUrl?: string;\n resolveAssetUrl?: AssetUrlResolver;\n};\n\nfunction optionalString(\n record: Record<string, unknown>,\n key: string\n): string | undefined {\n return record[key] === undefined\n ? undefined\n : requiredString(record[key], key);\n}\n\nexport function parsePanoProject(value: unknown): PanoProjectDefinition {\n if (!isRecord(value))\n throw new PanoDataError(\"INVALID_PROJECT\", \"Expected a project object\");\n if (value.schemaVersion !== 1)\n throw new PanoDataError(\n \"UNSUPPORTED_SCHEMA_VERSION\",\n \"Unsupported project schemaVersion\",\n { field: \"schemaVersion\" }\n );\n try {\n if (!Array.isArray(value.scenes) || !value.scenes.length)\n throw new Error(\"scenes: expected a nonempty array\");\n const ids = new Set<string>();\n const scenes = value.scenes.map(\n (entry: unknown, index): PanoProjectSceneDefinition => {\n let id: string | undefined;\n const field = `scenes[${index}]`;\n try {\n if (!isRecord(entry)) throw new Error(\"expected a scene object\");\n id = requiredString(entry.id, \"id\");\n if (ids.has(id)) throw new Error(\"id: duplicate scene ID\");\n ids.add(id);\n if (!isRecord(entry.source))\n throw new Error(\"source: expected an object\");\n const src = entry.source;\n if (\n (src.viewerUrl !== undefined) ===\n (src.viewerConfig !== undefined)\n )\n throw new Error(\n \"source: provide exactly one of viewerUrl or viewerConfig\"\n );\n const baseUrl = optionalString(src, \"baseUrl\");\n const source: PanoProjectSceneDefinition[\"source\"] =\n src.viewerUrl !== undefined\n ? {\n viewerUrl: requiredString(src.viewerUrl, \"source.viewerUrl\"),\n baseUrl,\n }\n : { viewerConfig: parseConfig(src.viewerConfig), baseUrl };\n let initialView: Partial<PanoViewerState> | undefined;\n if (entry.initialView !== undefined) {\n if (!isRecord(entry.initialView))\n throw new Error(\"initialView: expected an object\");\n const input = entry.initialView;\n const position = parsePosition(\n { yaw: input.yaw ?? 0, pitch: input.pitch ?? 0 },\n \"initialView\"\n );\n const fov = input.fov ?? 75;\n if (\n typeof fov !== \"number\" ||\n !Number.isFinite(fov) ||\n fov <= 0 ||\n fov >= 180\n )\n throw new Error(\n \"initialView.fov: expected a number between 0 and 180\"\n );\n initialView = { ...position, fov };\n }\n if (entry.hotspots !== undefined && !Array.isArray(entry.hotspots))\n throw new Error(\"hotspots: expected an array\");\n const hotspotIds = new Set<string>();\n const hotspots = ((entry.hotspots ?? []) as unknown[]).map(\n (hotspot, i) => {\n const result = parseHotspot(\n hotspot,\n id!,\n `${field}.hotspots[${i}]`\n );\n if (hotspotIds.has(result.id))\n throw new Error(`hotspots[${i}].id: duplicate hotspot ID`);\n hotspotIds.add(result.id);\n return result;\n }\n );\n return {\n id,\n title: optionalString(entry, \"title\"),\n source,\n initialView,\n hotspots,\n };\n } catch (cause) {\n if (cause instanceof PanoDataError && cause.sceneId) throw cause;\n const detail =\n cause instanceof Error ? cause.message : \"Invalid scene\";\n throw new PanoDataError(\n cause instanceof PanoDataError ? cause.code : \"INVALID_PROJECT\",\n `${field}.${detail}`,\n {\n sceneId: id,\n field: `${field}.${\n cause instanceof PanoDataError\n ? `source.viewerConfig.${cause.field ?? \"\"}`\n : detail.split(\":\")[0]\n }`,\n cause,\n }\n );\n }\n }\n );\n const initialSceneId =\n optionalString(value, \"initialSceneId\") ?? scenes[0]!.id;\n if (!ids.has(initialSceneId))\n throw new PanoDataError(\n \"INVALID_REFERENCE\",\n \"initialSceneId: scene does not exist\",\n { field: \"initialSceneId\" }\n );\n for (const [index, scene] of scenes.entries()) {\n for (const [i, hotspot] of (scene.hotspots ?? []).entries()) {\n if (hotspot.action && !ids.has(hotspot.action.sceneId))\n throw new PanoDataError(\n \"INVALID_REFERENCE\",\n \"Hotspot target scene does not exist\",\n {\n sceneId: scene.id,\n field: `scenes[${index}].hotspots[${i}].action.sceneId`,\n }\n );\n }\n }\n return {\n schemaVersion: 1,\n title: optionalString(value, \"title\"),\n initialSceneId,\n scenes,\n };\n } catch (cause) {\n if (cause instanceof PanoDataError) throw cause;\n const message = cause instanceof Error ? cause.message : \"Invalid project\";\n throw new PanoDataError(\"INVALID_PROJECT\", message, {\n cause,\n field: message.split(\":\")[0],\n });\n }\n}\n\nexport async function loadPanoProject(\n source: string | PanoProjectDefinition,\n options: LoadPanoProjectOptions = {}\n): Promise<LoadedPanoProject> {\n aborted(options.requestInit?.signal);\n let definition: PanoProjectDefinition;\n let baseUrl: string;\n if (typeof source === \"string\") {\n const response = await readJson(documentUrl(source), options);\n definition = parsePanoProject(response.value);\n baseUrl = options.baseUrl ?? new URL(\".\", response.url).href;\n } else {\n if (!options.baseUrl)\n throw new PanoDataError(\n \"INVALID_OPTIONS\",\n \"baseUrl is required for project object input\"\n );\n definition = parsePanoProject(source);\n baseUrl = options.baseUrl;\n }\n const root = directoryUrl(documentUrl(baseUrl));\n const controller = new AbortController();\n const signal = options.requestInit?.signal;\n const cancel = () => controller.abort();\n signal?.addEventListener(\"abort\", cancel, { once: true });\n const scenes: LoadedProjectScene[] = new Array(definition.scenes.length);\n let next = 0;\n let failure: PanoDataError | undefined;\n async function worker() {\n while (next < definition.scenes.length && !controller.signal.aborted) {\n const index = next++;\n const item = definition.scenes[index]!;\n try {\n const sourceBase =\n item.source.baseUrl === undefined\n ? undefined\n : resolveResource(root, item.source.baseUrl);\n const sceneOptions = {\n id: item.id,\n resolveAssetUrl: options.resolveAssetUrl,\n };\n const scene =\n item.source.viewerUrl !== undefined\n ? await loadSceneFromJson(\n resolveResource(root, item.source.viewerUrl),\n {\n ...sceneOptions,\n baseUrl: sourceBase,\n requestInit: {\n ...options.requestInit,\n signal: controller.signal,\n },\n }\n )\n : sceneFromViewerConfig(item.source.viewerConfig, {\n ...sceneOptions,\n baseUrl: sourceBase ?? root,\n });\n aborted(controller.signal);\n scenes[index] = {\n scene,\n title: item.title,\n initialView: item.initialView\n ? { yaw: 0, pitch: 0, fov: 75, ...item.initialView }\n : undefined,\n hotspots: item.hotspots!.map((h) =>\n resolveHotspotAssets(h, root, item.id, options.resolveAssetUrl)\n ),\n };\n } catch (cause) {\n if (!failure) {\n const error =\n cause instanceof PanoDataError\n ? cause\n : new PanoDataError(\n \"INVALID_CONFIG\",\n cause instanceof Error\n ? cause.message\n : \"Could not load scene\",\n { cause }\n );\n const field = `scenes[${index}].${\n error.field ??\n (item.source.viewerUrl !== undefined\n ? \"source.viewerUrl\"\n : \"source.viewerConfig\")\n }`;\n failure = new PanoDataError(\n error.code,\n `Scene ${item.id}: ${error.message}`,\n { status: error.status, sceneId: item.id, field, cause: error }\n );\n }\n controller.abort();\n }\n }\n }\n try {\n aborted(signal);\n await Promise.all(\n Array.from({ length: Math.min(4, scenes.length) }, worker)\n );\n aborted(signal);\n if (failure) throw failure;\n return {\n title: definition.title,\n initialSceneId: definition.initialSceneId!,\n scenes,\n };\n } finally {\n signal?.removeEventListener(\"abort\", cancel);\n }\n}\n"],"mappings":"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","names":["levels"]}