@vizor-vr/player 0.2.0 → 0.2.1
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.
- package/README.md +4 -0
- package/dist/__tests__/autoplay.test.d.ts +2 -0
- package/dist/__tests__/autoplay.test.d.ts.map +1 -0
- package/dist/__tests__/chapter-logic.test.d.ts +2 -0
- package/dist/__tests__/chapter-logic.test.d.ts.map +1 -0
- package/dist/__tests__/chapter-manager.test.d.ts +2 -0
- package/dist/__tests__/chapter-manager.test.d.ts.map +1 -0
- package/dist/__tests__/chapter-menu.test.d.ts +2 -0
- package/dist/__tests__/chapter-menu.test.d.ts.map +1 -0
- package/dist/__tests__/dom-drm.test.d.ts +2 -0
- package/dist/__tests__/dom-drm.test.d.ts.map +1 -0
- package/dist/__tests__/drm-gate.test.d.ts +2 -0
- package/dist/__tests__/drm-gate.test.d.ts.map +1 -0
- package/dist/__tests__/fairplay.test.d.ts +2 -0
- package/dist/__tests__/fairplay.test.d.ts.map +1 -0
- package/dist/__tests__/hub-controller.test.d.ts +2 -0
- package/dist/__tests__/hub-controller.test.d.ts.map +1 -0
- package/dist/__tests__/hub-layout.test.d.ts +2 -0
- package/dist/__tests__/hub-layout.test.d.ts.map +1 -0
- package/dist/__tests__/hub-model.test.d.ts +2 -0
- package/dist/__tests__/hub-model.test.d.ts.map +1 -0
- package/dist/__tests__/hub-panel-renderer.test.d.ts +2 -0
- package/dist/__tests__/hub-panel-renderer.test.d.ts.map +1 -0
- package/dist/__tests__/lens-angle.test.d.ts +2 -0
- package/dist/__tests__/lens-angle.test.d.ts.map +1 -0
- package/dist/__tests__/media-element-drm-gate.test.d.ts +2 -0
- package/dist/__tests__/media-element-drm-gate.test.d.ts.map +1 -0
- package/dist/__tests__/media-element-gating.test.d.ts +2 -0
- package/dist/__tests__/media-element-gating.test.d.ts.map +1 -0
- package/dist/__tests__/player-version-lock.test.d.ts +2 -0
- package/dist/__tests__/player-version-lock.test.d.ts.map +1 -0
- package/dist/__tests__/source-manager-drm.test.d.ts +2 -0
- package/dist/__tests__/source-manager-drm.test.d.ts.map +1 -0
- package/dist/__tests__/vz-chapter.test.d.ts +2 -0
- package/dist/__tests__/vz-chapter.test.d.ts.map +1 -0
- package/dist/__tests__/vz-cinema-gating.test.d.ts +2 -0
- package/dist/__tests__/vz-cinema-gating.test.d.ts.map +1 -0
- package/dist/__tests__/vz-hub-item.test.d.ts +2 -0
- package/dist/__tests__/vz-hub-item.test.d.ts.map +1 -0
- package/dist/__tests__/vz-tour-gating.test.d.ts +2 -0
- package/dist/__tests__/vz-tour-gating.test.d.ts.map +1 -0
- package/dist/__tests__/watch-time.test.d.ts +2 -0
- package/dist/__tests__/watch-time.test.d.ts.map +1 -0
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/annotations/annotation-popup.d.ts.map +1 -1
- package/dist/{annotations-C0ugfCn4.js → annotations-Du6ZWrqC.js} +82 -13
- package/dist/annotations-Du6ZWrqC.js.map +1 -0
- package/dist/captions/caption-renderer.d.ts.map +1 -1
- package/dist/{captions-BP0H2E03.js → captions-YvnHAwLY.js} +4 -4
- package/dist/captions-YvnHAwLY.js.map +1 -0
- package/dist/chapters/chapter-logic.d.ts +47 -0
- package/dist/chapters/chapter-logic.d.ts.map +1 -0
- package/dist/chapters/chapter-manager.d.ts +42 -0
- package/dist/chapters/chapter-manager.d.ts.map +1 -0
- package/dist/chapters/chapter-menu.d.ts +24 -0
- package/dist/chapters/chapter-menu.d.ts.map +1 -0
- package/dist/{collab-BXPomrS0.js → collab-BLpllHtb.js} +20 -14
- package/dist/collab-BLpllHtb.js.map +1 -0
- package/dist/collaborative/chat-button.d.ts.map +1 -1
- package/dist/collaborative/voice-button.d.ts.map +1 -1
- package/dist/controls/cc-button.d.ts.map +1 -1
- package/dist/controls/compass.d.ts.map +1 -1
- package/dist/controls/controls-overlay.d.ts.map +1 -1
- package/dist/controls/fullscreen-button.d.ts.map +1 -1
- package/dist/controls/icons.d.ts +1 -0
- package/dist/controls/icons.d.ts.map +1 -1
- package/dist/controls/live-indicator.d.ts.map +1 -1
- package/dist/controls/play-button.d.ts.map +1 -1
- package/dist/controls/playlist-controls.d.ts.map +1 -1
- package/dist/controls/quality-menu.d.ts.map +1 -1
- package/dist/controls/seek-bar.d.ts +9 -0
- package/dist/controls/seek-bar.d.ts.map +1 -1
- package/dist/controls/volume-control.d.ts.map +1 -1
- package/dist/controls/vr-button.d.ts.map +1 -1
- package/dist/core/base-element.d.ts +8 -0
- package/dist/core/base-element.d.ts.map +1 -1
- package/dist/core/media-element.d.ts +70 -1
- package/dist/core/media-element.d.ts.map +1 -1
- package/dist/{dash-adapter-tid9ZyhO.js → dash-adapter-BMpHWcBA.js} +9 -2
- package/dist/dash-adapter-BMpHWcBA.js.map +1 -0
- package/dist/delivery/__tests__/delivery-client.test.d.ts +2 -0
- package/dist/delivery/__tests__/delivery-client.test.d.ts.map +1 -0
- package/dist/delivery/__tests__/delivery-hydrate.test.d.ts +2 -0
- package/dist/delivery/__tests__/delivery-hydrate.test.d.ts.map +1 -0
- package/dist/delivery/delivery-client.d.ts +27 -0
- package/dist/delivery/delivery-client.d.ts.map +1 -0
- package/dist/delivery/delivery-hydrate.d.ts +18 -0
- package/dist/delivery/delivery-hydrate.d.ts.map +1 -0
- package/dist/delivery/dom-drm.d.ts +9 -0
- package/dist/delivery/dom-drm.d.ts.map +1 -0
- package/dist/elements/vz-chapter.d.ts +27 -0
- package/dist/elements/vz-chapter.d.ts.map +1 -0
- package/dist/elements/vz-cinema.d.ts +20 -0
- package/dist/elements/vz-cinema.d.ts.map +1 -1
- package/dist/elements/vz-hub-item.d.ts +23 -0
- package/dist/elements/vz-hub-item.d.ts.map +1 -0
- package/dist/elements/vz-hub.d.ts +57 -0
- package/dist/elements/vz-hub.d.ts.map +1 -0
- package/dist/elements/vz-playlist.d.ts +14 -0
- package/dist/elements/vz-playlist.d.ts.map +1 -1
- package/dist/elements/vz-tour.d.ts +16 -0
- package/dist/elements/vz-tour.d.ts.map +1 -1
- package/dist/hls-adapter-C_a65zia.js +161 -0
- package/dist/hls-adapter-C_a65zia.js.map +1 -0
- package/dist/hub/hub-controller.d.ts +31 -0
- package/dist/hub/hub-controller.d.ts.map +1 -0
- package/dist/hub/hub-layout.d.ts +23 -0
- package/dist/hub/hub-layout.d.ts.map +1 -0
- package/dist/hub/hub-model.d.ts +27 -0
- package/dist/hub/hub-model.d.ts.map +1 -0
- package/dist/hub/hub-panel-manager.d.ts +16 -0
- package/dist/hub/hub-panel-manager.d.ts.map +1 -0
- package/dist/hub/hub-panel-renderer.d.ts +26 -0
- package/dist/hub/hub-panel-renderer.d.ts.map +1 -0
- package/dist/license/__tests__/cache.test.d.ts +2 -0
- package/dist/license/__tests__/cache.test.d.ts.map +1 -0
- package/dist/license/__tests__/feature-gate.test.d.ts +2 -0
- package/dist/license/__tests__/feature-gate.test.d.ts.map +1 -0
- package/dist/license/__tests__/format-gate.test.d.ts +2 -0
- package/dist/license/__tests__/format-gate.test.d.ts.map +1 -0
- package/dist/license/__tests__/license-checker.test.d.ts.map +1 -0
- package/dist/license/__tests__/master-key.test.d.ts.map +1 -0
- package/dist/license/__tests__/verify-no-ed25519.test.d.ts +2 -0
- package/dist/license/__tests__/verify-no-ed25519.test.d.ts.map +1 -0
- package/dist/license/__tests__/verify.test.d.ts +2 -0
- package/dist/license/__tests__/verify.test.d.ts.map +1 -0
- package/dist/license/cache.d.ts +4 -0
- package/dist/license/cache.d.ts.map +1 -0
- package/dist/license/drm-gate.d.ts +15 -0
- package/dist/license/drm-gate.d.ts.map +1 -0
- package/dist/license/feature-gate.d.ts +27 -0
- package/dist/license/feature-gate.d.ts.map +1 -0
- package/dist/license/format-gate.d.ts +23 -0
- package/dist/license/format-gate.d.ts.map +1 -0
- package/dist/license/license-checker.d.ts.map +1 -1
- package/dist/license/master-key.d.ts +11 -7
- package/dist/license/master-key.d.ts.map +1 -1
- package/dist/license/trusted-key.d.ts +7 -0
- package/dist/license/trusted-key.d.ts.map +1 -0
- package/dist/license/verify.d.ts +7 -0
- package/dist/license/verify.d.ts.map +1 -0
- package/dist/{register-CwnmiGEs.js → register-BmZt_300.js} +1482 -163
- package/dist/register-BmZt_300.js.map +1 -0
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +1 -1
- package/dist/renderer/camera-controller.d.ts +1 -1
- package/dist/renderer/camera-controller.d.ts.map +1 -1
- package/dist/renderer/projections/fisheye-projection.d.ts +4 -0
- package/dist/renderer/projections/fisheye-projection.d.ts.map +1 -1
- package/dist/renderer/projections/spherical-projection.d.ts +26 -0
- package/dist/renderer/projections/spherical-projection.d.ts.map +1 -0
- package/dist/renderer/renderer.d.ts.map +1 -1
- package/dist/renderer/shaders/fisheye.glsl.d.ts +10 -1
- package/dist/renderer/shaders/fisheye.glsl.d.ts.map +1 -1
- package/dist/sri.json +8 -8
- package/dist/streaming/dash-adapter.d.ts +2 -2
- package/dist/streaming/dash-adapter.d.ts.map +1 -1
- package/dist/streaming/fairplay.d.ts +21 -0
- package/dist/streaming/fairplay.d.ts.map +1 -0
- package/dist/streaming/hls-adapter.d.ts +2 -2
- package/dist/streaming/hls-adapter.d.ts.map +1 -1
- package/dist/streaming/progressive-adapter.d.ts +2 -2
- package/dist/streaming/progressive-adapter.d.ts.map +1 -1
- package/dist/streaming/source-manager.d.ts +3 -1
- package/dist/streaming/source-manager.d.ts.map +1 -1
- package/dist/streaming/types.d.ts +9 -3
- package/dist/streaming/types.d.ts.map +1 -1
- package/dist/styles/controls.d.ts +1 -1
- package/dist/styles/controls.d.ts.map +1 -1
- package/dist/utils/static-html.d.ts +12 -0
- package/dist/utils/static-html.d.ts.map +1 -0
- package/dist/vizor.js +4 -4
- package/package.json +8 -5
- package/dist/__tests__/license-checker.test.d.ts.map +0 -1
- package/dist/__tests__/master-key.test.d.ts.map +0 -1
- package/dist/annotations-C0ugfCn4.js.map +0 -1
- package/dist/captions-BP0H2E03.js.map +0 -1
- package/dist/collab-BXPomrS0.js.map +0 -1
- package/dist/dash-adapter-tid9ZyhO.js.map +0 -1
- package/dist/hls-adapter-BivH46L_.js +0 -97
- package/dist/hls-adapter-BivH46L_.js.map +0 -1
- package/dist/register-CwnmiGEs.js.map +0 -1
- /package/dist/{__tests__ → license/__tests__}/license-checker.test.d.ts +0 -0
- /package/dist/{__tests__ → license/__tests__}/master-key.test.d.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hls-adapter-C_a65zia.js","sources":["../src/streaming/fairplay.ts","../src/streaming/hls-adapter.ts"],"sourcesContent":["/**\n * Native Safari FairPlay Streaming wiring. Safari plays HLS natively; FairPlay\n * is set up manually via EME: fetch the certificate, on `encrypted` create a\n * key session, on the SPC `message` POST it to the (Vizor-proxied) FairPlay\n * license URL with the x-api-key header, then update the session with the CKC.\n *\n * The pure helpers are unit-tested; the EME calls are runtime-only (no EME in\n * jsdom) and are documented for manual Safari verification. The exact EZDRM\n * FairPlay SPC/CKC encoding is pinned against the vendor guide at live\n * integration (isolated in buildSpcBody/parseCkc below).\n */\nimport type { DeliveryDrm } from '@vizor-vr/shared';\n\nconst FAIRPLAY_KEY_SYSTEM = 'com.apple.fps';\n\nexport function skdToContentId(skd: string): string {\n return skd.replace(/^skd:\\/\\//, '');\n}\n\nexport function toBase64(bytes: Uint8Array): string {\n let bin = '';\n for (const b of bytes) bin += String.fromCharCode(b);\n return btoa(bin);\n}\n\nexport function fromBase64(b64: string): Uint8Array {\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nexport interface FairPlayDeps {\n fetch: typeof fetch;\n requestMediaKeySystemAccess: typeof navigator.requestMediaKeySystemAccess;\n}\n\nexport async function setupFairPlay(\n video: HTMLVideoElement,\n drm: DeliveryDrm,\n apiKey: string | undefined,\n deps: FairPlayDeps = {\n fetch: (...a) => fetch(...a),\n requestMediaKeySystemAccess: (...a) => navigator.requestMediaKeySystemAccess(...a),\n },\n): Promise<void> {\n // Self-contain all setup failures (EME unavailable, cert fetch, setMediaKeys)\n // so callers can fire-and-forget without producing an unhandled rejection.\n try {\n const access = await deps.requestMediaKeySystemAccess(FAIRPLAY_KEY_SYSTEM, [\n {\n initDataTypes: ['skd', 'cenc'],\n videoCapabilities: [{ contentType: 'application/vnd.apple.mpegurl', robustness: '' }],\n distinctiveIdentifier: 'not-allowed',\n persistentState: 'not-allowed',\n } as MediaKeySystemConfiguration,\n ]);\n const mediaKeys = await access.createMediaKeys();\n\n if (drm.fairplayCertUrl) {\n const certRes = await deps.fetch(drm.fairplayCertUrl, { headers: apiKey ? { 'x-api-key': apiKey } : {} });\n const cert = new Uint8Array(await certRes.arrayBuffer());\n await mediaKeys.setServerCertificate(cert);\n }\n await video.setMediaKeys(mediaKeys);\n\n video.addEventListener('encrypted', (event) => {\n const e = event as unknown as { initDataType: string; initData: BufferSource };\n const session = mediaKeys.createSession();\n session.addEventListener('message', (msgEvent) => {\n const m = msgEvent as unknown as { message: ArrayBuffer };\n const spc = new Uint8Array(m.message);\n void (async () => {\n try {\n const res = await deps.fetch(drm.licenseUrls.fairplay, {\n method: 'POST',\n headers: { 'content-type': 'application/octet-stream', ...(apiKey ? { 'x-api-key': apiKey } : {}) },\n body: buildSpcBody(spc),\n });\n const ckc = new Uint8Array(await res.arrayBuffer());\n await session.update(parseCkc(ckc));\n } catch (err) {\n console.error('[Vizor] FairPlay license error:', err);\n }\n })();\n });\n void session.generateRequest(e.initDataType, e.initData);\n });\n } catch (err) {\n console.error('[Vizor] FairPlay setup failed:', err);\n }\n}\n\n/** EZDRM FairPlay request body. Pinned against the vendor guide at integration. */\nfunction buildSpcBody(spc: Uint8Array): BodyInit {\n return spc as BodyInit;\n}\n/** Parse the CKC out of the EZDRM response. Pinned at integration. */\nfunction parseCkc(ckc: Uint8Array): BufferSource {\n return ckc as unknown as BufferSource;\n}\n","import type { QualityLevel } from '@vizor-vr/shared';\nimport type { IStreamingAdapter, DrmContext } from './types.js';\nimport { setupFairPlay } from './fairplay.js';\n\n/**\n * HLS streaming adapter wrapping hls.js.\n * Lazy-loaded via dynamic import — only included in the bundle\n * when an HLS source is detected.\n *\n * Falls back to native HLS on Safari (no hls.js needed).\n */\nexport class HlsAdapter implements IStreamingAdapter {\n private videoElement: HTMLVideoElement | null = null;\n private hls: unknown | null = null;\n private _isAttached = false;\n private _isNative = false;\n private levels: QualityLevel[] = [];\n\n /** Enable low-latency mode for live streams */\n lowLatencyMode = false;\n\n get supportsABR(): boolean {\n return !this._isNative;\n }\n\n get isAttached(): boolean {\n return this._isAttached;\n }\n\n attach(videoElement: HTMLVideoElement): void {\n this.videoElement = videoElement;\n this._isAttached = true;\n }\n\n async load(url: string, drm?: DrmContext): Promise<void> {\n if (!this.videoElement) return;\n\n // Safari supports HLS natively — no need for hls.js\n if (this.videoElement.canPlayType('application/vnd.apple.mpegurl')) {\n this.videoElement.src = url;\n this._isNative = true;\n if (drm) void setupFairPlay(this.videoElement, drm.config, drm.apiKey);\n return;\n }\n\n try {\n const HlsModule = await import('hls.js');\n const Hls = HlsModule.default;\n\n if (!Hls.isSupported()) {\n console.error('[Vizor] HLS.js is not supported in this browser');\n return;\n }\n\n // Destroy previous instance\n if (this.hls) {\n (this.hls as { destroy(): void }).destroy();\n }\n\n const hls = new Hls({\n enableWorker: true,\n lowLatencyMode: this.lowLatencyMode,\n ...(this.lowLatencyMode\n ? { liveSyncDurationCount: 3, liveMaxLatencyDurationCount: 6 }\n : {}),\n ...(drm\n ? {\n emeEnabled: true,\n drmSystems: {\n 'com.widevine.alpha': { licenseUrl: drm.config.licenseUrls.widevine },\n 'com.microsoft.playready': { licenseUrl: drm.config.licenseUrls.playready },\n },\n licenseXhrSetup: (xhr: XMLHttpRequest, _url: string) => {\n if (drm.apiKey) xhr.setRequestHeader('x-api-key', drm.apiKey);\n },\n }\n : {}),\n });\n\n hls.attachMedia(this.videoElement);\n hls.loadSource(url);\n\n hls.on(Hls.Events.MANIFEST_PARSED, () => {\n this.levels = hls.levels.map(\n (level: { height: number; width: number; bitrate: number }, i: number) => ({\n label: level.height ? `${level.height}p` : `Level ${i}`,\n width: level.width,\n height: level.height,\n bitrate: level.bitrate,\n active: i === hls.currentLevel,\n }),\n );\n });\n\n hls.on(Hls.Events.ERROR, (_event: string, data: { fatal: boolean; type: string; details: string }) => {\n if (data.fatal) {\n console.error('[Vizor] Fatal HLS error:', data.type, data.details);\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n hls.startLoad();\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n hls.recoverMediaError();\n break;\n default:\n this.destroy();\n break;\n }\n }\n });\n\n this.hls = hls;\n } catch (e) {\n console.error('[Vizor] Failed to load hls.js:', e);\n }\n }\n\n getQualityLevels(): QualityLevel[] {\n return this.levels;\n }\n\n setQualityLevel(index: number): void {\n if (!this.hls || this._isNative) return;\n const hls = this.hls as { currentLevel: number };\n hls.currentLevel = index; // -1 = auto\n }\n\n destroy(): void {\n if (this.hls && !this._isNative) {\n (this.hls as { destroy(): void }).destroy();\n }\n this.hls = null;\n this.videoElement = null;\n this._isAttached = false;\n this._isNative = false;\n this.levels = [];\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { VzEventEmitter } from '../core/event-emitter.js';
|
|
2
|
+
import type { HubItem } from './hub-model.js';
|
|
3
|
+
export interface HubControllerOptions {
|
|
4
|
+
items: HubItem[];
|
|
5
|
+
events: VzEventEmitter;
|
|
6
|
+
/** Enter an item: swap the lobby scene for that item's playback. */
|
|
7
|
+
onShowItem: (item: HubItem, index: number) => void;
|
|
8
|
+
/** Return to the lobby scene. */
|
|
9
|
+
onShowLobby: () => void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Selection state machine for vz-hub. Tracks whether the viewer is in the lobby
|
|
13
|
+
* (activeIndex -1) or playing an item, drives the show-item/show-lobby callbacks
|
|
14
|
+
* the element wires to the renderer, and fires `vz-hub-select` on entry. Kept
|
|
15
|
+
* separate from the WebGL element so the transitions are unit-tested.
|
|
16
|
+
*/
|
|
17
|
+
export declare class HubController {
|
|
18
|
+
private items;
|
|
19
|
+
private events;
|
|
20
|
+
private onShowItem;
|
|
21
|
+
private onShowLobby;
|
|
22
|
+
private activeIndex;
|
|
23
|
+
constructor(opts: HubControllerOptions);
|
|
24
|
+
isInLobby(): boolean;
|
|
25
|
+
getActiveIndex(): number;
|
|
26
|
+
/** Select an item by index: play it and fire vz-hub-select. No-op if invalid or already active. */
|
|
27
|
+
select(index: number): void;
|
|
28
|
+
/** Return to the lobby. No-op if already there. */
|
|
29
|
+
back(): void;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=hub-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-controller.d.ts","sourceRoot":"","sources":["../../src/hub/hub-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;IACvB,oEAAoE;IACpE,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,iCAAiC;IACjC,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAED;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,UAAU,CAAyC;IAC3D,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,WAAW,CAAM;gBAEb,IAAI,EAAE,oBAAoB;IAOtC,SAAS,IAAI,OAAO;IAIpB,cAAc,IAAI,MAAM;IAIxB,mGAAmG;IACnG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAc3B,mDAAmD;IACnD,IAAI,IAAI,IAAI;CAKb"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, DOM-free layout math for the vz-hub lobby: distribute N content panels
|
|
3
|
+
* around the viewer as {lat, lon} positions (degrees), so the placement can be
|
|
4
|
+
* unit-tested without a renderer. Panels sit at eye level (lat 0) and are
|
|
5
|
+
* centered on dead-ahead (lon 0); once the arc would wrap past ~330° they
|
|
6
|
+
* spread evenly around a full ring instead.
|
|
7
|
+
*/
|
|
8
|
+
export interface HubPanelPosition {
|
|
9
|
+
/** Vertical angle in degrees (0 = eye level). */
|
|
10
|
+
lat: number;
|
|
11
|
+
/** Horizontal angle in degrees, normalized to [-180, 180] (0 = dead ahead). */
|
|
12
|
+
lon: number;
|
|
13
|
+
}
|
|
14
|
+
export interface HubLayoutOptions {
|
|
15
|
+
/** Degrees between adjacent panels in the front-arc layout. */
|
|
16
|
+
spacingDeg?: number;
|
|
17
|
+
/** Eye-level offset for all panels. */
|
|
18
|
+
lat?: number;
|
|
19
|
+
}
|
|
20
|
+
/** Normalize an angle in degrees to the range [-180, 180]. */
|
|
21
|
+
export declare function normalizeLon(lon: number): number;
|
|
22
|
+
export declare function hubPanelLayout(count: number, opts?: HubLayoutOptions): HubPanelPosition[];
|
|
23
|
+
//# sourceMappingURL=hub-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-layout.d.ts","sourceRoot":"","sources":["../../src/hub/hub-layout.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,+EAA+E;IAC/E,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,8DAA8D;AAC9D,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,gBAAgB,EAAE,CAe7F"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure item model for vz-hub. Turns raw parsed <vz-hub-item> attributes into a
|
|
3
|
+
* normalized, playable HubItem list (stable ids, defaults, drops items with no
|
|
4
|
+
* source) so the parsing is unit-tested rather than done inline in the element.
|
|
5
|
+
*/
|
|
6
|
+
export interface RawHubItem {
|
|
7
|
+
src?: string | null;
|
|
8
|
+
poster?: string | null;
|
|
9
|
+
title?: string | null;
|
|
10
|
+
format?: string | null;
|
|
11
|
+
contentId?: string | null;
|
|
12
|
+
}
|
|
13
|
+
export interface HubItem {
|
|
14
|
+
/** Stable id: the content-id if present, else a positional `item-<n>`. */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Playable media URL. */
|
|
17
|
+
src: string;
|
|
18
|
+
/** Thumbnail shown on the lobby panel (null = fall back to a placeholder). */
|
|
19
|
+
poster: string | null;
|
|
20
|
+
title: string;
|
|
21
|
+
/** VzFormat string; defaults to MONO_360. */
|
|
22
|
+
format: string;
|
|
23
|
+
}
|
|
24
|
+
/** Heuristic: does a source URL point at a still image (→ vz-img) vs video (→ vz-video)? */
|
|
25
|
+
export declare function isImageSource(src: string): boolean;
|
|
26
|
+
export declare function normalizeHubItems(raw: RawHubItem[]): HubItem[];
|
|
27
|
+
//# sourceMappingURL=hub-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-model.d.ts","sourceRoot":"","sources":["../../src/hub/hub-model.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,OAAO;IACtB,0EAA0E;IAC1E,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,8EAA8E;IAC9E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGlD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,CAc9D"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Scene, PerspectiveCamera } from 'three';
|
|
2
|
+
import type { HubItem } from './hub-model.js';
|
|
3
|
+
/**
|
|
4
|
+
* Orchestrates hub lobby panels: renders poster panels (HubPanelRenderer) and
|
|
5
|
+
* reuses the shared HotspotInteraction raycaster for click selection, mapping
|
|
6
|
+
* the sprite's index tag back to an item index. Mirrors HotspotManager.
|
|
7
|
+
*/
|
|
8
|
+
export declare class HubPanelManager {
|
|
9
|
+
private renderer;
|
|
10
|
+
private interaction;
|
|
11
|
+
constructor(scene: Scene, camera: PerspectiveCamera, domElement: HTMLElement, onSelect: (index: number) => void);
|
|
12
|
+
setItems(items: HubItem[]): void;
|
|
13
|
+
clear(): void;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=hub-panel-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-panel-manager.d.ts","sourceRoot":"","sources":["../../src/hub/hub-panel-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAGtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAmB;IACnC,OAAO,CAAC,WAAW,CAAqB;gBAGtC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,iBAAiB,EACzB,UAAU,EAAE,WAAW,EACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;IAYnC,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhC,KAAK,IAAI,IAAI;IAIb,OAAO,IAAI,IAAI;CAIhB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Sprite } from 'three';
|
|
2
|
+
import type { Scene } from 'three';
|
|
3
|
+
import type { HubItem } from './hub-model.js';
|
|
4
|
+
/**
|
|
5
|
+
* Renders clickable lobby panels for vz-hub: one sprite per HubItem, positioned
|
|
6
|
+
* around the viewer via hubPanelLayout on the inside of the panorama sphere.
|
|
7
|
+
* Each sprite starts as a titled placeholder card and, if the item has a poster,
|
|
8
|
+
* swaps to the poster texture once it loads. `userData.portalTo` carries the
|
|
9
|
+
* item index as a string so the shared HotspotInteraction raycaster can drive
|
|
10
|
+
* selection with no changes.
|
|
11
|
+
*/
|
|
12
|
+
export declare class HubPanelRenderer {
|
|
13
|
+
private sprites;
|
|
14
|
+
private posterTextures;
|
|
15
|
+
private scene;
|
|
16
|
+
private loader;
|
|
17
|
+
constructor(scene: Scene);
|
|
18
|
+
/** Build a panel sprite per item and add them to the scene. */
|
|
19
|
+
setItems(items: HubItem[]): void;
|
|
20
|
+
/** Sprites for raycasting (consumed by HotspotInteraction). */
|
|
21
|
+
getSprites(): Sprite[];
|
|
22
|
+
clear(): void;
|
|
23
|
+
dispose(): void;
|
|
24
|
+
private createPanelSprite;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=hub-panel-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-panel-renderer.d.ts","sourceRoot":"","sources":["../../src/hub/hub-panel-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA8E,MAAM,OAAO,CAAC;AAC3G,OAAO,KAAK,EAAE,KAAK,EAAW,MAAM,OAAO,CAAC;AAG5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAQ9C;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,MAAM,CAAuB;gBAEzB,KAAK,EAAE,KAAK;IAIxB,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI;IAUhC,+DAA+D;IAC/D,UAAU,IAAI,MAAM,EAAE;IAItB,KAAK,IAAI,IAAI;IAWb,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,iBAAiB;CAyD1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.test.d.ts","sourceRoot":"","sources":["../../../src/license/__tests__/cache.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-gate.test.d.ts","sourceRoot":"","sources":["../../../src/license/__tests__/feature-gate.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-gate.test.d.ts","sourceRoot":"","sources":["../../../src/license/__tests__/format-gate.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license-checker.test.d.ts","sourceRoot":"","sources":["../../../src/license/__tests__/license-checker.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"master-key.test.d.ts","sourceRoot":"","sources":["../../../src/license/__tests__/master-key.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-no-ed25519.test.d.ts","sourceRoot":"","sources":["../../../src/license/__tests__/verify-no-ed25519.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.test.d.ts","sourceRoot":"","sources":["../../../src/license/__tests__/verify.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LicenseResult } from '@vizor-vr/shared';
|
|
2
|
+
export declare function writeLicenseCache(licenseKey: string, domain: string, result: LicenseResult, now?: number): void;
|
|
3
|
+
export declare function readLicenseCache(licenseKey: string, domain: string, now?: number): LicenseResult | null;
|
|
4
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/license/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA8CtD,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,EACrB,GAAG,GAAE,MAAmB,GACvB,IAAI,CAYN;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,GAAG,GAAE,MAAmB,GACvB,aAAa,GAAG,IAAI,CA8BtB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DRM tier gate. Unlike other player features, a DRM asset is encrypted-only —
|
|
3
|
+
* there is no plain fallback — so an unlicensed tier is BLOCKED (an upgrade
|
|
4
|
+
* overlay) rather than gracefully degraded. The two inputs are whether the
|
|
5
|
+
* asset carries a DRM config and whether the resolved license enables `drm`.
|
|
6
|
+
*/
|
|
7
|
+
export type DrmGateDecision = {
|
|
8
|
+
action: 'none';
|
|
9
|
+
} | {
|
|
10
|
+
action: 'allow';
|
|
11
|
+
} | {
|
|
12
|
+
action: 'block';
|
|
13
|
+
};
|
|
14
|
+
export declare function resolveDrmGate(hasDrmConfig: boolean, drmFeatureEnabled: boolean): DrmGateDecision;
|
|
15
|
+
//# sourceMappingURL=drm-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drm-gate.d.ts","sourceRoot":"","sources":["../../src/license/drm-gate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7F,wBAAgB,cAAc,CAAC,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,OAAO,GAAG,eAAe,CAGjG"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { FeatureFlags } from '@vizor-vr/shared';
|
|
2
|
+
/**
|
|
3
|
+
* Tier gating for player features (webxr, spatialAudio, tours, cinema, playlist,
|
|
4
|
+
* …). This is the feature-flag analogue of `resolveFormatGate` in format-gate.ts.
|
|
5
|
+
*
|
|
6
|
+
* Per product decision the player degrades gracefully rather than hard-failing:
|
|
7
|
+
* a tier that lacks a feature falls back to a sensible baseline (e.g. a tour
|
|
8
|
+
* shows its start panorama without portal navigation, a playlist plays its first
|
|
9
|
+
* item, spatial audio plays as plain stereo) instead of blocking. So the only
|
|
10
|
+
* two outcomes here are `allow` (feature licensed) and `degrade` (feature not
|
|
11
|
+
* licensed — the caller applies its own fallback). A caller that has *no*
|
|
12
|
+
* sensible fallback can still choose to render an upgrade overlay on `degrade`.
|
|
13
|
+
*/
|
|
14
|
+
export type FeatureGateDecision = {
|
|
15
|
+
action: 'allow';
|
|
16
|
+
} | {
|
|
17
|
+
action: 'degrade';
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Decide whether a feature may run under the current license.
|
|
21
|
+
*
|
|
22
|
+
* @param _feature the feature flag name (kept for call-site clarity + future
|
|
23
|
+
* per-feature policy; the decision today depends only on `enabled`).
|
|
24
|
+
* @param enabled whether the resolved license enables the feature.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveFeatureGate(_feature: keyof FeatureFlags, enabled: boolean): FeatureGateDecision;
|
|
27
|
+
//# sourceMappingURL=feature-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-gate.d.ts","sourceRoot":"","sources":["../../src/license/feature-gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1B;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,YAAY,EAC5B,OAAO,EAAE,OAAO,GACf,mBAAmB,CAErB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { VzFormat } from '@vizor-vr/shared';
|
|
2
|
+
import type { FeatureFlags } from '@vizor-vr/shared';
|
|
3
|
+
/**
|
|
4
|
+
* Tier gating for playback formats. A free-tier viewer must not get the paid
|
|
5
|
+
* stereo/180 formats, but per product decision we degrade gracefully rather than
|
|
6
|
+
* hard-fail: a stereo format renders as its mono equivalent (one eye), and only
|
|
7
|
+
* formats with no sensible fallback (a 180 half-sphere projection) are blocked.
|
|
8
|
+
*/
|
|
9
|
+
export type FormatGateDecision = {
|
|
10
|
+
action: 'allow';
|
|
11
|
+
} | {
|
|
12
|
+
action: 'downgrade';
|
|
13
|
+
to: VzFormat;
|
|
14
|
+
} | {
|
|
15
|
+
action: 'block';
|
|
16
|
+
requires: 'stereoFormats' | 'formats180';
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Decide whether a format may play under the given license features, returning a
|
|
20
|
+
* graceful downgrade where one exists.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveFormatGate(format: VzFormat | string, features: FeatureFlags): FormatGateDecision;
|
|
23
|
+
//# sourceMappingURL=format-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-gate.d.ts","sourceRoot":"","sources":["../../src/license/format-gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAiB,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAA8B,MAAM,kBAAkB,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,QAAQ,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,eAAe,GAAG,YAAY,CAAA;CAAE,CAAC;AAiBlE;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,QAAQ,GAAG,MAAM,EACzB,QAAQ,EAAE,YAAY,GACrB,kBAAkB,CAgBpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"license-checker.d.ts","sourceRoot":"","sources":["../../src/license/license-checker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"license-checker.d.ts","sourceRoot":"","sources":["../../src/license/license-checker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAOnE,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAID;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAkBhF"}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { LicenseResult } from '@vizor-vr/shared';
|
|
2
2
|
/**
|
|
3
|
-
* Check
|
|
3
|
+
* Check whether a standalone license key is a master key (→ enterprise features).
|
|
4
4
|
*
|
|
5
|
-
* A master key is
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* A master key is an ordinary server-signed license whose verified payload tier
|
|
6
|
+
* is `'master'`. It is verified against the pinned trusted public key exactly
|
|
7
|
+
* like any other license — a REAL Ed25519 signature is required.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* SECURITY: the previous implementation granted enterprise on two plain
|
|
10
|
+
* string-equality checks (`tier === 'master'` and `payload.publicKey === masterPubKey`)
|
|
11
|
+
* with NO signature verification, so anyone who knew the master public key could
|
|
12
|
+
* self-sign a master license. That bypass is gone.
|
|
10
13
|
*
|
|
11
|
-
* @returns
|
|
14
|
+
* @returns an enterprise `LicenseResult`, or `null` if this is not a validly
|
|
15
|
+
* signed master key.
|
|
12
16
|
*/
|
|
13
|
-
export declare function checkMasterKey(licenseKey: string): LicenseResult | null
|
|
17
|
+
export declare function checkMasterKey(licenseKey: string): Promise<LicenseResult | null>;
|
|
14
18
|
//# sourceMappingURL=master-key.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"master-key.d.ts","sourceRoot":"","sources":["../../src/license/master-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"master-key.d.ts","sourceRoot":"","sources":["../../src/license/master-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAKtD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAWtF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single trusted server public key that ALL standalone license signatures are
|
|
3
|
+
* verified against. Returns '' when no key was pinned at build time (e.g. a dev
|
|
4
|
+
* build), in which case every standalone license fails closed (treated as free).
|
|
5
|
+
*/
|
|
6
|
+
export declare function getTrustedPublicKey(): string;
|
|
7
|
+
//# sourceMappingURL=trusted-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trusted-key.d.ts","sourceRoot":"","sources":["../../src/license/trusted-key.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/license/verify.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CAEpB;AAED,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA2CjC"}
|