@cloudpdf/engine 3.0.0-next.2 → 3.0.0-next.4
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/dist/index.cjs +116 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -6
- package/dist/index.d.ts +29 -6
- package/dist/index.js +116 -63
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["AbortablePromise","EngineError","EngineErrorCode","wirePaths","DocumentActionsSnapshotSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","WeakAnnotationSessionResponseSchema","AnnotationListPageSnapshotSchema","EngineError","EngineErrorCode","EmbeddedFileItemSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","AttachmentCreateResultSchema","AttachmentDeleteResultSchema","AbortablePromise","wirePaths","FormSnapshotSchema","FormFieldDTOSchema","FormSetValueResultSchema","FormEffectsResultSchema","FormImportResultSchema","FormFieldCreateResultSchema","FormFieldUpdateResultSchema","FormFieldDeleteResultSchema","FormWidgetLinkResultSchema","FormRepairResultSchema","EngineError","EngineErrorCode","AbortablePromise","EngineError","EngineErrorCode","wirePaths","PageListSnapshotSchema","PageMoveResultSchema","PageRotateResultSchema","PageDeleteResultSchema","PageFlattenResultSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","RedactionApplyResultSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","SearchSliceSchema","EngineError","EngineErrorCode","AbortablePromise","EngineError","EngineErrorCode","wirePaths","AccessResponseSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","DocumentMetadataSchema","MetadataUpdateResultSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","AnnotationListPageSnapshotSchema","AnnotationCreateResultSchema","AnnotationUpdateResultSchema","AnnotationDeleteResultSchema","AnnotationMoveResultSchema","AnnotationAppearanceManifestSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","PageGeometrySnapshotSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","AbortablePromise","EngineError","EngineErrorCode","wirePaths","PageTextSnapshotSchema","EngineError","EngineErrorCode","DEFAULT_LAYER_NAME","CONTINUOUS_RENDER_POLICY","EventHub","SessionEventPublisher","AbortablePromise","EngineError","EngineErrorCode","DEFAULT_PDF_SAVE_MODE","wirePaths","DocumentHeadSchema","DocumentManifestSchema","AbortError","EngineError","EngineErrorCode","AbortError","EngineErrorPayloadSchema","AbortablePromise","EngineError","EngineErrorCode","DEFAULT_LAYER_NAME","wirePaths","DocumentHeadSchema"],"sources":["../src/document/planes.ts","../src/document/CloudDocumentActionsService.ts","../src/document/CloudDocumentAnnotationsService.ts","../src/document/buildMutationForm.ts","../src/document/parseAttachmentContent.ts","../src/document/CloudDocumentAttachmentsService.ts","../src/document/CloudDocumentFormsService.ts","../src/document/CloudDocumentPagesService.ts","../src/document/CloudDocumentRedactionService.ts","../src/document/CloudDocumentSearchService.ts","../src/transport/decodeUnverifiedClaims.ts","../src/document/CloudDocumentSecurityService.ts","../src/document/CloudMetadataService.ts","../src/document/CloudPageAnnotationsService.ts","../src/document/CloudPageGeometryService.ts","../src/document/CloudPageRenderService.ts","../src/document/CloudPageTextService.ts","../src/document/CloudPageHandle.ts","../src/realtime/auditRowToEvent.ts","../src/realtime/SseClient.ts","../src/document/CloudDocumentHandle.ts","../src/transport/HttpClient.ts","../src/CloudEngine.ts","../src/share.ts","../src/index.ts"],"sourcesContent":["import type { DocumentManifest, LayerScopePlane } from '@embedpdf/engine-core/wire';\n\n/**\n * Plane-scope resolution — THE one rule every cloud service uses to pick a\n * path family: a read resolves at the DOC-LEVEL (shared base) path iff EVERY\n * plane it depends on is inherited (`'base'`) by this layer. One owned plane\n * → the layer-scoped path.\n *\n * Absent `scopes` (base manifests never carry it; pre-plane servers omit\n * it) means layer paths — never wrong, only unshared.\n */\nexport function planesInherited(\n manifest: DocumentManifest,\n planes: readonly LayerScopePlane[],\n): boolean {\n const scopes = manifest.scopes;\n if (!scopes) return false;\n return planes.every((plane) => scopes[plane] === 'base');\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type DocumentActionsService,\n type DocumentActionsSnapshot,\n} from '@embedpdf/engine-core/runtime';\nimport { DocumentActionsSnapshotSchema, wirePaths } from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudDocumentActionsService implements DocumentActionsService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n read(): AbortablePromise<DocumentActionsSnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run((signal) =>\n this.http.getJsonWithRefresh(\n async (currentSignal) => {\n const manifest = await this.manifest.get(currentSignal);\n // Plane-scope rule: catalog actions depend on the `actions` plane\n // (constant-inherited until action writing exists) — one\n // doc-level URL, base session, no layer warm-up on open.\n return planesInherited(manifest, ['actions'])\n ? wirePaths.docActions(this.docId, manifest.actionsVersion)\n : wirePaths.layerActions(this.docId, this.layerName, manifest.actionsVersion);\n },\n (raw) => DocumentActionsSnapshotSchema.parse(raw),\n async (currentSignal) => {\n await this.manifest.refresh(currentSignal);\n },\n signal,\n ),\n );\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type AnnotationListPageSnapshot,\n type AnnotationListSnapshotAllPages,\n type DocumentAnnotationsService,\n type PageObjectNumber,\n type WeakAnnotationEditSession,\n} from '@embedpdf/engine-core/runtime';\nimport {\n AnnotationListPageSnapshotSchema,\n WeakAnnotationSessionResponseSchema,\n wirePaths,\n type WeakAnnotationSessionResponse,\n} from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudDocumentAnnotationsService implements DocumentAnnotationsService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n listRawAll(): AbortablePromise<AnnotationListSnapshotAllPages> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AnnotationListSnapshotAllPages>(async (signal) => {\n const manifest = await this.manifest.get(signal);\n const pages = await Promise.all(\n manifest.pages.map((page) => this.readCurrentPage(page.state.pageObjectNumber, signal)),\n );\n return { pages };\n });\n }\n\n listRaw(pageObjectNumber: PageObjectNumber): AbortablePromise<AnnotationListPageSnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AnnotationListPageSnapshot>((signal) =>\n this.readCurrentPage(pageObjectNumber, signal),\n );\n }\n\n beginWeakEdit(\n pageObjectNumbers: readonly PageObjectNumber[],\n ): AbortablePromise<WeakAnnotationEditSession> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<WeakAnnotationEditSession>(async (signal) => {\n const response = await this.http.postJson(\n wirePaths.layerWeakAnnotationSession(this.docId, this.layerName),\n { pageObjectNumbers },\n (raw) => WeakAnnotationSessionResponseSchema.parse(raw),\n signal,\n );\n return new CloudWeakAnnotationEditSession(\n this.http,\n this.docId,\n this.layerName,\n () => this.isClosed(),\n response,\n );\n });\n }\n\n private async readCurrentPage(\n pageObjectNumber: PageObjectNumber,\n signal: AbortSignal,\n ): Promise<AnnotationListPageSnapshot> {\n return this.http.getJson(\n wirePaths.layerPageAnnotationsCurrent(this.docId, this.layerName, pageObjectNumber),\n (raw) => AnnotationListPageSnapshotSchema.parse(raw),\n signal,\n );\n }\n}\n\nclass CloudWeakAnnotationEditSession implements WeakAnnotationEditSession {\n private response: WeakAnnotationSessionResponse;\n private released = false;\n\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n response: WeakAnnotationSessionResponse,\n ) {\n this.response = response;\n }\n\n get id(): string {\n return this.response.sessionId;\n }\n\n get expiresAt(): number {\n return this.response.expiresAt;\n }\n\n get heartbeatIntervalMs(): number {\n return this.response.heartbeatIntervalMs;\n }\n\n get pageObjectNumbers(): readonly PageObjectNumber[] {\n return this.response.pageObjectNumbers;\n }\n\n covers(pageObjectNumber: PageObjectNumber): boolean {\n return this.response.pageObjectNumbers.includes(pageObjectNumber);\n }\n\n updatePages(pageObjectNumbers: readonly PageObjectNumber[]): AbortablePromise<void> {\n if (this.isClosed() || this.released) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `weak annotation session ${this.id} is closed`),\n );\n }\n return AbortablePromise.run<void>(async (signal) => {\n this.response = await this.http.postJson(\n wirePaths.layerWeakAnnotationSessionPages(this.docId, this.layerName, this.id),\n { pageObjectNumbers },\n (raw) => WeakAnnotationSessionResponseSchema.parse(raw),\n signal,\n );\n });\n }\n\n heartbeat(): AbortablePromise<void> {\n if (this.isClosed() || this.released) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `weak annotation session ${this.id} is closed`),\n );\n }\n return AbortablePromise.run<void>(async (signal) => {\n this.response = await this.http.postJson(\n wirePaths.layerWeakAnnotationSessionHeartbeat(this.docId, this.layerName, this.id),\n {},\n (raw) => WeakAnnotationSessionResponseSchema.parse(raw),\n signal,\n );\n });\n }\n\n release(): AbortablePromise<void> {\n if (this.released) {\n return AbortablePromise.resolveValue(undefined);\n }\n this.released = true;\n return AbortablePromise.run<void>((signal) =>\n this.http.deleteEmpty(\n wirePaths.layerWeakAnnotationSessionRelease(this.docId, this.layerName, this.id),\n signal,\n ),\n );\n }\n}\n","import type { WireResourceMap } from '@embedpdf/engine-core/runtime';\n\n/**\n * Multipart envelope for mutations that carry binaries: part `body` holds\n * the exact JSON the plain request would have been, plus one\n * `resource:{key}` file part per binary payload. Mirrors the appearance\n * response protocol (`manifest` part + named image parts) in reverse.\n * Shared by the annotation mutations (stamp images, attachment files) and\n * the document-level `attachments.create` — one envelope, one parser on\n * the server side.\n */\nexport function buildMutationForm(body: unknown, resources: WireResourceMap): FormData {\n const form = new FormData();\n form.append('body', JSON.stringify(body));\n for (const [key, resource] of Object.entries(resources)) {\n form.append(\n `resource:${key}`,\n new Blob([resource.bytes], { type: resource.mimeType ?? 'application/octet-stream' }),\n resource.name ?? key,\n );\n }\n return form;\n}\n\nexport function hasResources(resources: WireResourceMap): boolean {\n return Object.keys(resources).length > 0;\n}\n","import {\n EngineError,\n EngineErrorCode,\n type AttachmentContent,\n} from '@embedpdf/engine-core/runtime';\nimport { decodeTokenText } from '@embedpdf/engine-core/wire';\n\nimport type { HttpFileResponse } from '../transport/HttpClient';\n\n/** Header carrying the file's name, token-text encoded (names are\n * arbitrary UTF-8; HTTP header values are not). */\nconst FILE_NAME_HEADER = 'X-EmbedPDF-File-Name';\n\n/**\n * Project an attachment-file response into `AttachmentContent`. The body\n * IS the decoded bytes; the metadata rides as headers — `Content-Type`\n * for the declared mime type, `X-EmbedPDF-File-Name` for the file name.\n * Shared by the document-level `attachments.download()` and the\n * annotation-level `annotations.downloadFile()` reads — one wire shape\n * for both homes a file can live in.\n */\nexport function parseAttachmentContent(file: HttpFileResponse): AttachmentContent {\n const encodedName = file.headers.get(FILE_NAME_HEADER);\n if (encodedName === null) {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n `attachment response missing ${FILE_NAME_HEADER} header`,\n );\n }\n let name: string;\n try {\n name = decodeTokenText(encodedName);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n `malformed ${FILE_NAME_HEADER} header: ${(err as Error)?.message ?? err}`,\n { cause: err },\n );\n }\n const mimeType = file.headers.get('Content-Type');\n return {\n bytes: file.bytes,\n name,\n ...(mimeType !== null ? { mimeType } : {}),\n };\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n normalizeAttachmentFileSource,\n type AttachmentContent,\n type AttachmentCreateResult,\n type AttachmentDeleteResult,\n type AttachmentFileSource,\n type DocumentAttachmentsService,\n type EmbeddedFileItem,\n type EmbeddedFileRef,\n} from '@embedpdf/engine-core/runtime';\nimport {\n AttachmentCreateResultSchema,\n AttachmentDeleteResultSchema,\n EmbeddedFileItemSchema,\n wirePaths,\n} from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport { buildMutationForm } from './buildMutationForm';\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport { parseAttachmentContent } from './parseAttachmentContent';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/** The `/attachments@…` listing leaf is a bare array of name-tree entries. */\nconst EmbeddedFileListSchema = EmbeddedFileItemSchema.array();\n\n/**\n * Cloud-side document-level attachments (the catalog's `/EmbeddedFiles`\n * name tree). Reads use immutable leaves pinned by the manifest's\n * `attachmentsVersion`: `/attachments@…` for the metadata listing and\n * `/attachment-files/…@…` for one file's decoded bytes — a separate\n * capability tier, so a CDN credential for the listing can never egress\n * content. Mutations use unversioned collection/member URLs and are\n * never cached.\n */\nexport class CloudDocumentAttachmentsService implements DocumentAttachmentsService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n /**\n * Snapshot of the name tree, in tree (key-sorted) order. Pulls\n * `attachmentsVersion` from the cached manifest and, on a 404 (stale\n * pointer), transparently refreshes the manifest and retries once.\n * The pin bumps only on attachment writes, so this leaf stays cached\n * across page and annotation edits.\n */\n list(): AbortablePromise<EmbeddedFileItem[]> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<EmbeddedFileItem[]>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n // Plane-scope rule: the listing depends on the `attachments` plane —\n // while inherited, one CDN object serves every visitor's sidebar\n // from the base worker session.\n return planesInherited(manifest, ['attachments'])\n ? wirePaths.docAttachments(this.docId, manifest.attachmentsVersion)\n : wirePaths.layerAttachments(this.docId, this.layerName, manifest.attachmentsVersion);\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => EmbeddedFileListSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n\n /**\n * Decode and return one embedded file's bytes. The body is the decoded\n * stream; the name and mime type ride as response headers (see\n * `parseAttachmentContent`). Same versioned-leaf + refresh-retry rails\n * as {@link list}.\n */\n download(ref: EmbeddedFileRef): AbortablePromise<AttachmentContent> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AttachmentContent>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n // Same plane switch as list(): the byte leaf shares too.\n return planesInherited(manifest, ['attachments'])\n ? wirePaths.docAttachmentFile(this.docId, ref.key, manifest.attachmentsVersion)\n : wirePaths.layerAttachmentFile(\n this.docId,\n this.layerName,\n ref.key,\n manifest.attachmentsVersion,\n );\n };\n const file = await this.http.getFileWithRefresh(\n buildPath,\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n return parseAttachmentContent(file);\n });\n }\n\n /**\n * Create an embedded file in the name tree. Same splitter the\n * file-attachment annotation draft uses — metadata into the `body`\n * JSON part, bytes into the `resource:r0` file part — POSTed as the\n * standard multipart mutation envelope.\n */\n create(file: AttachmentFileSource): AbortablePromise<AttachmentCreateResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AttachmentCreateResult>(async (signal) => {\n const { wireFile, resource } = await normalizeAttachmentFileSource(file, 'r0');\n const result = await this.http.postMultipartJson(\n wirePaths.layerAttachmentsCollection(this.docId, this.layerName),\n buildMutationForm(wireFile, { r0: resource }),\n (raw) => AttachmentCreateResultSchema.parse(raw),\n signal,\n );\n // Patch the cached manifest, then publish (in that order — listeners\n // reading the manifest in their callback must see post-mutation\n // state). An attachment write only advances docVersion +\n // attachmentsVersion (no per-page pin changes, no layoutVersion), so\n // the cached manifest is patched in place — no refetch.\n if (result.cache) this.manifest.applyAttachments(result.cache);\n this.publisher.publishLocal({ type: 'attachment.created', ...result });\n return result;\n });\n }\n\n /** Delete an embedded file from the name tree by its durable key. */\n delete(ref: EmbeddedFileRef): AbortablePromise<AttachmentDeleteResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AttachmentDeleteResult>(async (signal) => {\n const result = await this.http.deleteJson(\n wirePaths.layerAttachmentItem(this.docId, this.layerName, ref.key),\n (raw) => AttachmentDeleteResultSchema.parse(raw),\n signal,\n );\n // Same absorb-then-publish rails as create().\n if (result.cache) this.manifest.applyAttachments(result.cache);\n this.publisher.publishLocal({ type: 'attachment.deleted', ...result });\n return result;\n });\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n encodeFieldRefKey,\n type DocumentEventInit,\n type DocumentFormsService,\n type FormDataExport,\n type FormDataFormat,\n type FormEffect,\n type FormEffectsResult,\n type FormFieldCreateResult,\n type FormFieldDeleteResult,\n type FormFieldDraft,\n type FormFieldDTO,\n type FormFieldPatch,\n type FormFieldRef,\n type FormFieldUpdateResult,\n type FormFieldValue,\n type FormImportResult,\n type FormRepairOptions,\n type FormRepairResult,\n type FormSetValueResult,\n type FormSnapshot,\n type FormWidgetLinkResult,\n type FormWidgetRef,\n type MutationMeta,\n} from '@embedpdf/engine-core/runtime';\nimport {\n FormFieldCreateResultSchema,\n FormFieldDeleteResultSchema,\n FormFieldDTOSchema,\n FormFieldUpdateResultSchema,\n FormEffectsResultSchema,\n FormImportResultSchema,\n FormRepairResultSchema,\n FormSetValueResultSchema,\n FormSnapshotSchema,\n FormWidgetLinkResultSchema,\n wirePaths,\n} from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/** Content types the import POST body may carry; the server sniffs the\n * actual format from the bytes, so this is advisory only. */\nconst IMPORT_CONTENT_TYPE: Record<FormDataFormat, string> = {\n fdf: 'application/vnd.fdf',\n xfdf: 'application/vnd.adobe.xfdf',\n};\n\n/**\n * Cloud-side document forms service. Mirrors the local wiring: each call\n * produces an `AbortablePromise` that propagates `signal.abort()` down to\n * `fetch` and validates the JSON response with the wire-stable Zod schema.\n *\n * Forms are document-scoped, so reads use the unversioned `/form` URLs\n * (always `no-store` — there is no content-addressed variant). Mutation\n * results carry the per-page `cacheDelta` for pages whose widget\n * appearances changed; `absorbMutation` folds it into the cached manifest\n * so annotation/render reads stay coherent.\n */\nexport class CloudDocumentFormsService implements DocumentFormsService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n list(): AbortablePromise<FormSnapshot> {\n const rejected = this.rejectIfClosed<FormSnapshot>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormSnapshot>((signal) =>\n this.http.getJson(\n wirePaths.layerForm(this.docId, this.layerName),\n (raw) => FormSnapshotSchema.parse(raw),\n signal,\n ),\n );\n }\n\n get(ref: FormFieldRef): AbortablePromise<FormFieldDTO> {\n const rejected = this.rejectIfClosed<FormFieldDTO>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormFieldDTO>((signal) =>\n this.http.getJson(\n wirePaths.layerFormFieldByKey(this.docId, this.layerName, encodeFieldRefKey(ref)),\n (raw) => FormFieldDTOSchema.parse(raw),\n signal,\n ),\n );\n }\n\n setValue(ref: FormFieldRef, value: FormFieldValue): AbortablePromise<FormSetValueResult> {\n const rejected = this.rejectIfClosed<FormSetValueResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormSetValueResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormFieldValue(this.docId, this.layerName, encodeFieldRefKey(ref)),\n { value },\n (raw) => FormSetValueResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.valueChanged');\n });\n }\n\n reset(ref: FormFieldRef): AbortablePromise<FormSetValueResult> {\n const rejected = this.rejectIfClosed<FormSetValueResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormSetValueResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormFieldReset(this.docId, this.layerName, encodeFieldRefKey(ref)),\n {},\n (raw) => FormSetValueResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.valueChanged');\n });\n }\n\n applyEffects(effects: FormEffect[]): AbortablePromise<FormEffectsResult> {\n const rejected = this.rejectIfClosed<FormEffectsResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormEffectsResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormEffects(this.docId, this.layerName),\n { effects },\n (raw) => FormEffectsResultSchema.parse(raw),\n signal,\n );\n // An all-no-op/all-preflight-rejected batch deliberately has no\n // artifact, cache advance, or event.\n if (result.meta === null) return result;\n this.manifest.apply(result.meta, ['annotations']);\n this.publisher.publishLocal({ type: 'form.effectsApplied', ...result });\n return result;\n });\n }\n\n exportData(format: FormDataFormat = 'xfdf'): AbortablePromise<FormDataExport> {\n const rejected = this.rejectIfClosed<FormDataExport>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormDataExport>(async (signal) => {\n const bytes = await this.http.getBytes(\n wirePaths.layerFormData(this.docId, this.layerName, format),\n signal,\n );\n return { format, bytes };\n });\n }\n\n importData(\n data: Uint8Array | ArrayBuffer,\n format?: FormDataFormat,\n ): AbortablePromise<FormImportResult> {\n const rejected = this.rejectIfClosed<FormImportResult>();\n if (rejected) return rejected;\n const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : data;\n return AbortablePromise.run<FormImportResult>(async (signal) => {\n const result = await this.http.postBytesJson(\n wirePaths.layerFormData(this.docId, this.layerName, format),\n bytes,\n format ? IMPORT_CONTENT_TYPE[format] : 'application/octet-stream',\n (raw) => FormImportResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.imported');\n });\n }\n\n createField(draft: FormFieldDraft): AbortablePromise<FormFieldCreateResult> {\n const rejected = this.rejectIfClosed<FormFieldCreateResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormFieldCreateResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormFields(this.docId, this.layerName),\n draft,\n (raw) => FormFieldCreateResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.fieldCreated');\n });\n }\n\n updateField(ref: FormFieldRef, patch: FormFieldPatch): AbortablePromise<FormFieldUpdateResult> {\n const rejected = this.rejectIfClosed<FormFieldUpdateResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormFieldUpdateResult>(async (signal) => {\n const result = await this.http.patchJson(\n wirePaths.layerFormFieldByKey(this.docId, this.layerName, encodeFieldRefKey(ref)),\n patch,\n (raw) => FormFieldUpdateResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.fieldUpdated');\n });\n }\n\n deleteField(ref: FormFieldRef): AbortablePromise<FormFieldDeleteResult> {\n const rejected = this.rejectIfClosed<FormFieldDeleteResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormFieldDeleteResult>(async (signal) => {\n const result = await this.http.deleteJson(\n wirePaths.layerFormFieldByKey(this.docId, this.layerName, encodeFieldRefKey(ref)),\n (raw) => FormFieldDeleteResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.fieldDeleted');\n });\n }\n\n attachWidget(\n ref: FormFieldRef,\n widget: FormWidgetRef,\n options?: { onState?: string },\n ): AbortablePromise<FormWidgetLinkResult> {\n const rejected = this.rejectIfClosed<FormWidgetLinkResult>();\n if (rejected) return rejected;\n const onState = options?.onState;\n return AbortablePromise.run<FormWidgetLinkResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormFieldWidgets(this.docId, this.layerName, encodeFieldRefKey(ref)),\n { widget, ...(onState ? { onState } : {}) },\n (raw) => FormWidgetLinkResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.widgetAttached');\n });\n }\n\n detachWidget(ref: FormFieldRef, widget: FormWidgetRef): AbortablePromise<FormWidgetLinkResult> {\n const rejected = this.rejectIfClosed<FormWidgetLinkResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormWidgetLinkResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormFieldWidgetsDetach(this.docId, this.layerName, encodeFieldRefKey(ref)),\n { widget },\n (raw) => FormWidgetLinkResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.widgetDetached');\n });\n }\n\n repair(options?: FormRepairOptions): AbortablePromise<FormRepairResult> {\n const rejected = this.rejectIfClosed<FormRepairResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormRepairResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormRepair(this.docId, this.layerName),\n { bakeAppearances: options?.bakeAppearances ?? false },\n (raw) => FormRepairResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.repaired');\n });\n }\n\n private rejectIfClosed<T>(): AbortablePromise<T> | null {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return null;\n }\n\n /**\n * Patch the cached manifest, then publish the mutation to the document's\n * event stream (in that order — listeners reading the manifest in their\n * callback must see post-mutation state). Same rails as annotations.\n */\n private absorbMutation<T extends { meta: MutationMeta }>(\n result: T,\n type:\n | 'form.valueChanged'\n | 'form.imported'\n | 'form.repaired'\n | 'form.fieldCreated'\n | 'form.fieldUpdated'\n | 'form.fieldDeleted'\n | 'form.widgetAttached'\n | 'form.widgetDetached',\n ): T {\n this.manifest.apply(result.meta, ['annotations']);\n this.publisher.publishLocal({ type, ...result } as unknown as DocumentEventInit);\n return result;\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type DocumentPagesService,\n type PageFlattenResult,\n type PageFlattenUsage,\n type PageDeleteResult,\n type PageListSnapshot,\n type PageMoveResult,\n type PageObjectNumber,\n type PageRotateResult,\n type PageRotation,\n} from '@embedpdf/engine-core/runtime';\nimport {\n PageDeleteResultSchema,\n PageFlattenResultSchema,\n PageListSnapshotSchema,\n PageMoveResultSchema,\n PageRotateResultSchema,\n wirePaths,\n} from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Cloud-side document pages service. Mirrors `LocalDocumentPagesService`\n * over HTTP: GET /pages for `list`, POST /pages/move for the reorder.\n *\n * Page identity rule (locked with the user, do not change):\n * - Pages are addressed exclusively by their indirect\n * `pageObjectNumber`. The wire never sends a page index for a\n * mutation. This keeps multi-call client logic from having to\n * account for index drift between requests.\n * - Successful `move()` returns the new `layout` (order + geometry) plus\n * cloud coherence pins. The server does NOT bump per-page revisions on a\n * page move (page reorder is intentionally outside the weak-ref staleness\n * model), only `docVersion` + `layoutVersion`.\n */\nexport class CloudDocumentPagesService implements DocumentPagesService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n /**\n * Page-geometry list. The geometry bytes live at the content-addressed\n * `/layout@layoutVersion=N` leaf (not in the manifest); the manifest only\n * publishes the `layoutVersion` pointer. So `list()` reads `layoutVersion`\n * from the cached manifest, fetches the layout leaf, and on a 404 (stale\n * pointer) transparently refreshes the manifest and retries once — the\n * same ladder the per-page text/geometry reads use. `layoutVersion` bumps\n * only on structural page ops, so this leaf stays cached across content\n * and annotation edits.\n */\n list(): AbortablePromise<PageListSnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageListSnapshot>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n // Plane-scope rule: the layout leaf depends on the `layout` plane —\n // while inherited (no move/rotate/insert/delete ever ran), every\n // visitor's page list is ONE doc-level URL served from the base\n // session; the SDK open sequence creates no layer session.\n return planesInherited(manifest, ['layout'])\n ? wirePaths.docLayout(this.docId, manifest.layoutVersion)\n : wirePaths.layerLayout(this.docId, this.layerName, manifest.layoutVersion);\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => PageListSnapshotSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n\n move(pageObjectNumbers: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageMoveResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerPagesMove(this.docId, this.layerName),\n { pageObjectNumbers, destIndex },\n (raw) => PageMoveResultSchema.parse(raw),\n signal,\n );\n // A move only advances docVersion + layoutVersion (no per-page pin\n // changes), so the cached manifest can be patched in place — no refetch.\n if (result.cache) this.manifest.applyPageStructure(result.cache);\n // Publish AFTER absorb: listeners reading the manifest in their\n // callback must see post-mutation state.\n this.publisher.publishLocal({ type: 'pages.moved', pageObjectNumbers, destIndex, ...result });\n return result;\n });\n }\n\n rotate(\n pageObjectNumbers: PageObjectNumber[],\n rotation: PageRotation,\n ): AbortablePromise<PageRotateResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageRotateResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerPagesRotate(this.docId, this.layerName),\n { pageObjectNumbers, rotation },\n (raw) => PageRotateResultSchema.parse(raw),\n signal,\n );\n // Rotation shares the move patch exactly: docVersion + layoutVersion\n // advance, every per-page pin (and its cached render) stays warm.\n if (result.cache) this.manifest.applyPageStructure(result.cache);\n this.publisher.publishLocal({\n type: 'pages.rotated',\n pageObjectNumbers,\n rotation,\n ...result,\n });\n return result;\n });\n }\n\n delete(pageObjectNumbers: PageObjectNumber[]): AbortablePromise<PageDeleteResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageDeleteResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerPagesDelete(this.docId, this.layerName),\n { pageObjectNumbers },\n (raw) => PageDeleteResultSchema.parse(raw),\n signal,\n );\n // The structural advance plus dropping the deleted pages' manifest\n // rows — a retired PON must not be buildable from the local cache.\n if (result.cache) this.manifest.applyPageDelete(result.cache, pageObjectNumbers);\n this.publisher.publishLocal({ type: 'pages.deleted', pageObjectNumbers, ...result });\n return result;\n });\n }\n\n flatten(\n pageObjectNumbers: PageObjectNumber[],\n usage: PageFlattenUsage = 'display',\n ): AbortablePromise<PageFlattenResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageFlattenResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerPagesFlatten(this.docId, this.layerName),\n { pageObjectNumbers, usage },\n (raw) => PageFlattenResultSchema.parse(raw),\n signal,\n );\n // Nothing flattened means no artifact and therefore no coherence bump.\n if (result.meta === null) return result;\n // Flatten bakes annotations into page content, so both planes flip.\n this.manifest.apply(result.meta, ['content', 'annotations']);\n this.publisher.publishLocal({\n type: 'pages.flattened',\n ...result,\n });\n return result;\n });\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type DocumentRedactionService,\n type RedactionApplyResult,\n type RedactionApplyScope,\n} from '@embedpdf/engine-core/runtime';\nimport { RedactionApplyResultSchema, wirePaths } from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Cloud-side redaction apply. Mirrors `LocalDocumentRedactionService` over\n * HTTP (POST /redactions/apply); the server enforces the capability gate\n * (`doc.pages.modify` + `doc.annotate.modify` + `doc.redact`) and persists\n * the rewritten layer artifact. See `DocumentRedactionService` for the\n * two-stage model and the layer trust boundary — an apply rewrites THIS\n * LAYER's bytes; the immutable base keeps the original.\n */\nexport class CloudDocumentRedactionService implements DocumentRedactionService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n apply(scope: RedactionApplyScope): AbortablePromise<RedactionApplyResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<RedactionApplyResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerRedactionsApply(this.docId, this.layerName),\n { scope },\n (raw) => RedactionApplyResultSchema.parse(raw),\n signal,\n );\n // Nothing applied means no artifact and therefore no coherence bump.\n if (result.meta === null) return result;\n // Redaction-apply rewrites content and consumes the marks, so both\n // planes flip.\n this.manifest.apply(result.meta, ['content', 'annotations']);\n this.publisher.publishLocal({\n type: 'redaction.applied',\n ...result,\n });\n return result;\n });\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n canonicalSearchQuery,\n searchContentEpoch,\n type DocumentSearchService,\n type SearchQuery,\n type SearchRequest,\n type SearchSlice,\n} from '@embedpdf/engine-core/runtime';\nimport {\n SearchSliceSchema,\n decodeSearchToken,\n encodeSearchToken,\n wirePaths,\n type SearchToken,\n} from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Cloud search transport: versioned GETs, one per budgeted slice.\n *\n * Every slice URL is a canonical cache key — the search token pins the\n * layer's content epoch (computed from the cached manifest), the\n * CANONICAL query (default-fold literals collapse case/diacritic\n * variants into one entry), and the resume position. Identical searches\n * from any reader of the document hit the same CDN entry; matches are\n * all that ever crosses the trust boundary, and the rects/full endpoint\n * split keeps permission tiers in disjoint cache namespaces.\n *\n * Staleness rides the standard versioned-read signal: a first slice\n * answered `NotFound` means OUR manifest is stale → refresh and retry\n * once; a continuation answered `NotFound` means the document changed\n * mid-search → `InvalidArg`, same contract as the local engine's cursor.\n */\nexport class CloudDocumentSearchService implements DocumentSearchService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n query(request: SearchRequest): AbortablePromise<SearchSlice> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document not open: ${this.docId}`),\n );\n }\n return AbortablePromise.run<SearchSlice>(async (signal) => {\n const mode = request.mode ?? 'full';\n const path = mode === 'rects' ? wirePaths.layerSearchRects : wirePaths.layerSearchFull;\n const get = (token: string) =>\n this.http.getJson(\n path(this.docId, this.layerName, token),\n (raw) => SearchSliceSchema.parse(raw),\n signal,\n );\n const query = canonicalSearchQuery(request.query);\n\n if (request.cursor !== undefined) {\n let token: SearchToken;\n try {\n token = decodeSearchToken(request.cursor);\n } catch {\n throw new EngineError(EngineErrorCode.InvalidArg, 'malformed search cursor');\n }\n // Local-engine cursor parity: a cursor is pinned to its query and\n // scan origin; replaying it against anything else is a caller bug.\n if (queryIdentity(token.query) !== queryIdentity(query)) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n 'search cursor belongs to a different query — restart the search',\n );\n }\n if (request.startPage !== undefined && request.startPage !== token.startPage) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n 'startPage conflicts with the cursor — omit startPage when resuming',\n );\n }\n try {\n return await get(request.cursor);\n } catch (err) {\n if (EngineError.is(err, EngineErrorCode.NotFound)) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n 'document changed since this search cursor was issued — restart the search',\n );\n }\n throw err;\n }\n }\n\n const mint = (epoch: string) =>\n encodeSearchToken({\n epoch,\n query,\n ...(request.startPage !== undefined ? { startPage: request.startPage } : {}),\n skip: 0,\n ...(request.budget !== undefined ? { budget: request.budget } : {}),\n });\n try {\n const manifest = await this.manifest.get(signal);\n return await get(mint(searchContentEpoch(manifest)));\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n // Our cached manifest is behind the layer — the standard\n // versioned-read retry: refresh once, re-mint, re-issue.\n const fresh = await this.manifest.refresh(signal);\n return await get(mint(searchContentEpoch(fresh)));\n }\n });\n }\n}\n\n/** Query identity for cursor validation (option order pinned by hand). */\nfunction queryIdentity(query: SearchQuery): string {\n return JSON.stringify([\n query.regex ? 'r' : 'l',\n query.text,\n query.matchCase ? 1 : 0,\n query.matchDiacritics ? 1 : 0,\n query.wholeWord ? 1 : 0,\n ]);\n}\n","import { EngineError, EngineErrorCode } from '@embedpdf/engine-core/runtime';\n\n/**\n * Lightweight, **unverified** JWT payload decoder.\n *\n * We use this on the SDK side purely to extract routing information\n * (the `doc_id` claim) so we know which `/v1/docs/:id/head` URL to\n * hit. Signature verification is the server's job — Layer 2 of the\n * token-class-confusion defense in `JwtVerifier.coerceClaims`\n * rejects anything malformed before the bytes are accepted.\n *\n * This module is intentionally cryptography-free: it never imports\n * `crypto` or `jose`. That keeps the SDK lean for browser bundles\n * (jose adds ~50KB minified) and means a misconfigured customer\n * can't accidentally rely on client-side verification.\n */\n\nexport interface UnverifiedClaims {\n doc_id?: string;\n tenant_id?: string;\n sub?: string;\n exp?: number;\n iat?: number;\n /** Pass-through; we don't validate anything else SDK-side. */\n [key: string]: unknown;\n}\n\nexport function decodeUnverifiedClaims(token: string): UnverifiedClaims {\n const parts = token.split('.');\n if (parts.length !== 3) {\n throw new EngineError(EngineErrorCode.InvalidArg, 'malformed jwt: expected 3 segments');\n }\n const payloadB64Url = parts[1]!;\n let bytes: Uint8Array;\n try {\n bytes = base64UrlDecode(payloadB64Url);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n `malformed jwt payload: ${(err as Error).message ?? err}`,\n );\n }\n let json: string;\n try {\n json = new TextDecoder().decode(bytes);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n `jwt payload is not valid utf-8: ${(err as Error).message ?? err}`,\n );\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n `jwt payload is not valid json: ${(err as Error).message ?? err}`,\n );\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new EngineError(EngineErrorCode.InvalidArg, 'jwt payload must be a json object');\n }\n return parsed as UnverifiedClaims;\n}\n\n/**\n * Decode a base64url string into a `Uint8Array`. Works in both Node\n * and modern browsers; we avoid `Buffer` so the SDK stays\n * browser-friendly. `atob` lives on the global in Node 16+ as well.\n */\nfunction base64UrlDecode(b64url: string): Uint8Array {\n const b64 = b64url.replace(/-/g, '+').replace(/_/g, '/');\n const pad = b64.length % 4;\n const padded = pad === 0 ? b64 : b64 + '='.repeat(4 - pad);\n const bin = atob(padded);\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","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n checkCapability,\n decodePdfBits,\n expandRawScope,\n passwordPromptFromState,\n securityStateFromHead,\n type DocCapability,\n type DocumentAccessInfo,\n type DocumentIdentity,\n type DocumentSecurityService,\n type DocumentSecurityState,\n type DocumentUnlockInput,\n type DocumentUnlockResult,\n type PasswordPrompt,\n} from '@embedpdf/engine-core/runtime';\nimport { AccessResponseSchema, wirePaths, type DocumentHead } from '@embedpdf/engine-core/wire';\n\nimport { decodeUnverifiedClaims } from '../transport/decodeUnverifiedClaims';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudDocumentSecurityService implements DocumentSecurityService {\n private state: DocumentSecurityState;\n private access: DocumentAccessInfo | null = null;\n\n /**\n * Parsed JWT identity + scope, decoded once at construction. Used by\n * the local-fallback path for `effectiveScope` and `identity` when\n * /access hasn't run yet (public-share with no CDN, password not\n * yet supplied, etc.).\n */\n private readonly tokenScope: ReadonlyArray<string>;\n private readonly tokenIdentity: DocumentIdentity | null;\n\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n initialHead: DocumentHead,\n private readonly view: { isClosed(): boolean },\n initialToken: string | null = null,\n ) {\n this.state = securityStateFromHead(initialHead);\n const claims = initialToken ? safeDecodeClaims(initialToken) : null;\n this.tokenScope = Array.isArray(claims?.scope) ? (claims!.scope as ReadonlyArray<string>) : [];\n this.tokenIdentity = claims ? identityFromClaims(claims) : null;\n }\n\n get current(): DocumentSecurityState {\n return this.state;\n }\n\n get currentAccess(): DocumentAccessInfo | null {\n return this.access;\n }\n\n /**\n * Expanded capability set. Cloud-canonical post-/access; otherwise\n * computed locally from the JWT scope + /head's pdf bits using the\n * SAME `expandRawScope` helper engine-local calls — so the value\n * matches across engines bit-for-bit on the same inputs.\n */\n get effectiveScope(): ReadonlyArray<string> {\n if (this.access) return this.access.effectiveScope;\n const bits = decodePdfBits(this.state.permissions.bits);\n return Array.from(expandRawScope(this.tokenScope, bits)).sort();\n }\n\n /**\n * Wildcard-aware authorization check — mirrors what the server route layer\n * enforces with. `effectiveScope` alone can't gate UI: it enumerates concrete\n * grants and drops the `*` admin wildcard. So we honor a server-canonical\n * concrete grant when present, then fall back to the same `checkCapability`\n * predicate (which short-circuits `*`) against the JWT scope + /head bits.\n */\n allows(cap: DocCapability): boolean {\n if (this.access?.effectiveScope.includes(cap)) return true;\n const bits = decodePdfBits(this.state.permissions.bits);\n return checkCapability(cap, this.tokenScope, bits);\n }\n\n /**\n * Identity of the current caller, or null when anonymous.\n *\n * Cloud-canonical post-/access; otherwise the identity claims from\n * the JWT itself. Both are the same shape — the post-/access\n * version is just refreshed to reflect any server-side identity\n * augmentation (rare; reserved for future tenant hooks).\n */\n get identity(): DocumentIdentity | null {\n return this.access?.identity ?? this.tokenIdentity;\n }\n\n /**\n * High-level \"should I prompt for a password?\" — single source of\n * truth, computed via `passwordPromptFromState` so the answer is\n * identical to what the local engine would say for the same\n * security state. See `passwordPromptFromState` for the rules.\n */\n get passwordPrompt(): PasswordPrompt {\n return passwordPromptFromState(this.state);\n }\n\n unlock(input: DocumentUnlockInput): AbortablePromise<DocumentUnlockResult> {\n if (this.view.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<DocumentUnlockResult>(async (signal) => {\n return await this.postAccess(signal, {\n password: input.password,\n mode: input.mode ?? 'any',\n });\n });\n }\n\n /**\n * Cloud-internal: call /v1/access with no password to establish\n * a CDN-credentialed session. Used by `CloudEngine.open` when\n * /head's `access.reasons` includes 'cdn' but NOT 'password' —\n * the server accepts an authenticated /access POST without a\n * password and returns the signed-URL block.\n *\n * Not on the public `DocumentSecurityService` interface — the\n * \"unlock\" verb implies user action, and this path is automatic.\n * Local engine has no equivalent (there's no CDN concept).\n */\n establishAccess(): AbortablePromise<DocumentUnlockResult> {\n if (this.view.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<DocumentUnlockResult>(async (signal) => {\n return await this.postAccess(signal, { mode: 'any' });\n });\n }\n\n /**\n * Single POST /v1/access implementation shared by `unlock()` (with\n * password) and `establishAccess()` (no password). Updates cached\n * security state, caches the access block, and pushes the CDN\n * binding into the HttpClient so subsequent fetches apply CDN\n * tokens via `applyCdnAccess`.\n *\n * `none` CDN adapter → the access block has null overrides/policies\n * and `applyCdnAccess` short-circuits to origin; safe to call always.\n */\n private async postAccess(\n signal: AbortSignal,\n body: { password?: string; mode: 'any' | 'owner' },\n ): Promise<DocumentUnlockResult> {\n const response = await this.http.postJson(\n wirePaths.access,\n {\n docId: this.docId,\n layerName: this.layerName,\n ...(body.password ? { password: body.password } : {}),\n mode: body.mode,\n },\n (raw) => AccessResponseSchema.parse(raw),\n signal,\n );\n this.state = response.security;\n this.access = {\n cdn: response.cdn,\n passwordGrant: response.passwordGrant,\n pdfPermissions: response.pdfPermissions,\n scope: response.scope,\n effectiveScope: response.effectiveScope,\n identity: response.identity,\n originPasswordPolicy: response.originPasswordPolicy,\n expiresAt: response.expiresAt,\n // Deployment render lattice. Absent on older servers without render policy support.\n ...(response.renderPolicy ? { renderPolicy: response.renderPolicy } : {}),\n };\n this.http.setCdnAccess({\n cdn: response.cdn,\n docId: this.docId,\n layerName: this.layerName,\n });\n // DocumentUnlockResult.access is `DocumentAccessInfo | undefined`,\n // not `| null`. We carry the local cache as `| null` (clearer\n // \"not yet unlocked\" semantic); coerce at the boundary.\n return { security: this.state, access: this.access ?? undefined };\n }\n}\n\n/**\n * Decode the JWT's payload without verifying. The SDK never verifies\n * tokens client-side — the server is the verifier of record — but it\n * needs the `scope` and identity claims for the local-fallback path\n * of `effectiveScope` / `identity`. Returns null if the token is\n * malformed; the security service treats that as \"no claims known\".\n */\nfunction safeDecodeClaims(token: string): Record<string, unknown> | null {\n try {\n return decodeUnverifiedClaims(token);\n } catch {\n return null;\n }\n}\n\nfunction identityFromClaims(claims: Record<string, unknown>): DocumentIdentity | null {\n const out: DocumentIdentity = {};\n if (typeof claims['user_id'] === 'string') out.user_id = claims['user_id'];\n if (typeof claims['group_id'] === 'string') out.group_id = claims['group_id'];\n if (typeof claims['display_name'] === 'string') out.display_name = claims['display_name'];\n if (Array.isArray(claims['groups'])) {\n const groups = (claims['groups'] as unknown[]).filter(\n (g): g is string => typeof g === 'string',\n );\n if (groups.length > 0) out.groups = groups;\n }\n return Object.keys(out).length > 0 ? out : null;\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type DocumentMetadata,\n type MetadataPatch,\n type MetadataService,\n type MetadataUpdateResult,\n} from '@embedpdf/engine-core/runtime';\nimport {\n DocumentMetadataSchema,\n MetadataUpdateResultSchema,\n wirePaths,\n} from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudMetadataService implements MetadataService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n /**\n * Document metadata read. The Info-dict JSON lives at the\n * content-addressed `/metadata@metadataVersion=N` leaf (not in the\n * manifest); the manifest only publishes the `metadataVersion` pointer.\n * So `read()` pulls `metadataVersion` from the cached manifest, fetches\n * the leaf, and on a 404 (stale pointer) transparently refreshes the\n * manifest and retries once. `metadataVersion` bumps only on metadata\n * writes, so this leaf stays cached across page and annotation edits.\n */\n read(): AbortablePromise<DocumentMetadata> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<DocumentMetadata>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n // Plane-scope rule: the metadata leaf depends on the `metadata`\n // plane — while inherited, one doc-level URL serves every visitor.\n return planesInherited(manifest, ['metadata'])\n ? wirePaths.docMetadata(this.docId, manifest.metadataVersion)\n : wirePaths.layerMetadata(this.docId, this.layerName, manifest.metadataVersion);\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => DocumentMetadataSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n\n update(patch: MetadataPatch): AbortablePromise<MetadataUpdateResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<MetadataUpdateResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerMetadataUpdate(this.docId, this.layerName),\n patch,\n (raw) => MetadataUpdateResultSchema.parse(raw),\n signal,\n );\n // A metadata write only advances docVersion + metadataVersion (no\n // per-page pin changes, no layoutVersion), so the cached manifest can\n // be patched in place — no refetch.\n if (result.cache) this.manifest.applyMetadata(result.cache);\n this.publisher.publishLocal({ type: 'metadata.updated', ...result });\n return result;\n });\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n createPageImageHandle,\n encodeStableIdKey,\n normalizeAnnotationDraft,\n normalizeAnnotationPatch,\n type WireResourceMap,\n type AnnotationAppearanceImage,\n type AnnotationAppearanceImageOptions,\n type AnnotationAppearanceImagesResult,\n type AnnotationAppearanceRenderOptions,\n type AnnotationAppearancesResult,\n type AnnotationDraft,\n type AnnotationListPageSnapshot,\n type AnnotationPatch,\n type AnnotationRef,\n type AnnotationCreateResult,\n type AnnotationDeleteResult,\n type AnnotationMoveResult,\n type AnnotationUpdateResult,\n type AttachmentContent,\n type DocumentEventInit,\n type MutationMeta,\n type PageAnnotationsService,\n type PageImageResult,\n type PageNetworkRenderFormat,\n type PageObjectNumber,\n} from '@embedpdf/engine-core/runtime';\nimport {\n AnnotationCreateResultSchema,\n AnnotationDeleteResultSchema,\n AnnotationListPageSnapshotSchema,\n AnnotationAppearanceManifestSchema,\n AnnotationMoveResultSchema,\n AnnotationUpdateResultSchema,\n annotationAppearancesImageOptionsToWire,\n wirePaths,\n} from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport { buildMutationForm, hasResources } from './buildMutationForm';\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport { parseAttachmentContent } from './parseAttachmentContent';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Cloud-side page annotation service. Mirrors the local wiring: each\n * call produces an `AbortablePromise` that propagates `signal.abort()`\n * down to `fetch` and validates the JSON response with the wire-stable\n * Zod schema.\n *\n * Reads use immutable versioned layer URLs discovered from the\n * manifest. Mutations use unversioned layer URLs and are never cached.\n */\nexport class CloudPageAnnotationsService implements PageAnnotationsService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly pageObjectNumber: PageObjectNumber,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n list(): AbortablePromise<AnnotationListPageSnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AnnotationListPageSnapshot>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n const page = manifest.pages.find((p) => p.state.pageObjectNumber === this.pageObjectNumber);\n if (!page) {\n throw new EngineError(\n EngineErrorCode.NotFound,\n `no page with object number ${this.pageObjectNumber} in document ${this.docId}`,\n );\n }\n // Plane-scope rule: the list depends on the `annotations` plane. A\n // base's own annotations (weak-identity ones included) are simply\n // VISIBLE through an inheriting layer, so every visitor reads ONE\n // doc-level URL served from the base session.\n return planesInherited(manifest, ['annotations'])\n ? wirePaths.docPageAnnotations(\n this.docId,\n this.pageObjectNumber,\n page.cache.annotationVersion,\n )\n : wirePaths.layerPageAnnotations(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n page.cache.annotationVersion,\n );\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => AnnotationListPageSnapshotSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n\n renderAppearances(\n _options?: AnnotationAppearanceRenderOptions,\n ): AbortablePromise<AnnotationAppearancesResult> {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.NotImplemented,\n 'annotations.renderAppearances() raw rasters are not available in the cloud engine; use renderAppearanceImages()',\n ),\n );\n }\n\n renderAppearanceImages(\n options: AnnotationAppearanceImageOptions = {},\n ): AbortablePromise<AnnotationAppearanceImagesResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AnnotationAppearanceImagesResult>(async (signal) => {\n // The cloud appearance endpoint is always content-addressed, so the URL\n // must carry an explicit network format (PNG/WebP). Default to WebP when\n // the caller omits it, matching render.image().\n const format: PageNetworkRenderFormat = options.format ?? 'webp';\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n const page = manifest.pages.find((p) => p.state.pageObjectNumber === this.pageObjectNumber);\n if (!page) {\n throw new EngineError(\n EngineErrorCode.NotFound,\n `no page with object number ${this.pageObjectNumber} in document ${this.docId}`,\n );\n }\n const wireToken = annotationAppearancesImageOptionsToWire(\n { ...options, format },\n { annotationVersion: page.cache.annotationVersion },\n );\n // Same `annotations` plane switch as list(): the appearance\n // batch shares too.\n return planesInherited(manifest, ['annotations'])\n ? wirePaths.docPageAnnotationAppearances(this.docId, this.pageObjectNumber, wireToken)\n : wirePaths.layerPageAnnotationAppearances(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n wireToken,\n );\n };\n const form = await this.http.getFormDataWithRefresh(\n buildPath,\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n return parseAppearanceForm(form);\n });\n }\n\n /**\n * Decode and return the file embedded in a FileAttachment annotation.\n * A read over the immutable `attachment-files` leaf, pinned by the\n * manifest's `attachmentsVersion` (annotation-level files re-key on the\n * same pin as document-level ones), with the same stale-404 refresh\n * retry as {@link list}. Weak `index` refs cannot be spliced into a GET\n * URL (no body to carry the revision), so bytes reads require a stable\n * id — the same `:annotKey` routing update()/delete() use.\n */\n downloadFile(ref: AnnotationRef): AbortablePromise<AttachmentContent> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n if (ref.pageObjectNumber !== this.pageObjectNumber) {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n `ref.pageObjectNumber ${ref.pageObjectNumber} != page ${this.pageObjectNumber}`,\n ),\n );\n }\n if (ref.kind === 'index') {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n 'downloadFile requires a stable ref (objectNumber or nm); index refs cannot address the content-addressed file leaf',\n ),\n );\n }\n const annotKey = encodeStableIdKey(refToStableId(ref));\n return AbortablePromise.run<AttachmentContent>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n // A FileAttachment annotation's bytes depend on BOTH planes —\n // the annotation must exist in this view (`annotations`) and the\n // byte pin is `attachmentsVersion` (`attachments`).\n return planesInherited(manifest, ['annotations', 'attachments'])\n ? wirePaths.docAnnotationFile(\n this.docId,\n this.pageObjectNumber,\n annotKey,\n manifest.attachmentsVersion,\n )\n : wirePaths.layerAnnotationFile(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n annotKey,\n manifest.attachmentsVersion,\n );\n };\n const file = await this.http.getFileWithRefresh(\n buildPath,\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n return parseAttachmentContent(file);\n });\n }\n\n create(draft: AnnotationDraft): AbortablePromise<AnnotationCreateResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AnnotationCreateResult>(async (signal) => {\n // Split inline BinarySource fields (stamp images, …) into the wire\n // draft + binary resources. Without resources the request is the\n // plain JSON POST it has always been; with resources it becomes\n // multipart: a `body` JSON part + one `resource:{key}` part each —\n // the mirror image of the appearance-render response.\n const { wire, resources } = await normalizeAnnotationDraft(draft);\n const path = wirePaths.layerPageAnnotationsCreate(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n );\n const parse = (raw: unknown) => AnnotationCreateResultSchema.parse(raw);\n const result = hasResources(resources)\n ? await this.http.postMultipartJson(path, buildMutationForm(wire, resources), parse, signal)\n : await this.http.postJson(path, wire, parse, signal);\n return this.absorbMutation(result, 'annotation.created');\n });\n }\n\n update(ref: AnnotationRef, patch: AnnotationPatch): AbortablePromise<AnnotationUpdateResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n if (ref.pageObjectNumber !== this.pageObjectNumber) {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n `ref.pageObjectNumber ${ref.pageObjectNumber} != page ${this.pageObjectNumber}`,\n ),\n );\n }\n if (ref.kind === 'index') {\n // Index refs cannot be addressed by stable id. Send the full ref\n // in the body so the server can validate the revision and resolve\n // it the same way the local mutator does.\n const path = wirePaths.layerAnnotationByKey(\n this.docId,\n this.layerName,\n ref.pageObjectNumber,\n 'index',\n );\n return AbortablePromise.run<AnnotationUpdateResult>(async (signal) => {\n const { wire, resources } = await normalizeAnnotationPatch(patch);\n const result = await this.patchMutation(path, { ref, patch: wire }, resources, signal);\n return this.absorbMutation(result, 'annotation.updated');\n });\n }\n const stableKey = encodeStableIdKey(refToStableId(ref));\n const path = wirePaths.layerAnnotationByKey(\n this.docId,\n this.layerName,\n ref.pageObjectNumber,\n stableKey,\n );\n return AbortablePromise.run<AnnotationUpdateResult>(async (signal) => {\n const { wire, resources } = await normalizeAnnotationPatch(patch);\n const result = await this.patchMutation(path, { patch: wire }, resources, signal);\n return this.absorbMutation(result, 'annotation.updated');\n });\n }\n\n /** PATCH as plain JSON, or as multipart when the patch carried binaries. */\n private patchMutation(\n path: string,\n body: unknown,\n resources: WireResourceMap,\n signal: AbortSignal,\n ): Promise<AnnotationUpdateResult> {\n const parse = (raw: unknown) => AnnotationUpdateResultSchema.parse(raw);\n if (hasResources(resources)) {\n return this.http.patchMultipartJson(path, buildMutationForm(body, resources), parse, signal);\n }\n return this.http.patchJson(path, body, parse, signal);\n }\n\n delete(ref: AnnotationRef): AbortablePromise<AnnotationDeleteResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n if (ref.pageObjectNumber !== this.pageObjectNumber) {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n `ref.pageObjectNumber ${ref.pageObjectNumber} != page ${this.pageObjectNumber}`,\n ),\n );\n }\n if (ref.kind === 'index') {\n // DELETE has no body in plain HTTP, so we PATCH the same\n // 'index' key with `{ ref, op: 'delete' }`. This keeps the\n // semantics atomic on the server (single round-trip).\n const path = wirePaths.layerAnnotationByKey(\n this.docId,\n this.layerName,\n ref.pageObjectNumber,\n 'index',\n );\n return AbortablePromise.run<AnnotationDeleteResult>(async (signal) => {\n const result = await this.http.patchJson(\n path,\n { ref, op: 'delete' },\n (raw) => AnnotationDeleteResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'annotation.deleted');\n });\n }\n const stableKey = encodeStableIdKey(refToStableId(ref));\n const path = wirePaths.layerAnnotationByKey(\n this.docId,\n this.layerName,\n ref.pageObjectNumber,\n stableKey,\n );\n return AbortablePromise.run<AnnotationDeleteResult>(async (signal) => {\n const result = await this.http.deleteJson(\n path,\n (raw) => AnnotationDeleteResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'annotation.deleted');\n });\n }\n\n move(refs: AnnotationRef[], toIndex: number): AbortablePromise<AnnotationMoveResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n // The page is part of the URL; the worker validates per-ref consistency\n // again, but rejecting up front gives a cleaner error from the client side.\n for (const r of refs) {\n if (r.pageObjectNumber !== this.pageObjectNumber) {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n `move ref points at page ${r.pageObjectNumber}; service is bound to page ${this.pageObjectNumber}`,\n ),\n );\n }\n }\n const path = wirePaths.layerPageAnnotationsMove(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n );\n return AbortablePromise.run<AnnotationMoveResult>(async (signal) => {\n const result = await this.http.postJson(\n path,\n { refs, toIndex },\n (raw) => AnnotationMoveResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'annotation.moved');\n });\n }\n\n /**\n * Patch the cached manifest, then publish the mutation to the document's\n * event stream (in that order — listeners reading the manifest in their\n * callback must see post-mutation state). Each call site pairs the event\n * `type` with the matching result by construction; the cast localizes that\n * pairing here instead of widening every site.\n */\n private absorbMutation<T extends { meta: MutationMeta }>(\n result: T,\n type: 'annotation.created' | 'annotation.updated' | 'annotation.deleted' | 'annotation.moved',\n ): T {\n this.manifest.apply(result.meta, ['annotations']);\n this.publisher.publishLocal({\n type,\n pageObjectNumber: this.pageObjectNumber,\n ...result,\n } as unknown as DocumentEventInit);\n return result;\n }\n}\n\n/**\n * Parse the appearance `multipart/form-data` response into the same\n * `AnnotationAppearanceImagesResult` shape the local engine produces. The\n * `manifest` part is validated against the wire schema; each image part is\n * wrapped in a `PageImageHandle` backed by the in-memory blob we already\n * downloaded.\n */\nasync function parseAppearanceForm(form: FormData): Promise<AnnotationAppearanceImagesResult> {\n const manifestRaw = form.get('manifest');\n if (typeof manifestRaw !== 'string') {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n 'appearance response missing JSON manifest part',\n );\n }\n let parsedJson: unknown;\n try {\n parsedJson = JSON.parse(manifestRaw);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n `appearance manifest is not valid JSON: ${(err as Error)?.message ?? err}`,\n );\n }\n const manifest = AnnotationAppearanceManifestSchema.parse(parsedJson);\n\n const appearances: AnnotationAppearanceImage[] = await Promise.all(\n manifest.appearances.map(async (entry) => {\n const partValue = form.get(entry.part);\n if (partValue === null || typeof partValue === 'string') {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n `appearance response missing image part \"${entry.part}\"`,\n );\n }\n const blob = partValue as Blob;\n const bytes = new Uint8Array(await blob.arrayBuffer());\n const result: PageImageResult = {\n width: entry.width,\n height: entry.height,\n format: entry.format,\n contentType: entry.contentType,\n source: { kind: 'bytes', bytes },\n };\n const image = createPageImageHandle(result, {\n async blob() {\n return blob;\n },\n });\n return {\n ref: entry.ref,\n mode: entry.mode,\n rect: entry.rect,\n image,\n };\n }),\n );\n\n return { pageState: manifest.pageState, appearances };\n}\n\n/**\n * Local helper: project a non-index `AnnotationRef` into the matching\n * `AnnotationStableId` shape so we can route by stable key. The compiler\n * narrows on `ref.kind` here so we can't accidentally pass an index ref.\n */\nfunction refToStableId(\n ref: Extract<AnnotationRef, { kind: 'objectNumber' | 'nm' }>,\n): { kind: 'objectNumber'; value: number } | { kind: 'nm'; value: string } {\n if (ref.kind === 'objectNumber') {\n return { kind: 'objectNumber', value: ref.annotObjectNumber };\n }\n return { kind: 'nm', value: ref.nm };\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type PageGeometryService,\n type PageGeometrySnapshot,\n type PageObjectNumber,\n} from '@embedpdf/engine-core/runtime';\nimport { PageGeometrySnapshotSchema, wirePaths } from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudPageGeometryService implements PageGeometryService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly pageObjectNumber: PageObjectNumber,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n read(): AbortablePromise<PageGeometrySnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageGeometrySnapshot>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n const page = manifest.pages.find((p) => p.state.pageObjectNumber === this.pageObjectNumber);\n if (!page) {\n throw new EngineError(\n EngineErrorCode.NotFound,\n `no page with object number ${this.pageObjectNumber} in document ${this.docId}`,\n );\n }\n // Plane-scope rule: geometry depends on the `content` plane (see\n // CloudPageTextService for the full rationale).\n return planesInherited(manifest, ['content'])\n ? wirePaths.docPageGeometry(this.docId, this.pageObjectNumber, page.cache.contentVersion)\n : wirePaths.layerPageGeometry(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n page.cache.contentVersion,\n );\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => PageGeometrySnapshotSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n createPageImageHandle,\n type PageImageHandle,\n type PageImageOptions,\n type PageImageResult,\n type PageNetworkRenderFormat,\n type PageObjectNumber,\n type PageRaster,\n type PageRenderOptions,\n type PageRenderService,\n} from '@embedpdf/engine-core/runtime';\nimport { renderImageOptionsToWire, wirePaths } from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudPageRenderService implements PageRenderService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly pageObjectNumber: PageObjectNumber,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n image(options: PageImageOptions = {}): AbortablePromise<PageImageHandle> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageImageHandle>(async (signal) => {\n const format = normalizeFormat(options.format);\n const includeAnnotations = options.includeAnnotations ?? true;\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n const page = manifest.pages.find((p) => p.state.pageObjectNumber === this.pageObjectNumber);\n if (!page) {\n throw new EngineError(\n EngineErrorCode.NotFound,\n `no page with object number ${this.pageObjectNumber} in document ${this.docId}`,\n );\n }\n // `format` flows through `options` and ends up in the token like\n // every other render option — the wire format treats it uniformly.\n // Normalized above so the URL always carries an explicit,\n // network-supported format (PNG or WebP; default WebP).\n // Annotatedness itself is PATH-expressed (the token/path law): the\n // token never carries it; the annotated family's token carries the\n // `annotationVersion` pin instead.\n const wireToken = renderImageOptionsToWire(\n { ...options, format },\n {\n contentVersion: page.cache.contentVersion,\n ...(includeAnnotations ? { annotationVersion: page.cache.annotationVersion } : {}),\n },\n );\n // Plane-scope rule: a render resolves at the DOC-LEVEL (shared base)\n // path iff every plane it depends on is inherited — annotation-free\n // renders (full pages AND tiles; the rect target rides the same\n // token) depend on `content`, annotated ones on\n // `content + annotations`. Each is its OWN family at BOTH tiers\n // (prefix law: edge grants see only prefixes). 1,000 inheriting\n // visitors → one URL set, one origin render, no layer session.\n if (includeAnnotations) {\n return planesInherited(manifest, ['content', 'annotations'])\n ? wirePaths.docPageRenderAnnotated(this.docId, this.pageObjectNumber, wireToken)\n : wirePaths.layerPageRenderAnnotated(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n wireToken,\n );\n }\n return planesInherited(manifest, ['content'])\n ? wirePaths.docPageRender(this.docId, this.pageObjectNumber, wireToken)\n : wirePaths.layerPageRender(this.docId, this.layerName, this.pageObjectNumber, wireToken);\n };\n // The advertised URL reflects the CURRENT manifest; the blob loader\n // re-resolves per fetch through the 404 → manifest-refresh rail, so a\n // scope flip (e.g. this layer's first annotation write) self-heals\n // instead of failing on a stale path family.\n const requestPath = await buildPath(signal);\n return createCloudPageImageHandle(\n {\n format,\n contentType: `image/${format}`,\n source: { kind: 'url', url: this.http.absoluteUrl(requestPath) },\n },\n this.http,\n buildPath,\n async (s) => {\n await this.manifest.refresh(s);\n },\n );\n });\n }\n\n raw(_options?: PageRenderOptions): AbortablePromise<PageRaster> {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.NotImplemented,\n 'render.raw() is not available in the cloud engine; use render.image()',\n ),\n );\n }\n}\n\nfunction createCloudPageImageHandle(\n result: PageImageResult,\n http: HttpClient,\n buildPath: (signal: AbortSignal) => Promise<string>,\n onStaleVersion: (signal: AbortSignal) => Promise<void>,\n): PageImageHandle {\n return createPageImageHandle(result, {\n blob: (signal) =>\n http.getBlobWithRefresh(buildPath, onStaleVersion, signal ?? new AbortController().signal),\n });\n}\n\nfunction normalizeFormat(format: PageImageOptions['format']): PageNetworkRenderFormat {\n if (format === undefined) return 'webp';\n if (format === 'png' || format === 'webp') return format;\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n `cloud render.image() supports only \"png\" and \"webp\" (got \"${format}\")`,\n );\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type PageObjectNumber,\n type PageTextService,\n type PageTextSnapshot,\n} from '@embedpdf/engine-core/runtime';\nimport { PageTextSnapshotSchema, wirePaths } from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Cloud-side per-page text service. `read()` fetches the\n * content-addressed URL `/v1/docs/:id/text/pages/:pon/data@contentVersion=N`, where\n * `:P` is the page's current `contentVersion` from the cached\n * manifest. On a 404 (stale version) the SDK transparently refreshes\n * `/head` + `/manifest@docVersion=N`, rebuilds the URL with the fresh `cN`,\n * and retries exactly once.\n */\nexport class CloudPageTextService implements PageTextService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly pageObjectNumber: PageObjectNumber,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n read(): AbortablePromise<PageTextSnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageTextSnapshot>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n const page = manifest.pages.find((p) => p.state.pageObjectNumber === this.pageObjectNumber);\n if (!page) {\n throw new EngineError(\n EngineErrorCode.NotFound,\n `no page with object number ${this.pageObjectNumber} in document ${this.docId}`,\n );\n }\n // Plane-scope rule: text depends on the `content` plane — while it\n // is inherited, every visitor's layer reads ONE doc-level URL (and\n // the base worker session at the origin).\n return planesInherited(manifest, ['content'])\n ? wirePaths.docPageText(this.docId, this.pageObjectNumber, page.cache.contentVersion)\n : wirePaths.layerPageText(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n page.cache.contentVersion,\n );\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => PageTextSnapshotSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n}\n","import type { PageHandle, PageObjectNumber } from '@embedpdf/engine-core/runtime';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { CloudPageAnnotationsService } from './CloudPageAnnotationsService';\nimport { CloudPageGeometryService } from './CloudPageGeometryService';\nimport { CloudPageRenderService } from './CloudPageRenderService';\nimport { CloudPageTextService } from './CloudPageTextService';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudPageHandle implements PageHandle {\n readonly annotations: CloudPageAnnotationsService;\n readonly text: CloudPageTextService;\n readonly geometry: CloudPageGeometryService;\n readonly render: CloudPageRenderService;\n\n constructor(\n readonly pageObjectNumber: PageObjectNumber,\n readonly pageIndex: number,\n http: HttpClient,\n docId: string,\n layerName: string,\n isClosed: () => boolean,\n manifest: ManifestAccessor,\n publisher: SessionEventPublisher,\n ) {\n this.annotations = new CloudPageAnnotationsService(\n http,\n docId,\n layerName,\n pageObjectNumber,\n isClosed,\n manifest,\n publisher,\n );\n this.text = new CloudPageTextService(\n http,\n docId,\n layerName,\n pageObjectNumber,\n isClosed,\n manifest,\n );\n this.geometry = new CloudPageGeometryService(\n http,\n docId,\n layerName,\n pageObjectNumber,\n isClosed,\n manifest,\n );\n this.render = new CloudPageRenderService(\n http,\n docId,\n layerName,\n pageObjectNumber,\n isClosed,\n manifest,\n );\n }\n}\n","import type {\n AnnotationCreateResult,\n AnnotationDeleteResult,\n AnnotationMoveResult,\n AnnotationUpdateResult,\n AttachmentCreateResult,\n AttachmentDeleteResult,\n DocumentEvent,\n EventOrigin,\n FormFieldCreateResult,\n FormFieldDeleteResult,\n FormFieldUpdateResult,\n FormEffectsResult,\n FormImportResult,\n FormRepairResult,\n FormSetValueResult,\n FormWidgetLinkResult,\n MetadataUpdateResult,\n PageDeleteResult,\n PageFlattenResult,\n PageMoveResult,\n PageRotateResult,\n PageRotation,\n} from '@embedpdf/engine-core/runtime';\n\n/** The SSE `mutation` event body — the audit row in JSON (the server's\n * `toJsonlEvent` shape). `payload` is byte-identical to what the mutating\n * caller received as its HTTP response. */\nexport interface AuditEventRow {\n id: number;\n ts: number;\n sub: string;\n kind: string;\n pageObjectNumber: number | null;\n affectedPages: number[];\n originSessionId: string | null;\n payload: unknown;\n}\n\n/**\n * Translate a remote audit row into a `DocumentEvent` — pure, so the\n * exactly-once and verbatim-payload invariants are unit-testable without a\n * server. Returns `null` for kinds this engine version doesn't know\n * (a NEWER server's events degrade to \"ignored\", never to a crash).\n *\n * Context-field fidelity differs by op, by design of the audit row:\n * - rotate/delete: `affectedPages` is exactly the op's page set; rotation\n * is recovered from the layout (it's absolute — every affected page\n * carries the value).\n * - move: the originator knows which block it moved; the audit row only\n * records the resulting order, so `pageObjectNumbers` is the full new\n * order and `destIndex` is absent (remote consumers use `layout`).\n */\nexport function auditRowToEvent(row: AuditEventRow, mySessionId: string): DocumentEvent | null {\n if (row.originSessionId === mySessionId) return null; // own echo — local publish covered it\n\n const origin: EventOrigin = {\n kind: 'remote',\n sessionId: row.originSessionId ?? `unknown:${row.sub}`,\n sub: row.sub,\n ts: row.ts,\n serverId: row.id,\n };\n\n switch (row.kind) {\n case 'annot.create':\n return {\n type: 'annotation.created',\n pageObjectNumber: row.pageObjectNumber ?? row.affectedPages[0] ?? 0,\n origin,\n ...(row.payload as AnnotationCreateResult),\n };\n case 'annot.update':\n return {\n type: 'annotation.updated',\n pageObjectNumber: row.pageObjectNumber ?? row.affectedPages[0] ?? 0,\n origin,\n ...(row.payload as AnnotationUpdateResult),\n };\n case 'annot.delete':\n return {\n type: 'annotation.deleted',\n pageObjectNumber: row.pageObjectNumber ?? row.affectedPages[0] ?? 0,\n origin,\n ...(row.payload as AnnotationDeleteResult),\n };\n case 'annot.move':\n return {\n type: 'annotation.moved',\n pageObjectNumber: row.pageObjectNumber ?? row.affectedPages[0] ?? 0,\n origin,\n ...(row.payload as AnnotationMoveResult),\n };\n case 'pages.move':\n return {\n type: 'pages.moved',\n pageObjectNumbers: row.affectedPages,\n origin,\n ...(row.payload as PageMoveResult),\n };\n case 'pages.rotate': {\n const payload = row.payload as PageRotateResult;\n const rotation = (payload.layout.pages.find(\n (page) => page.pageObjectNumber === row.affectedPages[0],\n )?.rotation ?? 0) as PageRotation;\n return {\n type: 'pages.rotated',\n pageObjectNumbers: row.affectedPages,\n rotation,\n origin,\n ...payload,\n };\n }\n case 'pages.delete':\n return {\n type: 'pages.deleted',\n pageObjectNumbers: row.affectedPages,\n origin,\n ...(row.payload as PageDeleteResult),\n };\n case 'pages.flatten':\n return {\n type: 'pages.flattened',\n origin,\n ...(row.payload as PageFlattenResult),\n };\n case 'metadata.update':\n return {\n type: 'metadata.updated',\n origin,\n ...(row.payload as MetadataUpdateResult),\n };\n case 'attachment.create':\n return {\n type: 'attachment.created',\n origin,\n ...(row.payload as AttachmentCreateResult),\n };\n case 'attachment.delete':\n return {\n type: 'attachment.deleted',\n origin,\n ...(row.payload as AttachmentDeleteResult),\n };\n // Form mutations: two audit kinds share the `form.valueChanged` event\n // (setValue and reset produce the same result shape) — the audit log\n // keeps them distinct for history, the event stream cares about effect.\n case 'form.setValue':\n case 'form.reset':\n return { type: 'form.valueChanged', origin, ...(row.payload as FormSetValueResult) };\n case 'form.import':\n return { type: 'form.imported', origin, ...(row.payload as FormImportResult) };\n case 'form.repair':\n return { type: 'form.repaired', origin, ...(row.payload as FormRepairResult) };\n case 'form.createField':\n return { type: 'form.fieldCreated', origin, ...(row.payload as FormFieldCreateResult) };\n case 'form.updateField':\n return { type: 'form.fieldUpdated', origin, ...(row.payload as FormFieldUpdateResult) };\n case 'form.deleteField':\n return { type: 'form.fieldDeleted', origin, ...(row.payload as FormFieldDeleteResult) };\n case 'form.attachWidget':\n return { type: 'form.widgetAttached', origin, ...(row.payload as FormWidgetLinkResult) };\n case 'form.detachWidget':\n return { type: 'form.widgetDetached', origin, ...(row.payload as FormWidgetLinkResult) };\n case 'form.applyEffects':\n return { type: 'form.effectsApplied', origin, ...(row.payload as FormEffectsResult) };\n default:\n return null;\n }\n}\n","import { EngineError, EngineErrorCode } from '@embedpdf/engine-core/runtime';\n\nimport type { AuditEventRow } from './auditRowToEvent';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport interface SseClientOptions {\n http: HttpClient;\n path: string;\n /** Resume cursor for the first connect (manifest `auditHead` /\n * `lastServerId`); `null` subscribes \"from now\". */\n initialCursor: number | null;\n /** One parsed audit row, in id order. The cursor has already advanced. */\n onRow(row: AuditEventRow): void;\n /** Server says the gap is too large to replay — refetch state. */\n onFullRefresh(): void;\n /** Auth is permanently gone (401/403); the client stopped for good. */\n onAuthLost(): void;\n}\n\n/**\n * Fetch-based SSE consumer. Browser-native `EventSource` cannot send an\n * `Authorization` header, so the stream rides the same `HttpClient` as\n * every other request (same token provider, same session header).\n *\n * Resilience model: the cursor is the only state that matters. Every\n * (re)connect sends `Last-Event-ID: cursor`; the server replays the gap\n * from the audit log. So a dropped stream costs latency, never events —\n * the client needs no buffering and no acknowledgements.\n *\n * - network drop / server close / `auth-expiring` → reconnect with\n * jittered exponential backoff (500ms → 30s; reset after a stream\n * that lived ≥30s). `auth-expiring` reconnects pick up a fresh token\n * from the HttpClient's provider automatically.\n * - 401/403 → permanent: `onAuthLost`, no retry loop against a dead\n * credential.\n */\nexport class SseClient {\n private cursor: number | null;\n private closed = false;\n private abort: AbortController | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private retryDelayMs = 500;\n\n constructor(private readonly opts: SseClientOptions) {\n this.cursor = opts.initialCursor;\n }\n\n open(): void {\n if (this.closed) return;\n void this.run();\n }\n\n close(): void {\n this.closed = true;\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.abort?.abort();\n }\n\n get lastEventId(): number | null {\n return this.cursor;\n }\n\n private async run(): Promise<void> {\n const startedAt = Date.now();\n this.abort = new AbortController();\n try {\n const res = await this.opts.http.stream(\n this.opts.path,\n this.cursor !== null ? { 'Last-Event-ID': String(this.cursor) } : {},\n this.abort.signal,\n );\n if (res.status === 401 || res.status === 403) {\n this.closed = true;\n this.opts.onAuthLost();\n return;\n }\n if (!res.ok || !res.body) {\n throw new EngineError(EngineErrorCode.Network, `events stream HTTP ${res.status}`);\n }\n await this.consume(res.body);\n // Stream ended (server close / auth-expiring / network): reconnect.\n if (Date.now() - startedAt >= 30_000) this.retryDelayMs = 500;\n } catch {\n // Aborts land here too; `closed` guards the reschedule below.\n }\n if (this.closed) return;\n const jitter = this.retryDelayMs * (0.5 + Math.random() * 0.5);\n this.retryTimer = setTimeout(() => void this.run(), jitter);\n this.retryDelayMs = Math.min(this.retryDelayMs * 2, 30_000);\n }\n\n private async consume(body: ReadableStream<Uint8Array>): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n for (;;) {\n const { done, value } = await reader.read();\n if (done || this.closed) return;\n buffer += decoder.decode(value, { stream: true });\n for (;;) {\n const sep = buffer.indexOf('\\n\\n');\n if (sep < 0) break;\n const block = buffer.slice(0, sep);\n buffer = buffer.slice(sep + 2);\n this.dispatch(block);\n }\n }\n }\n\n private dispatch(block: string): void {\n if (block.startsWith(':')) return; // heartbeat / comment\n let id: number | null = null;\n let event = 'message';\n const data: string[] = [];\n for (const line of block.split('\\n')) {\n if (line.startsWith('id:')) id = Number(line.slice(3).trim());\n else if (line.startsWith('event:')) event = line.slice(6).trim();\n else if (line.startsWith('data:')) data.push(line.slice(5).trim());\n }\n if (id !== null && Number.isFinite(id)) this.cursor = id;\n if (event === 'mutation') {\n try {\n this.opts.onRow(JSON.parse(data.join('\\n')) as AuditEventRow);\n } catch {\n // A malformed row advances the cursor and is skipped; the audit log\n // remains the source of truth for anyone who refetches.\n }\n } else if (event === 'full-refresh') {\n this.opts.onFullRefresh();\n } else if (event === 'auth-revoked') {\n // Terminal: the credential is dead by decree, not by clock — never\n // retry against it (a reconnect would just 401; this saves the trip\n // and surfaces the loss immediately).\n this.closed = true;\n this.abort?.abort();\n this.opts.onAuthLost();\n }\n // 'auth-expiring' needs no handling: the server ends the stream right\n // after, and the reconnect path fetches a fresh token.\n }\n}\n","import {\n AbortError,\n AbortablePromise,\n DEFAULT_PDF_SAVE_MODE,\n EngineError,\n EngineErrorCode,\n type AttachmentsCache,\n type DocumentAnnotationsService,\n type DocumentActionsService,\n type DocumentAttachmentsService,\n type DocumentEvent,\n type DocumentEventStream,\n type DocumentFormsService,\n type DocumentHandle,\n type DocumentPagesService,\n type DocumentRedactionService,\n CONTINUOUS_RENDER_POLICY,\n type DocumentRenderService,\n type DocumentSecurityService,\n type MetadataCache,\n type MutationMeta,\n type PageHandle,\n type PageObjectNumber,\n type PageStructureCache,\n type PdfSaveMode,\n} from '@embedpdf/engine-core/runtime';\nimport {\n DEFAULT_LAYER_NAME,\n DocumentHeadSchema,\n DocumentManifestSchema,\n wirePaths,\n type DocumentHead,\n type DocumentManifest,\n type LayerScopePlane,\n} from '@embedpdf/engine-core/wire';\nimport { EventHub, SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport { CloudDocumentActionsService } from './CloudDocumentActionsService';\nimport { CloudDocumentAnnotationsService } from './CloudDocumentAnnotationsService';\nimport { CloudDocumentAttachmentsService } from './CloudDocumentAttachmentsService';\nimport { CloudDocumentFormsService } from './CloudDocumentFormsService';\nimport { CloudDocumentPagesService } from './CloudDocumentPagesService';\nimport { CloudDocumentRedactionService } from './CloudDocumentRedactionService';\nimport { CloudDocumentSearchService } from './CloudDocumentSearchService';\nimport { CloudDocumentSecurityService } from './CloudDocumentSecurityService';\nimport { CloudMetadataService } from './CloudMetadataService';\nimport { CloudPageHandle } from './CloudPageHandle';\nimport { auditRowToEvent } from '../realtime/auditRowToEvent';\nimport { SseClient } from '../realtime/SseClient';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Read accessor handed to every `CloudPage…Service`. The closure\n * captures `this` so the services don't carry a direct reference\n * back to the document handle (smaller circular-ref surface, easier\n * to mock in unit tests).\n */\nexport interface ManifestAccessor {\n /** Cached manifest (cold-fetched once, kept across requests). */\n get(signal: AbortSignal): Promise<DocumentManifest>;\n /** Force re-fetch of `/head` + `/manifest@docVersion=N`; replaces the cache. */\n refresh(signal: AbortSignal): Promise<DocumentManifest>;\n /**\n * Absorb mutation-returned state/cache deltas when safe. `owns` names the\n * planes this mutation kind takes ownership of (the monotone-flip\n * rule): annotation/form writes own `annotations`; flatten and\n * redaction-apply own `content + annotations`. The flip runs even when\n * the version-gated delta merge is skipped — scopes only ever move\n * base → layer, so any observed mutation proves the plane diverged.\n */\n apply(meta: MutationMeta, owns: readonly LayerScopePlane[]): void;\n /** Advance the cached manifest's docVersion + layoutVersion after a page\n * STRUCTURE op that keeps the page set intact (move, rotate). */\n applyPageStructure(cache: PageStructureCache): void;\n /** Same advance for a page delete, additionally dropping the deleted\n * pages' manifest rows so per-page leaf URLs stop resolving locally. */\n applyPageDelete(cache: PageStructureCache, deletedPages: PageObjectNumber[]): void;\n /** Advance the cached manifest's docVersion + metadataVersion after a metadata write. */\n applyMetadata(cache: MetadataCache): void;\n /** Advance the cached manifest's docVersion + attachmentsVersion after an\n * attachment create/delete. */\n applyAttachments(cache: AttachmentsCache): void;\n}\n\nexport class CloudDocumentHandle implements DocumentHandle {\n readonly id: string;\n readonly capabilities = {\n weakAnnotationEditSessions: 'required',\n pageEditSessions: 'unsupported',\n } as const;\n readonly metadata: CloudMetadataService;\n readonly annotations: DocumentAnnotationsService;\n readonly actions: DocumentActionsService;\n readonly attachments: DocumentAttachmentsService;\n readonly forms: DocumentFormsService;\n readonly search: CloudDocumentSearchService;\n readonly pages: DocumentPagesService;\n readonly redaction: DocumentRedactionService;\n readonly security: DocumentSecurityService;\n readonly render: DocumentRenderService;\n readonly events: DocumentEventStream;\n private readonly publisher: SessionEventPublisher;\n private readonly hub: EventHub;\n private readonly sessionId: string;\n private sseClient: SseClient | null = null;\n private sseSubscribers = 0;\n private closed = false;\n\n /**\n * Cached current manifest. Populated on first read by `getManifest`\n * (or any `page().*` call that needs to know a version). Replaced\n * wholesale on `refreshManifest`. Cleared on `close`.\n *\n * Memory model: one DocumentManifest per open handle. Per-page\n * version reads are O(pages.length) `.find(...)` lookups; if a\n * profiling pass ever shows that as hot, swap for a Map keyed by\n * `pageObjectNumber`. Today's documents are page-sparse so the\n * scan is cheaper than the hash overhead.\n */\n private manifestCache: DocumentManifest | null = null;\n private inflightManifest: Promise<DocumentManifest> | null = null;\n private manifestFloorVersion = 0;\n private pendingInitialHead: DocumentHead | null;\n\n private readonly manifestAccessor: ManifestAccessor;\n\n constructor(\n private readonly http: HttpClient,\n id: string,\n private readonly layerName: string = DEFAULT_LAYER_NAME,\n initialHead?: DocumentHead,\n /**\n * The doc-scoped JWT the engine was opened with, decoded\n * unverified to populate the security service's local-fallback\n * `effectiveScope` / `identity` accessors. Optional for backward\n * compatibility; without it the local-fallback path returns an\n * empty scope and null identity until /access is called.\n */\n initialToken: string | null = null,\n sessionId: string = `cloud:anon:${id}`,\n ) {\n this.id = id;\n this.pendingInitialHead = initialHead ?? null;\n const security = new CloudDocumentSecurityService(\n http,\n id,\n layerName,\n initialHead ?? fallbackUnknownHead(id),\n { isClosed: () => this.closed },\n initialToken,\n );\n this.security = security;\n // The deployment's render lattice rides /v1/access (mutable policy\n // never lives in immutable manifests). Reuse the cached access block\n // when present; otherwise establish access on demand — the same call\n // the CDN path uses, so this can never add a second handshake shape.\n // A pre-lattice server (no renderPolicy field) enforces nothing:\n // `continuous` is the honest answer.\n this.render = {\n policy: async () => {\n const cached = security.currentAccess ?? (await security.establishAccess()).access ?? null;\n const advertised = cached?.renderPolicy;\n if (!advertised) return CONTINUOUS_RENDER_POLICY;\n return {\n kind: 'lattice',\n fullPage: { widths: advertised.fullPage.widths },\n ...(advertised.tiles ? { tiles: advertised.tiles } : {}),\n ...(advertised.appearances ? { appearances: advertised.appearances } : {}),\n ...(advertised.maxRenderPixels !== undefined\n ? { maxRenderPixels: advertised.maxRenderPixels }\n : {}),\n formats: advertised.formats,\n background: advertised.background,\n enforced: advertised.enforced,\n };\n },\n };\n const hub = new EventHub();\n this.hub = hub;\n this.sessionId = sessionId;\n // Your OWN mutations publish here at POST-confirmation time (kind:\n // 'local'); the remote channel (SSE) publishes everyone else's into the\n // same hub. Exactly one event per mutation, either way. The SSE stream\n // is LAZY: it opens on the first subscriber and closes on the last —\n // non-collaborative usage never holds a connection (browsers cap ~6\n // per origin on HTTP/1.1).\n this.events = {\n subscribe: (listener) => {\n const unsubscribe = hub.subscribe(listener);\n this.retainRemoteStream();\n let released = false;\n return () => {\n unsubscribe();\n if (!released) {\n released = true;\n this.releaseRemoteStream();\n }\n };\n },\n lastServerId: () => hub.lastServerId(),\n };\n this.publisher = new SessionEventPublisher(hub, sessionId);\n this.manifestAccessor = {\n get: (signal) => this.getManifest(signal),\n refresh: (signal) => this.refreshManifest(signal),\n apply: (meta, owns) => this.absorbMutation(meta, owns),\n applyPageStructure: (cache) => this.absorbPageStructure(cache),\n applyPageDelete: (cache, deletedPages) => this.absorbPageDelete(cache, deletedPages),\n applyMetadata: (cache) => this.absorbMetadata(cache),\n applyAttachments: (cache) => this.absorbAttachments(cache),\n };\n this.metadata = new CloudMetadataService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n this.annotations = new CloudDocumentAnnotationsService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n );\n this.actions = new CloudDocumentActionsService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n );\n this.attachments = new CloudDocumentAttachmentsService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n this.forms = new CloudDocumentFormsService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n this.search = new CloudDocumentSearchService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n );\n this.pages = new CloudDocumentPagesService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n this.redaction = new CloudDocumentRedactionService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n }\n\n page(pageObjectNumber: PageObjectNumber): PageHandle {\n return new CloudPageHandle(\n pageObjectNumber,\n -1,\n this.http,\n this.id,\n this.layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n }\n\n download(opts: { mode?: PdfSaveMode } = {}): AbortablePromise<Uint8Array> {\n if (this.closed) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.id} is closed`),\n );\n }\n const mode = opts.mode ?? DEFAULT_PDF_SAVE_MODE;\n return AbortablePromise.run<Uint8Array>(async (signal) => {\n const buildPath = async () => {\n const manifest = await this.getManifest(signal);\n return wirePaths.layerDownloadVersioned(this.id, this.layerName, {\n docVersion: manifest.docVersion,\n mode,\n });\n };\n try {\n return await this.http.getBytes(await buildPath(), signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n await this.refreshManifest(signal);\n return this.http.getBytes(await buildPath(), signal);\n }\n });\n }\n\n /**\n * Return the cached manifest, fetching cold-cache once if needed.\n * Concurrent callers share a single inflight request (singleflight)\n * so an N-page handle that opens N services in parallel still\n * triggers exactly one `/head` + `/manifest@docVersion=N` round-trip.\n */\n async getManifest(signal: AbortSignal): Promise<DocumentManifest> {\n if (this.manifestCache) return this.manifestCache;\n if (!this.inflightManifest) {\n this.startManifestFetch({ allowInitialHead: true });\n }\n const promise = this.inflightManifest;\n if (!promise) {\n throw new EngineError(\n EngineErrorCode.Unknown,\n `manifest fetch was not started for document ${this.id}`,\n );\n }\n return awaitSignal(promise, signal);\n }\n\n /**\n * Force re-fetch. Used by the transparent-retry path when a leaf\n * URL returns 404 (stale version). Replaces `manifestCache`\n * wholesale so the next `getManifest()` is a Map lookup.\n */\n async refreshManifest(signal: AbortSignal): Promise<DocumentManifest> {\n const promise = this.startManifestFetch({ allowInitialHead: false });\n return awaitSignal(promise, signal);\n }\n\n /**\n * Monotone plane-scope flip: mark the planes a mutation OWNS as layer-scoped in\n * the cached manifest. Scopes only ever move base → layer (no revert op\n * exists), so flipping is safe under ANY event ordering — a duplicate or\n * out-of-order event still proves the plane diverged at some point — and\n * the manifest fetch stays the authoritative source (the 404 → refresh\n * rail heals any miss, e.g. a future mutation kind this client doesn't\n * know about).\n */\n private flipScopes(owns: readonly LayerScopePlane[]): void {\n const cache = this.manifestCache;\n const scopes = cache?.scopes;\n if (!cache || !scopes) return;\n if (owns.every((plane) => scopes[plane] === 'layer')) return;\n const next = { ...scopes };\n for (const plane of owns) next[plane] = 'layer';\n this.manifestCache = { ...cache, scopes: next };\n }\n\n absorbMutation(meta: MutationMeta, owns: readonly LayerScopePlane[]): void {\n this.flipScopes(owns);\n const delta = meta.cacheDelta;\n if (delta) {\n this.manifestFloorVersion = Math.max(this.manifestFloorVersion, delta.docVersion);\n }\n this.inflightManifest = null;\n\n if (!this.manifestCache) return;\n if (delta) {\n if (delta.docVersion <= this.manifestCache.docVersion) return;\n if (delta.previousDocVersion !== this.manifestCache.docVersion) {\n this.manifestCache = null;\n return;\n }\n }\n\n const byPageObjectNumber = new Map(\n this.manifestCache.pages.map((page) => [page.state.pageObjectNumber, page]),\n );\n for (const pageState of meta.affectedPages) {\n const existing = byPageObjectNumber.get(pageState.pageObjectNumber);\n if (existing) {\n byPageObjectNumber.set(pageState.pageObjectNumber, {\n ...existing,\n state: pageState,\n });\n }\n }\n if (delta) {\n for (const page of delta.pages) {\n const existing = byPageObjectNumber.get(page.pageObjectNumber);\n if (existing) {\n byPageObjectNumber.set(page.pageObjectNumber, {\n ...existing,\n cache: page.cache,\n });\n }\n }\n }\n this.manifestCache = {\n ...this.manifestCache,\n docVersion: delta?.docVersion ?? this.manifestCache.docVersion,\n // The manifest is a per-page registry keyed by pageObjectNumber, not a\n // display-order list — geometry/order now lives in `pages.list()`\n // (/layout). Keep a deterministic order by PON so cache merges are\n // stable; display order is the SDK's concern via PageLayout.index.\n pages: Array.from(byPageObjectNumber.values()).sort(\n (a, b) => a.state.pageObjectNumber - b.state.pageObjectNumber,\n ),\n };\n }\n\n /**\n * Patch the cached manifest after a set-preserving page-structure op (move,\n * rotate). Both are purely structural: they advance `docVersion` (so leaf\n * URLs re-resolve) and `layoutVersion` (so the /layout leaf re-fetches),\n * but leave every per-page pin untouched — a rotate renders the SAME\n * normalized bitmaps, a move the same pages. We raise the floor\n * unconditionally and, when our cache is exactly one version behind,\n * advance it in place; otherwise we drop it and refetch lazily.\n */\n private absorbPageStructure(cache: PageStructureCache): void {\n // Move/rotate own the LAYOUT plane only: normalized render/text/\n // geometry artifacts survive structural ops, so content keeps sharing.\n this.flipScopes(['layout']);\n this.manifestFloorVersion = Math.max(this.manifestFloorVersion, cache.docVersion);\n this.inflightManifest = null;\n\n if (!this.manifestCache) return;\n if (cache.docVersion <= this.manifestCache.docVersion) return;\n if (cache.previousDocVersion !== this.manifestCache.docVersion) {\n this.manifestCache = null;\n return;\n }\n this.manifestCache = {\n ...this.manifestCache,\n docVersion: cache.docVersion,\n layoutVersion: cache.layoutVersion,\n };\n }\n\n /**\n * Patch the cached manifest after a page delete: the shared structural\n * advance plus dropping the deleted pages' manifest rows, so no leaf URL\n * for a retired PON can be built from the cache (a stale request would\n * 404 anyway — this keeps the failure local and instant).\n */\n private absorbPageDelete(cache: PageStructureCache, deletedPages: PageObjectNumber[]): void {\n // Delete changes the page SET: a view that removed content must never\n // resolve base artifacts again, so content AND annotations flip with\n // layout.\n this.flipScopes(['layout', 'content', 'annotations']);\n this.manifestFloorVersion = Math.max(this.manifestFloorVersion, cache.docVersion);\n this.inflightManifest = null;\n\n if (!this.manifestCache) return;\n if (cache.docVersion <= this.manifestCache.docVersion) return;\n if (cache.previousDocVersion !== this.manifestCache.docVersion) {\n this.manifestCache = null;\n return;\n }\n const deleted = new Set(deletedPages);\n this.manifestCache = {\n ...this.manifestCache,\n docVersion: cache.docVersion,\n layoutVersion: cache.layoutVersion,\n pages: this.manifestCache.pages.filter((page) => !deleted.has(page.state.pageObjectNumber)),\n };\n }\n\n /**\n * Patch the cached manifest after a metadata write. Symmetric with\n * {@link absorbPageMove}: a metadata edit advances `docVersion` (so leaf\n * URLs re-resolve) and `metadataVersion` (so the /metadata leaf re-fetches),\n * but leaves `layoutVersion` and every per-page pin untouched. Raise the\n * floor unconditionally and, when our cache is exactly one version behind,\n * advance it in place; otherwise drop it and refetch lazily.\n */\n private absorbMetadata(cache: MetadataCache): void {\n this.flipScopes(['metadata']);\n this.manifestFloorVersion = Math.max(this.manifestFloorVersion, cache.docVersion);\n this.inflightManifest = null;\n\n if (!this.manifestCache) return;\n if (cache.docVersion <= this.manifestCache.docVersion) return;\n if (cache.previousDocVersion !== this.manifestCache.docVersion) {\n this.manifestCache = null;\n return;\n }\n this.manifestCache = {\n ...this.manifestCache,\n docVersion: cache.docVersion,\n metadataVersion: cache.metadataVersion,\n };\n }\n\n /**\n * Patch the cached manifest after an attachment create/delete. Symmetric\n * with {@link absorbMetadata}: an attachment write advances `docVersion`\n * (so leaf URLs re-resolve) and `attachmentsVersion` (so the /attachments\n * listing and /attachment-files leaves re-fetch), but leaves\n * `layoutVersion` and every per-page pin untouched. Raise the floor\n * unconditionally and, when our cache is exactly one version behind,\n * advance it in place; otherwise drop it and refetch lazily.\n */\n private absorbAttachments(cache: AttachmentsCache): void {\n this.flipScopes(['attachments']);\n this.manifestFloorVersion = Math.max(this.manifestFloorVersion, cache.docVersion);\n this.inflightManifest = null;\n\n if (!this.manifestCache) return;\n if (cache.docVersion <= this.manifestCache.docVersion) return;\n if (cache.previousDocVersion !== this.manifestCache.docVersion) {\n this.manifestCache = null;\n return;\n }\n this.manifestCache = {\n ...this.manifestCache,\n docVersion: cache.docVersion,\n attachmentsVersion: cache.attachmentsVersion,\n };\n }\n\n private startManifestFetch(opts: { allowInitialHead: boolean }): Promise<DocumentManifest> {\n const ctrl = new AbortController();\n const promise = this.fetchManifest(ctrl.signal, opts);\n this.inflightManifest = promise;\n promise\n .then((manifest) => {\n if (\n manifest.docVersion >= this.manifestFloorVersion &&\n (!this.manifestCache || manifest.docVersion >= this.manifestCache.docVersion)\n ) {\n this.manifestCache = manifest;\n }\n })\n .catch(() => undefined)\n .finally(() => {\n if (this.inflightManifest === promise) {\n this.inflightManifest = null;\n }\n });\n return promise;\n }\n\n private async fetchManifest(\n signal: AbortSignal,\n opts: { allowInitialHead: boolean },\n ): Promise<DocumentManifest> {\n if (this.closed) {\n throw new EngineError(EngineErrorCode.DocNotOpen, `document ${this.id} is closed`);\n }\n const head = opts.allowInitialHead ? this.consumeInitialHead() : null;\n if (head) {\n try {\n return await this.fetchManifestForHead(head, signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n // A mutation may have landed between open() and the first\n // manifest read. The seed is one-shot, so fall through to the\n // normal /head path and learn the current docVersion.\n }\n }\n\n // Refreshes and stale-seed recovery always re-fetch `/head` first\n // so we learn the current `docVersion`; chasing the manifest with\n // a stale `:D` would 404 by definition.\n const freshHead = await this.http.getJson(\n wirePaths.layerHead(this.id, this.layerName),\n (raw) => DocumentHeadSchema.parse(raw),\n signal,\n );\n return this.fetchManifestForHead(freshHead, signal);\n }\n\n private consumeInitialHead(): DocumentHead | null {\n const head = this.pendingInitialHead;\n this.pendingInitialHead = null;\n return head;\n }\n\n private fetchManifestForHead(head: DocumentHead, signal: AbortSignal): Promise<DocumentManifest> {\n return this.http.getJson(\n wirePaths.layerManifest(this.id, this.layerName, head.docVersion),\n (raw) => DocumentManifestSchema.parse(raw),\n signal,\n );\n }\n\n close(): AbortablePromise<void> {\n if (this.closed) {\n return AbortablePromise.resolveValue<void>(undefined);\n }\n this.closed = true;\n this.sseClient?.close();\n this.sseClient = null;\n this.manifestCache = null;\n this.inflightManifest = null;\n return AbortablePromise.resolveValue<void>(undefined);\n }\n\n private retainRemoteStream(): void {\n this.sseSubscribers += 1;\n if (this.sseSubscribers > 1 || this.closed || this.sseClient) return;\n this.sseClient = new SseClient({\n http: this.http,\n path: wirePaths.layerEvents(this.id, this.layerName),\n // Gapless handshake: resume from the newest cursor we know — events\n // already seen, else the cached manifest's transactional auditHead.\n // Null (cold start, no manifest yet) subscribes \"from now\", which is\n // exact too: the first manifest fetched afterwards is newer anyway.\n initialCursor: this.hub.lastServerId() ?? this.manifestCache?.auditHead ?? null,\n onRow: (row) => {\n const event = auditRowToEvent(row, this.sessionId);\n if (!event) return; // own echo or unknown kind\n // Absorb BEFORE publish: a listener reading the manifest in its\n // callback must see post-mutation state (same order as local).\n this.absorbRemoteEvent(event);\n this.hub.publish(event);\n },\n onFullRefresh: () => {\n // Too far behind to replay: drop the cache; the next read refetches.\n this.manifestCache = null;\n this.inflightManifest = null;\n },\n onAuthLost: () => {\n // The stream is gone for good under this credential. Local events\n // keep flowing; remote delivery resumes if the doc is re-opened\n // with a fresh token.\n this.sseClient = null;\n },\n });\n this.sseClient.open();\n }\n\n private releaseRemoteStream(): void {\n this.sseSubscribers = Math.max(0, this.sseSubscribers - 1);\n if (this.sseSubscribers === 0 && this.sseClient) {\n this.sseClient.close();\n this.sseClient = null;\n }\n }\n\n /** Patch the cached manifest from a REMOTE event's coherence pins — the\n * same absorb rails local mutations use, so reads stay warm no matter\n * whose hand caused the change. */\n private absorbRemoteEvent(event: DocumentEvent): void {\n switch (event.type) {\n case 'annotation.created':\n case 'annotation.updated':\n case 'annotation.deleted':\n case 'annotation.moved':\n this.absorbMutation(event.meta, ['annotations']);\n return;\n case 'pages.moved':\n case 'pages.rotated':\n if (event.cache) this.absorbPageStructure(event.cache);\n return;\n case 'pages.deleted':\n if (event.cache) this.absorbPageDelete(event.cache, event.pageObjectNumbers);\n return;\n case 'metadata.updated':\n if (event.cache) this.absorbMetadata(event.cache);\n return;\n case 'attachment.created':\n case 'attachment.deleted':\n if (event.cache) this.absorbAttachments(event.cache);\n return;\n case 'form.valueChanged':\n case 'form.imported':\n case 'form.repaired':\n case 'form.fieldCreated':\n case 'form.fieldUpdated':\n case 'form.fieldDeleted':\n case 'form.widgetAttached':\n case 'form.widgetDetached':\n // Form mutations ship the same MutationMeta rails as annotations:\n // affected pages are the ones whose widget appearances changed.\n // Widgets ARE annotations, so they own the same plane.\n this.absorbMutation(event.meta, ['annotations']);\n return;\n case 'form.effectsApplied':\n // No-op batches are never audited, but keep the nullable guard at\n // the consumer boundary for forward/backward wire compatibility.\n if (event.meta) this.absorbMutation(event.meta, ['annotations']);\n return;\n case 'pages.flattened':\n // Flatten bakes annotations into page content: both planes flip.\n if (event.meta) this.absorbMutation(event.meta, ['content', 'annotations']);\n return;\n case 'redaction.applied':\n // Redaction-apply rewrites content and consumes the marks: both\n // planes flip — and this is the security-relevant divergence, so a\n // remote apply must stop this client's base reads immediately.\n if (event.meta) this.absorbMutation(event.meta, ['content', 'annotations']);\n return;\n }\n }\n}\n\nfunction fallbackUnknownHead(id: string): DocumentHead {\n return {\n id,\n baseSha: '',\n storageSizeBytes: 0,\n docVersion: 1,\n state: 'ready',\n encryption: { state: 'unknown', requiresPassword: null },\n permissions: {\n known: false,\n bits: null,\n allAllowed: null,\n openedAs: null,\n securityHandlerRevision: null,\n canUpgradeToOwner: false,\n },\n access: { required: true, reasons: ['permissions-unknown'], endpoint: wirePaths.access },\n };\n}\n\nfunction awaitSignal<T>(promise: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(new AbortError(signal.reason));\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n reject(new AbortError(signal.reason));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n (value) => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n (reason) => {\n signal.removeEventListener('abort', onAbort);\n reject(reason);\n },\n );\n });\n}\n","import {\n AbortError,\n EngineError,\n EngineErrorCode,\n type SerializedEngineError,\n} from '@embedpdf/engine-core/runtime';\nimport {\n applyCdnAccess,\n EngineErrorPayloadSchema,\n type CdnAccessInfoForApply,\n} from '@embedpdf/engine-core/wire';\n\nexport interface HttpClientOptions {\n baseUrl: string;\n /**\n * Optional bearer token. Either a string or a function that\n * returns a fresh token on every call (so callers can rotate\n * without re-creating the engine). When absent, requests go out\n * without an `Authorization` header — useful for the public-share\n * scenario where the doc-scoped token is provided per-`open` and\n * the engine itself has no engine-level credentials.\n */\n token?: string | (() => string | Promise<string>);\n /**\n * Engine-instance session id, sent as `X-Engine-Session-Id` on every\n * request. The server stores it on mutation audit rows so this\n * instance's SSE stream can drop its own echoes (exactly-once events).\n */\n sessionId?: string;\n /** Replace the global fetch (e.g. in Node tests with undici). */\n fetch?: typeof globalThis.fetch;\n}\n\n/**\n * Per-document binding for CDN URL rewriting. `CloudDocumentHandle`\n * calls `setCdnAccess` after `/v1/access` succeeds; the HttpClient\n * then runs every outgoing request through `applyCdnAccess` so\n * granted resources are routed to the CDN with the matching signed\n * query params (or cookies/auth header for the cookie/header\n * adapter modes).\n *\n * Set to `null` when the session is reset or when `/access` was\n * never called (public-share with no CDN configured).\n */\nexport interface CdnBinding {\n readonly cdn: CdnAccessInfoForApply | null;\n readonly docId: string;\n readonly layerName: string;\n}\n\n/**\n * A raw-bytes response plus its headers. The attachment-file leaves carry\n * their metadata as headers (`Content-Type`, `X-EmbedPDF-File-Name`), so\n * unlike `getBytes` the caller needs the `Headers` object back.\n */\nexport interface HttpFileResponse {\n bytes: Uint8Array;\n headers: Headers;\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly tokenFn: (() => string | Promise<string>) | null;\n private readonly fetchFn: typeof globalThis.fetch;\n private readonly sessionId: string | null;\n private cdnBinding: CdnBinding | null = null;\n\n constructor(opts: HttpClientOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/$/, '');\n const token = opts.token;\n this.tokenFn = token === undefined ? null : typeof token === 'function' ? token : () => token;\n this.sessionId = opts.sessionId ?? null;\n this.fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n /**\n * Return a clone of this client bound to a different bearer. Used\n * by `CloudEngine.open` to mint a per-handle client carrying the\n * per-open token, so each opened document's RPCs go out under\n * the right authorization without disturbing the engine-level\n * token.\n */\n withToken(token: string | (() => string | Promise<string>)): HttpClient {\n return new HttpClient({\n baseUrl: this.baseUrl,\n token,\n ...(this.sessionId ? { sessionId: this.sessionId } : {}),\n fetch: this.fetchFn,\n });\n }\n\n /**\n * Raw streaming GET (the SSE channel). Same auth/session headers and\n * error mapping as every other request; the caller owns the body stream.\n */\n async stream(\n path: string,\n headers: Record<string, string>,\n signal: AbortSignal,\n ): Promise<Response> {\n return this.request(path, {\n method: 'GET',\n headers: new Headers({ Accept: 'text/event-stream', ...headers }),\n signal,\n });\n }\n\n /**\n * Install (or clear) the per-session CDN binding. Pass `null` to\n * route everything to origin again — useful on session close or\n * when an adapter swap happens mid-session (rare).\n *\n * The HttpClient stays dumb about WHEN to do this; the cloud\n * document handle pushes the binding in after /access succeeds.\n *\n * Side effect: in the browser, signedCookies are written to\n * `document.cookie` once per setCdnAccess call so the CDN edge\n * receives them on subsequent fetches. Node side ignores cookies\n * for now (cookie jar wiring deferred until needed for tests).\n */\n setCdnAccess(binding: CdnBinding | null): void {\n this.cdnBinding = binding;\n if (binding?.cdn?.signedCookies && typeof globalThis.document !== 'undefined') {\n for (const cookie of binding.cdn.signedCookies) {\n const parts = [`${cookie.name}=${cookie.value}`];\n parts.push(`Path=${cookie.path ?? '/'}`);\n if (cookie.domain) parts.push(`Domain=${cookie.domain}`);\n if (cookie.expires) parts.push(`Expires=${new Date(cookie.expires * 1000).toUTCString()}`);\n parts.push('SameSite=None', 'Secure');\n globalThis.document.cookie = parts.join('; ');\n }\n }\n }\n\n /** Current CDN binding (or null). Exposed for diagnostics/tests. */\n get currentCdnBinding(): CdnBinding | null {\n return this.cdnBinding;\n }\n\n absoluteUrl(path: string): string {\n return `${this.baseUrl}${path}`;\n }\n\n async getBlob(path: string, signal: AbortSignal): Promise<Blob> {\n const res = await this.request(path, { method: 'GET', signal });\n if (!res.ok) await this.throwFromBody(res);\n return await res.blob();\n }\n\n async getBytes(path: string, signal: AbortSignal): Promise<Uint8Array> {\n const res = await this.request(path, {\n method: 'GET',\n headers: new Headers({ Accept: 'application/pdf' }),\n signal,\n });\n if (!res.ok) await this.throwFromBody(res);\n return new Uint8Array(await res.arrayBuffer());\n }\n\n /**\n * Resolve the current bearer token. Awaits the user-supplied\n * token factory if it returns a promise. Used by the cloud\n * engine to read doc-scoped claims **without** verifying — the\n * server is the verifier of record. Throws when no token is\n * configured.\n */\n async currentToken(): Promise<string> {\n if (!this.tokenFn) {\n throw new EngineError(EngineErrorCode.InvalidArg, 'http client has no token configured');\n }\n return await this.tokenFn();\n }\n\n async getJson<T>(path: string, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T> {\n const res = await this.request(path, { method: 'GET', signal });\n return await this.parseJsonResponse(res, parser);\n }\n\n /**\n * GET a versioned URL with transparent stale-version recovery. If\n * the server returns 404 (the well-known \"this version is gone\"\n * signal for content-addressed reads), call `onStaleVersion` (which\n * the caller wires to a manifest refresh), then re-resolve `buildPath`\n * and retry the GET exactly once. Any non-404 error propagates.\n *\n * The retry budget is hard-capped at 1: after a refresh, if the\n * server's idea of the current version is still ahead of the\n * client's view, the second request fails normally — this matches\n * the CDN cache invariant (\"a versioned URL's bytes are immutable\n * for its lifetime\").\n */\n async getJsonWithRefresh<T>(\n buildPath: (signal: AbortSignal) => Promise<string>,\n parser: (raw: unknown) => T,\n onStaleVersion: (signal: AbortSignal) => Promise<void>,\n signal: AbortSignal,\n ): Promise<T> {\n const initialPath = await buildPath(signal);\n try {\n return await this.getJson(initialPath, parser, signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n await onStaleVersion(signal);\n const retryPath = await buildPath(signal);\n return await this.getJson(retryPath, parser, signal);\n }\n }\n\n /**\n * GET a `multipart/form-data` body and parse it with the platform's\n * `Response.formData()` (works in browsers and undici). Text parts come\n * back as strings, parts with a filename as `Blob`s.\n */\n async getFormData(path: string, signal: AbortSignal): Promise<FormData> {\n const res = await this.request(path, {\n method: 'GET',\n headers: new Headers({ Accept: 'multipart/form-data' }),\n signal,\n });\n if (!res.ok) await this.throwFromBody(res);\n return await res.formData();\n }\n\n /**\n * `getFormData` with the same single-retry stale-version recovery as\n * {@link getJsonWithRefresh}: a 404 on a versioned URL triggers\n * `onStaleVersion` (a manifest refresh) and one re-resolve + retry.\n */\n async getFormDataWithRefresh(\n buildPath: (signal: AbortSignal) => Promise<string>,\n onStaleVersion: (signal: AbortSignal) => Promise<void>,\n signal: AbortSignal,\n ): Promise<FormData> {\n const initialPath = await buildPath(signal);\n try {\n return await this.getFormData(initialPath, signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n await onStaleVersion(signal);\n const retryPath = await buildPath(signal);\n return await this.getFormData(retryPath, signal);\n }\n }\n\n /**\n * `getBlob` with the same single-retry stale-version recovery as\n * {@link getJsonWithRefresh}: a 404 on a versioned URL triggers\n * `onStaleVersion` (a manifest refresh) and one re-resolve + retry.\n * Render blobs ride this rail: a scope flip re-resolves the\n * doc-vs-layer path family instead of failing on a stale URL.\n */\n async getBlobWithRefresh(\n buildPath: (signal: AbortSignal) => Promise<string>,\n onStaleVersion: (signal: AbortSignal) => Promise<void>,\n signal: AbortSignal,\n ): Promise<Blob> {\n const initialPath = await buildPath(signal);\n try {\n return await this.getBlob(initialPath, signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n await onStaleVersion(signal);\n const retryPath = await buildPath(signal);\n return await this.getBlob(retryPath, signal);\n }\n }\n\n /** GET raw bytes plus the response headers (attachment-file leaves). */\n async getFile(path: string, signal: AbortSignal): Promise<HttpFileResponse> {\n const res = await this.request(path, { method: 'GET', signal });\n if (!res.ok) await this.throwFromBody(res);\n return { bytes: new Uint8Array(await res.arrayBuffer()), headers: res.headers };\n }\n\n /**\n * `getFile` with the same single-retry stale-version recovery as\n * {@link getJsonWithRefresh}: a 404 on a versioned URL triggers\n * `onStaleVersion` (a manifest refresh) and one re-resolve + retry.\n */\n async getFileWithRefresh(\n buildPath: (signal: AbortSignal) => Promise<string>,\n onStaleVersion: (signal: AbortSignal) => Promise<void>,\n signal: AbortSignal,\n ): Promise<HttpFileResponse> {\n const initialPath = await buildPath(signal);\n try {\n return await this.getFile(initialPath, signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n await onStaleVersion(signal);\n const retryPath = await buildPath(signal);\n return await this.getFile(retryPath, signal);\n }\n }\n\n async postMultipartJson<T>(\n path: string,\n body: FormData,\n parser: (raw: unknown) => T,\n signal: AbortSignal,\n ): Promise<T> {\n const res = await this.request(path, { method: 'POST', body, signal });\n return await this.parseJsonResponse(res, parser);\n }\n\n /** PATCH counterpart of {@link postMultipartJson} (binary-carrying mutations). */\n async patchMultipartJson<T>(\n path: string,\n body: FormData,\n parser: (raw: unknown) => T,\n signal: AbortSignal,\n ): Promise<T> {\n const res = await this.request(path, { method: 'PATCH', body, signal });\n return await this.parseJsonResponse(res, parser);\n }\n\n async postJson<T>(\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n signal: AbortSignal,\n ): Promise<T> {\n const res = await this.requestJson(path, 'POST', body, signal);\n return await this.parseJsonResponse(res, parser);\n }\n\n /** POST a raw binary body (FDF/XFDF import) and parse the JSON response. */\n async postBytesJson<T>(\n path: string,\n bytes: Uint8Array,\n contentType: string,\n parser: (raw: unknown) => T,\n signal: AbortSignal,\n ): Promise<T> {\n const headers = new Headers({ 'Content-Type': contentType });\n // Copy into a fresh ArrayBuffer: `bytes` may be a view over a larger\n // (or SharedArrayBuffer-backed) buffer, which fetch bodies reject.\n const body = new Uint8Array(bytes).buffer as ArrayBuffer;\n const res = await this.request(path, { method: 'POST', body, headers, signal });\n return await this.parseJsonResponse(res, parser);\n }\n\n async patchJson<T>(\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n signal: AbortSignal,\n ): Promise<T> {\n const res = await this.requestJson(path, 'PATCH', body, signal);\n return await this.parseJsonResponse(res, parser);\n }\n\n async deleteJson<T>(path: string, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T> {\n const res = await this.request(path, { method: 'DELETE', signal });\n return await this.parseJsonResponse(res, parser);\n }\n\n async deleteEmpty(path: string, signal: AbortSignal): Promise<void> {\n const res = await this.request(path, { method: 'DELETE', signal });\n if (res.status === 204) return;\n if (!res.ok) await this.throwFromBody(res);\n }\n\n async postEmpty(path: string, body: unknown, signal: AbortSignal): Promise<void> {\n const res = await this.requestJson(path, 'POST', body, signal);\n if (res.status === 204) return;\n if (!res.ok) await this.throwFromBody(res);\n }\n\n private requestJson(\n path: string,\n method: 'POST' | 'PATCH' | 'PUT',\n body: unknown,\n signal: AbortSignal,\n ): Promise<Response> {\n const headers = new Headers({ 'Content-Type': 'application/json' });\n return this.request(path, {\n method,\n body: JSON.stringify(body ?? {}),\n headers,\n signal,\n });\n }\n\n private async request(path: string, init: RequestInit): Promise<Response> {\n const { url, extraHeader } = this.resolveOutgoing(path);\n const headers = new Headers(init.headers ?? {});\n if (this.tokenFn) {\n const token = await this.tokenFn();\n headers.set('Authorization', `Bearer ${token}`);\n }\n if (!headers.has('Accept')) headers.set('Accept', 'application/json');\n if (this.sessionId) headers.set('X-Engine-Session-Id', this.sessionId);\n if (extraHeader) headers.set(extraHeader.name, extraHeader.value);\n try {\n return await this.fetchFn(url, { ...init, headers });\n } catch (err) {\n // undici's fetch propagates whatever was passed to AbortController.abort().\n // Anything that arrives while signal.aborted is true is an abort, regardless\n // of the wire-shape (DOMException, plain Error, string, ...).\n if (init.signal?.aborted) {\n throw new AbortError(init.signal.reason ?? err);\n }\n if ((err as { name?: string } | null)?.name === 'AbortError') {\n throw new AbortError((err as Error).message);\n }\n throw new EngineError(\n EngineErrorCode.Network,\n `network error: ${(err as Error)?.message ?? err}`,\n {\n cause: err,\n },\n );\n }\n }\n\n private async parseJsonResponse<T>(res: Response, parser: (raw: unknown) => T): Promise<T> {\n if (!res.ok) await this.throwFromBody(res);\n const json: unknown = await res.json().catch(() => ({}));\n try {\n return parser(json);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n `unexpected response shape: ${(err as Error)?.message ?? err}`,\n {\n cause: err,\n },\n );\n }\n }\n\n /**\n * Decide where this request actually goes. With no CDN binding (or\n * binding's `cdn` is null) every request stays on origin. Otherwise\n * `applyCdnAccess` decides per-request based on the resource the\n * path resolves to (and whether the caller's scope granted CDN\n * access to it).\n */\n private resolveOutgoing(path: string): {\n url: string;\n extraHeader: { name: string; value: string } | null;\n } {\n if (!this.cdnBinding || !this.cdnBinding.cdn) {\n return { url: `${this.baseUrl}${path}`, extraHeader: null };\n }\n const applied = applyCdnAccess({\n path,\n originUrl: this.baseUrl,\n docId: this.cdnBinding.docId,\n layerName: this.cdnBinding.layerName,\n cdn: this.cdnBinding.cdn,\n });\n return {\n url: applied.url,\n extraHeader: applied.routedToCdn && applied.authHeader ? applied.authHeader : null,\n };\n }\n\n private async throwFromBody(res: Response): Promise<never> {\n let payload: unknown;\n try {\n payload = await res.json();\n } catch {\n payload = null;\n }\n const code = mapStatusToCode(res.status);\n if (payload && typeof payload === 'object' && 'error' in payload) {\n const inner = (payload as { error: unknown }).error;\n const parsed = trySerialized(inner);\n if (parsed) throw new EngineError(parsed.code, parsed.message, { details: parsed.details });\n const msg =\n typeof inner === 'object' && inner && 'message' in inner\n ? String((inner as { message: unknown }).message)\n : `HTTP ${res.status}`;\n throw new EngineError(code, msg, { details: { status: res.status } });\n }\n throw new EngineError(code, `HTTP ${res.status}`, { details: { status: res.status } });\n }\n}\n\nfunction mapStatusToCode(status: number): EngineErrorCode {\n if (status === 401) return EngineErrorCode.Unauthenticated;\n if (status === 403) return EngineErrorCode.Forbidden;\n if (status === 409) return EngineErrorCode.WeakAnnotationSessionConflict;\n if (status === 404) return EngineErrorCode.NotFound;\n if (status === 422) return EngineErrorCode.DocOpenFailed;\n if (status === 499) return EngineErrorCode.Aborted;\n if (status === 400) return EngineErrorCode.InvalidArg;\n return EngineErrorCode.Unknown;\n}\n\nfunction trySerialized(value: unknown): SerializedEngineError | null {\n const result = EngineErrorPayloadSchema.safeParse(value);\n return result.success ? result.data : null;\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type DocumentHandle,\n type Engine,\n type OpenInput,\n type OpenOptions,\n} from '@embedpdf/engine-core/runtime';\nimport { DEFAULT_LAYER_NAME, DocumentHeadSchema, wirePaths } from '@embedpdf/engine-core/wire';\nimport { generateUuid } from '@embedpdf/engine-services';\n\nimport { CloudDocumentHandle } from './document/CloudDocumentHandle';\nimport { CloudDocumentSecurityService } from './document/CloudDocumentSecurityService';\nimport { decodeUnverifiedClaims } from './transport/decodeUnverifiedClaims';\nimport { HttpClient, type HttpClientOptions } from './transport/HttpClient';\n\nexport interface CloudEngineOptions extends HttpClientOptions {}\n\n/**\n * Cloud engine: speaks the same Engine interface as @embedpdf/engine\n * but routes everything through HTTPS to a remote @cloudpdf/server (or\n * CloudPDF SaaS). Identical observable contract; only the transport differs.\n */\nexport class CloudEngine implements Engine {\n static fromOptions(opts: CloudEngineOptions): CloudEngine {\n // One identity per engine instance: it stamps local events' origins AND\n // travels as X-Engine-Session-Id so the server can mark this instance's\n // audit rows — the SSE stream drops those echoes (exactly-once events).\n const sessionId = `cloud:${generateUuid()}`;\n return new CloudEngine(new HttpClient({ ...opts, sessionId }), sessionId);\n }\n\n private destroyed = false;\n\n private constructor(\n private readonly http: HttpClient,\n /** This engine instance's identity on every event's `origin.sessionId`. */\n private readonly sessionId: string,\n ) {}\n\n open(input: OpenInput, options?: OpenOptions): AbortablePromise<DocumentHandle> {\n if (this.destroyed) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.RuntimeUnavailable, 'engine destroyed'),\n );\n }\n // Cloud reads scope + identity from the doc-scoped JWT — `options.scope`\n // and `options.identity` are engine-local concepts and are intentionally\n // ignored here. Same `OpenOptions` type for both engines is what makes\n // SDK code portable; the JWT is the authority cloud-side.\n void options?.scope;\n void options?.identity;\n\n // Presence-based precedence, same rule the local engine documents: an\n // options.password key wins (even explicitly null), else input.password.\n const effectivePassword =\n options && 'password' in options ? (options.password ?? null) : (input.password ?? null);\n\n if (input.kind === 'token') {\n // Open by doc-scoped JWT. We never verify the token SDK-side\n // (server is the verifier of record); we just decode the\n // unsigned payload to learn `doc_id`, then route to /head with\n // the per-open bearer. The resulting handle owns its own\n // scoped HttpClient — every subsequent RPC carries this\n // token, NOT the engine-level one, so one engine can hold\n // many handles each with a different bearer.\n const tokenSource = input.token;\n return AbortablePromise.run<DocumentHandle>(async (signal) => {\n const docHttp = this.http.withToken(tokenSource);\n const token = await docHttp.currentToken();\n const claims = decodeUnverifiedClaims(token);\n const docId = claims.doc_id;\n if (typeof docId !== 'string' || docId.length === 0) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n 'cloud engine: token has no doc_id claim — mint a doc-scoped JWT',\n );\n }\n const layerName =\n typeof claims.layer_name === 'string' && claims.layer_name.length > 0\n ? claims.layer_name\n : DEFAULT_LAYER_NAME;\n const head = await docHttp.getJson(\n wirePaths.layerHead(docId, layerName),\n (raw) => DocumentHeadSchema.parse(raw),\n signal,\n );\n const handle = new CloudDocumentHandle(\n docHttp,\n head.id,\n layerName,\n head,\n token,\n this.sessionId,\n );\n await maybeAutoEstablishAccess(handle, head, signal, effectivePassword);\n return handle;\n });\n }\n\n if (input.kind === 'id') {\n // Open by docId using the engine-level token (typical: a\n // tenant JWT). The caller can override per-open by setting\n // `input.token`; the resulting handle then carries that\n // override for all of its RPCs.\n const id = input.id;\n const docHttp = input.token ? this.http.withToken(input.token) : this.http;\n return AbortablePromise.run<DocumentHandle>(async (signal) => {\n let layerName = input.layerName ?? DEFAULT_LAYER_NAME;\n // Resolve the bearer once so we have it for the layer-name\n // claim AND for the security service's local-fallback scope/\n // identity. May be null when the engine has no token at all\n // (caller invokes /head anonymously — server will reject).\n let resolvedToken: string | null = null;\n try {\n resolvedToken = await docHttp.currentToken();\n } catch {\n resolvedToken = null;\n }\n if (!input.layerName && resolvedToken) {\n const claims = decodeUnverifiedClaims(resolvedToken);\n if (typeof claims.layer_name === 'string' && claims.layer_name.length > 0) {\n layerName = claims.layer_name;\n }\n }\n const head = await docHttp.getJson(\n wirePaths.layerHead(id, layerName),\n (raw) => DocumentHeadSchema.parse(raw),\n signal,\n );\n const handle = new CloudDocumentHandle(\n docHttp,\n head.id,\n layerName,\n head,\n resolvedToken,\n this.sessionId,\n );\n await maybeAutoEstablishAccess(handle, head, signal, effectivePassword);\n return handle;\n });\n }\n\n void options;\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n `cloud engine supports OpenInput.kind === 'token' or 'id' (got '${(input as { kind?: string }).kind}')`,\n ),\n );\n }\n\n destroy(): AbortablePromise<void> {\n if (this.destroyed) return AbortablePromise.resolveValue<void>(undefined);\n this.destroyed = true;\n return AbortablePromise.resolveValue<void>(undefined);\n }\n}\n\n/**\n * Post-/head access establishment, in two layers:\n *\n * 1. **Supplied password** — a password given at open is always TRIED\n * (PDFium parity: the local engine feeds it to the loader no matter\n * what). Two triggers, because `/head` only carries the `password`\n * reason when a password is needed to READ:\n * - `reasons` has `'password'` → required-to-read case\n * - `head.permissions.canUpgradeToOwner` → permission-only encrypted\n * doc; the password can still upgrade to owner. Skipping this arm\n * would silently drop supplied OWNER passwords — and diverge from\n * the local engine on identical input.\n * Outcomes follow \"a password failure may only block what the password\n * was needed for\": a rejection in the required case leaves the handle\n * locked (the caller's prompt takes over, showing \"incorrect\"); in the\n * upgrade case the document stays readable and the failure is\n * non-fatal. The one /access POST also installs the CDN binding, so a\n * successful unlock covers the `password + cdn` combined case.\n *\n * 2. **CDN-only** — unchanged: `/access` without a password, transparently.\n * A required password with NO supplied password never auto-calls; the\n * dev prompts and `unlock()` runs the same POST.\n *\n * Non-password /access failures never break `open()` (the first real\n * request still tries origin, where the JWT check produces a regular\n * Forbidden) — but they are also never mistaken for a wrong password:\n * only a DocPasswordRequired/Incorrect rejection means \"wrong password\".\n */\nasync function maybeAutoEstablishAccess(\n handle: CloudDocumentHandle,\n head: {\n access: { required: boolean; reasons: ReadonlyArray<string> };\n permissions: { canUpgradeToOwner: boolean };\n },\n signal: AbortSignal,\n password: string | null,\n): Promise<void> {\n const reasons = new Set(head.access.reasons);\n // CloudDocumentSecurityService exposes `establishAccess()` — the\n // no-password sibling of `unlock()`. The public DocumentSecurityService\n // interface doesn't carry it (unlock = user action), but every\n // CloudDocumentHandle's `.security` is a CloudDocumentSecurityService.\n const security = handle.security as CloudDocumentSecurityService;\n\n const tryPassword =\n password != null && (reasons.has('password') || head.permissions.canUpgradeToOwner);\n if (tryPassword) {\n const unlocked = await settleLinked(security.unlock({ password, mode: 'any' }), signal);\n if (unlocked) return; // /access succeeded — CDN binding installed too\n // Rejected or failed: in the required case the handle stays locked and\n // the caller's password prompt takes over (retrying re-POSTs /access);\n // in the upgrade case the document is readable regardless — fall\n // through so a CDN-only establishment still happens.\n if (reasons.has('password')) return;\n }\n\n if (!head.access.required) return;\n if (reasons.has('password')) return; // wait for explicit unlock()\n if (!reasons.has('cdn')) return; // nothing actionable for the SDK\n await settleLinked(security.establishAccess(), signal);\n}\n\n/** Await an /access attempt with open()-abort linkage. Returns whether it\n * succeeded; failures are contained (see maybeAutoEstablishAccess). */\nasync function settleLinked(\n pending: ReturnType<CloudDocumentSecurityService['unlock']>,\n signal: AbortSignal,\n): Promise<boolean> {\n const onAbort = () => pending.abort(signal.reason ?? new Error('aborted'));\n if (signal.aborted) onAbort();\n else signal.addEventListener('abort', onAbort, { once: true });\n try {\n await pending;\n return true;\n } catch {\n return false;\n } finally {\n signal.removeEventListener('abort', onAbort);\n }\n}\n","import type { TokenSource } from '@embedpdf/engine-core/runtime';\n\n/**\n * Share-session exchange: the client half of the no-backend embed flow.\n *\n * A share token (`shr_…`) is a REFERENCE to a stored grant on the\n * server, not a credential — `exchangeShareToken` trades it for an\n * ordinary short-lived doc JWT, and `shareSessionSource` wraps that in\n * a self-renewing {@link TokenSource}. Because the engine's transport\n * invokes its token source on every request (and SSE reconnects call\n * it again), renewal is nothing more than \"exchange again when the\n * cached session is nearly out\" — no timers, no listeners.\n *\n * The endpoint requires a browser `Origin` header (the server checks\n * it against the grant's allowlist). Browsers attach it automatically;\n * non-browser callers (tests, SSR) must supply a `fetch` that does.\n */\n\nexport interface ShareSession {\n /** Doc-scoped session JWT carrying the grant's capabilities. */\n token: string;\n docId: string;\n layerName: string;\n /** Unix seconds when `token` expires. */\n expiresAt: number;\n}\n\nexport interface ShareExchangeOptions {\n /** Passphrase for protected grants (`SharePasswordRequired` otherwise). */\n password?: string;\n fetch?: typeof globalThis.fetch;\n}\n\n/**\n * Thrown on a non-OK exchange. `code` is the server's wire code:\n * `SharePasswordRequired` (prompt and retry with a password),\n * `OriginNotAllowed` / `OriginRequired`, `ShareExpired`, `NotFound`\n * (unknown or revoked — indistinguishable by design), or\n * `TooManyRequests`.\n */\nexport class ShareExchangeError extends Error {\n constructor(\n readonly code: string,\n message: string,\n readonly status: number,\n ) {\n super(message);\n this.name = 'ShareExchangeError';\n }\n}\n\nexport async function exchangeShareToken(\n baseUrl: string,\n shareToken: string,\n opts: ShareExchangeOptions = {},\n): Promise<ShareSession> {\n const doFetch = opts.fetch ?? globalThis.fetch;\n const res = await doFetch(`${baseUrl.replace(/\\/$/, '')}/v1/share-sessions`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n shareToken,\n ...(opts.password !== undefined ? { password: opts.password } : {}),\n }),\n });\n if (!res.ok) {\n let code = 'Unknown';\n let message = `share exchange failed with status ${res.status}`;\n try {\n const payload = (await res.json()) as { error?: { code?: string; message?: string } };\n if (payload.error?.code) code = payload.error.code;\n if (payload.error?.message) message = payload.error.message;\n } catch {\n // Non-JSON error body; keep the status-shaped message.\n }\n throw new ShareExchangeError(code, message, res.status);\n }\n return (await res.json()) as ShareSession;\n}\n\n/** Renew this many seconds before `expiresAt` so in-flight requests never race expiry. */\nconst RENEW_MARGIN_SECONDS = 60;\n\n/**\n * A caching, self-renewing {@link TokenSource} over the exchange.\n * Concurrent callers share one in-flight exchange; a failed exchange\n * clears it so the next request retries rather than caching the error.\n */\nexport function shareSessionSource(\n baseUrl: string,\n shareToken: string,\n opts: ShareExchangeOptions = {},\n): TokenSource {\n let session: ShareSession | null = null;\n let inflight: Promise<string> | null = null;\n return async () => {\n if (session && session.expiresAt - Date.now() / 1000 > RENEW_MARGIN_SECONDS) {\n return session.token;\n }\n inflight ??= exchangeShareToken(baseUrl, shareToken, opts)\n .then((next) => {\n session = next;\n return next.token;\n })\n .finally(() => {\n inflight = null;\n });\n return inflight;\n };\n}\n","/**\n * @cloudpdf/engine - Engine v3 cloud client.\n *\n * Implements the same {@link Engine} interface as `@embedpdf/engine` but\n * routes calls to a remote `@cloudpdf/server` over HTTP. Same observable\n * contract: {@link AbortablePromise}-based, EngineError-coded, parity-tested\n * with `runMetadataConformance`.\n */\nexport { CloudEngine } from './CloudEngine';\nexport type { CloudEngineOptions } from './CloudEngine';\nexport { CloudDocumentHandle } from './document/CloudDocumentHandle';\nexport { CloudMetadataService } from './document/CloudMetadataService';\nexport { CloudDocumentAnnotationsService } from './document/CloudDocumentAnnotationsService';\nexport { CloudDocumentPagesService } from './document/CloudDocumentPagesService';\nexport { CloudPageHandle } from './document/CloudPageHandle';\nexport { CloudPageAnnotationsService } from './document/CloudPageAnnotationsService';\nexport { CloudPageGeometryService } from './document/CloudPageGeometryService';\nexport { CloudPageRenderService } from './document/CloudPageRenderService';\nexport { HttpClient } from './transport/HttpClient';\nexport type { HttpClientOptions } from './transport/HttpClient';\nexport { decodeUnverifiedClaims } from './transport/decodeUnverifiedClaims';\nexport type { UnverifiedClaims } from './transport/decodeUnverifiedClaims';\nexport { exchangeShareToken, shareSessionSource, ShareExchangeError } from './share';\nexport type { ShareSession, ShareExchangeOptions } from './share';\n\nimport { CloudEngine, type CloudEngineOptions } from './CloudEngine';\n\nexport function createCloudEngine(opts: CloudEngineOptions): CloudEngine {\n return CloudEngine.fromOptions(opts);\n}\n\n/**\n * Create a cloud {@link CloudEngine} — the drop-in counterpart of\n * `localEngine()`, so swapping local for cloud is a one-import change.\n *\n * Synchronous and cheap: no WASM to compile, no worker to spawn — the engine\n * holds an HTTP client and nothing else. Like `localEngine()`, the returned\n * instance is yours (call `destroy()` when done, usually never for a\n * module-scope singleton); pass a thunk (`engine={() => cloudEngine(...)}`)\n * to let a `<Viewer>` own the lifetime instead.\n *\n * Note the deliberate asymmetry with `localEngine()`: there is no `fonts`\n * option. Fallback fonts are a SERVER policy on the cloud (`Engine.fonts` is\n * `undefined` cloud-side), so they cannot be configured from the client. This\n * is the local-vs-cloud split, surfaced in the API.\n *\n * ```ts\n * const engine = cloudEngine({ baseUrl: 'https://pdf.example.com', token });\n * <Viewer engine={engine} plugins={[stagePlugin(), renderPlugin()]} />\n * ```\n */\nexport function cloudEngine(opts: CloudEngineOptions): CloudEngine {\n return CloudEngine.fromOptions(opts);\n}\n\n// Re-export the shared engine runtime surface so consumers import every\n// public type and primitive from a single `@cloudpdf/engine` entrypoint\n// instead of reaching into the transitive `@embedpdf/engine-core` dep.\nexport {\n AbortablePromise,\n AbortError,\n EngineError,\n EngineErrorCode,\n} from '@embedpdf/engine-core/runtime';\nexport type {\n Engine,\n EngineFactory,\n DocumentHandle,\n DocumentCapabilities,\n PageHandle,\n OpenInput,\n OpenOptions,\n TokenSource,\n MetadataService,\n DocumentPagesService,\n DocumentAnnotationsService,\n PageAnnotationsService,\n PageTextService,\n PageGeometryService,\n PageRenderService,\n DocumentSecurityService,\n DocumentSecurityState,\n DocumentUnlockInput,\n DocumentUnlockResult,\n DocumentAccessInfo,\n DocumentIdentity,\n PdfSaveMode,\n} from '@embedpdf/engine-core/runtime';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["AbortablePromise","EngineError","EngineErrorCode","wirePaths","DocumentActionsSnapshotSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","WeakAnnotationSessionResponseSchema","AnnotationListPageSnapshotSchema","EngineError","EngineErrorCode","EmbeddedFileItemSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","AttachmentCreateResultSchema","AttachmentDeleteResultSchema","AbortablePromise","wirePaths","FormSnapshotSchema","FormFieldDTOSchema","FormSetValueResultSchema","FormEffectsResultSchema","FormImportResultSchema","FormFieldCreateResultSchema","FormFieldUpdateResultSchema","FormFieldDeleteResultSchema","FormWidgetLinkResultSchema","FormRepairResultSchema","EngineError","EngineErrorCode","AbortablePromise","EngineError","EngineErrorCode","wirePaths","PageListSnapshotSchema","PageMoveResultSchema","PageRotateResultSchema","PageDeleteResultSchema","PageFlattenResultSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","RedactionApplyResultSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","SearchSliceSchema","EngineError","EngineErrorCode","AbortablePromise","EngineError","EngineErrorCode","wirePaths","AccessResponseSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","DocumentMetadataSchema","MetadataUpdateResultSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","AnnotationListPageSnapshotSchema","AnnotationCreateResultSchema","AnnotationUpdateResultSchema","AnnotationDeleteResultSchema","AnnotationMoveResultSchema","AnnotationAppearanceManifestSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","PageGeometrySnapshotSchema","AbortablePromise","EngineError","EngineErrorCode","wirePaths","AbortablePromise","EngineError","EngineErrorCode","wirePaths","PageTextSnapshotSchema","EngineError","EngineErrorCode","DEFAULT_LAYER_NAME","CONTINUOUS_RENDER_POLICY","EventHub","SessionEventPublisher","AbortablePromise","EngineError","EngineErrorCode","DEFAULT_PDF_SAVE_MODE","wirePaths","DocumentHeadSchema","DocumentManifestSchema","AbortError","EngineError","EngineErrorCode","EngineError","EngineErrorCode","AbortError","EngineErrorPayloadSchema","AbortablePromise","EngineError","EngineErrorCode","DEFAULT_LAYER_NAME","wirePaths","DocumentHeadSchema"],"sources":["../src/document/planes.ts","../src/document/CloudDocumentActionsService.ts","../src/document/CloudDocumentAnnotationsService.ts","../src/document/buildMutationForm.ts","../src/document/parseAttachmentContent.ts","../src/document/CloudDocumentAttachmentsService.ts","../src/document/CloudDocumentFormsService.ts","../src/document/CloudDocumentPagesService.ts","../src/document/CloudDocumentRedactionService.ts","../src/document/CloudDocumentSearchService.ts","../src/transport/decodeUnverifiedClaims.ts","../src/document/CloudDocumentSecurityService.ts","../src/document/CloudMetadataService.ts","../src/document/CloudPageAnnotationsService.ts","../src/document/CloudPageGeometryService.ts","../src/document/CloudPageRenderService.ts","../src/document/CloudPageTextService.ts","../src/document/CloudPageHandle.ts","../src/realtime/auditRowToEvent.ts","../src/realtime/SseClient.ts","../src/document/CloudDocumentHandle.ts","../src/share.ts","../src/transport/HttpClient.ts","../src/CloudEngine.ts","../src/index.ts"],"sourcesContent":["import type { DocumentManifest, LayerScopePlane } from '@embedpdf/engine-core/wire';\n\n/**\n * Plane-scope resolution — THE one rule every cloud service uses to pick a\n * path family: a read resolves at the DOC-LEVEL (shared base) path iff EVERY\n * plane it depends on is inherited (`'base'`) by this layer. One owned plane\n * → the layer-scoped path.\n *\n * Absent `scopes` (base manifests never carry it; pre-plane servers omit\n * it) means layer paths — never wrong, only unshared.\n */\nexport function planesInherited(\n manifest: DocumentManifest,\n planes: readonly LayerScopePlane[],\n): boolean {\n const scopes = manifest.scopes;\n if (!scopes) return false;\n return planes.every((plane) => scopes[plane] === 'base');\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type DocumentActionsService,\n type DocumentActionsSnapshot,\n} from '@embedpdf/engine-core/runtime';\nimport { DocumentActionsSnapshotSchema, wirePaths } from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudDocumentActionsService implements DocumentActionsService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n read(): AbortablePromise<DocumentActionsSnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run((signal) =>\n this.http.getJsonWithRefresh(\n async (currentSignal) => {\n const manifest = await this.manifest.get(currentSignal);\n // Plane-scope rule: catalog actions depend on the `actions` plane\n // (constant-inherited until action writing exists) — one\n // doc-level URL, base session, no layer warm-up on open.\n return planesInherited(manifest, ['actions'])\n ? wirePaths.docActions(this.docId, manifest.actionsVersion)\n : wirePaths.layerActions(this.docId, this.layerName, manifest.actionsVersion);\n },\n (raw) => DocumentActionsSnapshotSchema.parse(raw),\n async (currentSignal) => {\n await this.manifest.refresh(currentSignal);\n },\n signal,\n ),\n );\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type AnnotationListPageSnapshot,\n type AnnotationListSnapshotAllPages,\n type DocumentAnnotationsService,\n type PageObjectNumber,\n type WeakAnnotationEditSession,\n} from '@embedpdf/engine-core/runtime';\nimport {\n AnnotationListPageSnapshotSchema,\n WeakAnnotationSessionResponseSchema,\n wirePaths,\n type WeakAnnotationSessionResponse,\n} from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudDocumentAnnotationsService implements DocumentAnnotationsService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n listRawAll(): AbortablePromise<AnnotationListSnapshotAllPages> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AnnotationListSnapshotAllPages>(async (signal) => {\n const manifest = await this.manifest.get(signal);\n const pages = await Promise.all(\n manifest.pages.map((page) => this.readCurrentPage(page.state.pageObjectNumber, signal)),\n );\n return { pages };\n });\n }\n\n listRaw(pageObjectNumber: PageObjectNumber): AbortablePromise<AnnotationListPageSnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AnnotationListPageSnapshot>((signal) =>\n this.readCurrentPage(pageObjectNumber, signal),\n );\n }\n\n beginWeakEdit(\n pageObjectNumbers: readonly PageObjectNumber[],\n ): AbortablePromise<WeakAnnotationEditSession> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<WeakAnnotationEditSession>(async (signal) => {\n const response = await this.http.postJson(\n wirePaths.layerWeakAnnotationSession(this.docId, this.layerName),\n { pageObjectNumbers },\n (raw) => WeakAnnotationSessionResponseSchema.parse(raw),\n signal,\n );\n return new CloudWeakAnnotationEditSession(\n this.http,\n this.docId,\n this.layerName,\n () => this.isClosed(),\n response,\n );\n });\n }\n\n private async readCurrentPage(\n pageObjectNumber: PageObjectNumber,\n signal: AbortSignal,\n ): Promise<AnnotationListPageSnapshot> {\n return this.http.getJson(\n wirePaths.layerPageAnnotationsCurrent(this.docId, this.layerName, pageObjectNumber),\n (raw) => AnnotationListPageSnapshotSchema.parse(raw),\n signal,\n );\n }\n}\n\nclass CloudWeakAnnotationEditSession implements WeakAnnotationEditSession {\n private response: WeakAnnotationSessionResponse;\n private released = false;\n\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n response: WeakAnnotationSessionResponse,\n ) {\n this.response = response;\n }\n\n get id(): string {\n return this.response.sessionId;\n }\n\n get expiresAt(): number {\n return this.response.expiresAt;\n }\n\n get heartbeatIntervalMs(): number {\n return this.response.heartbeatIntervalMs;\n }\n\n get pageObjectNumbers(): readonly PageObjectNumber[] {\n return this.response.pageObjectNumbers;\n }\n\n covers(pageObjectNumber: PageObjectNumber): boolean {\n return this.response.pageObjectNumbers.includes(pageObjectNumber);\n }\n\n updatePages(pageObjectNumbers: readonly PageObjectNumber[]): AbortablePromise<void> {\n if (this.isClosed() || this.released) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `weak annotation session ${this.id} is closed`),\n );\n }\n return AbortablePromise.run<void>(async (signal) => {\n this.response = await this.http.postJson(\n wirePaths.layerWeakAnnotationSessionPages(this.docId, this.layerName, this.id),\n { pageObjectNumbers },\n (raw) => WeakAnnotationSessionResponseSchema.parse(raw),\n signal,\n );\n });\n }\n\n heartbeat(): AbortablePromise<void> {\n if (this.isClosed() || this.released) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `weak annotation session ${this.id} is closed`),\n );\n }\n return AbortablePromise.run<void>(async (signal) => {\n this.response = await this.http.postJson(\n wirePaths.layerWeakAnnotationSessionHeartbeat(this.docId, this.layerName, this.id),\n {},\n (raw) => WeakAnnotationSessionResponseSchema.parse(raw),\n signal,\n );\n });\n }\n\n release(): AbortablePromise<void> {\n if (this.released) {\n return AbortablePromise.resolveValue(undefined);\n }\n this.released = true;\n return AbortablePromise.run<void>((signal) =>\n this.http.deleteEmpty(\n wirePaths.layerWeakAnnotationSessionRelease(this.docId, this.layerName, this.id),\n signal,\n ),\n );\n }\n}\n","import type { WireResourceMap } from '@embedpdf/engine-core/runtime';\n\n/**\n * Multipart envelope for mutations that carry binaries: part `body` holds\n * the exact JSON the plain request would have been, plus one\n * `resource:{key}` file part per binary payload. Mirrors the appearance\n * response protocol (`manifest` part + named image parts) in reverse.\n * Shared by the annotation mutations (stamp images, attachment files) and\n * the document-level `attachments.create` — one envelope, one parser on\n * the server side.\n */\nexport function buildMutationForm(body: unknown, resources: WireResourceMap): FormData {\n const form = new FormData();\n form.append('body', JSON.stringify(body));\n for (const [key, resource] of Object.entries(resources)) {\n form.append(\n `resource:${key}`,\n new Blob([resource.bytes], { type: resource.mimeType ?? 'application/octet-stream' }),\n resource.name ?? key,\n );\n }\n return form;\n}\n\nexport function hasResources(resources: WireResourceMap): boolean {\n return Object.keys(resources).length > 0;\n}\n","import {\n EngineError,\n EngineErrorCode,\n type AttachmentContent,\n} from '@embedpdf/engine-core/runtime';\nimport { decodeTokenText } from '@embedpdf/engine-core/wire';\n\nimport type { HttpFileResponse } from '../transport/HttpClient';\n\n/** Header carrying the file's name, token-text encoded (names are\n * arbitrary UTF-8; HTTP header values are not). */\nconst FILE_NAME_HEADER = 'X-EmbedPDF-File-Name';\n\n/**\n * Project an attachment-file response into `AttachmentContent`. The body\n * IS the decoded bytes; the metadata rides as headers — `Content-Type`\n * for the declared mime type, `X-EmbedPDF-File-Name` for the file name.\n * Shared by the document-level `attachments.download()` and the\n * annotation-level `annotations.downloadFile()` reads — one wire shape\n * for both homes a file can live in.\n */\nexport function parseAttachmentContent(file: HttpFileResponse): AttachmentContent {\n const encodedName = file.headers.get(FILE_NAME_HEADER);\n if (encodedName === null) {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n `attachment response missing ${FILE_NAME_HEADER} header`,\n );\n }\n let name: string;\n try {\n name = decodeTokenText(encodedName);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n `malformed ${FILE_NAME_HEADER} header: ${(err as Error)?.message ?? err}`,\n { cause: err },\n );\n }\n const mimeType = file.headers.get('Content-Type');\n return {\n bytes: file.bytes,\n name,\n ...(mimeType !== null ? { mimeType } : {}),\n };\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n normalizeAttachmentFileSource,\n type AttachmentContent,\n type AttachmentCreateResult,\n type AttachmentDeleteResult,\n type AttachmentFileSource,\n type DocumentAttachmentsService,\n type EmbeddedFileItem,\n type EmbeddedFileRef,\n} from '@embedpdf/engine-core/runtime';\nimport {\n AttachmentCreateResultSchema,\n AttachmentDeleteResultSchema,\n EmbeddedFileItemSchema,\n wirePaths,\n} from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport { buildMutationForm } from './buildMutationForm';\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport { parseAttachmentContent } from './parseAttachmentContent';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/** The `/attachments@…` listing leaf is a bare array of name-tree entries. */\nconst EmbeddedFileListSchema = EmbeddedFileItemSchema.array();\n\n/**\n * Cloud-side document-level attachments (the catalog's `/EmbeddedFiles`\n * name tree). Reads use immutable leaves pinned by the manifest's\n * `attachmentsVersion`: `/attachments@…` for the metadata listing and\n * `/attachment-files/…@…` for one file's decoded bytes — a separate\n * capability tier, so a CDN credential for the listing can never egress\n * content. Mutations use unversioned collection/member URLs and are\n * never cached.\n */\nexport class CloudDocumentAttachmentsService implements DocumentAttachmentsService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n /**\n * Snapshot of the name tree, in tree (key-sorted) order. Pulls\n * `attachmentsVersion` from the cached manifest and, on a 404 (stale\n * pointer), transparently refreshes the manifest and retries once.\n * The pin bumps only on attachment writes, so this leaf stays cached\n * across page and annotation edits.\n */\n list(): AbortablePromise<EmbeddedFileItem[]> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<EmbeddedFileItem[]>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n // Plane-scope rule: the listing depends on the `attachments` plane —\n // while inherited, one CDN object serves every visitor's sidebar\n // from the base worker session.\n return planesInherited(manifest, ['attachments'])\n ? wirePaths.docAttachments(this.docId, manifest.attachmentsVersion)\n : wirePaths.layerAttachments(this.docId, this.layerName, manifest.attachmentsVersion);\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => EmbeddedFileListSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n\n /**\n * Decode and return one embedded file's bytes. The body is the decoded\n * stream; the name and mime type ride as response headers (see\n * `parseAttachmentContent`). Same versioned-leaf + refresh-retry rails\n * as {@link list}.\n */\n download(ref: EmbeddedFileRef): AbortablePromise<AttachmentContent> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AttachmentContent>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n // Same plane switch as list(): the byte leaf shares too.\n return planesInherited(manifest, ['attachments'])\n ? wirePaths.docAttachmentFile(this.docId, ref.key, manifest.attachmentsVersion)\n : wirePaths.layerAttachmentFile(\n this.docId,\n this.layerName,\n ref.key,\n manifest.attachmentsVersion,\n );\n };\n const file = await this.http.getFileWithRefresh(\n buildPath,\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n return parseAttachmentContent(file);\n });\n }\n\n /**\n * Create an embedded file in the name tree. Same splitter the\n * file-attachment annotation draft uses — metadata into the `body`\n * JSON part, bytes into the `resource:r0` file part — POSTed as the\n * standard multipart mutation envelope.\n */\n create(file: AttachmentFileSource): AbortablePromise<AttachmentCreateResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AttachmentCreateResult>(async (signal) => {\n const { wireFile, resource } = await normalizeAttachmentFileSource(file, 'r0');\n const result = await this.http.postMultipartJson(\n wirePaths.layerAttachmentsCollection(this.docId, this.layerName),\n buildMutationForm(wireFile, { r0: resource }),\n (raw) => AttachmentCreateResultSchema.parse(raw),\n signal,\n );\n // Patch the cached manifest, then publish (in that order — listeners\n // reading the manifest in their callback must see post-mutation\n // state). An attachment write only advances docVersion +\n // attachmentsVersion (no per-page pin changes, no layoutVersion), so\n // the cached manifest is patched in place — no refetch.\n if (result.cache) this.manifest.applyAttachments(result.cache);\n this.publisher.publishLocal({ type: 'attachment.created', ...result });\n return result;\n });\n }\n\n /** Delete an embedded file from the name tree by its durable key. */\n delete(ref: EmbeddedFileRef): AbortablePromise<AttachmentDeleteResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AttachmentDeleteResult>(async (signal) => {\n const result = await this.http.deleteJson(\n wirePaths.layerAttachmentItem(this.docId, this.layerName, ref.key),\n (raw) => AttachmentDeleteResultSchema.parse(raw),\n signal,\n );\n // Same absorb-then-publish rails as create().\n if (result.cache) this.manifest.applyAttachments(result.cache);\n this.publisher.publishLocal({ type: 'attachment.deleted', ...result });\n return result;\n });\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n encodeFieldRefKey,\n type DocumentEventInit,\n type DocumentFormsService,\n type FormDataExport,\n type FormDataFormat,\n type FormEffect,\n type FormEffectsResult,\n type FormFieldCreateResult,\n type FormFieldDeleteResult,\n type FormFieldDraft,\n type FormFieldDTO,\n type FormFieldPatch,\n type FormFieldRef,\n type FormFieldUpdateResult,\n type FormFieldValue,\n type FormImportResult,\n type FormRepairOptions,\n type FormRepairResult,\n type FormSetValueResult,\n type FormSnapshot,\n type FormWidgetLinkResult,\n type FormWidgetRef,\n type MutationMeta,\n} from '@embedpdf/engine-core/runtime';\nimport {\n FormFieldCreateResultSchema,\n FormFieldDeleteResultSchema,\n FormFieldDTOSchema,\n FormFieldUpdateResultSchema,\n FormEffectsResultSchema,\n FormImportResultSchema,\n FormRepairResultSchema,\n FormSetValueResultSchema,\n FormSnapshotSchema,\n FormWidgetLinkResultSchema,\n wirePaths,\n} from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/** Content types the import POST body may carry; the server sniffs the\n * actual format from the bytes, so this is advisory only. */\nconst IMPORT_CONTENT_TYPE: Record<FormDataFormat, string> = {\n fdf: 'application/vnd.fdf',\n xfdf: 'application/vnd.adobe.xfdf',\n};\n\n/**\n * Cloud-side document forms service. Mirrors the local wiring: each call\n * produces an `AbortablePromise` that propagates `signal.abort()` down to\n * `fetch` and validates the JSON response with the wire-stable Zod schema.\n *\n * Forms are document-scoped, so reads use the unversioned `/form` URLs\n * (always `no-store` — there is no content-addressed variant). Mutation\n * results carry the per-page `cacheDelta` for pages whose widget\n * appearances changed; `absorbMutation` folds it into the cached manifest\n * so annotation/render reads stay coherent.\n */\nexport class CloudDocumentFormsService implements DocumentFormsService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n list(): AbortablePromise<FormSnapshot> {\n const rejected = this.rejectIfClosed<FormSnapshot>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormSnapshot>((signal) =>\n this.http.getJson(\n wirePaths.layerForm(this.docId, this.layerName),\n (raw) => FormSnapshotSchema.parse(raw),\n signal,\n ),\n );\n }\n\n get(ref: FormFieldRef): AbortablePromise<FormFieldDTO> {\n const rejected = this.rejectIfClosed<FormFieldDTO>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormFieldDTO>((signal) =>\n this.http.getJson(\n wirePaths.layerFormFieldByKey(this.docId, this.layerName, encodeFieldRefKey(ref)),\n (raw) => FormFieldDTOSchema.parse(raw),\n signal,\n ),\n );\n }\n\n setValue(ref: FormFieldRef, value: FormFieldValue): AbortablePromise<FormSetValueResult> {\n const rejected = this.rejectIfClosed<FormSetValueResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormSetValueResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormFieldValue(this.docId, this.layerName, encodeFieldRefKey(ref)),\n { value },\n (raw) => FormSetValueResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.valueChanged');\n });\n }\n\n reset(ref: FormFieldRef): AbortablePromise<FormSetValueResult> {\n const rejected = this.rejectIfClosed<FormSetValueResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormSetValueResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormFieldReset(this.docId, this.layerName, encodeFieldRefKey(ref)),\n {},\n (raw) => FormSetValueResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.valueChanged');\n });\n }\n\n applyEffects(effects: FormEffect[]): AbortablePromise<FormEffectsResult> {\n const rejected = this.rejectIfClosed<FormEffectsResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormEffectsResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormEffects(this.docId, this.layerName),\n { effects },\n (raw) => FormEffectsResultSchema.parse(raw),\n signal,\n );\n // An all-no-op/all-preflight-rejected batch deliberately has no\n // artifact, cache advance, or event.\n if (result.meta === null) return result;\n this.manifest.apply(result.meta, ['annotations']);\n this.publisher.publishLocal({ type: 'form.effectsApplied', ...result });\n return result;\n });\n }\n\n exportData(format: FormDataFormat = 'xfdf'): AbortablePromise<FormDataExport> {\n const rejected = this.rejectIfClosed<FormDataExport>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormDataExport>(async (signal) => {\n const bytes = await this.http.getBytes(\n wirePaths.layerFormData(this.docId, this.layerName, format),\n signal,\n );\n return { format, bytes };\n });\n }\n\n importData(\n data: Uint8Array | ArrayBuffer,\n format?: FormDataFormat,\n ): AbortablePromise<FormImportResult> {\n const rejected = this.rejectIfClosed<FormImportResult>();\n if (rejected) return rejected;\n const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : data;\n return AbortablePromise.run<FormImportResult>(async (signal) => {\n const result = await this.http.postBytesJson(\n wirePaths.layerFormData(this.docId, this.layerName, format),\n bytes,\n format ? IMPORT_CONTENT_TYPE[format] : 'application/octet-stream',\n (raw) => FormImportResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.imported');\n });\n }\n\n createField(draft: FormFieldDraft): AbortablePromise<FormFieldCreateResult> {\n const rejected = this.rejectIfClosed<FormFieldCreateResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormFieldCreateResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormFields(this.docId, this.layerName),\n draft,\n (raw) => FormFieldCreateResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.fieldCreated');\n });\n }\n\n updateField(ref: FormFieldRef, patch: FormFieldPatch): AbortablePromise<FormFieldUpdateResult> {\n const rejected = this.rejectIfClosed<FormFieldUpdateResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormFieldUpdateResult>(async (signal) => {\n const result = await this.http.patchJson(\n wirePaths.layerFormFieldByKey(this.docId, this.layerName, encodeFieldRefKey(ref)),\n patch,\n (raw) => FormFieldUpdateResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.fieldUpdated');\n });\n }\n\n deleteField(ref: FormFieldRef): AbortablePromise<FormFieldDeleteResult> {\n const rejected = this.rejectIfClosed<FormFieldDeleteResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormFieldDeleteResult>(async (signal) => {\n const result = await this.http.deleteJson(\n wirePaths.layerFormFieldByKey(this.docId, this.layerName, encodeFieldRefKey(ref)),\n (raw) => FormFieldDeleteResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.fieldDeleted');\n });\n }\n\n attachWidget(\n ref: FormFieldRef,\n widget: FormWidgetRef,\n options?: { onState?: string },\n ): AbortablePromise<FormWidgetLinkResult> {\n const rejected = this.rejectIfClosed<FormWidgetLinkResult>();\n if (rejected) return rejected;\n const onState = options?.onState;\n return AbortablePromise.run<FormWidgetLinkResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormFieldWidgets(this.docId, this.layerName, encodeFieldRefKey(ref)),\n { widget, ...(onState ? { onState } : {}) },\n (raw) => FormWidgetLinkResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.widgetAttached');\n });\n }\n\n detachWidget(ref: FormFieldRef, widget: FormWidgetRef): AbortablePromise<FormWidgetLinkResult> {\n const rejected = this.rejectIfClosed<FormWidgetLinkResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormWidgetLinkResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormFieldWidgetsDetach(this.docId, this.layerName, encodeFieldRefKey(ref)),\n { widget },\n (raw) => FormWidgetLinkResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.widgetDetached');\n });\n }\n\n repair(options?: FormRepairOptions): AbortablePromise<FormRepairResult> {\n const rejected = this.rejectIfClosed<FormRepairResult>();\n if (rejected) return rejected;\n return AbortablePromise.run<FormRepairResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerFormRepair(this.docId, this.layerName),\n { bakeAppearances: options?.bakeAppearances ?? false },\n (raw) => FormRepairResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'form.repaired');\n });\n }\n\n private rejectIfClosed<T>(): AbortablePromise<T> | null {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return null;\n }\n\n /**\n * Patch the cached manifest, then publish the mutation to the document's\n * event stream (in that order — listeners reading the manifest in their\n * callback must see post-mutation state). Same rails as annotations.\n */\n private absorbMutation<T extends { meta: MutationMeta }>(\n result: T,\n type:\n | 'form.valueChanged'\n | 'form.imported'\n | 'form.repaired'\n | 'form.fieldCreated'\n | 'form.fieldUpdated'\n | 'form.fieldDeleted'\n | 'form.widgetAttached'\n | 'form.widgetDetached',\n ): T {\n this.manifest.apply(result.meta, ['annotations']);\n this.publisher.publishLocal({ type, ...result } as unknown as DocumentEventInit);\n return result;\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type DocumentPagesService,\n type PageFlattenResult,\n type PageFlattenUsage,\n type PageDeleteResult,\n type PageListSnapshot,\n type PageMoveResult,\n type PageObjectNumber,\n type PageRotateResult,\n type PageRotation,\n} from '@embedpdf/engine-core/runtime';\nimport {\n PageDeleteResultSchema,\n PageFlattenResultSchema,\n PageListSnapshotSchema,\n PageMoveResultSchema,\n PageRotateResultSchema,\n wirePaths,\n} from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Cloud-side document pages service. Mirrors `LocalDocumentPagesService`\n * over HTTP: GET /pages for `list`, POST /pages/move for the reorder.\n *\n * Page identity rule (locked with the user, do not change):\n * - Pages are addressed exclusively by their indirect\n * `pageObjectNumber`. The wire never sends a page index for a\n * mutation. This keeps multi-call client logic from having to\n * account for index drift between requests.\n * - Successful `move()` returns the new `layout` (order + geometry) plus\n * cloud coherence pins. The server does NOT bump per-page revisions on a\n * page move (page reorder is intentionally outside the weak-ref staleness\n * model), only `docVersion` + `layoutVersion`.\n */\nexport class CloudDocumentPagesService implements DocumentPagesService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n /**\n * Page-geometry list. The geometry bytes live at the content-addressed\n * `/layout@layoutVersion=N` leaf (not in the manifest); the manifest only\n * publishes the `layoutVersion` pointer. So `list()` reads `layoutVersion`\n * from the cached manifest, fetches the layout leaf, and on a 404 (stale\n * pointer) transparently refreshes the manifest and retries once — the\n * same ladder the per-page text/geometry reads use. `layoutVersion` bumps\n * only on structural page ops, so this leaf stays cached across content\n * and annotation edits.\n */\n list(): AbortablePromise<PageListSnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageListSnapshot>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n // Plane-scope rule: the layout leaf depends on the `layout` plane —\n // while inherited (no move/rotate/insert/delete ever ran), every\n // visitor's page list is ONE doc-level URL served from the base\n // session; the SDK open sequence creates no layer session.\n return planesInherited(manifest, ['layout'])\n ? wirePaths.docLayout(this.docId, manifest.layoutVersion)\n : wirePaths.layerLayout(this.docId, this.layerName, manifest.layoutVersion);\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => PageListSnapshotSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n\n move(pageObjectNumbers: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageMoveResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerPagesMove(this.docId, this.layerName),\n { pageObjectNumbers, destIndex },\n (raw) => PageMoveResultSchema.parse(raw),\n signal,\n );\n // A move only advances docVersion + layoutVersion (no per-page pin\n // changes), so the cached manifest can be patched in place — no refetch.\n if (result.cache) this.manifest.applyPageStructure(result.cache);\n // Publish AFTER absorb: listeners reading the manifest in their\n // callback must see post-mutation state.\n this.publisher.publishLocal({ type: 'pages.moved', pageObjectNumbers, destIndex, ...result });\n return result;\n });\n }\n\n rotate(\n pageObjectNumbers: PageObjectNumber[],\n rotation: PageRotation,\n ): AbortablePromise<PageRotateResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageRotateResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerPagesRotate(this.docId, this.layerName),\n { pageObjectNumbers, rotation },\n (raw) => PageRotateResultSchema.parse(raw),\n signal,\n );\n // Rotation shares the move patch exactly: docVersion + layoutVersion\n // advance, every per-page pin (and its cached render) stays warm.\n if (result.cache) this.manifest.applyPageStructure(result.cache);\n this.publisher.publishLocal({\n type: 'pages.rotated',\n pageObjectNumbers,\n rotation,\n ...result,\n });\n return result;\n });\n }\n\n delete(pageObjectNumbers: PageObjectNumber[]): AbortablePromise<PageDeleteResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageDeleteResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerPagesDelete(this.docId, this.layerName),\n { pageObjectNumbers },\n (raw) => PageDeleteResultSchema.parse(raw),\n signal,\n );\n // The structural advance plus dropping the deleted pages' manifest\n // rows — a retired PON must not be buildable from the local cache.\n if (result.cache) this.manifest.applyPageDelete(result.cache, pageObjectNumbers);\n this.publisher.publishLocal({ type: 'pages.deleted', pageObjectNumbers, ...result });\n return result;\n });\n }\n\n flatten(\n pageObjectNumbers: PageObjectNumber[],\n usage: PageFlattenUsage = 'display',\n ): AbortablePromise<PageFlattenResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageFlattenResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerPagesFlatten(this.docId, this.layerName),\n { pageObjectNumbers, usage },\n (raw) => PageFlattenResultSchema.parse(raw),\n signal,\n );\n // Nothing flattened means no artifact and therefore no coherence bump.\n if (result.meta === null) return result;\n // Flatten bakes annotations into page content, so both planes flip.\n this.manifest.apply(result.meta, ['content', 'annotations']);\n this.publisher.publishLocal({\n type: 'pages.flattened',\n ...result,\n });\n return result;\n });\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type DocumentRedactionService,\n type RedactionApplyResult,\n type RedactionApplyScope,\n} from '@embedpdf/engine-core/runtime';\nimport { RedactionApplyResultSchema, wirePaths } from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Cloud-side redaction apply. Mirrors `LocalDocumentRedactionService` over\n * HTTP (POST /redactions/apply); the server enforces the capability gate\n * (`doc.pages.modify` + `doc.annotate.modify` + `doc.redact`) and persists\n * the rewritten layer artifact. See `DocumentRedactionService` for the\n * two-stage model and the layer trust boundary — an apply rewrites THIS\n * LAYER's bytes; the immutable base keeps the original.\n */\nexport class CloudDocumentRedactionService implements DocumentRedactionService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n apply(scope: RedactionApplyScope): AbortablePromise<RedactionApplyResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<RedactionApplyResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerRedactionsApply(this.docId, this.layerName),\n { scope },\n (raw) => RedactionApplyResultSchema.parse(raw),\n signal,\n );\n // Nothing applied means no artifact and therefore no coherence bump.\n if (result.meta === null) return result;\n // Redaction-apply rewrites content and consumes the marks, so both\n // planes flip.\n this.manifest.apply(result.meta, ['content', 'annotations']);\n this.publisher.publishLocal({\n type: 'redaction.applied',\n ...result,\n });\n return result;\n });\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n canonicalSearchQuery,\n searchContentEpoch,\n type DocumentSearchService,\n type SearchQuery,\n type SearchRequest,\n type SearchSlice,\n} from '@embedpdf/engine-core/runtime';\nimport {\n SearchSliceSchema,\n decodeSearchToken,\n encodeSearchToken,\n wirePaths,\n type SearchToken,\n} from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Cloud search transport: versioned GETs, one per budgeted slice.\n *\n * Every slice URL is a canonical cache key — the search token pins the\n * layer's content epoch (computed from the cached manifest), the\n * CANONICAL query (default-fold literals collapse case/diacritic\n * variants into one entry), and the resume position. Identical searches\n * from any reader of the document hit the same CDN entry; matches are\n * all that ever crosses the trust boundary, and the rects/full endpoint\n * split keeps permission tiers in disjoint cache namespaces.\n *\n * Staleness rides the standard versioned-read signal: a first slice\n * answered `NotFound` means OUR manifest is stale → refresh and retry\n * once; a continuation answered `NotFound` means the document changed\n * mid-search → `InvalidArg`, same contract as the local engine's cursor.\n */\nexport class CloudDocumentSearchService implements DocumentSearchService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n query(request: SearchRequest): AbortablePromise<SearchSlice> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document not open: ${this.docId}`),\n );\n }\n return AbortablePromise.run<SearchSlice>(async (signal) => {\n const mode = request.mode ?? 'full';\n const path = mode === 'rects' ? wirePaths.layerSearchRects : wirePaths.layerSearchFull;\n const get = (token: string) =>\n this.http.getJson(\n path(this.docId, this.layerName, token),\n (raw) => SearchSliceSchema.parse(raw),\n signal,\n );\n const query = canonicalSearchQuery(request.query);\n\n if (request.cursor !== undefined) {\n let token: SearchToken;\n try {\n token = decodeSearchToken(request.cursor);\n } catch {\n throw new EngineError(EngineErrorCode.InvalidArg, 'malformed search cursor');\n }\n // Local-engine cursor parity: a cursor is pinned to its query and\n // scan origin; replaying it against anything else is a caller bug.\n if (queryIdentity(token.query) !== queryIdentity(query)) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n 'search cursor belongs to a different query — restart the search',\n );\n }\n if (request.startPage !== undefined && request.startPage !== token.startPage) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n 'startPage conflicts with the cursor — omit startPage when resuming',\n );\n }\n try {\n return await get(request.cursor);\n } catch (err) {\n if (EngineError.is(err, EngineErrorCode.NotFound)) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n 'document changed since this search cursor was issued — restart the search',\n );\n }\n throw err;\n }\n }\n\n const mint = (epoch: string) =>\n encodeSearchToken({\n epoch,\n query,\n ...(request.startPage !== undefined ? { startPage: request.startPage } : {}),\n skip: 0,\n ...(request.budget !== undefined ? { budget: request.budget } : {}),\n });\n try {\n const manifest = await this.manifest.get(signal);\n return await get(mint(searchContentEpoch(manifest)));\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n // Our cached manifest is behind the layer — the standard\n // versioned-read retry: refresh once, re-mint, re-issue.\n const fresh = await this.manifest.refresh(signal);\n return await get(mint(searchContentEpoch(fresh)));\n }\n });\n }\n}\n\n/** Query identity for cursor validation (option order pinned by hand). */\nfunction queryIdentity(query: SearchQuery): string {\n return JSON.stringify([\n query.regex ? 'r' : 'l',\n query.text,\n query.matchCase ? 1 : 0,\n query.matchDiacritics ? 1 : 0,\n query.wholeWord ? 1 : 0,\n ]);\n}\n","import { EngineError, EngineErrorCode } from '@embedpdf/engine-core/runtime';\n\n/**\n * Lightweight, **unverified** JWT payload decoder.\n *\n * We use this on the SDK side purely to extract routing information\n * (the `doc_id` claim) so we know which `/v1/docs/:id/head` URL to\n * hit. Signature verification is the server's job — Layer 2 of the\n * token-class-confusion defense in `JwtVerifier.coerceClaims`\n * rejects anything malformed before the bytes are accepted.\n *\n * This module is intentionally cryptography-free: it never imports\n * `crypto` or `jose`. That keeps the SDK lean for browser bundles\n * (jose adds ~50KB minified) and means a misconfigured customer\n * can't accidentally rely on client-side verification.\n */\n\nexport interface UnverifiedClaims {\n doc_id?: string;\n tenant_id?: string;\n sub?: string;\n exp?: number;\n iat?: number;\n /** Pass-through; we don't validate anything else SDK-side. */\n [key: string]: unknown;\n}\n\nexport function decodeUnverifiedClaims(token: string): UnverifiedClaims {\n const parts = token.split('.');\n if (parts.length !== 3) {\n throw new EngineError(EngineErrorCode.InvalidArg, 'malformed jwt: expected 3 segments');\n }\n const payloadB64Url = parts[1]!;\n let bytes: Uint8Array;\n try {\n bytes = base64UrlDecode(payloadB64Url);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n `malformed jwt payload: ${(err as Error).message ?? err}`,\n );\n }\n let json: string;\n try {\n json = new TextDecoder().decode(bytes);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n `jwt payload is not valid utf-8: ${(err as Error).message ?? err}`,\n );\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n `jwt payload is not valid json: ${(err as Error).message ?? err}`,\n );\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new EngineError(EngineErrorCode.InvalidArg, 'jwt payload must be a json object');\n }\n return parsed as UnverifiedClaims;\n}\n\n/**\n * Decode a base64url string into a `Uint8Array`. Works in both Node\n * and modern browsers; we avoid `Buffer` so the SDK stays\n * browser-friendly. `atob` lives on the global in Node 16+ as well.\n */\nfunction base64UrlDecode(b64url: string): Uint8Array {\n const b64 = b64url.replace(/-/g, '+').replace(/_/g, '/');\n const pad = b64.length % 4;\n const padded = pad === 0 ? b64 : b64 + '='.repeat(4 - pad);\n const bin = atob(padded);\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","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n checkCapability,\n decodePdfBits,\n expandRawScope,\n passwordPromptFromState,\n securityStateFromHead,\n type DocCapability,\n type DocumentAccessInfo,\n type DocumentIdentity,\n type DocumentSecurityService,\n type DocumentSecurityState,\n type DocumentUnlockInput,\n type DocumentUnlockResult,\n type PasswordPrompt,\n} from '@embedpdf/engine-core/runtime';\nimport { AccessResponseSchema, wirePaths, type DocumentHead } from '@embedpdf/engine-core/wire';\n\nimport { decodeUnverifiedClaims } from '../transport/decodeUnverifiedClaims';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudDocumentSecurityService implements DocumentSecurityService {\n private state: DocumentSecurityState;\n private access: DocumentAccessInfo | null = null;\n\n /**\n * Parsed JWT identity + scope, decoded once at construction. Used by\n * the local-fallback path for `effectiveScope` and `identity` when\n * /access hasn't run yet (public-share with no CDN, password not\n * yet supplied, etc.).\n */\n private readonly tokenScope: ReadonlyArray<string>;\n private readonly tokenIdentity: DocumentIdentity | null;\n\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n initialHead: DocumentHead,\n private readonly view: { isClosed(): boolean },\n initialToken: string | null = null,\n ) {\n this.state = securityStateFromHead(initialHead);\n const claims = initialToken ? safeDecodeClaims(initialToken) : null;\n this.tokenScope = Array.isArray(claims?.scope) ? (claims!.scope as ReadonlyArray<string>) : [];\n this.tokenIdentity = claims ? identityFromClaims(claims) : null;\n }\n\n get current(): DocumentSecurityState {\n return this.state;\n }\n\n get currentAccess(): DocumentAccessInfo | null {\n return this.access;\n }\n\n /**\n * Expanded capability set. Cloud-canonical post-/access; otherwise\n * computed locally from the JWT scope + /head's pdf bits using the\n * SAME `expandRawScope` helper engine-local calls — so the value\n * matches across engines bit-for-bit on the same inputs.\n */\n get effectiveScope(): ReadonlyArray<string> {\n if (this.access) return this.access.effectiveScope;\n const bits = decodePdfBits(this.state.permissions.bits);\n return Array.from(expandRawScope(this.tokenScope, bits)).sort();\n }\n\n /**\n * Wildcard-aware authorization check — mirrors what the server route layer\n * enforces with. `effectiveScope` alone can't gate UI: it enumerates concrete\n * grants and drops the `*` admin wildcard. So we honor a server-canonical\n * concrete grant when present, then fall back to the same `checkCapability`\n * predicate (which short-circuits `*`) against the JWT scope + /head bits.\n */\n allows(cap: DocCapability): boolean {\n if (this.access?.effectiveScope.includes(cap)) return true;\n const bits = decodePdfBits(this.state.permissions.bits);\n return checkCapability(cap, this.tokenScope, bits);\n }\n\n /**\n * Identity of the current caller, or null when anonymous.\n *\n * Cloud-canonical post-/access; otherwise the identity claims from\n * the JWT itself. Both are the same shape — the post-/access\n * version is just refreshed to reflect any server-side identity\n * augmentation (rare; reserved for future tenant hooks).\n */\n get identity(): DocumentIdentity | null {\n return this.access?.identity ?? this.tokenIdentity;\n }\n\n /**\n * High-level \"should I prompt for a password?\" — single source of\n * truth, computed via `passwordPromptFromState` so the answer is\n * identical to what the local engine would say for the same\n * security state. See `passwordPromptFromState` for the rules.\n */\n get passwordPrompt(): PasswordPrompt {\n return passwordPromptFromState(this.state);\n }\n\n unlock(input: DocumentUnlockInput): AbortablePromise<DocumentUnlockResult> {\n if (this.view.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<DocumentUnlockResult>(async (signal) => {\n return await this.postAccess(signal, {\n password: input.password,\n mode: input.mode ?? 'any',\n });\n });\n }\n\n /**\n * Cloud-internal: call /v1/access with no password to establish\n * a CDN-credentialed session. Used by `CloudEngine.open` when\n * /head's `access.reasons` includes 'cdn' but NOT 'password' —\n * the server accepts an authenticated /access POST without a\n * password and returns the signed-URL block.\n *\n * Not on the public `DocumentSecurityService` interface — the\n * \"unlock\" verb implies user action, and this path is automatic.\n * Local engine has no equivalent (there's no CDN concept).\n */\n establishAccess(): AbortablePromise<DocumentUnlockResult> {\n if (this.view.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<DocumentUnlockResult>(async (signal) => {\n return await this.postAccess(signal, { mode: 'any' });\n });\n }\n\n /**\n * Single POST /v1/access implementation shared by `unlock()` (with\n * password) and `establishAccess()` (no password). Updates cached\n * security state, caches the access block, and pushes the CDN\n * binding into the HttpClient so subsequent fetches apply CDN\n * tokens via `applyCdnAccess`.\n *\n * `none` CDN adapter → the access block has null overrides/policies\n * and `applyCdnAccess` short-circuits to origin; safe to call always.\n */\n private async postAccess(\n signal: AbortSignal,\n body: { password?: string; mode: 'any' | 'owner' },\n ): Promise<DocumentUnlockResult> {\n const response = await this.http.postJson(\n wirePaths.access,\n {\n docId: this.docId,\n layerName: this.layerName,\n ...(body.password ? { password: body.password } : {}),\n mode: body.mode,\n },\n (raw) => AccessResponseSchema.parse(raw),\n signal,\n );\n this.state = response.security;\n this.access = {\n cdn: response.cdn,\n passwordGrant: response.passwordGrant,\n pdfPermissions: response.pdfPermissions,\n scope: response.scope,\n effectiveScope: response.effectiveScope,\n identity: response.identity,\n originPasswordPolicy: response.originPasswordPolicy,\n expiresAt: response.expiresAt,\n // Deployment render lattice. Absent on older servers without render policy support.\n ...(response.renderPolicy ? { renderPolicy: response.renderPolicy } : {}),\n };\n this.http.setCdnAccess({\n cdn: response.cdn,\n docId: this.docId,\n layerName: this.layerName,\n });\n // DocumentUnlockResult.access is `DocumentAccessInfo | undefined`,\n // not `| null`. We carry the local cache as `| null` (clearer\n // \"not yet unlocked\" semantic); coerce at the boundary.\n return { security: this.state, access: this.access ?? undefined };\n }\n}\n\n/**\n * Decode the JWT's payload without verifying. The SDK never verifies\n * tokens client-side — the server is the verifier of record — but it\n * needs the `scope` and identity claims for the local-fallback path\n * of `effectiveScope` / `identity`. Returns null if the token is\n * malformed; the security service treats that as \"no claims known\".\n */\nfunction safeDecodeClaims(token: string): Record<string, unknown> | null {\n try {\n return decodeUnverifiedClaims(token);\n } catch {\n return null;\n }\n}\n\nfunction identityFromClaims(claims: Record<string, unknown>): DocumentIdentity | null {\n const out: DocumentIdentity = {};\n if (typeof claims['user_id'] === 'string') out.user_id = claims['user_id'];\n if (typeof claims['group_id'] === 'string') out.group_id = claims['group_id'];\n if (typeof claims['display_name'] === 'string') out.display_name = claims['display_name'];\n if (Array.isArray(claims['groups'])) {\n const groups = (claims['groups'] as unknown[]).filter(\n (g): g is string => typeof g === 'string',\n );\n if (groups.length > 0) out.groups = groups;\n }\n return Object.keys(out).length > 0 ? out : null;\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type DocumentMetadata,\n type MetadataPatch,\n type MetadataService,\n type MetadataUpdateResult,\n} from '@embedpdf/engine-core/runtime';\nimport {\n DocumentMetadataSchema,\n MetadataUpdateResultSchema,\n wirePaths,\n} from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudMetadataService implements MetadataService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n /**\n * Document metadata read. The Info-dict JSON lives at the\n * content-addressed `/metadata@metadataVersion=N` leaf (not in the\n * manifest); the manifest only publishes the `metadataVersion` pointer.\n * So `read()` pulls `metadataVersion` from the cached manifest, fetches\n * the leaf, and on a 404 (stale pointer) transparently refreshes the\n * manifest and retries once. `metadataVersion` bumps only on metadata\n * writes, so this leaf stays cached across page and annotation edits.\n */\n read(): AbortablePromise<DocumentMetadata> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<DocumentMetadata>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n // Plane-scope rule: the metadata leaf depends on the `metadata`\n // plane — while inherited, one doc-level URL serves every visitor.\n return planesInherited(manifest, ['metadata'])\n ? wirePaths.docMetadata(this.docId, manifest.metadataVersion)\n : wirePaths.layerMetadata(this.docId, this.layerName, manifest.metadataVersion);\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => DocumentMetadataSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n\n update(patch: MetadataPatch): AbortablePromise<MetadataUpdateResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<MetadataUpdateResult>(async (signal) => {\n const result = await this.http.postJson(\n wirePaths.layerMetadataUpdate(this.docId, this.layerName),\n patch,\n (raw) => MetadataUpdateResultSchema.parse(raw),\n signal,\n );\n // A metadata write only advances docVersion + metadataVersion (no\n // per-page pin changes, no layoutVersion), so the cached manifest can\n // be patched in place — no refetch.\n if (result.cache) this.manifest.applyMetadata(result.cache);\n this.publisher.publishLocal({ type: 'metadata.updated', ...result });\n return result;\n });\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n createPageImageHandle,\n encodeStableIdKey,\n normalizeAnnotationDraft,\n normalizeAnnotationPatch,\n type WireResourceMap,\n type AnnotationAppearanceImage,\n type AnnotationAppearanceImageOptions,\n type AnnotationAppearanceImagesResult,\n type AnnotationAppearanceRenderOptions,\n type AnnotationAppearancesResult,\n type AnnotationDraft,\n type AnnotationListPageSnapshot,\n type AnnotationPatch,\n type AnnotationRef,\n type AnnotationCreateResult,\n type AnnotationDeleteResult,\n type AnnotationMoveResult,\n type AnnotationUpdateResult,\n type AttachmentContent,\n type DocumentEventInit,\n type MutationMeta,\n type PageAnnotationsService,\n type PageImageResult,\n type PageNetworkRenderFormat,\n type PageObjectNumber,\n} from '@embedpdf/engine-core/runtime';\nimport {\n AnnotationCreateResultSchema,\n AnnotationDeleteResultSchema,\n AnnotationListPageSnapshotSchema,\n AnnotationAppearanceManifestSchema,\n AnnotationMoveResultSchema,\n AnnotationUpdateResultSchema,\n annotationAppearancesImageOptionsToWire,\n wirePaths,\n} from '@embedpdf/engine-core/wire';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport { buildMutationForm, hasResources } from './buildMutationForm';\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport { parseAttachmentContent } from './parseAttachmentContent';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Cloud-side page annotation service. Mirrors the local wiring: each\n * call produces an `AbortablePromise` that propagates `signal.abort()`\n * down to `fetch` and validates the JSON response with the wire-stable\n * Zod schema.\n *\n * Reads use immutable versioned layer URLs discovered from the\n * manifest. Mutations use unversioned layer URLs and are never cached.\n */\nexport class CloudPageAnnotationsService implements PageAnnotationsService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly pageObjectNumber: PageObjectNumber,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n private readonly publisher: SessionEventPublisher,\n ) {}\n\n list(): AbortablePromise<AnnotationListPageSnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AnnotationListPageSnapshot>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n const page = manifest.pages.find((p) => p.state.pageObjectNumber === this.pageObjectNumber);\n if (!page) {\n throw new EngineError(\n EngineErrorCode.NotFound,\n `no page with object number ${this.pageObjectNumber} in document ${this.docId}`,\n );\n }\n // Plane-scope rule: the list depends on the `annotations` plane. A\n // base's own annotations (weak-identity ones included) are simply\n // VISIBLE through an inheriting layer, so every visitor reads ONE\n // doc-level URL served from the base session.\n return planesInherited(manifest, ['annotations'])\n ? wirePaths.docPageAnnotations(\n this.docId,\n this.pageObjectNumber,\n page.cache.annotationVersion,\n )\n : wirePaths.layerPageAnnotations(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n page.cache.annotationVersion,\n );\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => AnnotationListPageSnapshotSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n\n renderAppearances(\n _options?: AnnotationAppearanceRenderOptions,\n ): AbortablePromise<AnnotationAppearancesResult> {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.NotImplemented,\n 'annotations.renderAppearances() raw rasters are not available in the cloud engine; use renderAppearanceImages()',\n ),\n );\n }\n\n renderAppearanceImages(\n options: AnnotationAppearanceImageOptions = {},\n ): AbortablePromise<AnnotationAppearanceImagesResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AnnotationAppearanceImagesResult>(async (signal) => {\n // The cloud appearance endpoint is always content-addressed, so the URL\n // must carry an explicit network format (PNG/WebP). Default to WebP when\n // the caller omits it, matching render.image().\n const format: PageNetworkRenderFormat = options.format ?? 'webp';\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n const page = manifest.pages.find((p) => p.state.pageObjectNumber === this.pageObjectNumber);\n if (!page) {\n throw new EngineError(\n EngineErrorCode.NotFound,\n `no page with object number ${this.pageObjectNumber} in document ${this.docId}`,\n );\n }\n const wireToken = annotationAppearancesImageOptionsToWire(\n { ...options, format },\n { annotationVersion: page.cache.annotationVersion },\n );\n // Same `annotations` plane switch as list(): the appearance\n // batch shares too.\n return planesInherited(manifest, ['annotations'])\n ? wirePaths.docPageAnnotationAppearances(this.docId, this.pageObjectNumber, wireToken)\n : wirePaths.layerPageAnnotationAppearances(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n wireToken,\n );\n };\n const form = await this.http.getFormDataWithRefresh(\n buildPath,\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n return parseAppearanceForm(form);\n });\n }\n\n /**\n * Decode and return the file embedded in a FileAttachment annotation.\n * A read over the immutable `attachment-files` leaf, pinned by the\n * manifest's `attachmentsVersion` (annotation-level files re-key on the\n * same pin as document-level ones), with the same stale-404 refresh\n * retry as {@link list}. Weak `index` refs cannot be spliced into a GET\n * URL (no body to carry the revision), so bytes reads require a stable\n * id — the same `:annotKey` routing update()/delete() use.\n */\n downloadFile(ref: AnnotationRef): AbortablePromise<AttachmentContent> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n if (ref.pageObjectNumber !== this.pageObjectNumber) {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n `ref.pageObjectNumber ${ref.pageObjectNumber} != page ${this.pageObjectNumber}`,\n ),\n );\n }\n if (ref.kind === 'index') {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n 'downloadFile requires a stable ref (objectNumber or nm); index refs cannot address the content-addressed file leaf',\n ),\n );\n }\n const annotKey = encodeStableIdKey(refToStableId(ref));\n return AbortablePromise.run<AttachmentContent>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n // A FileAttachment annotation's bytes depend on BOTH planes —\n // the annotation must exist in this view (`annotations`) and the\n // byte pin is `attachmentsVersion` (`attachments`).\n return planesInherited(manifest, ['annotations', 'attachments'])\n ? wirePaths.docAnnotationFile(\n this.docId,\n this.pageObjectNumber,\n annotKey,\n manifest.attachmentsVersion,\n )\n : wirePaths.layerAnnotationFile(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n annotKey,\n manifest.attachmentsVersion,\n );\n };\n const file = await this.http.getFileWithRefresh(\n buildPath,\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n return parseAttachmentContent(file);\n });\n }\n\n create(draft: AnnotationDraft): AbortablePromise<AnnotationCreateResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<AnnotationCreateResult>(async (signal) => {\n // Split inline BinarySource fields (stamp images, …) into the wire\n // draft + binary resources. Without resources the request is the\n // plain JSON POST it has always been; with resources it becomes\n // multipart: a `body` JSON part + one `resource:{key}` part each —\n // the mirror image of the appearance-render response.\n const { wire, resources } = await normalizeAnnotationDraft(draft);\n const path = wirePaths.layerPageAnnotationsCreate(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n );\n const parse = (raw: unknown) => AnnotationCreateResultSchema.parse(raw);\n const result = hasResources(resources)\n ? await this.http.postMultipartJson(path, buildMutationForm(wire, resources), parse, signal)\n : await this.http.postJson(path, wire, parse, signal);\n return this.absorbMutation(result, 'annotation.created');\n });\n }\n\n update(ref: AnnotationRef, patch: AnnotationPatch): AbortablePromise<AnnotationUpdateResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n if (ref.pageObjectNumber !== this.pageObjectNumber) {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n `ref.pageObjectNumber ${ref.pageObjectNumber} != page ${this.pageObjectNumber}`,\n ),\n );\n }\n if (ref.kind === 'index') {\n // Index refs cannot be addressed by stable id. Send the full ref\n // in the body so the server can validate the revision and resolve\n // it the same way the local mutator does.\n const path = wirePaths.layerAnnotationByKey(\n this.docId,\n this.layerName,\n ref.pageObjectNumber,\n 'index',\n );\n return AbortablePromise.run<AnnotationUpdateResult>(async (signal) => {\n const { wire, resources } = await normalizeAnnotationPatch(patch);\n const result = await this.patchMutation(path, { ref, patch: wire }, resources, signal);\n return this.absorbMutation(result, 'annotation.updated');\n });\n }\n const stableKey = encodeStableIdKey(refToStableId(ref));\n const path = wirePaths.layerAnnotationByKey(\n this.docId,\n this.layerName,\n ref.pageObjectNumber,\n stableKey,\n );\n return AbortablePromise.run<AnnotationUpdateResult>(async (signal) => {\n const { wire, resources } = await normalizeAnnotationPatch(patch);\n const result = await this.patchMutation(path, { patch: wire }, resources, signal);\n return this.absorbMutation(result, 'annotation.updated');\n });\n }\n\n /** PATCH as plain JSON, or as multipart when the patch carried binaries. */\n private patchMutation(\n path: string,\n body: unknown,\n resources: WireResourceMap,\n signal: AbortSignal,\n ): Promise<AnnotationUpdateResult> {\n const parse = (raw: unknown) => AnnotationUpdateResultSchema.parse(raw);\n if (hasResources(resources)) {\n return this.http.patchMultipartJson(path, buildMutationForm(body, resources), parse, signal);\n }\n return this.http.patchJson(path, body, parse, signal);\n }\n\n delete(ref: AnnotationRef): AbortablePromise<AnnotationDeleteResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n if (ref.pageObjectNumber !== this.pageObjectNumber) {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n `ref.pageObjectNumber ${ref.pageObjectNumber} != page ${this.pageObjectNumber}`,\n ),\n );\n }\n if (ref.kind === 'index') {\n // DELETE has no body in plain HTTP, so we PATCH the same\n // 'index' key with `{ ref, op: 'delete' }`. This keeps the\n // semantics atomic on the server (single round-trip).\n const path = wirePaths.layerAnnotationByKey(\n this.docId,\n this.layerName,\n ref.pageObjectNumber,\n 'index',\n );\n return AbortablePromise.run<AnnotationDeleteResult>(async (signal) => {\n const result = await this.http.patchJson(\n path,\n { ref, op: 'delete' },\n (raw) => AnnotationDeleteResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'annotation.deleted');\n });\n }\n const stableKey = encodeStableIdKey(refToStableId(ref));\n const path = wirePaths.layerAnnotationByKey(\n this.docId,\n this.layerName,\n ref.pageObjectNumber,\n stableKey,\n );\n return AbortablePromise.run<AnnotationDeleteResult>(async (signal) => {\n const result = await this.http.deleteJson(\n path,\n (raw) => AnnotationDeleteResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'annotation.deleted');\n });\n }\n\n move(refs: AnnotationRef[], toIndex: number): AbortablePromise<AnnotationMoveResult> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n // The page is part of the URL; the worker validates per-ref consistency\n // again, but rejecting up front gives a cleaner error from the client side.\n for (const r of refs) {\n if (r.pageObjectNumber !== this.pageObjectNumber) {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n `move ref points at page ${r.pageObjectNumber}; service is bound to page ${this.pageObjectNumber}`,\n ),\n );\n }\n }\n const path = wirePaths.layerPageAnnotationsMove(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n );\n return AbortablePromise.run<AnnotationMoveResult>(async (signal) => {\n const result = await this.http.postJson(\n path,\n { refs, toIndex },\n (raw) => AnnotationMoveResultSchema.parse(raw),\n signal,\n );\n return this.absorbMutation(result, 'annotation.moved');\n });\n }\n\n /**\n * Patch the cached manifest, then publish the mutation to the document's\n * event stream (in that order — listeners reading the manifest in their\n * callback must see post-mutation state). Each call site pairs the event\n * `type` with the matching result by construction; the cast localizes that\n * pairing here instead of widening every site.\n */\n private absorbMutation<T extends { meta: MutationMeta }>(\n result: T,\n type: 'annotation.created' | 'annotation.updated' | 'annotation.deleted' | 'annotation.moved',\n ): T {\n this.manifest.apply(result.meta, ['annotations']);\n this.publisher.publishLocal({\n type,\n pageObjectNumber: this.pageObjectNumber,\n ...result,\n } as unknown as DocumentEventInit);\n return result;\n }\n}\n\n/**\n * Parse the appearance `multipart/form-data` response into the same\n * `AnnotationAppearanceImagesResult` shape the local engine produces. The\n * `manifest` part is validated against the wire schema; each image part is\n * wrapped in a `PageImageHandle` backed by the in-memory blob we already\n * downloaded.\n */\nasync function parseAppearanceForm(form: FormData): Promise<AnnotationAppearanceImagesResult> {\n const manifestRaw = form.get('manifest');\n if (typeof manifestRaw !== 'string') {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n 'appearance response missing JSON manifest part',\n );\n }\n let parsedJson: unknown;\n try {\n parsedJson = JSON.parse(manifestRaw);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n `appearance manifest is not valid JSON: ${(err as Error)?.message ?? err}`,\n );\n }\n const manifest = AnnotationAppearanceManifestSchema.parse(parsedJson);\n\n const appearances: AnnotationAppearanceImage[] = await Promise.all(\n manifest.appearances.map(async (entry) => {\n const partValue = form.get(entry.part);\n if (partValue === null || typeof partValue === 'string') {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n `appearance response missing image part \"${entry.part}\"`,\n );\n }\n const blob = partValue as Blob;\n const bytes = new Uint8Array(await blob.arrayBuffer());\n const result: PageImageResult = {\n width: entry.width,\n height: entry.height,\n format: entry.format,\n contentType: entry.contentType,\n source: { kind: 'bytes', bytes },\n };\n const image = createPageImageHandle(result, {\n async blob() {\n return blob;\n },\n });\n return {\n ref: entry.ref,\n mode: entry.mode,\n rect: entry.rect,\n image,\n };\n }),\n );\n\n return { pageState: manifest.pageState, appearances };\n}\n\n/**\n * Local helper: project a non-index `AnnotationRef` into the matching\n * `AnnotationStableId` shape so we can route by stable key. The compiler\n * narrows on `ref.kind` here so we can't accidentally pass an index ref.\n */\nfunction refToStableId(\n ref: Extract<AnnotationRef, { kind: 'objectNumber' | 'nm' }>,\n): { kind: 'objectNumber'; value: number } | { kind: 'nm'; value: string } {\n if (ref.kind === 'objectNumber') {\n return { kind: 'objectNumber', value: ref.annotObjectNumber };\n }\n return { kind: 'nm', value: ref.nm };\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type PageGeometryService,\n type PageGeometrySnapshot,\n type PageObjectNumber,\n} from '@embedpdf/engine-core/runtime';\nimport { PageGeometrySnapshotSchema, wirePaths } from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudPageGeometryService implements PageGeometryService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly pageObjectNumber: PageObjectNumber,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n read(): AbortablePromise<PageGeometrySnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageGeometrySnapshot>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n const page = manifest.pages.find((p) => p.state.pageObjectNumber === this.pageObjectNumber);\n if (!page) {\n throw new EngineError(\n EngineErrorCode.NotFound,\n `no page with object number ${this.pageObjectNumber} in document ${this.docId}`,\n );\n }\n // Plane-scope rule: geometry depends on the `content` plane (see\n // CloudPageTextService for the full rationale).\n return planesInherited(manifest, ['content'])\n ? wirePaths.docPageGeometry(this.docId, this.pageObjectNumber, page.cache.contentVersion)\n : wirePaths.layerPageGeometry(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n page.cache.contentVersion,\n );\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => PageGeometrySnapshotSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n createPageImageHandle,\n type PageImageHandle,\n type PageImageOptions,\n type PageImageResult,\n type PageNetworkRenderFormat,\n type PageObjectNumber,\n type PageRaster,\n type PageRenderOptions,\n type PageRenderService,\n} from '@embedpdf/engine-core/runtime';\nimport { renderImageOptionsToWire, wirePaths } from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudPageRenderService implements PageRenderService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly pageObjectNumber: PageObjectNumber,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n image(options: PageImageOptions = {}): AbortablePromise<PageImageHandle> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageImageHandle>(async (signal) => {\n const format = normalizeFormat(options.format);\n const includeAnnotations = options.includeAnnotations ?? true;\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n const page = manifest.pages.find((p) => p.state.pageObjectNumber === this.pageObjectNumber);\n if (!page) {\n throw new EngineError(\n EngineErrorCode.NotFound,\n `no page with object number ${this.pageObjectNumber} in document ${this.docId}`,\n );\n }\n // `format` flows through `options` and ends up in the token like\n // every other render option — the wire format treats it uniformly.\n // Normalized above so the URL always carries an explicit,\n // network-supported format (PNG or WebP; default WebP).\n // Annotatedness itself is PATH-expressed (the token/path law): the\n // token never carries it; the annotated family's token carries the\n // `annotationVersion` pin instead.\n const wireToken = renderImageOptionsToWire(\n { ...options, format },\n {\n contentVersion: page.cache.contentVersion,\n ...(includeAnnotations ? { annotationVersion: page.cache.annotationVersion } : {}),\n },\n );\n // Plane-scope rule: a render resolves at the DOC-LEVEL (shared base)\n // path iff every plane it depends on is inherited — annotation-free\n // renders (full pages AND tiles; the rect target rides the same\n // token) depend on `content`, annotated ones on\n // `content + annotations`. Each is its OWN family at BOTH tiers\n // (prefix law: edge grants see only prefixes). 1,000 inheriting\n // visitors → one URL set, one origin render, no layer session.\n if (includeAnnotations) {\n return planesInherited(manifest, ['content', 'annotations'])\n ? wirePaths.docPageRenderAnnotated(this.docId, this.pageObjectNumber, wireToken)\n : wirePaths.layerPageRenderAnnotated(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n wireToken,\n );\n }\n return planesInherited(manifest, ['content'])\n ? wirePaths.docPageRender(this.docId, this.pageObjectNumber, wireToken)\n : wirePaths.layerPageRender(this.docId, this.layerName, this.pageObjectNumber, wireToken);\n };\n // The advertised URL reflects the CURRENT manifest; the blob loader\n // re-resolves per fetch through the 404 → manifest-refresh rail, so a\n // scope flip (e.g. this layer's first annotation write) self-heals\n // instead of failing on a stale path family.\n const requestPath = await buildPath(signal);\n return createCloudPageImageHandle(\n {\n format,\n contentType: `image/${format}`,\n source: { kind: 'url', url: this.http.absoluteUrl(requestPath) },\n },\n this.http,\n buildPath,\n async (s) => {\n await this.manifest.refresh(s);\n },\n );\n });\n }\n\n raw(_options?: PageRenderOptions): AbortablePromise<PageRaster> {\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.NotImplemented,\n 'render.raw() is not available in the cloud engine; use render.image()',\n ),\n );\n }\n}\n\nfunction createCloudPageImageHandle(\n result: PageImageResult,\n http: HttpClient,\n buildPath: (signal: AbortSignal) => Promise<string>,\n onStaleVersion: (signal: AbortSignal) => Promise<void>,\n): PageImageHandle {\n return createPageImageHandle(result, {\n blob: (signal) =>\n http.getBlobWithRefresh(buildPath, onStaleVersion, signal ?? new AbortController().signal),\n });\n}\n\nfunction normalizeFormat(format: PageImageOptions['format']): PageNetworkRenderFormat {\n if (format === undefined) return 'webp';\n if (format === 'png' || format === 'webp') return format;\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n `cloud render.image() supports only \"png\" and \"webp\" (got \"${format}\")`,\n );\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type PageObjectNumber,\n type PageTextService,\n type PageTextSnapshot,\n} from '@embedpdf/engine-core/runtime';\nimport { PageTextSnapshotSchema, wirePaths } from '@embedpdf/engine-core/wire';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { planesInherited } from './planes';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Cloud-side per-page text service. `read()` fetches the\n * content-addressed URL `/v1/docs/:id/text/pages/:pon/data@contentVersion=N`, where\n * `:P` is the page's current `contentVersion` from the cached\n * manifest. On a 404 (stale version) the SDK transparently refreshes\n * `/head` + `/manifest@docVersion=N`, rebuilds the URL with the fresh `cN`,\n * and retries exactly once.\n */\nexport class CloudPageTextService implements PageTextService {\n constructor(\n private readonly http: HttpClient,\n private readonly docId: string,\n private readonly layerName: string,\n private readonly pageObjectNumber: PageObjectNumber,\n private readonly isClosed: () => boolean,\n private readonly manifest: ManifestAccessor,\n ) {}\n\n read(): AbortablePromise<PageTextSnapshot> {\n if (this.isClosed()) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.docId} is closed`),\n );\n }\n return AbortablePromise.run<PageTextSnapshot>(async (signal) => {\n const buildPath = async (s: AbortSignal): Promise<string> => {\n const manifest = await this.manifest.get(s);\n const page = manifest.pages.find((p) => p.state.pageObjectNumber === this.pageObjectNumber);\n if (!page) {\n throw new EngineError(\n EngineErrorCode.NotFound,\n `no page with object number ${this.pageObjectNumber} in document ${this.docId}`,\n );\n }\n // Plane-scope rule: text depends on the `content` plane — while it\n // is inherited, every visitor's layer reads ONE doc-level URL (and\n // the base worker session at the origin).\n return planesInherited(manifest, ['content'])\n ? wirePaths.docPageText(this.docId, this.pageObjectNumber, page.cache.contentVersion)\n : wirePaths.layerPageText(\n this.docId,\n this.layerName,\n this.pageObjectNumber,\n page.cache.contentVersion,\n );\n };\n return this.http.getJsonWithRefresh(\n buildPath,\n (raw) => PageTextSnapshotSchema.parse(raw),\n async (s) => {\n await this.manifest.refresh(s);\n },\n signal,\n );\n });\n }\n}\n","import type { PageHandle, PageObjectNumber } from '@embedpdf/engine-core/runtime';\nimport type { SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport type { ManifestAccessor } from './CloudDocumentHandle';\nimport { CloudPageAnnotationsService } from './CloudPageAnnotationsService';\nimport { CloudPageGeometryService } from './CloudPageGeometryService';\nimport { CloudPageRenderService } from './CloudPageRenderService';\nimport { CloudPageTextService } from './CloudPageTextService';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport class CloudPageHandle implements PageHandle {\n readonly annotations: CloudPageAnnotationsService;\n readonly text: CloudPageTextService;\n readonly geometry: CloudPageGeometryService;\n readonly render: CloudPageRenderService;\n\n constructor(\n readonly pageObjectNumber: PageObjectNumber,\n readonly pageIndex: number,\n http: HttpClient,\n docId: string,\n layerName: string,\n isClosed: () => boolean,\n manifest: ManifestAccessor,\n publisher: SessionEventPublisher,\n ) {\n this.annotations = new CloudPageAnnotationsService(\n http,\n docId,\n layerName,\n pageObjectNumber,\n isClosed,\n manifest,\n publisher,\n );\n this.text = new CloudPageTextService(\n http,\n docId,\n layerName,\n pageObjectNumber,\n isClosed,\n manifest,\n );\n this.geometry = new CloudPageGeometryService(\n http,\n docId,\n layerName,\n pageObjectNumber,\n isClosed,\n manifest,\n );\n this.render = new CloudPageRenderService(\n http,\n docId,\n layerName,\n pageObjectNumber,\n isClosed,\n manifest,\n );\n }\n}\n","import type {\n AnnotationCreateResult,\n AnnotationDeleteResult,\n AnnotationMoveResult,\n AnnotationUpdateResult,\n AttachmentCreateResult,\n AttachmentDeleteResult,\n DocumentEvent,\n EventOrigin,\n FormFieldCreateResult,\n FormFieldDeleteResult,\n FormFieldUpdateResult,\n FormEffectsResult,\n FormImportResult,\n FormRepairResult,\n FormSetValueResult,\n FormWidgetLinkResult,\n MetadataUpdateResult,\n PageDeleteResult,\n PageFlattenResult,\n PageMoveResult,\n PageRotateResult,\n PageRotation,\n} from '@embedpdf/engine-core/runtime';\n\n/** The SSE `mutation` event body — the audit row in JSON (the server's\n * `toJsonlEvent` shape). `payload` is byte-identical to what the mutating\n * caller received as its HTTP response. */\nexport interface AuditEventRow {\n id: number;\n ts: number;\n sub: string;\n kind: string;\n pageObjectNumber: number | null;\n affectedPages: number[];\n originSessionId: string | null;\n payload: unknown;\n}\n\n/**\n * Translate a remote audit row into a `DocumentEvent` — pure, so the\n * exactly-once and verbatim-payload invariants are unit-testable without a\n * server. Returns `null` for kinds this engine version doesn't know\n * (a NEWER server's events degrade to \"ignored\", never to a crash).\n *\n * Context-field fidelity differs by op, by design of the audit row:\n * - rotate/delete: `affectedPages` is exactly the op's page set; rotation\n * is recovered from the layout (it's absolute — every affected page\n * carries the value).\n * - move: the originator knows which block it moved; the audit row only\n * records the resulting order, so `pageObjectNumbers` is the full new\n * order and `destIndex` is absent (remote consumers use `layout`).\n */\nexport function auditRowToEvent(row: AuditEventRow, mySessionId: string): DocumentEvent | null {\n if (row.originSessionId === mySessionId) return null; // own echo — local publish covered it\n\n const origin: EventOrigin = {\n kind: 'remote',\n sessionId: row.originSessionId ?? `unknown:${row.sub}`,\n sub: row.sub,\n ts: row.ts,\n serverId: row.id,\n };\n\n switch (row.kind) {\n case 'annot.create':\n return {\n type: 'annotation.created',\n pageObjectNumber: row.pageObjectNumber ?? row.affectedPages[0] ?? 0,\n origin,\n ...(row.payload as AnnotationCreateResult),\n };\n case 'annot.update':\n return {\n type: 'annotation.updated',\n pageObjectNumber: row.pageObjectNumber ?? row.affectedPages[0] ?? 0,\n origin,\n ...(row.payload as AnnotationUpdateResult),\n };\n case 'annot.delete':\n return {\n type: 'annotation.deleted',\n pageObjectNumber: row.pageObjectNumber ?? row.affectedPages[0] ?? 0,\n origin,\n ...(row.payload as AnnotationDeleteResult),\n };\n case 'annot.move':\n return {\n type: 'annotation.moved',\n pageObjectNumber: row.pageObjectNumber ?? row.affectedPages[0] ?? 0,\n origin,\n ...(row.payload as AnnotationMoveResult),\n };\n case 'pages.move':\n return {\n type: 'pages.moved',\n pageObjectNumbers: row.affectedPages,\n origin,\n ...(row.payload as PageMoveResult),\n };\n case 'pages.rotate': {\n const payload = row.payload as PageRotateResult;\n const rotation = (payload.layout.pages.find(\n (page) => page.pageObjectNumber === row.affectedPages[0],\n )?.rotation ?? 0) as PageRotation;\n return {\n type: 'pages.rotated',\n pageObjectNumbers: row.affectedPages,\n rotation,\n origin,\n ...payload,\n };\n }\n case 'pages.delete':\n return {\n type: 'pages.deleted',\n pageObjectNumbers: row.affectedPages,\n origin,\n ...(row.payload as PageDeleteResult),\n };\n case 'pages.flatten':\n return {\n type: 'pages.flattened',\n origin,\n ...(row.payload as PageFlattenResult),\n };\n case 'metadata.update':\n return {\n type: 'metadata.updated',\n origin,\n ...(row.payload as MetadataUpdateResult),\n };\n case 'attachment.create':\n return {\n type: 'attachment.created',\n origin,\n ...(row.payload as AttachmentCreateResult),\n };\n case 'attachment.delete':\n return {\n type: 'attachment.deleted',\n origin,\n ...(row.payload as AttachmentDeleteResult),\n };\n // Form mutations: two audit kinds share the `form.valueChanged` event\n // (setValue and reset produce the same result shape) — the audit log\n // keeps them distinct for history, the event stream cares about effect.\n case 'form.setValue':\n case 'form.reset':\n return { type: 'form.valueChanged', origin, ...(row.payload as FormSetValueResult) };\n case 'form.import':\n return { type: 'form.imported', origin, ...(row.payload as FormImportResult) };\n case 'form.repair':\n return { type: 'form.repaired', origin, ...(row.payload as FormRepairResult) };\n case 'form.createField':\n return { type: 'form.fieldCreated', origin, ...(row.payload as FormFieldCreateResult) };\n case 'form.updateField':\n return { type: 'form.fieldUpdated', origin, ...(row.payload as FormFieldUpdateResult) };\n case 'form.deleteField':\n return { type: 'form.fieldDeleted', origin, ...(row.payload as FormFieldDeleteResult) };\n case 'form.attachWidget':\n return { type: 'form.widgetAttached', origin, ...(row.payload as FormWidgetLinkResult) };\n case 'form.detachWidget':\n return { type: 'form.widgetDetached', origin, ...(row.payload as FormWidgetLinkResult) };\n case 'form.applyEffects':\n return { type: 'form.effectsApplied', origin, ...(row.payload as FormEffectsResult) };\n default:\n return null;\n }\n}\n","import { EngineError, EngineErrorCode } from '@embedpdf/engine-core/runtime';\n\nimport type { AuditEventRow } from './auditRowToEvent';\nimport type { HttpClient } from '../transport/HttpClient';\n\nexport interface SseClientOptions {\n http: HttpClient;\n path: string;\n /** Resume cursor for the first connect (manifest `auditHead` /\n * `lastServerId`); `null` subscribes \"from now\". */\n initialCursor: number | null;\n /** One parsed audit row, in id order. The cursor has already advanced. */\n onRow(row: AuditEventRow): void;\n /** Server says the gap is too large to replay — refetch state. */\n onFullRefresh(): void;\n /** Auth is permanently gone (401/403); the client stopped for good. */\n onAuthLost(): void;\n}\n\n/**\n * Fetch-based SSE consumer. Browser-native `EventSource` cannot send an\n * `Authorization` header, so the stream rides the same `HttpClient` as\n * every other request (same token provider, same session header).\n *\n * Resilience model: the cursor is the only state that matters. Every\n * (re)connect sends `Last-Event-ID: cursor`; the server replays the gap\n * from the audit log. So a dropped stream costs latency, never events —\n * the client needs no buffering and no acknowledgements.\n *\n * - network drop / server close / `auth-expiring` → reconnect with\n * jittered exponential backoff (500ms → 30s; reset after a stream\n * that lived ≥30s). `auth-expiring` reconnects pick up a fresh token\n * from the HttpClient's provider automatically.\n * - 401/403 → permanent: `onAuthLost`, no retry loop against a dead\n * credential.\n */\nexport class SseClient {\n private cursor: number | null;\n private closed = false;\n private abort: AbortController | null = null;\n private retryTimer: ReturnType<typeof setTimeout> | null = null;\n private retryDelayMs = 500;\n\n constructor(private readonly opts: SseClientOptions) {\n this.cursor = opts.initialCursor;\n }\n\n open(): void {\n if (this.closed) return;\n void this.run();\n }\n\n close(): void {\n this.closed = true;\n if (this.retryTimer) clearTimeout(this.retryTimer);\n this.abort?.abort();\n }\n\n get lastEventId(): number | null {\n return this.cursor;\n }\n\n private async run(): Promise<void> {\n const startedAt = Date.now();\n this.abort = new AbortController();\n try {\n const res = await this.opts.http.stream(\n this.opts.path,\n this.cursor !== null ? { 'Last-Event-ID': String(this.cursor) } : {},\n this.abort.signal,\n );\n if (res.status === 401 || res.status === 403) {\n this.closed = true;\n this.opts.onAuthLost();\n return;\n }\n if (!res.ok || !res.body) {\n throw new EngineError(EngineErrorCode.Network, `events stream HTTP ${res.status}`);\n }\n await this.consume(res.body);\n // Stream ended (server close / auth-expiring / network): reconnect.\n if (Date.now() - startedAt >= 30_000) this.retryDelayMs = 500;\n } catch {\n // Aborts land here too; `closed` guards the reschedule below.\n }\n if (this.closed) return;\n const jitter = this.retryDelayMs * (0.5 + Math.random() * 0.5);\n this.retryTimer = setTimeout(() => void this.run(), jitter);\n this.retryDelayMs = Math.min(this.retryDelayMs * 2, 30_000);\n }\n\n private async consume(body: ReadableStream<Uint8Array>): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n for (;;) {\n const { done, value } = await reader.read();\n if (done || this.closed) return;\n buffer += decoder.decode(value, { stream: true });\n for (;;) {\n const sep = buffer.indexOf('\\n\\n');\n if (sep < 0) break;\n const block = buffer.slice(0, sep);\n buffer = buffer.slice(sep + 2);\n this.dispatch(block);\n }\n }\n }\n\n private dispatch(block: string): void {\n if (block.startsWith(':')) return; // heartbeat / comment\n let id: number | null = null;\n let event = 'message';\n const data: string[] = [];\n for (const line of block.split('\\n')) {\n if (line.startsWith('id:')) id = Number(line.slice(3).trim());\n else if (line.startsWith('event:')) event = line.slice(6).trim();\n else if (line.startsWith('data:')) data.push(line.slice(5).trim());\n }\n if (id !== null && Number.isFinite(id)) this.cursor = id;\n if (event === 'mutation') {\n try {\n this.opts.onRow(JSON.parse(data.join('\\n')) as AuditEventRow);\n } catch {\n // A malformed row advances the cursor and is skipped; the audit log\n // remains the source of truth for anyone who refetches.\n }\n } else if (event === 'full-refresh') {\n this.opts.onFullRefresh();\n } else if (event === 'auth-revoked') {\n // Terminal: the credential is dead by decree, not by clock — never\n // retry against it (a reconnect would just 401; this saves the trip\n // and surfaces the loss immediately).\n this.closed = true;\n this.abort?.abort();\n this.opts.onAuthLost();\n }\n // 'auth-expiring' needs no handling: the server ends the stream right\n // after, and the reconnect path fetches a fresh token.\n }\n}\n","import {\n AbortError,\n AbortablePromise,\n DEFAULT_PDF_SAVE_MODE,\n EngineError,\n EngineErrorCode,\n type AttachmentsCache,\n type DocumentAnnotationsService,\n type DocumentActionsService,\n type DocumentAttachmentsService,\n type DocumentEvent,\n type DocumentEventStream,\n type DocumentFormsService,\n type DocumentHandle,\n type DocumentPagesService,\n type DocumentRedactionService,\n CONTINUOUS_RENDER_POLICY,\n type DocumentRenderService,\n type DocumentSecurityService,\n type MetadataCache,\n type MutationMeta,\n type PageHandle,\n type PageObjectNumber,\n type PageStructureCache,\n type PdfSaveMode,\n} from '@embedpdf/engine-core/runtime';\nimport {\n DEFAULT_LAYER_NAME,\n DocumentHeadSchema,\n DocumentManifestSchema,\n wirePaths,\n type DocumentHead,\n type DocumentManifest,\n type LayerScopePlane,\n} from '@embedpdf/engine-core/wire';\nimport { EventHub, SessionEventPublisher } from '@embedpdf/engine-services';\n\nimport { CloudDocumentActionsService } from './CloudDocumentActionsService';\nimport { CloudDocumentAnnotationsService } from './CloudDocumentAnnotationsService';\nimport { CloudDocumentAttachmentsService } from './CloudDocumentAttachmentsService';\nimport { CloudDocumentFormsService } from './CloudDocumentFormsService';\nimport { CloudDocumentPagesService } from './CloudDocumentPagesService';\nimport { CloudDocumentRedactionService } from './CloudDocumentRedactionService';\nimport { CloudDocumentSearchService } from './CloudDocumentSearchService';\nimport { CloudDocumentSecurityService } from './CloudDocumentSecurityService';\nimport { CloudMetadataService } from './CloudMetadataService';\nimport { CloudPageHandle } from './CloudPageHandle';\nimport { auditRowToEvent } from '../realtime/auditRowToEvent';\nimport { SseClient } from '../realtime/SseClient';\nimport type { HttpClient } from '../transport/HttpClient';\n\n/**\n * Read accessor handed to every `CloudPage…Service`. The closure\n * captures `this` so the services don't carry a direct reference\n * back to the document handle (smaller circular-ref surface, easier\n * to mock in unit tests).\n */\nexport interface ManifestAccessor {\n /** Cached manifest (cold-fetched once, kept across requests). */\n get(signal: AbortSignal): Promise<DocumentManifest>;\n /** Force re-fetch of `/head` + `/manifest@docVersion=N`; replaces the cache. */\n refresh(signal: AbortSignal): Promise<DocumentManifest>;\n /**\n * Absorb mutation-returned state/cache deltas when safe. `owns` names the\n * planes this mutation kind takes ownership of (the monotone-flip\n * rule): annotation/form writes own `annotations`; flatten and\n * redaction-apply own `content + annotations`. The flip runs even when\n * the version-gated delta merge is skipped — scopes only ever move\n * base → layer, so any observed mutation proves the plane diverged.\n */\n apply(meta: MutationMeta, owns: readonly LayerScopePlane[]): void;\n /** Advance the cached manifest's docVersion + layoutVersion after a page\n * STRUCTURE op that keeps the page set intact (move, rotate). */\n applyPageStructure(cache: PageStructureCache): void;\n /** Same advance for a page delete, additionally dropping the deleted\n * pages' manifest rows so per-page leaf URLs stop resolving locally. */\n applyPageDelete(cache: PageStructureCache, deletedPages: PageObjectNumber[]): void;\n /** Advance the cached manifest's docVersion + metadataVersion after a metadata write. */\n applyMetadata(cache: MetadataCache): void;\n /** Advance the cached manifest's docVersion + attachmentsVersion after an\n * attachment create/delete. */\n applyAttachments(cache: AttachmentsCache): void;\n}\n\nexport class CloudDocumentHandle implements DocumentHandle {\n readonly id: string;\n readonly capabilities = {\n weakAnnotationEditSessions: 'required',\n pageEditSessions: 'unsupported',\n } as const;\n readonly metadata: CloudMetadataService;\n readonly annotations: DocumentAnnotationsService;\n readonly actions: DocumentActionsService;\n readonly attachments: DocumentAttachmentsService;\n readonly forms: DocumentFormsService;\n readonly search: CloudDocumentSearchService;\n readonly pages: DocumentPagesService;\n readonly redaction: DocumentRedactionService;\n readonly security: DocumentSecurityService;\n readonly render: DocumentRenderService;\n readonly events: DocumentEventStream;\n private readonly publisher: SessionEventPublisher;\n private readonly hub: EventHub;\n private readonly sessionId: string;\n private sseClient: SseClient | null = null;\n private sseSubscribers = 0;\n private closed = false;\n\n /**\n * Cached current manifest. Populated on first read by `getManifest`\n * (or any `page().*` call that needs to know a version). Replaced\n * wholesale on `refreshManifest`. Cleared on `close`.\n *\n * Memory model: one DocumentManifest per open handle. Per-page\n * version reads are O(pages.length) `.find(...)` lookups; if a\n * profiling pass ever shows that as hot, swap for a Map keyed by\n * `pageObjectNumber`. Today's documents are page-sparse so the\n * scan is cheaper than the hash overhead.\n */\n private manifestCache: DocumentManifest | null = null;\n private inflightManifest: Promise<DocumentManifest> | null = null;\n private manifestFloorVersion = 0;\n private pendingInitialHead: DocumentHead | null;\n\n private readonly manifestAccessor: ManifestAccessor;\n\n constructor(\n private readonly http: HttpClient,\n id: string,\n private readonly layerName: string = DEFAULT_LAYER_NAME,\n initialHead?: DocumentHead,\n /**\n * The doc-scoped JWT the engine was opened with, decoded\n * unverified to populate the security service's local-fallback\n * `effectiveScope` / `identity` accessors. Optional for backward\n * compatibility; without it the local-fallback path returns an\n * empty scope and null identity until /access is called.\n */\n initialToken: string | null = null,\n sessionId: string = `cloud:anon:${id}`,\n ) {\n this.id = id;\n this.pendingInitialHead = initialHead ?? null;\n const security = new CloudDocumentSecurityService(\n http,\n id,\n layerName,\n initialHead ?? fallbackUnknownHead(id),\n { isClosed: () => this.closed },\n initialToken,\n );\n this.security = security;\n // The deployment's render lattice rides /v1/access (mutable policy\n // never lives in immutable manifests). Reuse the cached access block\n // when present; otherwise establish access on demand — the same call\n // the CDN path uses, so this can never add a second handshake shape.\n // A pre-lattice server (no renderPolicy field) enforces nothing:\n // `continuous` is the honest answer.\n this.render = {\n policy: async () => {\n const cached = security.currentAccess ?? (await security.establishAccess()).access ?? null;\n const advertised = cached?.renderPolicy;\n if (!advertised) return CONTINUOUS_RENDER_POLICY;\n return {\n kind: 'lattice',\n fullPage: { widths: advertised.fullPage.widths },\n ...(advertised.tiles ? { tiles: advertised.tiles } : {}),\n ...(advertised.appearances ? { appearances: advertised.appearances } : {}),\n ...(advertised.maxRenderPixels !== undefined\n ? { maxRenderPixels: advertised.maxRenderPixels }\n : {}),\n formats: advertised.formats,\n background: advertised.background,\n enforced: advertised.enforced,\n };\n },\n };\n const hub = new EventHub();\n this.hub = hub;\n this.sessionId = sessionId;\n // Your OWN mutations publish here at POST-confirmation time (kind:\n // 'local'); the remote channel (SSE) publishes everyone else's into the\n // same hub. Exactly one event per mutation, either way. The SSE stream\n // is LAZY: it opens on the first subscriber and closes on the last —\n // non-collaborative usage never holds a connection (browsers cap ~6\n // per origin on HTTP/1.1).\n this.events = {\n subscribe: (listener) => {\n const unsubscribe = hub.subscribe(listener);\n this.retainRemoteStream();\n let released = false;\n return () => {\n unsubscribe();\n if (!released) {\n released = true;\n this.releaseRemoteStream();\n }\n };\n },\n lastServerId: () => hub.lastServerId(),\n };\n this.publisher = new SessionEventPublisher(hub, sessionId);\n this.manifestAccessor = {\n get: (signal) => this.getManifest(signal),\n refresh: (signal) => this.refreshManifest(signal),\n apply: (meta, owns) => this.absorbMutation(meta, owns),\n applyPageStructure: (cache) => this.absorbPageStructure(cache),\n applyPageDelete: (cache, deletedPages) => this.absorbPageDelete(cache, deletedPages),\n applyMetadata: (cache) => this.absorbMetadata(cache),\n applyAttachments: (cache) => this.absorbAttachments(cache),\n };\n this.metadata = new CloudMetadataService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n this.annotations = new CloudDocumentAnnotationsService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n );\n this.actions = new CloudDocumentActionsService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n );\n this.attachments = new CloudDocumentAttachmentsService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n this.forms = new CloudDocumentFormsService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n this.search = new CloudDocumentSearchService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n );\n this.pages = new CloudDocumentPagesService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n this.redaction = new CloudDocumentRedactionService(\n http,\n id,\n layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n }\n\n page(pageObjectNumber: PageObjectNumber): PageHandle {\n return new CloudPageHandle(\n pageObjectNumber,\n -1,\n this.http,\n this.id,\n this.layerName,\n () => this.closed,\n this.manifestAccessor,\n this.publisher,\n );\n }\n\n download(opts: { mode?: PdfSaveMode } = {}): AbortablePromise<Uint8Array> {\n if (this.closed) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.DocNotOpen, `document ${this.id} is closed`),\n );\n }\n const mode = opts.mode ?? DEFAULT_PDF_SAVE_MODE;\n return AbortablePromise.run<Uint8Array>(async (signal) => {\n const buildPath = async () => {\n const manifest = await this.getManifest(signal);\n return wirePaths.layerDownloadVersioned(this.id, this.layerName, {\n docVersion: manifest.docVersion,\n mode,\n });\n };\n try {\n return await this.http.getBytes(await buildPath(), signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n await this.refreshManifest(signal);\n return this.http.getBytes(await buildPath(), signal);\n }\n });\n }\n\n /**\n * Return the cached manifest, fetching cold-cache once if needed.\n * Concurrent callers share a single inflight request (singleflight)\n * so an N-page handle that opens N services in parallel still\n * triggers exactly one `/head` + `/manifest@docVersion=N` round-trip.\n */\n async getManifest(signal: AbortSignal): Promise<DocumentManifest> {\n if (this.manifestCache) return this.manifestCache;\n if (!this.inflightManifest) {\n this.startManifestFetch({ allowInitialHead: true });\n }\n const promise = this.inflightManifest;\n if (!promise) {\n throw new EngineError(\n EngineErrorCode.Unknown,\n `manifest fetch was not started for document ${this.id}`,\n );\n }\n return awaitSignal(promise, signal);\n }\n\n /**\n * Force re-fetch. Used by the transparent-retry path when a leaf\n * URL returns 404 (stale version). Replaces `manifestCache`\n * wholesale so the next `getManifest()` is a Map lookup.\n */\n async refreshManifest(signal: AbortSignal): Promise<DocumentManifest> {\n const promise = this.startManifestFetch({ allowInitialHead: false });\n return awaitSignal(promise, signal);\n }\n\n /**\n * Monotone plane-scope flip: mark the planes a mutation OWNS as layer-scoped in\n * the cached manifest. Scopes only ever move base → layer (no revert op\n * exists), so flipping is safe under ANY event ordering — a duplicate or\n * out-of-order event still proves the plane diverged at some point — and\n * the manifest fetch stays the authoritative source (the 404 → refresh\n * rail heals any miss, e.g. a future mutation kind this client doesn't\n * know about).\n */\n private flipScopes(owns: readonly LayerScopePlane[]): void {\n const cache = this.manifestCache;\n const scopes = cache?.scopes;\n if (!cache || !scopes) return;\n if (owns.every((plane) => scopes[plane] === 'layer')) return;\n const next = { ...scopes };\n for (const plane of owns) next[plane] = 'layer';\n this.manifestCache = { ...cache, scopes: next };\n }\n\n absorbMutation(meta: MutationMeta, owns: readonly LayerScopePlane[]): void {\n this.flipScopes(owns);\n const delta = meta.cacheDelta;\n if (delta) {\n this.manifestFloorVersion = Math.max(this.manifestFloorVersion, delta.docVersion);\n }\n this.inflightManifest = null;\n\n if (!this.manifestCache) return;\n if (delta) {\n if (delta.docVersion <= this.manifestCache.docVersion) return;\n if (delta.previousDocVersion !== this.manifestCache.docVersion) {\n this.manifestCache = null;\n return;\n }\n }\n\n const byPageObjectNumber = new Map(\n this.manifestCache.pages.map((page) => [page.state.pageObjectNumber, page]),\n );\n for (const pageState of meta.affectedPages) {\n const existing = byPageObjectNumber.get(pageState.pageObjectNumber);\n if (existing) {\n byPageObjectNumber.set(pageState.pageObjectNumber, {\n ...existing,\n state: pageState,\n });\n }\n }\n if (delta) {\n for (const page of delta.pages) {\n const existing = byPageObjectNumber.get(page.pageObjectNumber);\n if (existing) {\n byPageObjectNumber.set(page.pageObjectNumber, {\n ...existing,\n cache: page.cache,\n });\n }\n }\n }\n this.manifestCache = {\n ...this.manifestCache,\n docVersion: delta?.docVersion ?? this.manifestCache.docVersion,\n // The manifest is a per-page registry keyed by pageObjectNumber, not a\n // display-order list — geometry/order now lives in `pages.list()`\n // (/layout). Keep a deterministic order by PON so cache merges are\n // stable; display order is the SDK's concern via PageLayout.index.\n pages: Array.from(byPageObjectNumber.values()).sort(\n (a, b) => a.state.pageObjectNumber - b.state.pageObjectNumber,\n ),\n };\n }\n\n /**\n * Patch the cached manifest after a set-preserving page-structure op (move,\n * rotate). Both are purely structural: they advance `docVersion` (so leaf\n * URLs re-resolve) and `layoutVersion` (so the /layout leaf re-fetches),\n * but leave every per-page pin untouched — a rotate renders the SAME\n * normalized bitmaps, a move the same pages. We raise the floor\n * unconditionally and, when our cache is exactly one version behind,\n * advance it in place; otherwise we drop it and refetch lazily.\n */\n private absorbPageStructure(cache: PageStructureCache): void {\n // Move/rotate own the LAYOUT plane only: normalized render/text/\n // geometry artifacts survive structural ops, so content keeps sharing.\n this.flipScopes(['layout']);\n this.manifestFloorVersion = Math.max(this.manifestFloorVersion, cache.docVersion);\n this.inflightManifest = null;\n\n if (!this.manifestCache) return;\n if (cache.docVersion <= this.manifestCache.docVersion) return;\n if (cache.previousDocVersion !== this.manifestCache.docVersion) {\n this.manifestCache = null;\n return;\n }\n this.manifestCache = {\n ...this.manifestCache,\n docVersion: cache.docVersion,\n layoutVersion: cache.layoutVersion,\n };\n }\n\n /**\n * Patch the cached manifest after a page delete: the shared structural\n * advance plus dropping the deleted pages' manifest rows, so no leaf URL\n * for a retired PON can be built from the cache (a stale request would\n * 404 anyway — this keeps the failure local and instant).\n */\n private absorbPageDelete(cache: PageStructureCache, deletedPages: PageObjectNumber[]): void {\n // Delete changes the page SET: a view that removed content must never\n // resolve base artifacts again, so content AND annotations flip with\n // layout.\n this.flipScopes(['layout', 'content', 'annotations']);\n this.manifestFloorVersion = Math.max(this.manifestFloorVersion, cache.docVersion);\n this.inflightManifest = null;\n\n if (!this.manifestCache) return;\n if (cache.docVersion <= this.manifestCache.docVersion) return;\n if (cache.previousDocVersion !== this.manifestCache.docVersion) {\n this.manifestCache = null;\n return;\n }\n const deleted = new Set(deletedPages);\n this.manifestCache = {\n ...this.manifestCache,\n docVersion: cache.docVersion,\n layoutVersion: cache.layoutVersion,\n pages: this.manifestCache.pages.filter((page) => !deleted.has(page.state.pageObjectNumber)),\n };\n }\n\n /**\n * Patch the cached manifest after a metadata write. Symmetric with\n * {@link absorbPageMove}: a metadata edit advances `docVersion` (so leaf\n * URLs re-resolve) and `metadataVersion` (so the /metadata leaf re-fetches),\n * but leaves `layoutVersion` and every per-page pin untouched. Raise the\n * floor unconditionally and, when our cache is exactly one version behind,\n * advance it in place; otherwise drop it and refetch lazily.\n */\n private absorbMetadata(cache: MetadataCache): void {\n this.flipScopes(['metadata']);\n this.manifestFloorVersion = Math.max(this.manifestFloorVersion, cache.docVersion);\n this.inflightManifest = null;\n\n if (!this.manifestCache) return;\n if (cache.docVersion <= this.manifestCache.docVersion) return;\n if (cache.previousDocVersion !== this.manifestCache.docVersion) {\n this.manifestCache = null;\n return;\n }\n this.manifestCache = {\n ...this.manifestCache,\n docVersion: cache.docVersion,\n metadataVersion: cache.metadataVersion,\n };\n }\n\n /**\n * Patch the cached manifest after an attachment create/delete. Symmetric\n * with {@link absorbMetadata}: an attachment write advances `docVersion`\n * (so leaf URLs re-resolve) and `attachmentsVersion` (so the /attachments\n * listing and /attachment-files leaves re-fetch), but leaves\n * `layoutVersion` and every per-page pin untouched. Raise the floor\n * unconditionally and, when our cache is exactly one version behind,\n * advance it in place; otherwise drop it and refetch lazily.\n */\n private absorbAttachments(cache: AttachmentsCache): void {\n this.flipScopes(['attachments']);\n this.manifestFloorVersion = Math.max(this.manifestFloorVersion, cache.docVersion);\n this.inflightManifest = null;\n\n if (!this.manifestCache) return;\n if (cache.docVersion <= this.manifestCache.docVersion) return;\n if (cache.previousDocVersion !== this.manifestCache.docVersion) {\n this.manifestCache = null;\n return;\n }\n this.manifestCache = {\n ...this.manifestCache,\n docVersion: cache.docVersion,\n attachmentsVersion: cache.attachmentsVersion,\n };\n }\n\n private startManifestFetch(opts: { allowInitialHead: boolean }): Promise<DocumentManifest> {\n const ctrl = new AbortController();\n const promise = this.fetchManifest(ctrl.signal, opts);\n this.inflightManifest = promise;\n promise\n .then((manifest) => {\n if (\n manifest.docVersion >= this.manifestFloorVersion &&\n (!this.manifestCache || manifest.docVersion >= this.manifestCache.docVersion)\n ) {\n this.manifestCache = manifest;\n }\n })\n .catch(() => undefined)\n .finally(() => {\n if (this.inflightManifest === promise) {\n this.inflightManifest = null;\n }\n });\n return promise;\n }\n\n private async fetchManifest(\n signal: AbortSignal,\n opts: { allowInitialHead: boolean },\n ): Promise<DocumentManifest> {\n if (this.closed) {\n throw new EngineError(EngineErrorCode.DocNotOpen, `document ${this.id} is closed`);\n }\n const head = opts.allowInitialHead ? this.consumeInitialHead() : null;\n if (head) {\n try {\n return await this.fetchManifestForHead(head, signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n // A mutation may have landed between open() and the first\n // manifest read. The seed is one-shot, so fall through to the\n // normal /head path and learn the current docVersion.\n }\n }\n\n // Refreshes and stale-seed recovery always re-fetch `/head` first\n // so we learn the current `docVersion`; chasing the manifest with\n // a stale `:D` would 404 by definition.\n const freshHead = await this.http.getJson(\n wirePaths.layerHead(this.id, this.layerName),\n (raw) => DocumentHeadSchema.parse(raw),\n signal,\n );\n return this.fetchManifestForHead(freshHead, signal);\n }\n\n private consumeInitialHead(): DocumentHead | null {\n const head = this.pendingInitialHead;\n this.pendingInitialHead = null;\n return head;\n }\n\n private fetchManifestForHead(head: DocumentHead, signal: AbortSignal): Promise<DocumentManifest> {\n return this.http.getJson(\n wirePaths.layerManifest(this.id, this.layerName, head.docVersion),\n (raw) => DocumentManifestSchema.parse(raw),\n signal,\n );\n }\n\n close(): AbortablePromise<void> {\n if (this.closed) {\n return AbortablePromise.resolveValue<void>(undefined);\n }\n this.closed = true;\n this.sseClient?.close();\n this.sseClient = null;\n this.manifestCache = null;\n this.inflightManifest = null;\n return AbortablePromise.resolveValue<void>(undefined);\n }\n\n private retainRemoteStream(): void {\n this.sseSubscribers += 1;\n if (this.sseSubscribers > 1 || this.closed || this.sseClient) return;\n this.sseClient = new SseClient({\n http: this.http,\n path: wirePaths.layerEvents(this.id, this.layerName),\n // Gapless handshake: resume from the newest cursor we know — events\n // already seen, else the cached manifest's transactional auditHead.\n // Null (cold start, no manifest yet) subscribes \"from now\", which is\n // exact too: the first manifest fetched afterwards is newer anyway.\n initialCursor: this.hub.lastServerId() ?? this.manifestCache?.auditHead ?? null,\n onRow: (row) => {\n const event = auditRowToEvent(row, this.sessionId);\n if (!event) return; // own echo or unknown kind\n // Absorb BEFORE publish: a listener reading the manifest in its\n // callback must see post-mutation state (same order as local).\n this.absorbRemoteEvent(event);\n this.hub.publish(event);\n },\n onFullRefresh: () => {\n // Too far behind to replay: drop the cache; the next read refetches.\n this.manifestCache = null;\n this.inflightManifest = null;\n },\n onAuthLost: () => {\n // The stream is gone for good under this credential. Local events\n // keep flowing; remote delivery resumes if the doc is re-opened\n // with a fresh token.\n this.sseClient = null;\n },\n });\n this.sseClient.open();\n }\n\n private releaseRemoteStream(): void {\n this.sseSubscribers = Math.max(0, this.sseSubscribers - 1);\n if (this.sseSubscribers === 0 && this.sseClient) {\n this.sseClient.close();\n this.sseClient = null;\n }\n }\n\n /** Patch the cached manifest from a REMOTE event's coherence pins — the\n * same absorb rails local mutations use, so reads stay warm no matter\n * whose hand caused the change. */\n private absorbRemoteEvent(event: DocumentEvent): void {\n switch (event.type) {\n case 'annotation.created':\n case 'annotation.updated':\n case 'annotation.deleted':\n case 'annotation.moved':\n this.absorbMutation(event.meta, ['annotations']);\n return;\n case 'pages.moved':\n case 'pages.rotated':\n if (event.cache) this.absorbPageStructure(event.cache);\n return;\n case 'pages.deleted':\n if (event.cache) this.absorbPageDelete(event.cache, event.pageObjectNumbers);\n return;\n case 'metadata.updated':\n if (event.cache) this.absorbMetadata(event.cache);\n return;\n case 'attachment.created':\n case 'attachment.deleted':\n if (event.cache) this.absorbAttachments(event.cache);\n return;\n case 'form.valueChanged':\n case 'form.imported':\n case 'form.repaired':\n case 'form.fieldCreated':\n case 'form.fieldUpdated':\n case 'form.fieldDeleted':\n case 'form.widgetAttached':\n case 'form.widgetDetached':\n // Form mutations ship the same MutationMeta rails as annotations:\n // affected pages are the ones whose widget appearances changed.\n // Widgets ARE annotations, so they own the same plane.\n this.absorbMutation(event.meta, ['annotations']);\n return;\n case 'form.effectsApplied':\n // No-op batches are never audited, but keep the nullable guard at\n // the consumer boundary for forward/backward wire compatibility.\n if (event.meta) this.absorbMutation(event.meta, ['annotations']);\n return;\n case 'pages.flattened':\n // Flatten bakes annotations into page content: both planes flip.\n if (event.meta) this.absorbMutation(event.meta, ['content', 'annotations']);\n return;\n case 'redaction.applied':\n // Redaction-apply rewrites content and consumes the marks: both\n // planes flip — and this is the security-relevant divergence, so a\n // remote apply must stop this client's base reads immediately.\n if (event.meta) this.absorbMutation(event.meta, ['content', 'annotations']);\n return;\n }\n }\n}\n\nfunction fallbackUnknownHead(id: string): DocumentHead {\n return {\n id,\n baseSha: '',\n storageSizeBytes: 0,\n docVersion: 1,\n state: 'ready',\n encryption: { state: 'unknown', requiresPassword: null },\n permissions: {\n known: false,\n bits: null,\n allAllowed: null,\n openedAs: null,\n securityHandlerRevision: null,\n canUpgradeToOwner: false,\n },\n access: { required: true, reasons: ['permissions-unknown'], endpoint: wirePaths.access },\n };\n}\n\nfunction awaitSignal<T>(promise: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(new AbortError(signal.reason));\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n reject(new AbortError(signal.reason));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n (value) => {\n signal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n (reason) => {\n signal.removeEventListener('abort', onAbort);\n reject(reason);\n },\n );\n });\n}\n","import { EngineError, EngineErrorCode } from '@embedpdf/engine-core/runtime';\n\n/**\n * Share-session exchange: the client half of the no-backend embed flow.\n *\n * A share token (`shr_…`) is a REFERENCE to a stored grant on the\n * server, not a credential — `exchangeShareToken` trades it for an\n * ordinary short-lived doc JWT, and `shareSessionSource` wraps that in\n * a self-renewing token source. Because the engine's transport\n * invokes its token source on every request (and SSE reconnects call\n * it again), renewal is nothing more than \"exchange again when the\n * cached session is nearly out\" — no timers, no listeners.\n *\n * The endpoint requires a browser `Origin` header (the server checks\n * it against the grant's allowlist). Browsers attach it automatically;\n * non-browser callers (tests, SSR) must supply a `fetch` that does.\n */\n\nexport interface ShareSession {\n /** Doc-scoped session JWT carrying the grant's capabilities. */\n token: string;\n docId: string;\n layerName: string;\n /** Unix seconds when `token` expires. */\n expiresAt: number;\n}\n\nexport interface ShareExchangeOptions {\n /** Passphrase for protected grants (`SharePasswordRequired` otherwise). */\n password?: string;\n fetch?: typeof globalThis.fetch;\n}\n\n/**\n * Thrown on a non-OK exchange. `code` is the server's wire code:\n * `SharePasswordRequired` (prompt and retry with a password),\n * `OriginNotAllowed` / `OriginRequired`, `ShareExpired`, `NotFound`\n * (unknown or revoked — indistinguishable by design), or\n * `TooManyRequests`.\n */\nexport class ShareExchangeError extends Error {\n constructor(\n readonly code: string,\n message: string,\n readonly status: number,\n ) {\n super(message);\n this.name = 'ShareExchangeError';\n }\n}\n\nexport async function exchangeShareToken(\n baseUrl: string,\n shareToken: string,\n opts: ShareExchangeOptions = {},\n): Promise<ShareSession> {\n const doFetch = opts.fetch ?? globalThis.fetch;\n const res = await doFetch(`${baseUrl.replace(/\\/$/, '')}/v1/share-sessions`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n shareToken,\n ...(opts.password !== undefined ? { password: opts.password } : {}),\n }),\n });\n if (!res.ok) {\n let code = 'Unknown';\n let message = `share exchange failed with status ${res.status}`;\n try {\n const payload = (await res.json()) as { error?: { code?: string; message?: string } };\n if (payload.error?.code) code = payload.error.code;\n if (payload.error?.message) message = payload.error.message;\n } catch {\n // Non-JSON error body; keep the status-shaped message.\n }\n throw new ShareExchangeError(code, message, res.status);\n }\n return (await res.json()) as ShareSession;\n}\n\n/**\n * Lift a {@link ShareExchangeError} into the engine's error taxonomy, so\n * `open({ kind: 'share' })` and every later renewal fail with the same\n * `EngineError` family as all other engine calls. The wire code and HTTP\n * status survive in `details`; the original error rides as `cause`.\n *\n * `SharePasswordRequired` gets its own engine code — it is the one outcome\n * callers branch on programmatically (prompt for the grant passphrase and\n * retry). Everything else maps by meaning, with the HTTP status as the\n * fallback discriminator.\n */\nexport function engineErrorFromShareExchange(error: ShareExchangeError): EngineError {\n const code =\n error.code === 'SharePasswordRequired'\n ? EngineErrorCode.SharePasswordRequired\n : error.code === 'NotFound'\n ? EngineErrorCode.NotFound\n : error.code === 'ShareExpired' ||\n error.code === 'OriginNotAllowed' ||\n error.code === 'OriginRequired'\n ? EngineErrorCode.Forbidden\n : error.status === 401\n ? EngineErrorCode.Unauthenticated\n : error.status === 400\n ? EngineErrorCode.InvalidArg\n : EngineErrorCode.Unknown;\n return new EngineError(code, `share exchange failed: ${error.message}`, {\n details: { shareCode: error.code, status: error.status },\n cause: error,\n });\n}\n\n/** Renew this many seconds before `expiresAt` so in-flight requests never race expiry. */\nconst RENEW_MARGIN_SECONDS = 60;\n\n/**\n * A caching, self-renewing token source over the exchange — the callable\n * member of the engine's `TokenSource` union, assignable wherever one is\n * taken.\n * Concurrent callers share one in-flight exchange; a failed exchange\n * clears it so the next request retries rather than caching the error.\n */\nexport function shareSessionSource(\n baseUrl: string,\n shareToken: string,\n opts: ShareExchangeOptions = {},\n): () => Promise<string> {\n let session: ShareSession | null = null;\n let inflight: Promise<string> | null = null;\n return async () => {\n if (session && session.expiresAt - Date.now() / 1000 > RENEW_MARGIN_SECONDS) {\n return session.token;\n }\n inflight ??= exchangeShareToken(baseUrl, shareToken, opts)\n .then((next) => {\n session = next;\n return next.token;\n })\n .finally(() => {\n inflight = null;\n });\n return inflight;\n };\n}\n","import {\n AbortError,\n EngineError,\n EngineErrorCode,\n type SerializedEngineError,\n} from '@embedpdf/engine-core/runtime';\nimport {\n applyCdnAccess,\n EngineErrorPayloadSchema,\n type CdnAccessInfoForApply,\n} from '@embedpdf/engine-core/wire';\n\nexport interface HttpClientOptions {\n baseUrl: string;\n /**\n * Optional bearer token. Either a string or a function that\n * returns a fresh token on every call (so callers can rotate\n * without re-creating the engine). When absent, requests go out\n * without an `Authorization` header — useful for the public-share\n * scenario where the doc-scoped token is provided per-`open` and\n * the engine itself has no engine-level credentials.\n */\n token?: string | (() => string | Promise<string>);\n /**\n * Engine-instance session id, sent as `X-Engine-Session-Id` on every\n * request. The server stores it on mutation audit rows so this\n * instance's SSE stream can drop its own echoes (exactly-once events).\n */\n sessionId?: string;\n /** Replace the global fetch (e.g. in Node tests with undici). */\n fetch?: typeof globalThis.fetch;\n}\n\n/**\n * Per-document binding for CDN URL rewriting. `CloudDocumentHandle`\n * calls `setCdnAccess` after `/v1/access` succeeds; the HttpClient\n * then runs every outgoing request through `applyCdnAccess` so\n * granted resources are routed to the CDN with the matching signed\n * query params (or cookies/auth header for the cookie/header\n * adapter modes).\n *\n * Set to `null` when the session is reset or when `/access` was\n * never called (public-share with no CDN configured).\n */\nexport interface CdnBinding {\n readonly cdn: CdnAccessInfoForApply | null;\n readonly docId: string;\n readonly layerName: string;\n}\n\n/**\n * A raw-bytes response plus its headers. The attachment-file leaves carry\n * their metadata as headers (`Content-Type`, `X-EmbedPDF-File-Name`), so\n * unlike `getBytes` the caller needs the `Headers` object back.\n */\nexport interface HttpFileResponse {\n bytes: Uint8Array;\n headers: Headers;\n}\n\nexport class HttpClient {\n private readonly base: string;\n private readonly tokenFn: (() => string | Promise<string>) | null;\n private readonly fetchFn: typeof globalThis.fetch;\n private readonly sessionId: string | null;\n private cdnBinding: CdnBinding | null = null;\n\n constructor(opts: HttpClientOptions) {\n this.base = opts.baseUrl.replace(/\\/$/, '');\n const token = opts.token;\n this.tokenFn = token === undefined ? null : typeof token === 'function' ? token : () => token;\n this.sessionId = opts.sessionId ?? null;\n this.fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n /** Normalized server base URL (no trailing slash). */\n get baseUrl(): string {\n return this.base;\n }\n\n /**\n * The fetch implementation this client sends requests through (injected\n * or global). Exposed so sibling transports spawned per-open — the\n * share-session exchange, most of all — ride the same fetch the engine\n * was configured with (test doubles, SSR `Origin`-attaching wrappers).\n */\n get fetchImpl(): typeof globalThis.fetch {\n return this.fetchFn;\n }\n\n /**\n * Return a clone of this client bound to a different bearer. Used\n * by `CloudEngine.open` to mint a per-handle client carrying the\n * per-open token, so each opened document's RPCs go out under\n * the right authorization without disturbing the engine-level\n * token.\n */\n withToken(token: string | (() => string | Promise<string>)): HttpClient {\n return new HttpClient({\n baseUrl: this.baseUrl,\n token,\n ...(this.sessionId ? { sessionId: this.sessionId } : {}),\n fetch: this.fetchFn,\n });\n }\n\n /**\n * Raw streaming GET (the SSE channel). Same auth/session headers and\n * error mapping as every other request; the caller owns the body stream.\n */\n async stream(\n path: string,\n headers: Record<string, string>,\n signal: AbortSignal,\n ): Promise<Response> {\n return this.request(path, {\n method: 'GET',\n headers: new Headers({ Accept: 'text/event-stream', ...headers }),\n signal,\n });\n }\n\n /**\n * Install (or clear) the per-session CDN binding. Pass `null` to\n * route everything to origin again — useful on session close or\n * when an adapter swap happens mid-session (rare).\n *\n * The HttpClient stays dumb about WHEN to do this; the cloud\n * document handle pushes the binding in after /access succeeds.\n *\n * Side effect: in the browser, signedCookies are written to\n * `document.cookie` once per setCdnAccess call so the CDN edge\n * receives them on subsequent fetches. Node side ignores cookies\n * for now (cookie jar wiring deferred until needed for tests).\n */\n setCdnAccess(binding: CdnBinding | null): void {\n this.cdnBinding = binding;\n if (binding?.cdn?.signedCookies && typeof globalThis.document !== 'undefined') {\n for (const cookie of binding.cdn.signedCookies) {\n const parts = [`${cookie.name}=${cookie.value}`];\n parts.push(`Path=${cookie.path ?? '/'}`);\n if (cookie.domain) parts.push(`Domain=${cookie.domain}`);\n if (cookie.expires) parts.push(`Expires=${new Date(cookie.expires * 1000).toUTCString()}`);\n parts.push('SameSite=None', 'Secure');\n globalThis.document.cookie = parts.join('; ');\n }\n }\n }\n\n /** Current CDN binding (or null). Exposed for diagnostics/tests. */\n get currentCdnBinding(): CdnBinding | null {\n return this.cdnBinding;\n }\n\n absoluteUrl(path: string): string {\n return `${this.baseUrl}${path}`;\n }\n\n async getBlob(path: string, signal: AbortSignal): Promise<Blob> {\n const res = await this.request(path, { method: 'GET', signal });\n if (!res.ok) await this.throwFromBody(res);\n return await res.blob();\n }\n\n async getBytes(path: string, signal: AbortSignal): Promise<Uint8Array> {\n const res = await this.request(path, {\n method: 'GET',\n headers: new Headers({ Accept: 'application/pdf' }),\n signal,\n });\n if (!res.ok) await this.throwFromBody(res);\n return new Uint8Array(await res.arrayBuffer());\n }\n\n /**\n * Resolve the current bearer token. Awaits the user-supplied\n * token factory if it returns a promise. Used by the cloud\n * engine to read doc-scoped claims **without** verifying — the\n * server is the verifier of record. Throws when no token is\n * configured.\n */\n async currentToken(): Promise<string> {\n if (!this.tokenFn) {\n throw new EngineError(EngineErrorCode.InvalidArg, 'http client has no token configured');\n }\n return await this.tokenFn();\n }\n\n async getJson<T>(path: string, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T> {\n const res = await this.request(path, { method: 'GET', signal });\n return await this.parseJsonResponse(res, parser);\n }\n\n /**\n * GET a versioned URL with transparent stale-version recovery. If\n * the server returns 404 (the well-known \"this version is gone\"\n * signal for content-addressed reads), call `onStaleVersion` (which\n * the caller wires to a manifest refresh), then re-resolve `buildPath`\n * and retry the GET exactly once. Any non-404 error propagates.\n *\n * The retry budget is hard-capped at 1: after a refresh, if the\n * server's idea of the current version is still ahead of the\n * client's view, the second request fails normally — this matches\n * the CDN cache invariant (\"a versioned URL's bytes are immutable\n * for its lifetime\").\n */\n async getJsonWithRefresh<T>(\n buildPath: (signal: AbortSignal) => Promise<string>,\n parser: (raw: unknown) => T,\n onStaleVersion: (signal: AbortSignal) => Promise<void>,\n signal: AbortSignal,\n ): Promise<T> {\n const initialPath = await buildPath(signal);\n try {\n return await this.getJson(initialPath, parser, signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n await onStaleVersion(signal);\n const retryPath = await buildPath(signal);\n return await this.getJson(retryPath, parser, signal);\n }\n }\n\n /**\n * GET a `multipart/form-data` body and parse it with the platform's\n * `Response.formData()` (works in browsers and undici). Text parts come\n * back as strings, parts with a filename as `Blob`s.\n */\n async getFormData(path: string, signal: AbortSignal): Promise<FormData> {\n const res = await this.request(path, {\n method: 'GET',\n headers: new Headers({ Accept: 'multipart/form-data' }),\n signal,\n });\n if (!res.ok) await this.throwFromBody(res);\n return await res.formData();\n }\n\n /**\n * `getFormData` with the same single-retry stale-version recovery as\n * {@link getJsonWithRefresh}: a 404 on a versioned URL triggers\n * `onStaleVersion` (a manifest refresh) and one re-resolve + retry.\n */\n async getFormDataWithRefresh(\n buildPath: (signal: AbortSignal) => Promise<string>,\n onStaleVersion: (signal: AbortSignal) => Promise<void>,\n signal: AbortSignal,\n ): Promise<FormData> {\n const initialPath = await buildPath(signal);\n try {\n return await this.getFormData(initialPath, signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n await onStaleVersion(signal);\n const retryPath = await buildPath(signal);\n return await this.getFormData(retryPath, signal);\n }\n }\n\n /**\n * `getBlob` with the same single-retry stale-version recovery as\n * {@link getJsonWithRefresh}: a 404 on a versioned URL triggers\n * `onStaleVersion` (a manifest refresh) and one re-resolve + retry.\n * Render blobs ride this rail: a scope flip re-resolves the\n * doc-vs-layer path family instead of failing on a stale URL.\n */\n async getBlobWithRefresh(\n buildPath: (signal: AbortSignal) => Promise<string>,\n onStaleVersion: (signal: AbortSignal) => Promise<void>,\n signal: AbortSignal,\n ): Promise<Blob> {\n const initialPath = await buildPath(signal);\n try {\n return await this.getBlob(initialPath, signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n await onStaleVersion(signal);\n const retryPath = await buildPath(signal);\n return await this.getBlob(retryPath, signal);\n }\n }\n\n /** GET raw bytes plus the response headers (attachment-file leaves). */\n async getFile(path: string, signal: AbortSignal): Promise<HttpFileResponse> {\n const res = await this.request(path, { method: 'GET', signal });\n if (!res.ok) await this.throwFromBody(res);\n return { bytes: new Uint8Array(await res.arrayBuffer()), headers: res.headers };\n }\n\n /**\n * `getFile` with the same single-retry stale-version recovery as\n * {@link getJsonWithRefresh}: a 404 on a versioned URL triggers\n * `onStaleVersion` (a manifest refresh) and one re-resolve + retry.\n */\n async getFileWithRefresh(\n buildPath: (signal: AbortSignal) => Promise<string>,\n onStaleVersion: (signal: AbortSignal) => Promise<void>,\n signal: AbortSignal,\n ): Promise<HttpFileResponse> {\n const initialPath = await buildPath(signal);\n try {\n return await this.getFile(initialPath, signal);\n } catch (err) {\n if (!EngineError.is(err, EngineErrorCode.NotFound)) throw err;\n await onStaleVersion(signal);\n const retryPath = await buildPath(signal);\n return await this.getFile(retryPath, signal);\n }\n }\n\n async postMultipartJson<T>(\n path: string,\n body: FormData,\n parser: (raw: unknown) => T,\n signal: AbortSignal,\n ): Promise<T> {\n const res = await this.request(path, { method: 'POST', body, signal });\n return await this.parseJsonResponse(res, parser);\n }\n\n /** PATCH counterpart of {@link postMultipartJson} (binary-carrying mutations). */\n async patchMultipartJson<T>(\n path: string,\n body: FormData,\n parser: (raw: unknown) => T,\n signal: AbortSignal,\n ): Promise<T> {\n const res = await this.request(path, { method: 'PATCH', body, signal });\n return await this.parseJsonResponse(res, parser);\n }\n\n async postJson<T>(\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n signal: AbortSignal,\n ): Promise<T> {\n const res = await this.requestJson(path, 'POST', body, signal);\n return await this.parseJsonResponse(res, parser);\n }\n\n /** POST a raw binary body (FDF/XFDF import) and parse the JSON response. */\n async postBytesJson<T>(\n path: string,\n bytes: Uint8Array,\n contentType: string,\n parser: (raw: unknown) => T,\n signal: AbortSignal,\n ): Promise<T> {\n const headers = new Headers({ 'Content-Type': contentType });\n // Copy into a fresh ArrayBuffer: `bytes` may be a view over a larger\n // (or SharedArrayBuffer-backed) buffer, which fetch bodies reject.\n const body = new Uint8Array(bytes).buffer as ArrayBuffer;\n const res = await this.request(path, { method: 'POST', body, headers, signal });\n return await this.parseJsonResponse(res, parser);\n }\n\n async patchJson<T>(\n path: string,\n body: unknown,\n parser: (raw: unknown) => T,\n signal: AbortSignal,\n ): Promise<T> {\n const res = await this.requestJson(path, 'PATCH', body, signal);\n return await this.parseJsonResponse(res, parser);\n }\n\n async deleteJson<T>(path: string, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T> {\n const res = await this.request(path, { method: 'DELETE', signal });\n return await this.parseJsonResponse(res, parser);\n }\n\n async deleteEmpty(path: string, signal: AbortSignal): Promise<void> {\n const res = await this.request(path, { method: 'DELETE', signal });\n if (res.status === 204) return;\n if (!res.ok) await this.throwFromBody(res);\n }\n\n async postEmpty(path: string, body: unknown, signal: AbortSignal): Promise<void> {\n const res = await this.requestJson(path, 'POST', body, signal);\n if (res.status === 204) return;\n if (!res.ok) await this.throwFromBody(res);\n }\n\n private requestJson(\n path: string,\n method: 'POST' | 'PATCH' | 'PUT',\n body: unknown,\n signal: AbortSignal,\n ): Promise<Response> {\n const headers = new Headers({ 'Content-Type': 'application/json' });\n return this.request(path, {\n method,\n body: JSON.stringify(body ?? {}),\n headers,\n signal,\n });\n }\n\n private async request(path: string, init: RequestInit): Promise<Response> {\n const { url, extraHeader } = this.resolveOutgoing(path);\n const headers = new Headers(init.headers ?? {});\n if (this.tokenFn) {\n const token = await this.tokenFn();\n headers.set('Authorization', `Bearer ${token}`);\n }\n if (!headers.has('Accept')) headers.set('Accept', 'application/json');\n if (this.sessionId) headers.set('X-Engine-Session-Id', this.sessionId);\n if (extraHeader) headers.set(extraHeader.name, extraHeader.value);\n try {\n return await this.fetchFn(url, { ...init, headers });\n } catch (err) {\n // undici's fetch propagates whatever was passed to AbortController.abort().\n // Anything that arrives while signal.aborted is true is an abort, regardless\n // of the wire-shape (DOMException, plain Error, string, ...).\n if (init.signal?.aborted) {\n throw new AbortError(init.signal.reason ?? err);\n }\n if ((err as { name?: string } | null)?.name === 'AbortError') {\n throw new AbortError((err as Error).message);\n }\n throw new EngineError(\n EngineErrorCode.Network,\n `network error: ${(err as Error)?.message ?? err}`,\n {\n cause: err,\n },\n );\n }\n }\n\n private async parseJsonResponse<T>(res: Response, parser: (raw: unknown) => T): Promise<T> {\n if (!res.ok) await this.throwFromBody(res);\n const json: unknown = await res.json().catch(() => ({}));\n try {\n return parser(json);\n } catch (err) {\n throw new EngineError(\n EngineErrorCode.WireFormat,\n `unexpected response shape: ${(err as Error)?.message ?? err}`,\n {\n cause: err,\n },\n );\n }\n }\n\n /**\n * Decide where this request actually goes. With no CDN binding (or\n * binding's `cdn` is null) every request stays on origin. Otherwise\n * `applyCdnAccess` decides per-request based on the resource the\n * path resolves to (and whether the caller's scope granted CDN\n * access to it).\n */\n private resolveOutgoing(path: string): {\n url: string;\n extraHeader: { name: string; value: string } | null;\n } {\n if (!this.cdnBinding || !this.cdnBinding.cdn) {\n return { url: `${this.baseUrl}${path}`, extraHeader: null };\n }\n const applied = applyCdnAccess({\n path,\n originUrl: this.baseUrl,\n docId: this.cdnBinding.docId,\n layerName: this.cdnBinding.layerName,\n cdn: this.cdnBinding.cdn,\n });\n return {\n url: applied.url,\n extraHeader: applied.routedToCdn && applied.authHeader ? applied.authHeader : null,\n };\n }\n\n private async throwFromBody(res: Response): Promise<never> {\n let payload: unknown;\n try {\n payload = await res.json();\n } catch {\n payload = null;\n }\n const code = mapStatusToCode(res.status);\n if (payload && typeof payload === 'object' && 'error' in payload) {\n const inner = (payload as { error: unknown }).error;\n const parsed = trySerialized(inner);\n if (parsed) throw new EngineError(parsed.code, parsed.message, { details: parsed.details });\n const msg =\n typeof inner === 'object' && inner && 'message' in inner\n ? String((inner as { message: unknown }).message)\n : `HTTP ${res.status}`;\n throw new EngineError(code, msg, { details: { status: res.status } });\n }\n throw new EngineError(code, `HTTP ${res.status}`, { details: { status: res.status } });\n }\n}\n\nfunction mapStatusToCode(status: number): EngineErrorCode {\n if (status === 401) return EngineErrorCode.Unauthenticated;\n if (status === 403) return EngineErrorCode.Forbidden;\n if (status === 409) return EngineErrorCode.WeakAnnotationSessionConflict;\n if (status === 404) return EngineErrorCode.NotFound;\n if (status === 422) return EngineErrorCode.DocOpenFailed;\n if (status === 499) return EngineErrorCode.Aborted;\n if (status === 400) return EngineErrorCode.InvalidArg;\n return EngineErrorCode.Unknown;\n}\n\nfunction trySerialized(value: unknown): SerializedEngineError | null {\n const result = EngineErrorPayloadSchema.safeParse(value);\n return result.success ? result.data : null;\n}\n","import {\n AbortablePromise,\n EngineError,\n EngineErrorCode,\n type DocumentHandle,\n type Engine,\n type OpenInput,\n type OpenOptions,\n} from '@embedpdf/engine-core/runtime';\nimport { DEFAULT_LAYER_NAME, DocumentHeadSchema, wirePaths } from '@embedpdf/engine-core/wire';\nimport { generateUuid } from '@embedpdf/engine-services';\n\nimport { CloudDocumentHandle } from './document/CloudDocumentHandle';\nimport { CloudDocumentSecurityService } from './document/CloudDocumentSecurityService';\nimport { engineErrorFromShareExchange, ShareExchangeError, shareSessionSource } from './share';\nimport { decodeUnverifiedClaims } from './transport/decodeUnverifiedClaims';\nimport { HttpClient, type HttpClientOptions } from './transport/HttpClient';\n\nexport interface CloudEngineOptions extends HttpClientOptions {}\n\n/**\n * Cloud engine: speaks the same Engine interface as @embedpdf/engine\n * but routes everything through HTTPS to a remote @cloudpdf/server (or\n * CloudPDF SaaS). Identical observable contract; only the transport differs.\n */\nexport class CloudEngine implements Engine {\n static fromOptions(opts: CloudEngineOptions): CloudEngine {\n // One identity per engine instance: it stamps local events' origins AND\n // travels as X-Engine-Session-Id so the server can mark this instance's\n // audit rows — the SSE stream drops those echoes (exactly-once events).\n const sessionId = `cloud:${generateUuid()}`;\n return new CloudEngine(new HttpClient({ ...opts, sessionId }), sessionId);\n }\n\n private destroyed = false;\n\n private constructor(\n private readonly http: HttpClient,\n /** This engine instance's identity on every event's `origin.sessionId`. */\n private readonly sessionId: string,\n ) {}\n\n open(input: OpenInput, options?: OpenOptions): AbortablePromise<DocumentHandle> {\n if (this.destroyed) {\n return AbortablePromise.rejectReason(\n new EngineError(EngineErrorCode.RuntimeUnavailable, 'engine destroyed'),\n );\n }\n // Cloud reads scope + identity from the doc-scoped JWT — `options.scope`\n // and `options.identity` are engine-local concepts and are intentionally\n // ignored here. Same `OpenOptions` type for both engines is what makes\n // SDK code portable; the JWT is the authority cloud-side.\n void options?.scope;\n void options?.identity;\n\n // Presence-based precedence, same rule the local engine documents: an\n // options.password key wins (even explicitly null), else input.password.\n // For 'share' inputs `input.password` is still the PDF password — the\n // grant passphrase travels separately as `input.sharePassword`.\n const effectivePassword =\n options && 'password' in options ? (options.password ?? null) : (input.password ?? null);\n\n if (input.kind === 'share') {\n // Open by public share token: exchange `shr_…` for a short-lived\n // doc-scoped session JWT, then delegate to the 'token' arm — the\n // handle binds to a SELF-RENEWING source, so revoking or editing\n // the share retargets this open at the next renewal. The exchange\n // rides the engine's own transport config (baseUrl + fetch);\n // exchange failures surface as EngineErrors on open AND on every\n // later renewal (RPCs, SSE reconnects), never as raw\n // ShareExchangeErrors.\n const raw = shareSessionSource(this.http.baseUrl, input.shareToken, {\n ...(input.sharePassword !== undefined ? { password: input.sharePassword } : {}),\n fetch: this.http.fetchImpl,\n });\n const token = async () => {\n try {\n return await raw();\n } catch (error) {\n throw error instanceof ShareExchangeError ? engineErrorFromShareExchange(error) : error;\n }\n };\n return this.open({ kind: 'token', token, password: input.password ?? null }, options);\n }\n\n if (input.kind === 'token') {\n // Open by doc-scoped JWT. We never verify the token SDK-side\n // (server is the verifier of record); we just decode the\n // unsigned payload to learn `doc_id`, then route to /head with\n // the per-open bearer. The resulting handle owns its own\n // scoped HttpClient — every subsequent RPC carries this\n // token, NOT the engine-level one, so one engine can hold\n // many handles each with a different bearer.\n const tokenSource = input.token;\n return AbortablePromise.run<DocumentHandle>(async (signal) => {\n const docHttp = this.http.withToken(tokenSource);\n const token = await docHttp.currentToken();\n const claims = decodeUnverifiedClaims(token);\n const docId = claims.doc_id;\n if (typeof docId !== 'string' || docId.length === 0) {\n throw new EngineError(\n EngineErrorCode.InvalidArg,\n 'cloud engine: token has no doc_id claim — mint a doc-scoped JWT',\n );\n }\n const layerName =\n typeof claims.layer_name === 'string' && claims.layer_name.length > 0\n ? claims.layer_name\n : DEFAULT_LAYER_NAME;\n const head = await docHttp.getJson(\n wirePaths.layerHead(docId, layerName),\n (raw) => DocumentHeadSchema.parse(raw),\n signal,\n );\n const handle = new CloudDocumentHandle(\n docHttp,\n head.id,\n layerName,\n head,\n token,\n this.sessionId,\n );\n await maybeAutoEstablishAccess(handle, head, signal, effectivePassword);\n return handle;\n });\n }\n\n if (input.kind === 'id') {\n // Open by docId using the engine-level token (typical: a\n // tenant JWT). The caller can override per-open by setting\n // `input.token`; the resulting handle then carries that\n // override for all of its RPCs.\n const id = input.id;\n const docHttp = input.token ? this.http.withToken(input.token) : this.http;\n return AbortablePromise.run<DocumentHandle>(async (signal) => {\n let layerName = input.layerName ?? DEFAULT_LAYER_NAME;\n // Resolve the bearer once so we have it for the layer-name\n // claim AND for the security service's local-fallback scope/\n // identity. May be null when the engine has no token at all\n // (caller invokes /head anonymously — server will reject).\n let resolvedToken: string | null = null;\n try {\n resolvedToken = await docHttp.currentToken();\n } catch {\n resolvedToken = null;\n }\n if (!input.layerName && resolvedToken) {\n const claims = decodeUnverifiedClaims(resolvedToken);\n if (typeof claims.layer_name === 'string' && claims.layer_name.length > 0) {\n layerName = claims.layer_name;\n }\n }\n const head = await docHttp.getJson(\n wirePaths.layerHead(id, layerName),\n (raw) => DocumentHeadSchema.parse(raw),\n signal,\n );\n const handle = new CloudDocumentHandle(\n docHttp,\n head.id,\n layerName,\n head,\n resolvedToken,\n this.sessionId,\n );\n await maybeAutoEstablishAccess(handle, head, signal, effectivePassword);\n return handle;\n });\n }\n\n void options;\n return AbortablePromise.rejectReason(\n new EngineError(\n EngineErrorCode.InvalidArg,\n `cloud engine supports OpenInput.kind === 'token', 'id', or 'share' (got '${(input as { kind?: string }).kind}')`,\n ),\n );\n }\n\n destroy(): AbortablePromise<void> {\n if (this.destroyed) return AbortablePromise.resolveValue<void>(undefined);\n this.destroyed = true;\n return AbortablePromise.resolveValue<void>(undefined);\n }\n}\n\n/**\n * Post-/head access establishment, in two layers:\n *\n * 1. **Supplied password** — a password given at open is always TRIED\n * (PDFium parity: the local engine feeds it to the loader no matter\n * what). Two triggers, because `/head` only carries the `password`\n * reason when a password is needed to READ:\n * - `reasons` has `'password'` → required-to-read case\n * - `head.permissions.canUpgradeToOwner` → permission-only encrypted\n * doc; the password can still upgrade to owner. Skipping this arm\n * would silently drop supplied OWNER passwords — and diverge from\n * the local engine on identical input.\n * Outcomes follow \"a password failure may only block what the password\n * was needed for\": a rejection in the required case leaves the handle\n * locked (the caller's prompt takes over, showing \"incorrect\"); in the\n * upgrade case the document stays readable and the failure is\n * non-fatal. The one /access POST also installs the CDN binding, so a\n * successful unlock covers the `password + cdn` combined case.\n *\n * 2. **CDN-only** — unchanged: `/access` without a password, transparently.\n * A required password with NO supplied password never auto-calls; the\n * dev prompts and `unlock()` runs the same POST.\n *\n * Non-password /access failures never break `open()` (the first real\n * request still tries origin, where the JWT check produces a regular\n * Forbidden) — but they are also never mistaken for a wrong password:\n * only a DocPasswordRequired/Incorrect rejection means \"wrong password\".\n */\nasync function maybeAutoEstablishAccess(\n handle: CloudDocumentHandle,\n head: {\n access: { required: boolean; reasons: ReadonlyArray<string> };\n permissions: { canUpgradeToOwner: boolean };\n },\n signal: AbortSignal,\n password: string | null,\n): Promise<void> {\n const reasons = new Set(head.access.reasons);\n // CloudDocumentSecurityService exposes `establishAccess()` — the\n // no-password sibling of `unlock()`. The public DocumentSecurityService\n // interface doesn't carry it (unlock = user action), but every\n // CloudDocumentHandle's `.security` is a CloudDocumentSecurityService.\n const security = handle.security as CloudDocumentSecurityService;\n\n const tryPassword =\n password != null && (reasons.has('password') || head.permissions.canUpgradeToOwner);\n if (tryPassword) {\n const unlocked = await settleLinked(security.unlock({ password, mode: 'any' }), signal);\n if (unlocked) return; // /access succeeded — CDN binding installed too\n // Rejected or failed: in the required case the handle stays locked and\n // the caller's password prompt takes over (retrying re-POSTs /access);\n // in the upgrade case the document is readable regardless — fall\n // through so a CDN-only establishment still happens.\n if (reasons.has('password')) return;\n }\n\n if (!head.access.required) return;\n if (reasons.has('password')) return; // wait for explicit unlock()\n if (!reasons.has('cdn')) return; // nothing actionable for the SDK\n await settleLinked(security.establishAccess(), signal);\n}\n\n/** Await an /access attempt with open()-abort linkage. Returns whether it\n * succeeded; failures are contained (see maybeAutoEstablishAccess). */\nasync function settleLinked(\n pending: ReturnType<CloudDocumentSecurityService['unlock']>,\n signal: AbortSignal,\n): Promise<boolean> {\n const onAbort = () => pending.abort(signal.reason ?? new Error('aborted'));\n if (signal.aborted) onAbort();\n else signal.addEventListener('abort', onAbort, { once: true });\n try {\n await pending;\n return true;\n } catch {\n return false;\n } finally {\n signal.removeEventListener('abort', onAbort);\n }\n}\n","/**\n * @cloudpdf/engine - Engine v3 cloud client.\n *\n * Implements the same {@link Engine} interface as `@embedpdf/engine` but\n * routes calls to a remote `@cloudpdf/server` over HTTP. Same observable\n * contract: {@link AbortablePromise}-based, EngineError-coded, parity-tested\n * with `runMetadataConformance`.\n */\nexport { CloudEngine } from './CloudEngine';\nexport type { CloudEngineOptions } from './CloudEngine';\nexport { CloudDocumentHandle } from './document/CloudDocumentHandle';\nexport { CloudMetadataService } from './document/CloudMetadataService';\nexport { CloudDocumentAnnotationsService } from './document/CloudDocumentAnnotationsService';\nexport { CloudDocumentPagesService } from './document/CloudDocumentPagesService';\nexport { CloudPageHandle } from './document/CloudPageHandle';\nexport { CloudPageAnnotationsService } from './document/CloudPageAnnotationsService';\nexport { CloudPageGeometryService } from './document/CloudPageGeometryService';\nexport { CloudPageRenderService } from './document/CloudPageRenderService';\nexport { HttpClient } from './transport/HttpClient';\nexport type { HttpClientOptions } from './transport/HttpClient';\nexport { decodeUnverifiedClaims } from './transport/decodeUnverifiedClaims';\nexport type { UnverifiedClaims } from './transport/decodeUnverifiedClaims';\nexport {\n exchangeShareToken,\n shareSessionSource,\n ShareExchangeError,\n engineErrorFromShareExchange,\n} from './share';\nexport type { ShareSession, ShareExchangeOptions } from './share';\n\nimport { CloudEngine, type CloudEngineOptions } from './CloudEngine';\n\nexport function createCloudEngine(opts: CloudEngineOptions): CloudEngine {\n return CloudEngine.fromOptions(opts);\n}\n\n/**\n * Create a cloud {@link CloudEngine} — the drop-in counterpart of\n * `localEngine()`, so swapping local for cloud is a one-import change.\n *\n * Synchronous and cheap: no WASM to compile, no worker to spawn — the engine\n * holds an HTTP client and nothing else. Like `localEngine()`, the returned\n * instance is yours (call `destroy()` when done, usually never for a\n * module-scope singleton); pass a thunk (`engine={() => cloudEngine(...)}`)\n * to let a `<Viewer>` own the lifetime instead.\n *\n * Note the deliberate asymmetry with `localEngine()`: there is no `fonts`\n * option. Fallback fonts are a SERVER policy on the cloud (`Engine.fonts` is\n * `undefined` cloud-side), so they cannot be configured from the client. This\n * is the local-vs-cloud split, surfaced in the API.\n *\n * ```ts\n * const engine = cloudEngine({ baseUrl: 'https://pdf.example.com', token });\n * <Viewer engine={engine} plugins={[stagePlugin(), renderPlugin()]} />\n * ```\n */\nexport function cloudEngine(opts: CloudEngineOptions): CloudEngine {\n return CloudEngine.fromOptions(opts);\n}\n\n// Re-export the shared engine runtime surface so consumers import every\n// public type and primitive from a single `@cloudpdf/engine` entrypoint\n// instead of reaching into the transitive `@embedpdf/engine-core` dep.\nexport {\n AbortablePromise,\n AbortError,\n EngineError,\n EngineErrorCode,\n} from '@embedpdf/engine-core/runtime';\nexport type {\n Engine,\n EngineFactory,\n DocumentHandle,\n DocumentCapabilities,\n PageHandle,\n OpenInput,\n OpenInputShare,\n OpenOptions,\n TokenSource,\n MetadataService,\n DocumentPagesService,\n DocumentAnnotationsService,\n PageAnnotationsService,\n PageTextService,\n PageGeometryService,\n PageRenderService,\n DocumentSecurityService,\n DocumentSecurityState,\n DocumentUnlockInput,\n DocumentUnlockResult,\n DocumentAccessInfo,\n DocumentIdentity,\n PdfSaveMode,\n} from '@embedpdf/engine-core/runtime';\n"],"mappings":";;;;;;;;;;;;;;AAWA,SAAgB,gBACd,UACA,QACS;CACT,MAAM,SAAS,SAAS;CACxB,IAAI,CAAC,QAAQ,OAAO;CACpB,OAAO,OAAO,OAAO,UAAU,OAAO,WAAW,MAAM;AACzD;;;ACLA,IAAa,8BAAb,MAA2E;CACzE,YACE,MACA,OACA,WACA,UACA,UACA;EALiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;CAChB;CAEH,OAAkD;EAChD,IAAI,KAAK,SAAS,GAChB,OAAOA,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,KAAK,WAC3B,KAAK,KAAK,mBACR,OAAO,kBAAkB;GACvB,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,aAAa;GAItD,OAAO,gBAAgB,UAAU,CAAC,SAAS,CAAC,IACxCG,2BAAAA,UAAU,WAAW,KAAK,OAAO,SAAS,cAAc,IACxDA,2BAAAA,UAAU,aAAa,KAAK,OAAO,KAAK,WAAW,SAAS,cAAc;EAChF,IACC,QAAQC,2BAAAA,8BAA8B,MAAM,GAAG,GAChD,OAAO,kBAAkB;GACvB,MAAM,KAAK,SAAS,QAAQ,aAAa;EAC3C,GACA,MACF,CACF;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3BA,IAAa,kCAAb,MAAmF;CACjF,YACE,MACA,OACA,WACA,UACA,UACA;EALiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;CAChB;CAEH,aAA+D;EAC7D,IAAI,KAAK,SAAS,GAChB,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAoC,OAAO,WAAW;GAC5E,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,MAAM;GAI/C,OAAO,EAAE,OAAA,MAHW,QAAQ,IAC1B,SAAS,MAAM,KAAK,SAAS,KAAK,gBAAgB,KAAK,MAAM,kBAAkB,MAAM,CAAC,CACxF,EACe;EACjB,CAAC;CACH;CAEA,QAAQ,kBAAkF;EACxF,IAAI,KAAK,SAAS,GAChB,OAAOA,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,KAAiC,WACvD,KAAK,gBAAgB,kBAAkB,MAAM,CAC/C;CACF;CAEA,cACE,mBAC6C;EAC7C,IAAI,KAAK,SAAS,GAChB,OAAOA,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAA+B,OAAO,WAAW;GACvE,MAAM,WAAW,MAAM,KAAK,KAAK,SAC/BG,2BAAAA,UAAU,2BAA2B,KAAK,OAAO,KAAK,SAAS,GAC/D,EAAE,kBAAkB,IACnB,QAAQC,2BAAAA,oCAAoC,MAAM,GAAG,GACtD,MACF;GACA,OAAO,IAAI,+BACT,KAAK,MACL,KAAK,OACL,KAAK,iBACC,KAAK,SAAS,GACpB,QACF;EACF,CAAC;CACH;CAEA,MAAc,gBACZ,kBACA,QACqC;EACrC,OAAO,KAAK,KAAK,QACfD,2BAAAA,UAAU,4BAA4B,KAAK,OAAO,KAAK,WAAW,gBAAgB,IACjF,QAAQE,2BAAAA,iCAAiC,MAAM,GAAG,GACnD,MACF;CACF;AACF;AAEA,IAAM,iCAAN,MAA0E;CAIxE,YACE,MACA,OACA,WACA,UACA,UACA;EALiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,WAAA;EAPX,gBAAA,MAAA,YAAA,KAAA,CAAA;EACA,gBAAA,MAAA,YAAW,KAAA;EASjB,KAAK,WAAW;CAClB;CAEA,IAAI,KAAa;EACf,OAAO,KAAK,SAAS;CACvB;CAEA,IAAI,YAAoB;EACtB,OAAO,KAAK,SAAS;CACvB;CAEA,IAAI,sBAA8B;EAChC,OAAO,KAAK,SAAS;CACvB;CAEA,IAAI,oBAAiD;EACnD,OAAO,KAAK,SAAS;CACvB;CAEA,OAAO,kBAA6C;EAClD,OAAO,KAAK,SAAS,kBAAkB,SAAS,gBAAgB;CAClE;CAEA,YAAY,mBAAwE;EAClF,IAAI,KAAK,SAAS,KAAK,KAAK,UAC1B,OAAOL,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,2BAA2B,KAAK,GAAG,WAAW,CAC5F;EAEF,OAAOF,8BAAAA,iBAAiB,IAAU,OAAO,WAAW;GAClD,KAAK,WAAW,MAAM,KAAK,KAAK,SAC9BG,2BAAAA,UAAU,gCAAgC,KAAK,OAAO,KAAK,WAAW,KAAK,EAAE,GAC7E,EAAE,kBAAkB,IACnB,QAAQC,2BAAAA,oCAAoC,MAAM,GAAG,GACtD,MACF;EACF,CAAC;CACH;CAEA,YAAoC;EAClC,IAAI,KAAK,SAAS,KAAK,KAAK,UAC1B,OAAOJ,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,2BAA2B,KAAK,GAAG,WAAW,CAC5F;EAEF,OAAOF,8BAAAA,iBAAiB,IAAU,OAAO,WAAW;GAClD,KAAK,WAAW,MAAM,KAAK,KAAK,SAC9BG,2BAAAA,UAAU,oCAAoC,KAAK,OAAO,KAAK,WAAW,KAAK,EAAE,GACjF,CAAC,IACA,QAAQC,2BAAAA,oCAAoC,MAAM,GAAG,GACtD,MACF;EACF,CAAC;CACH;CAEA,UAAkC;EAChC,IAAI,KAAK,UACP,OAAOJ,8BAAAA,iBAAiB,aAAa,KAAA,CAAS;EAEhD,KAAK,WAAW;EAChB,OAAOA,8BAAAA,iBAAiB,KAAW,WACjC,KAAK,KAAK,YACRG,2BAAAA,UAAU,kCAAkC,KAAK,OAAO,KAAK,WAAW,KAAK,EAAE,GAC/E,MACF,CACF;CACF;AACF;;;;;;;;;;;;AC/JA,SAAgB,kBAAkB,MAAe,WAAsC;CACrF,MAAM,OAAO,IAAI,SAAS;CAC1B,KAAK,OAAO,QAAQ,KAAK,UAAU,IAAI,CAAC;CACxC,KAAK,MAAM,CAAC,KAAK,aAAa,OAAO,QAAQ,SAAS,GACpD,KAAK,OACH,YAAY,OACZ,IAAI,KAAK,CAAC,SAAS,KAAK,GAAG,EAAE,MAAM,SAAS,YAAY,2BAA2B,CAAC,GACpF,SAAS,QAAQ,GACnB;CAEF,OAAO;AACT;AAEA,SAAgB,aAAa,WAAqC;CAChE,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,SAAS;AACzC;;;;;ACfA,MAAM,mBAAmB;;;;;;;;;AAUzB,SAAgB,uBAAuB,MAA2C;CAChF,MAAM,cAAc,KAAK,QAAQ,IAAI,gBAAgB;CACrD,IAAI,gBAAgB,MAClB,MAAM,IAAIG,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,+BAA+B,iBAAiB,QAClD;CAEF,IAAI;CACJ,IAAI;EACF,QAAA,GAAA,2BAAA,gBAAA,CAAuB,WAAW;CACpC,SAAS,KAAK;EACZ,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,aAAa,iBAAiB,WAAY,KAAe,WAAW,OACpE,EAAE,OAAO,IAAI,CACf;CACF;CACA,MAAM,WAAW,KAAK,QAAQ,IAAI,cAAc;CAChD,OAAO;EACL,OAAO,KAAK;EACZ;EACA,GAAI,aAAa,OAAO,EAAE,SAAS,IAAI,CAAC;CAC1C;AACF;;;;ACjBA,MAAM,yBAAyBC,2BAAAA,uBAAuB,MAAM;;;;;;;;;;AAW5D,IAAa,kCAAb,MAAmF;CACjF,YACE,MACA,OACA,WACA,UACA,UACA,WACA;EANiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;EACA,KAAA,YAAA;CAChB;;;;;;;;CASH,OAA6C;EAC3C,IAAI,KAAK,SAAS,GAChB,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAwB,OAAO,WAAW;GAChE,MAAM,YAAY,OAAO,MAAoC;IAC3D,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,CAAC;IAI1C,OAAO,gBAAgB,UAAU,CAAC,aAAa,CAAC,IAC5CG,2BAAAA,UAAU,eAAe,KAAK,OAAO,SAAS,kBAAkB,IAChEA,2BAAAA,UAAU,iBAAiB,KAAK,OAAO,KAAK,WAAW,SAAS,kBAAkB;GACxF;GACA,OAAO,KAAK,KAAK,mBACf,YACC,QAAQ,uBAAuB,MAAM,GAAG,GACzC,OAAO,MAAM;IACX,MAAM,KAAK,SAAS,QAAQ,CAAC;GAC/B,GACA,MACF;EACF,CAAC;CACH;;;;;;;CAQA,SAAS,KAA2D;EAClE,IAAI,KAAK,SAAS,GAChB,OAAOH,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAuB,OAAO,WAAW;GAC/D,MAAM,YAAY,OAAO,MAAoC;IAC3D,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,CAAC;IAE1C,OAAO,gBAAgB,UAAU,CAAC,aAAa,CAAC,IAC5CG,2BAAAA,UAAU,kBAAkB,KAAK,OAAO,IAAI,KAAK,SAAS,kBAAkB,IAC5EA,2BAAAA,UAAU,oBACR,KAAK,OACL,KAAK,WACL,IAAI,KACJ,SAAS,kBACX;GACN;GAQA,OAAO,uBAAuB,MAPX,KAAK,KAAK,mBAC3B,WACA,OAAO,MAAM;IACX,MAAM,KAAK,SAAS,QAAQ,CAAC;GAC/B,GACA,MACF,CACkC;EACpC,CAAC;CACH;;;;;;;CAQA,OAAO,MAAsE;EAC3E,IAAI,KAAK,SAAS,GAChB,OAAOH,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAA4B,OAAO,WAAW;GACpE,MAAM,EAAE,UAAU,aAAa,OAAA,GAAA,8BAAA,8BAAA,CAAoC,MAAM,IAAI;GAC7E,MAAM,SAAS,MAAM,KAAK,KAAK,kBAC7BG,2BAAAA,UAAU,2BAA2B,KAAK,OAAO,KAAK,SAAS,GAC/D,kBAAkB,UAAU,EAAE,IAAI,SAAS,CAAC,IAC3C,QAAQC,2BAAAA,6BAA6B,MAAM,GAAG,GAC/C,MACF;GAMA,IAAI,OAAO,OAAO,KAAK,SAAS,iBAAiB,OAAO,KAAK;GAC7D,KAAK,UAAU,aAAa;IAAE,MAAM;IAAsB,GAAG;GAAO,CAAC;GACrE,OAAO;EACT,CAAC;CACH;;CAGA,OAAO,KAAgE;EACrE,IAAI,KAAK,SAAS,GAChB,OAAOJ,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAA4B,OAAO,WAAW;GACpE,MAAM,SAAS,MAAM,KAAK,KAAK,WAC7BG,2BAAAA,UAAU,oBAAoB,KAAK,OAAO,KAAK,WAAW,IAAI,GAAG,IAChE,QAAQE,2BAAAA,6BAA6B,MAAM,GAAG,GAC/C,MACF;GAEA,IAAI,OAAO,OAAO,KAAK,SAAS,iBAAiB,OAAO,KAAK;GAC7D,KAAK,UAAU,aAAa;IAAE,MAAM;IAAsB,GAAG;GAAO,CAAC;GACrE,OAAO;EACT,CAAC;CACH;AACF;;;;;ACzHA,MAAM,sBAAsD;CAC1D,KAAK;CACL,MAAM;AACR;;;;;;;;;;;;AAaA,IAAa,4BAAb,MAAuE;CACrE,YACE,MACA,OACA,WACA,UACA,UACA,WACA;EANiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;EACA,KAAA,YAAA;CAChB;CAEH,OAAuC;EACrC,MAAM,WAAW,KAAK,eAA6B;EACnD,IAAI,UAAU,OAAO;EACrB,OAAOC,8BAAAA,iBAAiB,KAAmB,WACzC,KAAK,KAAK,QACRC,2BAAAA,UAAU,UAAU,KAAK,OAAO,KAAK,SAAS,IAC7C,QAAQC,2BAAAA,mBAAmB,MAAM,GAAG,GACrC,MACF,CACF;CACF;CAEA,IAAI,KAAmD;EACrD,MAAM,WAAW,KAAK,eAA6B;EACnD,IAAI,UAAU,OAAO;EACrB,OAAOF,8BAAAA,iBAAiB,KAAmB,WACzC,KAAK,KAAK,QACRC,2BAAAA,UAAU,oBAAoB,KAAK,OAAO,KAAK,YAAA,GAAA,8BAAA,kBAAA,CAA6B,GAAG,CAAC,IAC/E,QAAQE,2BAAAA,mBAAmB,MAAM,GAAG,GACrC,MACF,CACF;CACF;CAEA,SAAS,KAAmB,OAA6D;EACvF,MAAM,WAAW,KAAK,eAAmC;EACzD,IAAI,UAAU,OAAO;EACrB,OAAOH,8BAAAA,iBAAiB,IAAwB,OAAO,WAAW;GAChE,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BC,2BAAAA,UAAU,oBAAoB,KAAK,OAAO,KAAK,YAAA,GAAA,8BAAA,kBAAA,CAA6B,GAAG,CAAC,GAChF,EAAE,MAAM,IACP,QAAQG,2BAAAA,yBAAyB,MAAM,GAAG,GAC3C,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,mBAAmB;EACxD,CAAC;CACH;CAEA,MAAM,KAAyD;EAC7D,MAAM,WAAW,KAAK,eAAmC;EACzD,IAAI,UAAU,OAAO;EACrB,OAAOJ,8BAAAA,iBAAiB,IAAwB,OAAO,WAAW;GAChE,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BC,2BAAAA,UAAU,oBAAoB,KAAK,OAAO,KAAK,YAAA,GAAA,8BAAA,kBAAA,CAA6B,GAAG,CAAC,GAChF,CAAC,IACA,QAAQG,2BAAAA,yBAAyB,MAAM,GAAG,GAC3C,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,mBAAmB;EACxD,CAAC;CACH;CAEA,aAAa,SAA4D;EACvE,MAAM,WAAW,KAAK,eAAkC;EACxD,IAAI,UAAU,OAAO;EACrB,OAAOJ,8BAAAA,iBAAiB,IAAuB,OAAO,WAAW;GAC/D,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BC,2BAAAA,UAAU,iBAAiB,KAAK,OAAO,KAAK,SAAS,GACrD,EAAE,QAAQ,IACT,QAAQI,2BAAAA,wBAAwB,MAAM,GAAG,GAC1C,MACF;GAGA,IAAI,OAAO,SAAS,MAAM,OAAO;GACjC,KAAK,SAAS,MAAM,OAAO,MAAM,CAAC,aAAa,CAAC;GAChD,KAAK,UAAU,aAAa;IAAE,MAAM;IAAuB,GAAG;GAAO,CAAC;GACtE,OAAO;EACT,CAAC;CACH;CAEA,WAAW,SAAyB,QAA0C;EAC5E,MAAM,WAAW,KAAK,eAA+B;EACrD,IAAI,UAAU,OAAO;EACrB,OAAOL,8BAAAA,iBAAiB,IAAoB,OAAO,WAAW;GAK5D,OAAO;IAAE;IAAQ,OAAA,MAJG,KAAK,KAAK,SAC5BC,2BAAAA,UAAU,cAAc,KAAK,OAAO,KAAK,WAAW,MAAM,GAC1D,MACF;GACuB;EACzB,CAAC;CACH;CAEA,WACE,MACA,QACoC;EACpC,MAAM,WAAW,KAAK,eAAiC;EACvD,IAAI,UAAU,OAAO;EACrB,MAAM,QAAQ,gBAAgB,cAAc,IAAI,WAAW,IAAI,IAAI;EACnE,OAAOD,8BAAAA,iBAAiB,IAAsB,OAAO,WAAW;GAC9D,MAAM,SAAS,MAAM,KAAK,KAAK,cAC7BC,2BAAAA,UAAU,cAAc,KAAK,OAAO,KAAK,WAAW,MAAM,GAC1D,OACA,SAAS,oBAAoB,UAAU,6BACtC,QAAQK,2BAAAA,uBAAuB,MAAM,GAAG,GACzC,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,eAAe;EACpD,CAAC;CACH;CAEA,YAAY,OAAgE;EAC1E,MAAM,WAAW,KAAK,eAAsC;EAC5D,IAAI,UAAU,OAAO;EACrB,OAAON,8BAAAA,iBAAiB,IAA2B,OAAO,WAAW;GACnE,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BC,2BAAAA,UAAU,gBAAgB,KAAK,OAAO,KAAK,SAAS,GACpD,QACC,QAAQM,2BAAAA,4BAA4B,MAAM,GAAG,GAC9C,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,mBAAmB;EACxD,CAAC;CACH;CAEA,YAAY,KAAmB,OAAgE;EAC7F,MAAM,WAAW,KAAK,eAAsC;EAC5D,IAAI,UAAU,OAAO;EACrB,OAAOP,8BAAAA,iBAAiB,IAA2B,OAAO,WAAW;GACnE,MAAM,SAAS,MAAM,KAAK,KAAK,UAC7BC,2BAAAA,UAAU,oBAAoB,KAAK,OAAO,KAAK,YAAA,GAAA,8BAAA,kBAAA,CAA6B,GAAG,CAAC,GAChF,QACC,QAAQO,2BAAAA,4BAA4B,MAAM,GAAG,GAC9C,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,mBAAmB;EACxD,CAAC;CACH;CAEA,YAAY,KAA4D;EACtE,MAAM,WAAW,KAAK,eAAsC;EAC5D,IAAI,UAAU,OAAO;EACrB,OAAOR,8BAAAA,iBAAiB,IAA2B,OAAO,WAAW;GACnE,MAAM,SAAS,MAAM,KAAK,KAAK,WAC7BC,2BAAAA,UAAU,oBAAoB,KAAK,OAAO,KAAK,YAAA,GAAA,8BAAA,kBAAA,CAA6B,GAAG,CAAC,IAC/E,QAAQQ,2BAAAA,4BAA4B,MAAM,GAAG,GAC9C,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,mBAAmB;EACxD,CAAC;CACH;CAEA,aACE,KACA,QACA,SACwC;EACxC,MAAM,WAAW,KAAK,eAAqC;EAC3D,IAAI,UAAU,OAAO;EACrB,MAAM,UAAU,SAAS;EACzB,OAAOT,8BAAAA,iBAAiB,IAA0B,OAAO,WAAW;GAClE,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BC,2BAAAA,UAAU,sBAAsB,KAAK,OAAO,KAAK,YAAA,GAAA,8BAAA,kBAAA,CAA6B,GAAG,CAAC,GAClF;IAAE;IAAQ,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;GAAG,IACzC,QAAQS,2BAAAA,2BAA2B,MAAM,GAAG,GAC7C,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,qBAAqB;EAC1D,CAAC;CACH;CAEA,aAAa,KAAmB,QAA+D;EAC7F,MAAM,WAAW,KAAK,eAAqC;EAC3D,IAAI,UAAU,OAAO;EACrB,OAAOV,8BAAAA,iBAAiB,IAA0B,OAAO,WAAW;GAClE,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BC,2BAAAA,UAAU,4BAA4B,KAAK,OAAO,KAAK,YAAA,GAAA,8BAAA,kBAAA,CAA6B,GAAG,CAAC,GACxF,EAAE,OAAO,IACR,QAAQS,2BAAAA,2BAA2B,MAAM,GAAG,GAC7C,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,qBAAqB;EAC1D,CAAC;CACH;CAEA,OAAO,SAAiE;EACtE,MAAM,WAAW,KAAK,eAAiC;EACvD,IAAI,UAAU,OAAO;EACrB,OAAOV,8BAAAA,iBAAiB,IAAsB,OAAO,WAAW;GAC9D,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BC,2BAAAA,UAAU,gBAAgB,KAAK,OAAO,KAAK,SAAS,GACpD,EAAE,iBAAiB,SAAS,mBAAmB,MAAM,IACpD,QAAQU,2BAAAA,uBAAuB,MAAM,GAAG,GACzC,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,eAAe;EACpD,CAAC;CACH;CAEA,iBAAwD;EACtD,IAAI,KAAK,SAAS,GAChB,OAAOX,8BAAAA,iBAAiB,aACtB,IAAIY,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAO;CACT;;;;;;CAOA,eACE,QACA,MASG;EACH,KAAK,SAAS,MAAM,OAAO,MAAM,CAAC,aAAa,CAAC;EAChD,KAAK,UAAU,aAAa;GAAE;GAAM,GAAG;EAAO,CAAiC;EAC/E,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;AC5PA,IAAa,4BAAb,MAAuE;CACrE,YACE,MACA,OACA,WACA,UACA,UACA,WACA;EANiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;EACA,KAAA,YAAA;CAChB;;;;;;;;;;;CAYH,OAA2C;EACzC,IAAI,KAAK,SAAS,GAChB,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAsB,OAAO,WAAW;GAC9D,MAAM,YAAY,OAAO,MAAoC;IAC3D,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,CAAC;IAK1C,OAAO,gBAAgB,UAAU,CAAC,QAAQ,CAAC,IACvCG,2BAAAA,UAAU,UAAU,KAAK,OAAO,SAAS,aAAa,IACtDA,2BAAAA,UAAU,YAAY,KAAK,OAAO,KAAK,WAAW,SAAS,aAAa;GAC9E;GACA,OAAO,KAAK,KAAK,mBACf,YACC,QAAQC,2BAAAA,uBAAuB,MAAM,GAAG,GACzC,OAAO,MAAM;IACX,MAAM,KAAK,SAAS,QAAQ,CAAC;GAC/B,GACA,MACF;EACF,CAAC;CACH;CAEA,KAAK,mBAAuC,WAAqD;EAC/F,IAAI,KAAK,SAAS,GAChB,OAAOJ,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAoB,OAAO,WAAW;GAC5D,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BG,2BAAAA,UAAU,eAAe,KAAK,OAAO,KAAK,SAAS,GACnD;IAAE;IAAmB;GAAU,IAC9B,QAAQE,2BAAAA,qBAAqB,MAAM,GAAG,GACvC,MACF;GAGA,IAAI,OAAO,OAAO,KAAK,SAAS,mBAAmB,OAAO,KAAK;GAG/D,KAAK,UAAU,aAAa;IAAE,MAAM;IAAe;IAAmB;IAAW,GAAG;GAAO,CAAC;GAC5F,OAAO;EACT,CAAC;CACH;CAEA,OACE,mBACA,UACoC;EACpC,IAAI,KAAK,SAAS,GAChB,OAAOL,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAsB,OAAO,WAAW;GAC9D,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BG,2BAAAA,UAAU,iBAAiB,KAAK,OAAO,KAAK,SAAS,GACrD;IAAE;IAAmB;GAAS,IAC7B,QAAQG,2BAAAA,uBAAuB,MAAM,GAAG,GACzC,MACF;GAGA,IAAI,OAAO,OAAO,KAAK,SAAS,mBAAmB,OAAO,KAAK;GAC/D,KAAK,UAAU,aAAa;IAC1B,MAAM;IACN;IACA;IACA,GAAG;GACL,CAAC;GACD,OAAO;EACT,CAAC;CACH;CAEA,OAAO,mBAA2E;EAChF,IAAI,KAAK,SAAS,GAChB,OAAON,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAsB,OAAO,WAAW;GAC9D,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BG,2BAAAA,UAAU,iBAAiB,KAAK,OAAO,KAAK,SAAS,GACrD,EAAE,kBAAkB,IACnB,QAAQI,2BAAAA,uBAAuB,MAAM,GAAG,GACzC,MACF;GAGA,IAAI,OAAO,OAAO,KAAK,SAAS,gBAAgB,OAAO,OAAO,iBAAiB;GAC/E,KAAK,UAAU,aAAa;IAAE,MAAM;IAAiB;IAAmB,GAAG;GAAO,CAAC;GACnF,OAAO;EACT,CAAC;CACH;CAEA,QACE,mBACA,QAA0B,WACW;EACrC,IAAI,KAAK,SAAS,GAChB,OAAOP,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAuB,OAAO,WAAW;GAC/D,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BG,2BAAAA,UAAU,kBAAkB,KAAK,OAAO,KAAK,SAAS,GACtD;IAAE;IAAmB;GAAM,IAC1B,QAAQK,2BAAAA,wBAAwB,MAAM,GAAG,GAC1C,MACF;GAEA,IAAI,OAAO,SAAS,MAAM,OAAO;GAEjC,KAAK,SAAS,MAAM,OAAO,MAAM,CAAC,WAAW,aAAa,CAAC;GAC3D,KAAK,UAAU,aAAa;IAC1B,MAAM;IACN,GAAG;GACL,CAAC;GACD,OAAO;EACT,CAAC;CACH;AACF;;;;;;;;;;;ACxKA,IAAa,gCAAb,MAA+E;CAC7E,YACE,MACA,OACA,WACA,UACA,UACA,WACA;EANiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;EACA,KAAA,YAAA;CAChB;CAEH,MAAM,OAAoE;EACxE,IAAI,KAAK,SAAS,GAChB,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAA0B,OAAO,WAAW;GAClE,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BG,2BAAAA,UAAU,qBAAqB,KAAK,OAAO,KAAK,SAAS,GACzD,EAAE,MAAM,IACP,QAAQC,2BAAAA,2BAA2B,MAAM,GAAG,GAC7C,MACF;GAEA,IAAI,OAAO,SAAS,MAAM,OAAO;GAGjC,KAAK,SAAS,MAAM,OAAO,MAAM,CAAC,WAAW,aAAa,CAAC;GAC3D,KAAK,UAAU,aAAa;IAC1B,MAAM;IACN,GAAG;GACL,CAAC;GACD,OAAO;EACT,CAAC;CACH;AACF;;;;;;;;;;;;;;;;;;;ACnBA,IAAa,6BAAb,MAAyE;CACvE,YACE,MACA,OACA,WACA,UACA,UACA;EALiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;CAChB;CAEH,MAAM,SAAuD;EAC3D,IAAI,KAAK,SAAS,GAChB,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,sBAAsB,KAAK,OAAO,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAiB,OAAO,WAAW;GAEzD,MAAM,QADO,QAAQ,QAAQ,YACP,UAAUG,2BAAAA,UAAU,mBAAmBA,2BAAAA,UAAU;GACvE,MAAM,OAAO,UACX,KAAK,KAAK,QACR,KAAK,KAAK,OAAO,KAAK,WAAW,KAAK,IACrC,QAAQC,2BAAAA,kBAAkB,MAAM,GAAG,GACpC,MACF;GACF,MAAM,SAAA,GAAA,8BAAA,qBAAA,CAA6B,QAAQ,KAAK;GAEhD,IAAI,QAAQ,WAAW,KAAA,GAAW;IAChC,IAAI;IACJ,IAAI;KACF,SAAA,GAAA,2BAAA,kBAAA,CAA0B,QAAQ,MAAM;IAC1C,QAAQ;KACN,MAAM,IAAIH,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,yBAAyB;IAC7E;IAGA,IAAI,cAAc,MAAM,KAAK,MAAM,cAAc,KAAK,GACpD,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,iEACF;IAEF,IAAI,QAAQ,cAAc,KAAA,KAAa,QAAQ,cAAc,MAAM,WACjE,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,oEACF;IAEF,IAAI;KACF,OAAO,MAAM,IAAI,QAAQ,MAAM;IACjC,SAAS,KAAK;KACZ,IAAID,8BAAAA,YAAY,GAAG,KAAKC,8BAAAA,gBAAgB,QAAQ,GAC9C,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,2EACF;KAEF,MAAM;IACR;GACF;GAEA,MAAM,QAAQ,WAAA,GAAA,2BAAA,kBAAA,CACM;IAChB;IACA;IACA,GAAI,QAAQ,cAAc,KAAA,IAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;IAC1E,MAAM;IACN,GAAI,QAAQ,WAAW,KAAA,IAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;GACnE,CAAC;GACH,IAAI;IAEF,OAAO,MAAM,IAAI,MAAA,GAAA,8BAAA,mBAAA,CAAwB,MADlB,KAAK,SAAS,IAAI,MAAM,CACE,CAAC,CAAC;GACrD,SAAS,KAAK;IACZ,IAAI,CAACD,8BAAAA,YAAY,GAAG,KAAKC,8BAAAA,gBAAgB,QAAQ,GAAG,MAAM;IAI1D,OAAO,MAAM,IAAI,MAAA,GAAA,8BAAA,mBAAA,CAAwB,MADrB,KAAK,SAAS,QAAQ,MAAM,CACF,CAAC,CAAC;GAClD;EACF,CAAC;CACH;AACF;;AAGA,SAAS,cAAc,OAA4B;CACjD,OAAO,KAAK,UAAU;EACpB,MAAM,QAAQ,MAAM;EACpB,MAAM;EACN,MAAM,YAAY,IAAI;EACtB,MAAM,kBAAkB,IAAI;EAC5B,MAAM,YAAY,IAAI;CACxB,CAAC;AACH;;;ACtGA,SAAgB,uBAAuB,OAAiC;CACtE,MAAM,QAAQ,MAAM,MAAM,GAAG;CAC7B,IAAI,MAAM,WAAW,GACnB,MAAM,IAAIG,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,oCAAoC;CAExF,MAAM,gBAAgB,MAAM;CAC5B,IAAI;CACJ,IAAI;EACF,QAAQ,gBAAgB,aAAa;CACvC,SAAS,KAAK;EACZ,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,0BAA2B,IAAc,WAAW,KACtD;CACF;CACA,IAAI;CACJ,IAAI;EACF,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK;CACvC,SAAS,KAAK;EACZ,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,mCAAoC,IAAc,WAAW,KAC/D;CACF;CACA,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,IAAI;CAC1B,SAAS,KAAK;EACZ,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,kCAAmC,IAAc,WAAW,KAC9D;CACF;CACA,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GACvE,MAAM,IAAID,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,mCAAmC;CAEvF,OAAO;AACT;;;;;;AAOA,SAAS,gBAAgB,QAA4B;CACnD,MAAM,MAAM,OAAO,QAAQ,MAAM,GAAG,CAAC,CAAC,QAAQ,MAAM,GAAG;CACvD,MAAM,MAAM,IAAI,SAAS;CACzB,MAAM,SAAS,QAAQ,IAAI,MAAM,MAAM,IAAI,OAAO,IAAI,GAAG;CACzD,MAAM,MAAM,KAAK,MAAM;CACvB,MAAM,MAAM,IAAI,WAAW,IAAI,MAAM;CACrC,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,IAAI,KAAK,IAAI,WAAW,CAAC;CAC9D,OAAO;AACT;;;ACxDA,IAAa,+BAAb,MAA6E;CAa3E,YACE,MACA,OACA,WACA,aACA,MACA,eAA8B,MAC9B;EANiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EAEA,KAAA,OAAA;EAjBX,gBAAA,MAAA,SAAA,KAAA,CAAA;EACA,gBAAA,MAAA,UAAoC,IAAA;EAQ3B,gBAAA,MAAA,cAAA,KAAA,CAAA;EACA,gBAAA,MAAA,iBAAA,KAAA,CAAA;EAUf,KAAK,SAAA,GAAA,8BAAA,sBAAA,CAA8B,WAAW;EAC9C,MAAM,SAAS,eAAe,iBAAiB,YAAY,IAAI;EAC/D,KAAK,aAAa,MAAM,QAAQ,QAAQ,KAAK,IAAK,OAAQ,QAAkC,CAAC;EAC7F,KAAK,gBAAgB,SAAS,mBAAmB,MAAM,IAAI;CAC7D;CAEA,IAAI,UAAiC;EACnC,OAAO,KAAK;CACd;CAEA,IAAI,gBAA2C;EAC7C,OAAO,KAAK;CACd;;;;;;;CAQA,IAAI,iBAAwC;EAC1C,IAAI,KAAK,QAAQ,OAAO,KAAK,OAAO;EACpC,MAAM,QAAA,GAAA,8BAAA,cAAA,CAAqB,KAAK,MAAM,YAAY,IAAI;EACtD,OAAO,MAAM,MAAA,GAAA,8BAAA,eAAA,CAAoB,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK;CAChE;;;;;;;;CASA,OAAO,KAA6B;EAClC,IAAI,KAAK,QAAQ,eAAe,SAAS,GAAG,GAAG,OAAO;EACtD,MAAM,QAAA,GAAA,8BAAA,cAAA,CAAqB,KAAK,MAAM,YAAY,IAAI;EACtD,QAAA,GAAA,8BAAA,gBAAA,CAAuB,KAAK,KAAK,YAAY,IAAI;CACnD;;;;;;;;;CAUA,IAAI,WAAoC;EACtC,OAAO,KAAK,QAAQ,YAAY,KAAK;CACvC;;;;;;;CAQA,IAAI,iBAAiC;EACnC,QAAA,GAAA,8BAAA,wBAAA,CAA+B,KAAK,KAAK;CAC3C;CAEA,OAAO,OAAoE;EACzE,IAAI,KAAK,KAAK,SAAS,GACrB,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAA0B,OAAO,WAAW;GAClE,OAAO,MAAM,KAAK,WAAW,QAAQ;IACnC,UAAU,MAAM;IAChB,MAAM,MAAM,QAAQ;GACtB,CAAC;EACH,CAAC;CACH;;;;;;;;;;;;CAaA,kBAA0D;EACxD,IAAI,KAAK,KAAK,SAAS,GACrB,OAAOA,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAA0B,OAAO,WAAW;GAClE,OAAO,MAAM,KAAK,WAAW,QAAQ,EAAE,MAAM,MAAM,CAAC;EACtD,CAAC;CACH;;;;;;;;;;;CAYA,MAAc,WACZ,QACA,MAC+B;EAC/B,MAAM,WAAW,MAAM,KAAK,KAAK,SAC/BG,2BAAAA,UAAU,QACV;GACE,OAAO,KAAK;GACZ,WAAW,KAAK;GAChB,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;GACnD,MAAM,KAAK;EACb,IACC,QAAQC,2BAAAA,qBAAqB,MAAM,GAAG,GACvC,MACF;EACA,KAAK,QAAQ,SAAS;EACtB,KAAK,SAAS;GACZ,KAAK,SAAS;GACd,eAAe,SAAS;GACxB,gBAAgB,SAAS;GACzB,OAAO,SAAS;GAChB,gBAAgB,SAAS;GACzB,UAAU,SAAS;GACnB,sBAAsB,SAAS;GAC/B,WAAW,SAAS;GAEpB,GAAI,SAAS,eAAe,EAAE,cAAc,SAAS,aAAa,IAAI,CAAC;EACzE;EACA,KAAK,KAAK,aAAa;GACrB,KAAK,SAAS;GACd,OAAO,KAAK;GACZ,WAAW,KAAK;EAClB,CAAC;EAID,OAAO;GAAE,UAAU,KAAK;GAAO,QAAQ,KAAK,UAAU,KAAA;EAAU;CAClE;AACF;;;;;;;;AASA,SAAS,iBAAiB,OAA+C;CACvE,IAAI;EACF,OAAO,uBAAuB,KAAK;CACrC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,mBAAmB,QAA0D;CACpF,MAAM,MAAwB,CAAC;CAC/B,IAAI,OAAO,OAAO,eAAe,UAAU,IAAI,UAAU,OAAO;CAChE,IAAI,OAAO,OAAO,gBAAgB,UAAU,IAAI,WAAW,OAAO;CAClE,IAAI,OAAO,OAAO,oBAAoB,UAAU,IAAI,eAAe,OAAO;CAC1E,IAAI,MAAM,QAAQ,OAAO,SAAS,GAAG;EACnC,MAAM,SAAU,OAAO,SAAS,CAAe,QAC5C,MAAmB,OAAO,MAAM,QACnC;EACA,IAAI,OAAO,SAAS,GAAG,IAAI,SAAS;CACtC;CACA,OAAO,OAAO,KAAK,GAAG,CAAC,CAAC,SAAS,IAAI,MAAM;AAC7C;;;ACtMA,IAAa,uBAAb,MAA6D;CAC3D,YACE,MACA,OACA,WACA,UACA,UACA,WACA;EANiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;EACA,KAAA,YAAA;CAChB;;;;;;;;;;CAWH,OAA2C;EACzC,IAAI,KAAK,SAAS,GAChB,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAsB,OAAO,WAAW;GAC9D,MAAM,YAAY,OAAO,MAAoC;IAC3D,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,CAAC;IAG1C,OAAO,gBAAgB,UAAU,CAAC,UAAU,CAAC,IACzCG,2BAAAA,UAAU,YAAY,KAAK,OAAO,SAAS,eAAe,IAC1DA,2BAAAA,UAAU,cAAc,KAAK,OAAO,KAAK,WAAW,SAAS,eAAe;GAClF;GACA,OAAO,KAAK,KAAK,mBACf,YACC,QAAQC,2BAAAA,uBAAuB,MAAM,GAAG,GACzC,OAAO,MAAM;IACX,MAAM,KAAK,SAAS,QAAQ,CAAC;GAC/B,GACA,MACF;EACF,CAAC;CACH;CAEA,OAAO,OAA8D;EACnE,IAAI,KAAK,SAAS,GAChB,OAAOJ,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAA0B,OAAO,WAAW;GAClE,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7BG,2BAAAA,UAAU,oBAAoB,KAAK,OAAO,KAAK,SAAS,GACxD,QACC,QAAQE,2BAAAA,2BAA2B,MAAM,GAAG,GAC7C,MACF;GAIA,IAAI,OAAO,OAAO,KAAK,SAAS,cAAc,OAAO,KAAK;GAC1D,KAAK,UAAU,aAAa;IAAE,MAAM;IAAoB,GAAG;GAAO,CAAC;GACnE,OAAO;EACT,CAAC;CACH;AACF;;;;;;;;;;;;AC7BA,IAAa,8BAAb,MAA2E;CACzE,YACE,MACA,OACA,WACA,kBACA,UACA,UACA,WACA;EAPiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,mBAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;EACA,KAAA,YAAA;CAChB;CAEH,OAAqD;EACnD,IAAI,KAAK,SAAS,GAChB,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAgC,OAAO,WAAW;GACxE,MAAM,YAAY,OAAO,MAAoC;IAC3D,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,CAAC;IAC1C,MAAM,OAAO,SAAS,MAAM,MAAM,MAAM,EAAE,MAAM,qBAAqB,KAAK,gBAAgB;IAC1F,IAAI,CAAC,MACH,MAAM,IAAIC,8BAAAA,YACRC,8BAAAA,gBAAgB,UAChB,8BAA8B,KAAK,iBAAiB,eAAe,KAAK,OAC1E;IAMF,OAAO,gBAAgB,UAAU,CAAC,aAAa,CAAC,IAC5CC,2BAAAA,UAAU,mBACR,KAAK,OACL,KAAK,kBACL,KAAK,MAAM,iBACb,IACAA,2BAAAA,UAAU,qBACR,KAAK,OACL,KAAK,WACL,KAAK,kBACL,KAAK,MAAM,iBACb;GACN;GACA,OAAO,KAAK,KAAK,mBACf,YACC,QAAQC,2BAAAA,iCAAiC,MAAM,GAAG,GACnD,OAAO,MAAM;IACX,MAAM,KAAK,SAAS,QAAQ,CAAC;GAC/B,GACA,MACF;EACF,CAAC;CACH;CAEA,kBACE,UAC+C;EAC/C,OAAOJ,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YACFC,8BAAAA,gBAAgB,gBAChB,iHACF,CACF;CACF;CAEA,uBACE,UAA4C,CAAC,GACO;EACpD,IAAI,KAAK,SAAS,GAChB,OAAOF,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAsC,OAAO,WAAW;GAI9E,MAAM,SAAkC,QAAQ,UAAU;GAC1D,MAAM,YAAY,OAAO,MAAoC;IAC3D,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,CAAC;IAC1C,MAAM,OAAO,SAAS,MAAM,MAAM,MAAM,EAAE,MAAM,qBAAqB,KAAK,gBAAgB;IAC1F,IAAI,CAAC,MACH,MAAM,IAAIC,8BAAAA,YACRC,8BAAAA,gBAAgB,UAChB,8BAA8B,KAAK,iBAAiB,eAAe,KAAK,OAC1E;IAEF,MAAM,aAAA,GAAA,2BAAA,wCAAA,CACJ;KAAE,GAAG;KAAS;IAAO,GACrB,EAAE,mBAAmB,KAAK,MAAM,kBAAkB,CACpD;IAGA,OAAO,gBAAgB,UAAU,CAAC,aAAa,CAAC,IAC5CC,2BAAAA,UAAU,6BAA6B,KAAK,OAAO,KAAK,kBAAkB,SAAS,IACnFA,2BAAAA,UAAU,+BACR,KAAK,OACL,KAAK,WACL,KAAK,kBACL,SACF;GACN;GAQA,OAAO,oBAAoB,MAPR,KAAK,KAAK,uBAC3B,WACA,OAAO,MAAM;IACX,MAAM,KAAK,SAAS,QAAQ,CAAC;GAC/B,GACA,MACF,CAC+B;EACjC,CAAC;CACH;;;;;;;;;;CAWA,aAAa,KAAyD;EACpE,IAAI,KAAK,SAAS,GAChB,OAAOH,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,IAAI,IAAI,qBAAqB,KAAK,kBAChC,OAAOF,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YACFC,8BAAAA,gBAAgB,YAChB,wBAAwB,IAAI,iBAAiB,WAAW,KAAK,kBAC/D,CACF;EAEF,IAAI,IAAI,SAAS,SACf,OAAOF,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YACFC,8BAAAA,gBAAgB,YAChB,oHACF,CACF;EAEF,MAAM,YAAA,GAAA,8BAAA,kBAAA,CAA6B,cAAc,GAAG,CAAC;EACrD,OAAOF,8BAAAA,iBAAiB,IAAuB,OAAO,WAAW;GAC/D,MAAM,YAAY,OAAO,MAAoC;IAC3D,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,CAAC;IAI1C,OAAO,gBAAgB,UAAU,CAAC,eAAe,aAAa,CAAC,IAC3DG,2BAAAA,UAAU,kBACR,KAAK,OACL,KAAK,kBACL,UACA,SAAS,kBACX,IACAA,2BAAAA,UAAU,oBACR,KAAK,OACL,KAAK,WACL,KAAK,kBACL,UACA,SAAS,kBACX;GACN;GAQA,OAAO,uBAAuB,MAPX,KAAK,KAAK,mBAC3B,WACA,OAAO,MAAM;IACX,MAAM,KAAK,SAAS,QAAQ,CAAC;GAC/B,GACA,MACF,CACkC;EACpC,CAAC;CACH;CAEA,OAAO,OAAkE;EACvE,IAAI,KAAK,SAAS,GAChB,OAAOH,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAA4B,OAAO,WAAW;GAMpE,MAAM,EAAE,MAAM,cAAc,OAAA,GAAA,8BAAA,yBAAA,CAA+B,KAAK;GAChE,MAAM,OAAOG,2BAAAA,UAAU,2BACrB,KAAK,OACL,KAAK,WACL,KAAK,gBACP;GACA,MAAM,SAAS,QAAiBE,2BAAAA,6BAA6B,MAAM,GAAG;GACtE,MAAM,SAAS,aAAa,SAAS,IACjC,MAAM,KAAK,KAAK,kBAAkB,MAAM,kBAAkB,MAAM,SAAS,GAAG,OAAO,MAAM,IACzF,MAAM,KAAK,KAAK,SAAS,MAAM,MAAM,OAAO,MAAM;GACtD,OAAO,KAAK,eAAe,QAAQ,oBAAoB;EACzD,CAAC;CACH;CAEA,OAAO,KAAoB,OAAkE;EAC3F,IAAI,KAAK,SAAS,GAChB,OAAOL,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,IAAI,IAAI,qBAAqB,KAAK,kBAChC,OAAOF,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YACFC,8BAAAA,gBAAgB,YAChB,wBAAwB,IAAI,iBAAiB,WAAW,KAAK,kBAC/D,CACF;EAEF,IAAI,IAAI,SAAS,SAAS;GAIxB,MAAM,OAAOC,2BAAAA,UAAU,qBACrB,KAAK,OACL,KAAK,WACL,IAAI,kBACJ,OACF;GACA,OAAOH,8BAAAA,iBAAiB,IAA4B,OAAO,WAAW;IACpE,MAAM,EAAE,MAAM,cAAc,OAAA,GAAA,8BAAA,yBAAA,CAA+B,KAAK;IAChE,MAAM,SAAS,MAAM,KAAK,cAAc,MAAM;KAAE;KAAK,OAAO;IAAK,GAAG,WAAW,MAAM;IACrF,OAAO,KAAK,eAAe,QAAQ,oBAAoB;GACzD,CAAC;EACH;EACA,MAAM,aAAA,GAAA,8BAAA,kBAAA,CAA8B,cAAc,GAAG,CAAC;EACtD,MAAM,OAAOG,2BAAAA,UAAU,qBACrB,KAAK,OACL,KAAK,WACL,IAAI,kBACJ,SACF;EACA,OAAOH,8BAAAA,iBAAiB,IAA4B,OAAO,WAAW;GACpE,MAAM,EAAE,MAAM,cAAc,OAAA,GAAA,8BAAA,yBAAA,CAA+B,KAAK;GAChE,MAAM,SAAS,MAAM,KAAK,cAAc,MAAM,EAAE,OAAO,KAAK,GAAG,WAAW,MAAM;GAChF,OAAO,KAAK,eAAe,QAAQ,oBAAoB;EACzD,CAAC;CACH;;CAGA,cACE,MACA,MACA,WACA,QACiC;EACjC,MAAM,SAAS,QAAiBM,2BAAAA,6BAA6B,MAAM,GAAG;EACtE,IAAI,aAAa,SAAS,GACxB,OAAO,KAAK,KAAK,mBAAmB,MAAM,kBAAkB,MAAM,SAAS,GAAG,OAAO,MAAM;EAE7F,OAAO,KAAK,KAAK,UAAU,MAAM,MAAM,OAAO,MAAM;CACtD;CAEA,OAAO,KAA8D;EACnE,IAAI,KAAK,SAAS,GAChB,OAAON,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,IAAI,IAAI,qBAAqB,KAAK,kBAChC,OAAOF,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YACFC,8BAAAA,gBAAgB,YAChB,wBAAwB,IAAI,iBAAiB,WAAW,KAAK,kBAC/D,CACF;EAEF,IAAI,IAAI,SAAS,SAAS;GAIxB,MAAM,OAAOC,2BAAAA,UAAU,qBACrB,KAAK,OACL,KAAK,WACL,IAAI,kBACJ,OACF;GACA,OAAOH,8BAAAA,iBAAiB,IAA4B,OAAO,WAAW;IACpE,MAAM,SAAS,MAAM,KAAK,KAAK,UAC7B,MACA;KAAE;KAAK,IAAI;IAAS,IACnB,QAAQO,2BAAAA,6BAA6B,MAAM,GAAG,GAC/C,MACF;IACA,OAAO,KAAK,eAAe,QAAQ,oBAAoB;GACzD,CAAC;EACH;EACA,MAAM,aAAA,GAAA,8BAAA,kBAAA,CAA8B,cAAc,GAAG,CAAC;EACtD,MAAM,OAAOJ,2BAAAA,UAAU,qBACrB,KAAK,OACL,KAAK,WACL,IAAI,kBACJ,SACF;EACA,OAAOH,8BAAAA,iBAAiB,IAA4B,OAAO,WAAW;GACpE,MAAM,SAAS,MAAM,KAAK,KAAK,WAC7B,OACC,QAAQO,2BAAAA,6BAA6B,MAAM,GAAG,GAC/C,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,oBAAoB;EACzD,CAAC;CACH;CAEA,KAAK,MAAuB,SAAyD;EACnF,IAAI,KAAK,SAAS,GAChB,OAAOP,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAIF,KAAK,MAAM,KAAK,MACd,IAAI,EAAE,qBAAqB,KAAK,kBAC9B,OAAOF,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YACFC,8BAAAA,gBAAgB,YAChB,2BAA2B,EAAE,iBAAiB,6BAA6B,KAAK,kBAClF,CACF;EAGJ,MAAM,OAAOC,2BAAAA,UAAU,yBACrB,KAAK,OACL,KAAK,WACL,KAAK,gBACP;EACA,OAAOH,8BAAAA,iBAAiB,IAA0B,OAAO,WAAW;GAClE,MAAM,SAAS,MAAM,KAAK,KAAK,SAC7B,MACA;IAAE;IAAM;GAAQ,IACf,QAAQQ,2BAAAA,2BAA2B,MAAM,GAAG,GAC7C,MACF;GACA,OAAO,KAAK,eAAe,QAAQ,kBAAkB;EACvD,CAAC;CACH;;;;;;;;CASA,eACE,QACA,MACG;EACH,KAAK,SAAS,MAAM,OAAO,MAAM,CAAC,aAAa,CAAC;EAChD,KAAK,UAAU,aAAa;GAC1B;GACA,kBAAkB,KAAK;GACvB,GAAG;EACL,CAAiC;EACjC,OAAO;CACT;AACF;;;;;;;;AASA,eAAe,oBAAoB,MAA2D;CAC5F,MAAM,cAAc,KAAK,IAAI,UAAU;CACvC,IAAI,OAAO,gBAAgB,UACzB,MAAM,IAAIP,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,gDACF;CAEF,IAAI;CACJ,IAAI;EACF,aAAa,KAAK,MAAM,WAAW;CACrC,SAAS,KAAK;EACZ,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,0CAA2C,KAAe,WAAW,KACvE;CACF;CACA,MAAM,WAAWO,2BAAAA,mCAAmC,MAAM,UAAU;CAEpE,MAAM,cAA2C,MAAM,QAAQ,IAC7D,SAAS,YAAY,IAAI,OAAO,UAAU;EACxC,MAAM,YAAY,KAAK,IAAI,MAAM,IAAI;EACrC,IAAI,cAAc,QAAQ,OAAO,cAAc,UAC7C,MAAM,IAAIR,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,2CAA2C,MAAM,KAAK,EACxD;EAEF,MAAM,OAAO;EACb,MAAM,QAAQ,IAAI,WAAW,MAAM,KAAK,YAAY,CAAC;EAQrD,MAAM,SAAA,GAAA,8BAAA,sBAAA,CAA8B;GANlC,OAAO,MAAM;GACb,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,aAAa,MAAM;GACnB,QAAQ;IAAE,MAAM;IAAS;GAAM;EAEQ,GAAG,EAC1C,MAAM,OAAO;GACX,OAAO;EACT,EACF,CAAC;EACD,OAAO;GACL,KAAK,MAAM;GACX,MAAM,MAAM;GACZ,MAAM,MAAM;GACZ;EACF;CACF,CAAC,CACH;CAEA,OAAO;EAAE,WAAW,SAAS;EAAW;CAAY;AACtD;;;;;;AAOA,SAAS,cACP,KACyE;CACzE,IAAI,IAAI,SAAS,gBACf,OAAO;EAAE,MAAM;EAAgB,OAAO,IAAI;CAAkB;CAE9D,OAAO;EAAE,MAAM;EAAM,OAAO,IAAI;CAAG;AACrC;;;ACpeA,IAAa,2BAAb,MAAqE;CACnE,YACE,MACA,OACA,WACA,kBACA,UACA,UACA;EANiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,mBAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;CAChB;CAEH,OAA+C;EAC7C,IAAI,KAAK,SAAS,GAChB,OAAOQ,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAA0B,OAAO,WAAW;GAClE,MAAM,YAAY,OAAO,MAAoC;IAC3D,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,CAAC;IAC1C,MAAM,OAAO,SAAS,MAAM,MAAM,MAAM,EAAE,MAAM,qBAAqB,KAAK,gBAAgB;IAC1F,IAAI,CAAC,MACH,MAAM,IAAIC,8BAAAA,YACRC,8BAAAA,gBAAgB,UAChB,8BAA8B,KAAK,iBAAiB,eAAe,KAAK,OAC1E;IAIF,OAAO,gBAAgB,UAAU,CAAC,SAAS,CAAC,IACxCC,2BAAAA,UAAU,gBAAgB,KAAK,OAAO,KAAK,kBAAkB,KAAK,MAAM,cAAc,IACtFA,2BAAAA,UAAU,kBACR,KAAK,OACL,KAAK,WACL,KAAK,kBACL,KAAK,MAAM,cACb;GACN;GACA,OAAO,KAAK,KAAK,mBACf,YACC,QAAQC,2BAAAA,2BAA2B,MAAM,GAAG,GAC7C,OAAO,MAAM;IACX,MAAM,KAAK,SAAS,QAAQ,CAAC;GAC/B,GACA,MACF;EACF,CAAC;CACH;AACF;;;ACzCA,IAAa,yBAAb,MAAiE;CAC/D,YACE,MACA,OACA,WACA,kBACA,UACA,UACA;EANiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,mBAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;CAChB;CAEH,MAAM,UAA4B,CAAC,GAAsC;EACvE,IAAI,KAAK,SAAS,GAChB,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAqB,OAAO,WAAW;GAC7D,MAAM,SAAS,gBAAgB,QAAQ,MAAM;GAC7C,MAAM,qBAAqB,QAAQ,sBAAsB;GACzD,MAAM,YAAY,OAAO,MAAoC;IAC3D,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,CAAC;IAC1C,MAAM,OAAO,SAAS,MAAM,MAAM,MAAM,EAAE,MAAM,qBAAqB,KAAK,gBAAgB;IAC1F,IAAI,CAAC,MACH,MAAM,IAAIC,8BAAAA,YACRC,8BAAAA,gBAAgB,UAChB,8BAA8B,KAAK,iBAAiB,eAAe,KAAK,OAC1E;IASF,MAAM,aAAA,GAAA,2BAAA,yBAAA,CACJ;KAAE,GAAG;KAAS;IAAO,GACrB;KACE,gBAAgB,KAAK,MAAM;KAC3B,GAAI,qBAAqB,EAAE,mBAAmB,KAAK,MAAM,kBAAkB,IAAI,CAAC;IAClF,CACF;IAQA,IAAI,oBACF,OAAO,gBAAgB,UAAU,CAAC,WAAW,aAAa,CAAC,IACvDC,2BAAAA,UAAU,uBAAuB,KAAK,OAAO,KAAK,kBAAkB,SAAS,IAC7EA,2BAAAA,UAAU,yBACR,KAAK,OACL,KAAK,WACL,KAAK,kBACL,SACF;IAEN,OAAO,gBAAgB,UAAU,CAAC,SAAS,CAAC,IACxCA,2BAAAA,UAAU,cAAc,KAAK,OAAO,KAAK,kBAAkB,SAAS,IACpEA,2BAAAA,UAAU,gBAAgB,KAAK,OAAO,KAAK,WAAW,KAAK,kBAAkB,SAAS;GAC5F;GAKA,MAAM,cAAc,MAAM,UAAU,MAAM;GAC1C,OAAO,2BACL;IACE;IACA,aAAa,SAAS;IACtB,QAAQ;KAAE,MAAM;KAAO,KAAK,KAAK,KAAK,YAAY,WAAW;IAAE;GACjE,GACA,KAAK,MACL,WACA,OAAO,MAAM;IACX,MAAM,KAAK,SAAS,QAAQ,CAAC;GAC/B,CACF;EACF,CAAC;CACH;CAEA,IAAI,UAA4D;EAC9D,OAAOH,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YACFC,8BAAAA,gBAAgB,gBAChB,uEACF,CACF;CACF;AACF;AAEA,SAAS,2BACP,QACA,MACA,WACA,gBACiB;CACjB,QAAA,GAAA,8BAAA,sBAAA,CAA6B,QAAQ,EACnC,OAAO,WACL,KAAK,mBAAmB,WAAW,gBAAgB,UAAU,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAC7F,CAAC;AACH;AAEA,SAAS,gBAAgB,QAA6D;CACpF,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,IAAI,WAAW,SAAS,WAAW,QAAQ,OAAO;CAClD,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,6DAA6D,OAAO,GACtE;AACF;;;;;;;;;;;AC9GA,IAAa,uBAAb,MAA6D;CAC3D,YACE,MACA,OACA,WACA,kBACA,UACA,UACA;EANiB,KAAA,OAAA;EACA,KAAA,QAAA;EACA,KAAA,YAAA;EACA,KAAA,mBAAA;EACA,KAAA,WAAA;EACA,KAAA,WAAA;CAChB;CAEH,OAA2C;EACzC,IAAI,KAAK,SAAS,GAChB,OAAOE,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,MAAM,WAAW,CAChF;EAEF,OAAOF,8BAAAA,iBAAiB,IAAsB,OAAO,WAAW;GAC9D,MAAM,YAAY,OAAO,MAAoC;IAC3D,MAAM,WAAW,MAAM,KAAK,SAAS,IAAI,CAAC;IAC1C,MAAM,OAAO,SAAS,MAAM,MAAM,MAAM,EAAE,MAAM,qBAAqB,KAAK,gBAAgB;IAC1F,IAAI,CAAC,MACH,MAAM,IAAIC,8BAAAA,YACRC,8BAAAA,gBAAgB,UAChB,8BAA8B,KAAK,iBAAiB,eAAe,KAAK,OAC1E;IAKF,OAAO,gBAAgB,UAAU,CAAC,SAAS,CAAC,IACxCC,2BAAAA,UAAU,YAAY,KAAK,OAAO,KAAK,kBAAkB,KAAK,MAAM,cAAc,IAClFA,2BAAAA,UAAU,cACR,KAAK,OACL,KAAK,WACL,KAAK,kBACL,KAAK,MAAM,cACb;GACN;GACA,OAAO,KAAK,KAAK,mBACf,YACC,QAAQC,2BAAAA,uBAAuB,MAAM,GAAG,GACzC,OAAO,MAAM;IACX,MAAM,KAAK,SAAS,QAAQ,CAAC;GAC/B,GACA,MACF;EACF,CAAC;CACH;AACF;;;AC5DA,IAAa,kBAAb,MAAmD;CAMjD,YACE,kBACA,WACA,MACA,OACA,WACA,UACA,UACA,WACA;EARS,KAAA,mBAAA;EACA,KAAA,YAAA;EAPF,gBAAA,MAAA,eAAA,KAAA,CAAA;EACA,gBAAA,MAAA,QAAA,KAAA,CAAA;EACA,gBAAA,MAAA,YAAA,KAAA,CAAA;EACA,gBAAA,MAAA,UAAA,KAAA,CAAA;EAYP,KAAK,cAAc,IAAI,4BACrB,MACA,OACA,WACA,kBACA,UACA,UACA,SACF;EACA,KAAK,OAAO,IAAI,qBACd,MACA,OACA,WACA,kBACA,UACA,QACF;EACA,KAAK,WAAW,IAAI,yBAClB,MACA,OACA,WACA,kBACA,UACA,QACF;EACA,KAAK,SAAS,IAAI,uBAChB,MACA,OACA,WACA,kBACA,UACA,QACF;CACF;AACF;;;;;;;;;;;;;;;;;ACPA,SAAgB,gBAAgB,KAAoB,aAA2C;CAC7F,IAAI,IAAI,oBAAoB,aAAa,OAAO;CAEhD,MAAM,SAAsB;EAC1B,MAAM;EACN,WAAW,IAAI,mBAAmB,WAAW,IAAI;EACjD,KAAK,IAAI;EACT,IAAI,IAAI;EACR,UAAU,IAAI;CAChB;CAEA,QAAQ,IAAI,MAAZ;EACE,KAAK,gBACH,OAAO;GACL,MAAM;GACN,kBAAkB,IAAI,oBAAoB,IAAI,cAAc,MAAM;GAClE;GACA,GAAI,IAAI;EACV;EACF,KAAK,gBACH,OAAO;GACL,MAAM;GACN,kBAAkB,IAAI,oBAAoB,IAAI,cAAc,MAAM;GAClE;GACA,GAAI,IAAI;EACV;EACF,KAAK,gBACH,OAAO;GACL,MAAM;GACN,kBAAkB,IAAI,oBAAoB,IAAI,cAAc,MAAM;GAClE;GACA,GAAI,IAAI;EACV;EACF,KAAK,cACH,OAAO;GACL,MAAM;GACN,kBAAkB,IAAI,oBAAoB,IAAI,cAAc,MAAM;GAClE;GACA,GAAI,IAAI;EACV;EACF,KAAK,cACH,OAAO;GACL,MAAM;GACN,mBAAmB,IAAI;GACvB;GACA,GAAI,IAAI;EACV;EACF,KAAK,gBAAgB;GACnB,MAAM,UAAU,IAAI;GACpB,MAAM,WAAY,QAAQ,OAAO,MAAM,MACpC,SAAS,KAAK,qBAAqB,IAAI,cAAc,EACxD,CAAC,EAAE,YAAY;GACf,OAAO;IACL,MAAM;IACN,mBAAmB,IAAI;IACvB;IACA;IACA,GAAG;GACL;EACF;EACA,KAAK,gBACH,OAAO;GACL,MAAM;GACN,mBAAmB,IAAI;GACvB;GACA,GAAI,IAAI;EACV;EACF,KAAK,iBACH,OAAO;GACL,MAAM;GACN;GACA,GAAI,IAAI;EACV;EACF,KAAK,mBACH,OAAO;GACL,MAAM;GACN;GACA,GAAI,IAAI;EACV;EACF,KAAK,qBACH,OAAO;GACL,MAAM;GACN;GACA,GAAI,IAAI;EACV;EACF,KAAK,qBACH,OAAO;GACL,MAAM;GACN;GACA,GAAI,IAAI;EACV;EAIF,KAAK;EACL,KAAK,cACH,OAAO;GAAE,MAAM;GAAqB;GAAQ,GAAI,IAAI;EAA+B;EACrF,KAAK,eACH,OAAO;GAAE,MAAM;GAAiB;GAAQ,GAAI,IAAI;EAA6B;EAC/E,KAAK,eACH,OAAO;GAAE,MAAM;GAAiB;GAAQ,GAAI,IAAI;EAA6B;EAC/E,KAAK,oBACH,OAAO;GAAE,MAAM;GAAqB;GAAQ,GAAI,IAAI;EAAkC;EACxF,KAAK,oBACH,OAAO;GAAE,MAAM;GAAqB;GAAQ,GAAI,IAAI;EAAkC;EACxF,KAAK,oBACH,OAAO;GAAE,MAAM;GAAqB;GAAQ,GAAI,IAAI;EAAkC;EACxF,KAAK,qBACH,OAAO;GAAE,MAAM;GAAuB;GAAQ,GAAI,IAAI;EAAiC;EACzF,KAAK,qBACH,OAAO;GAAE,MAAM;GAAuB;GAAQ,GAAI,IAAI;EAAiC;EACzF,KAAK,qBACH,OAAO;GAAE,MAAM;GAAuB;GAAQ,GAAI,IAAI;EAA8B;EACtF,SACE,OAAO;CACX;AACF;;;;;;;;;;;;;;;;;;;;ACrIA,IAAa,YAAb,MAAuB;CAOrB,YAAY,MAAyC;EAAxB,KAAA,OAAA;EANrB,gBAAA,MAAA,UAAA,KAAA,CAAA;EACA,gBAAA,MAAA,UAAS,KAAA;EACT,gBAAA,MAAA,SAAgC,IAAA;EAChC,gBAAA,MAAA,cAAmD,IAAA;EACnD,gBAAA,MAAA,gBAAe,GAAA;EAGrB,KAAK,SAAS,KAAK;CACrB;CAEA,OAAa;EACX,IAAI,KAAK,QAAQ;EACjB,KAAU,IAAI;CAChB;CAEA,QAAc;EACZ,KAAK,SAAS;EACd,IAAI,KAAK,YAAY,aAAa,KAAK,UAAU;EACjD,KAAK,OAAO,MAAM;CACpB;CAEA,IAAI,cAA6B;EAC/B,OAAO,KAAK;CACd;CAEA,MAAc,MAAqB;EACjC,MAAM,YAAY,KAAK,IAAI;EAC3B,KAAK,QAAQ,IAAI,gBAAgB;EACjC,IAAI;GACF,MAAM,MAAM,MAAM,KAAK,KAAK,KAAK,OAC/B,KAAK,KAAK,MACV,KAAK,WAAW,OAAO,EAAE,iBAAiB,OAAO,KAAK,MAAM,EAAE,IAAI,CAAC,GACnE,KAAK,MAAM,MACb;GACA,IAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;IAC5C,KAAK,SAAS;IACd,KAAK,KAAK,WAAW;IACrB;GACF;GACA,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,MAClB,MAAM,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,SAAS,sBAAsB,IAAI,QAAQ;GAEnF,MAAM,KAAK,QAAQ,IAAI,IAAI;GAE3B,IAAI,KAAK,IAAI,IAAI,aAAa,KAAQ,KAAK,eAAe;EAC5D,QAAQ,CAER;EACA,IAAI,KAAK,QAAQ;EACjB,MAAM,SAAS,KAAK,gBAAgB,KAAM,KAAK,OAAO,IAAI;EAC1D,KAAK,aAAa,iBAAiB,KAAK,KAAK,IAAI,GAAG,MAAM;EAC1D,KAAK,eAAe,KAAK,IAAI,KAAK,eAAe,GAAG,GAAM;CAC5D;CAEA,MAAc,QAAQ,MAAiD;EACrE,MAAM,SAAS,KAAK,UAAU;EAC9B,MAAM,UAAU,IAAI,YAAY;EAChC,IAAI,SAAS;EACb,SAAS;GACP,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK;GAC1C,IAAI,QAAQ,KAAK,QAAQ;GACzB,UAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;GAChD,SAAS;IACP,MAAM,MAAM,OAAO,QAAQ,MAAM;IACjC,IAAI,MAAM,GAAG;IACb,MAAM,QAAQ,OAAO,MAAM,GAAG,GAAG;IACjC,SAAS,OAAO,MAAM,MAAM,CAAC;IAC7B,KAAK,SAAS,KAAK;GACrB;EACF;CACF;CAEA,SAAiB,OAAqB;EACpC,IAAI,MAAM,WAAW,GAAG,GAAG;EAC3B,IAAI,KAAoB;EACxB,IAAI,QAAQ;EACZ,MAAM,OAAiB,CAAC;EACxB,KAAK,MAAM,QAAQ,MAAM,MAAM,IAAI,GACjC,IAAI,KAAK,WAAW,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;OACvD,IAAI,KAAK,WAAW,QAAQ,GAAG,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK;OAC1D,IAAI,KAAK,WAAW,OAAO,GAAG,KAAK,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;EAEnE,IAAI,OAAO,QAAQ,OAAO,SAAS,EAAE,GAAG,KAAK,SAAS;EACtD,IAAI,UAAU,YACZ,IAAI;GACF,KAAK,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,IAAI,CAAC,CAAkB;EAC9D,QAAQ,CAGR;OACK,IAAI,UAAU,gBACnB,KAAK,KAAK,cAAc;OACnB,IAAI,UAAU,gBAAgB;GAInC,KAAK,SAAS;GACd,KAAK,OAAO,MAAM;GAClB,KAAK,KAAK,WAAW;EACvB;CAGF;AACF;;;ACxDA,IAAa,sBAAb,MAA2D;CA0CzD,YACE,MACA,IACA,YAAqCC,2BAAAA,oBACrC,aAQA,eAA8B,MAC9B,YAAoB,cAAc,MAClC;EAbiB,KAAA,OAAA;EAEA,KAAA,YAAA;EA5CV,gBAAA,MAAA,MAAA,KAAA,CAAA;EACA,gBAAA,MAAA,gBAAe;GACtB,4BAA4B;GAC5B,kBAAkB;EACpB,CAAA;EACS,gBAAA,MAAA,YAAA,KAAA,CAAA;EACA,gBAAA,MAAA,eAAA,KAAA,CAAA;EACA,gBAAA,MAAA,WAAA,KAAA,CAAA;EACA,gBAAA,MAAA,eAAA,KAAA,CAAA;EACA,gBAAA,MAAA,SAAA,KAAA,CAAA;EACA,gBAAA,MAAA,UAAA,KAAA,CAAA;EACA,gBAAA,MAAA,SAAA,KAAA,CAAA;EACA,gBAAA,MAAA,aAAA,KAAA,CAAA;EACA,gBAAA,MAAA,YAAA,KAAA,CAAA;EACA,gBAAA,MAAA,UAAA,KAAA,CAAA;EACA,gBAAA,MAAA,UAAA,KAAA,CAAA;EACQ,gBAAA,MAAA,aAAA,KAAA,CAAA;EACA,gBAAA,MAAA,OAAA,KAAA,CAAA;EACA,gBAAA,MAAA,aAAA,KAAA,CAAA;EACT,gBAAA,MAAA,aAA8B,IAAA;EAC9B,gBAAA,MAAA,kBAAiB,CAAA;EACjB,gBAAA,MAAA,UAAS,KAAA;EAaT,gBAAA,MAAA,iBAAyC,IAAA;EACzC,gBAAA,MAAA,oBAAqD,IAAA;EACrD,gBAAA,MAAA,wBAAuB,CAAA;EACvB,gBAAA,MAAA,sBAAA,KAAA,CAAA;EAES,gBAAA,MAAA,oBAAA,KAAA,CAAA;EAiBf,KAAK,KAAK;EACV,KAAK,qBAAqB,eAAe;EACzC,MAAM,WAAW,IAAI,6BACnB,MACA,IACA,WACA,eAAe,oBAAoB,EAAE,GACrC,EAAE,gBAAgB,KAAK,OAAO,GAC9B,YACF;EACA,KAAK,WAAW;EAOhB,KAAK,SAAS,EACZ,QAAQ,YAAY;GAElB,MAAM,cADS,SAAS,kBAAkB,MAAM,SAAS,gBAAgB,EAAA,CAAG,UAAU,KAAA,EAC3D;GAC3B,IAAI,CAAC,YAAY,OAAOC,8BAAAA;GACxB,OAAO;IACL,MAAM;IACN,UAAU,EAAE,QAAQ,WAAW,SAAS,OAAO;IAC/C,GAAI,WAAW,QAAQ,EAAE,OAAO,WAAW,MAAM,IAAI,CAAC;IACtD,GAAI,WAAW,cAAc,EAAE,aAAa,WAAW,YAAY,IAAI,CAAC;IACxE,GAAI,WAAW,oBAAoB,KAAA,IAC/B,EAAE,iBAAiB,WAAW,gBAAgB,IAC9C,CAAC;IACL,SAAS,WAAW;IACpB,YAAY,WAAW;IACvB,UAAU,WAAW;GACvB;EACF,EACF;EACA,MAAM,MAAM,IAAIC,0BAAAA,SAAS;EACzB,KAAK,MAAM;EACX,KAAK,YAAY;EAOjB,KAAK,SAAS;GACZ,YAAY,aAAa;IACvB,MAAM,cAAc,IAAI,UAAU,QAAQ;IAC1C,KAAK,mBAAmB;IACxB,IAAI,WAAW;IACf,aAAa;KACX,YAAY;KACZ,IAAI,CAAC,UAAU;MACb,WAAW;MACX,KAAK,oBAAoB;KAC3B;IACF;GACF;GACA,oBAAoB,IAAI,aAAa;EACvC;EACA,KAAK,YAAY,IAAIC,0BAAAA,sBAAsB,KAAK,SAAS;EACzD,KAAK,mBAAmB;GACtB,MAAM,WAAW,KAAK,YAAY,MAAM;GACxC,UAAU,WAAW,KAAK,gBAAgB,MAAM;GAChD,QAAQ,MAAM,SAAS,KAAK,eAAe,MAAM,IAAI;GACrD,qBAAqB,UAAU,KAAK,oBAAoB,KAAK;GAC7D,kBAAkB,OAAO,iBAAiB,KAAK,iBAAiB,OAAO,YAAY;GACnF,gBAAgB,UAAU,KAAK,eAAe,KAAK;GACnD,mBAAmB,UAAU,KAAK,kBAAkB,KAAK;EAC3D;EACA,KAAK,WAAW,IAAI,qBAClB,MACA,IACA,iBACM,KAAK,QACX,KAAK,kBACL,KAAK,SACP;EACA,KAAK,cAAc,IAAI,gCACrB,MACA,IACA,iBACM,KAAK,QACX,KAAK,gBACP;EACA,KAAK,UAAU,IAAI,4BACjB,MACA,IACA,iBACM,KAAK,QACX,KAAK,gBACP;EACA,KAAK,cAAc,IAAI,gCACrB,MACA,IACA,iBACM,KAAK,QACX,KAAK,kBACL,KAAK,SACP;EACA,KAAK,QAAQ,IAAI,0BACf,MACA,IACA,iBACM,KAAK,QACX,KAAK,kBACL,KAAK,SACP;EACA,KAAK,SAAS,IAAI,2BAChB,MACA,IACA,iBACM,KAAK,QACX,KAAK,gBACP;EACA,KAAK,QAAQ,IAAI,0BACf,MACA,IACA,iBACM,KAAK,QACX,KAAK,kBACL,KAAK,SACP;EACA,KAAK,YAAY,IAAI,8BACnB,MACA,IACA,iBACM,KAAK,QACX,KAAK,kBACL,KAAK,SACP;CACF;CAEA,KAAK,kBAAgD;EACnD,OAAO,IAAI,gBACT,kBACA,IACA,KAAK,MACL,KAAK,IACL,KAAK,iBACC,KAAK,QACX,KAAK,kBACL,KAAK,SACP;CACF;CAEA,SAAS,OAA+B,CAAC,GAAiC;EACxE,IAAI,KAAK,QACP,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,GAAG,WAAW,CAC7E;EAEF,MAAM,OAAO,KAAK,QAAQC,8BAAAA;EAC1B,OAAOH,8BAAAA,iBAAiB,IAAgB,OAAO,WAAW;GACxD,MAAM,YAAY,YAAY;IAC5B,MAAM,WAAW,MAAM,KAAK,YAAY,MAAM;IAC9C,OAAOI,2BAAAA,UAAU,uBAAuB,KAAK,IAAI,KAAK,WAAW;KAC/D,YAAY,SAAS;KACrB;IACF,CAAC;GACH;GACA,IAAI;IACF,OAAO,MAAM,KAAK,KAAK,SAAS,MAAM,UAAU,GAAG,MAAM;GAC3D,SAAS,KAAK;IACZ,IAAI,CAACH,8BAAAA,YAAY,GAAG,KAAKC,8BAAAA,gBAAgB,QAAQ,GAAG,MAAM;IAC1D,MAAM,KAAK,gBAAgB,MAAM;IACjC,OAAO,KAAK,KAAK,SAAS,MAAM,UAAU,GAAG,MAAM;GACrD;EACF,CAAC;CACH;;;;;;;CAQA,MAAM,YAAY,QAAgD;EAChE,IAAI,KAAK,eAAe,OAAO,KAAK;EACpC,IAAI,CAAC,KAAK,kBACR,KAAK,mBAAmB,EAAE,kBAAkB,KAAK,CAAC;EAEpD,MAAM,UAAU,KAAK;EACrB,IAAI,CAAC,SACH,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,SAChB,+CAA+C,KAAK,IACtD;EAEF,OAAO,YAAY,SAAS,MAAM;CACpC;;;;;;CAOA,MAAM,gBAAgB,QAAgD;EAEpE,OAAO,YADS,KAAK,mBAAmB,EAAE,kBAAkB,MAAM,CACzC,GAAG,MAAM;CACpC;;;;;;;;;;CAWA,WAAmB,MAAwC;EACzD,MAAM,QAAQ,KAAK;EACnB,MAAM,SAAS,OAAO;EACtB,IAAI,CAAC,SAAS,CAAC,QAAQ;EACvB,IAAI,KAAK,OAAO,UAAU,OAAO,WAAW,OAAO,GAAG;EACtD,MAAM,OAAO,EAAE,GAAG,OAAO;EACzB,KAAK,MAAM,SAAS,MAAM,KAAK,SAAS;EACxC,KAAK,gBAAgB;GAAE,GAAG;GAAO,QAAQ;EAAK;CAChD;CAEA,eAAe,MAAoB,MAAwC;EACzE,KAAK,WAAW,IAAI;EACpB,MAAM,QAAQ,KAAK;EACnB,IAAI,OACF,KAAK,uBAAuB,KAAK,IAAI,KAAK,sBAAsB,MAAM,UAAU;EAElF,KAAK,mBAAmB;EAExB,IAAI,CAAC,KAAK,eAAe;EACzB,IAAI,OAAO;GACT,IAAI,MAAM,cAAc,KAAK,cAAc,YAAY;GACvD,IAAI,MAAM,uBAAuB,KAAK,cAAc,YAAY;IAC9D,KAAK,gBAAgB;IACrB;GACF;EACF;EAEA,MAAM,qBAAqB,IAAI,IAC7B,KAAK,cAAc,MAAM,KAAK,SAAS,CAAC,KAAK,MAAM,kBAAkB,IAAI,CAAC,CAC5E;EACA,KAAK,MAAM,aAAa,KAAK,eAAe;GAC1C,MAAM,WAAW,mBAAmB,IAAI,UAAU,gBAAgB;GAClE,IAAI,UACF,mBAAmB,IAAI,UAAU,kBAAkB;IACjD,GAAG;IACH,OAAO;GACT,CAAC;EAEL;EACA,IAAI,OACF,KAAK,MAAM,QAAQ,MAAM,OAAO;GAC9B,MAAM,WAAW,mBAAmB,IAAI,KAAK,gBAAgB;GAC7D,IAAI,UACF,mBAAmB,IAAI,KAAK,kBAAkB;IAC5C,GAAG;IACH,OAAO,KAAK;GACd,CAAC;EAEL;EAEF,KAAK,gBAAgB;GACnB,GAAG,KAAK;GACR,YAAY,OAAO,cAAc,KAAK,cAAc;GAKpD,OAAO,MAAM,KAAK,mBAAmB,OAAO,CAAC,CAAC,CAAC,MAC5C,GAAG,MAAM,EAAE,MAAM,mBAAmB,EAAE,MAAM,gBAC/C;EACF;CACF;;;;;;;;;;CAWA,oBAA4B,OAAiC;EAG3D,KAAK,WAAW,CAAC,QAAQ,CAAC;EAC1B,KAAK,uBAAuB,KAAK,IAAI,KAAK,sBAAsB,MAAM,UAAU;EAChF,KAAK,mBAAmB;EAExB,IAAI,CAAC,KAAK,eAAe;EACzB,IAAI,MAAM,cAAc,KAAK,cAAc,YAAY;EACvD,IAAI,MAAM,uBAAuB,KAAK,cAAc,YAAY;GAC9D,KAAK,gBAAgB;GACrB;EACF;EACA,KAAK,gBAAgB;GACnB,GAAG,KAAK;GACR,YAAY,MAAM;GAClB,eAAe,MAAM;EACvB;CACF;;;;;;;CAQA,iBAAyB,OAA2B,cAAwC;EAI1F,KAAK,WAAW;GAAC;GAAU;GAAW;EAAa,CAAC;EACpD,KAAK,uBAAuB,KAAK,IAAI,KAAK,sBAAsB,MAAM,UAAU;EAChF,KAAK,mBAAmB;EAExB,IAAI,CAAC,KAAK,eAAe;EACzB,IAAI,MAAM,cAAc,KAAK,cAAc,YAAY;EACvD,IAAI,MAAM,uBAAuB,KAAK,cAAc,YAAY;GAC9D,KAAK,gBAAgB;GACrB;EACF;EACA,MAAM,UAAU,IAAI,IAAI,YAAY;EACpC,KAAK,gBAAgB;GACnB,GAAG,KAAK;GACR,YAAY,MAAM;GAClB,eAAe,MAAM;GACrB,OAAO,KAAK,cAAc,MAAM,QAAQ,SAAS,CAAC,QAAQ,IAAI,KAAK,MAAM,gBAAgB,CAAC;EAC5F;CACF;;;;;;;;;CAUA,eAAuB,OAA4B;EACjD,KAAK,WAAW,CAAC,UAAU,CAAC;EAC5B,KAAK,uBAAuB,KAAK,IAAI,KAAK,sBAAsB,MAAM,UAAU;EAChF,KAAK,mBAAmB;EAExB,IAAI,CAAC,KAAK,eAAe;EACzB,IAAI,MAAM,cAAc,KAAK,cAAc,YAAY;EACvD,IAAI,MAAM,uBAAuB,KAAK,cAAc,YAAY;GAC9D,KAAK,gBAAgB;GACrB;EACF;EACA,KAAK,gBAAgB;GACnB,GAAG,KAAK;GACR,YAAY,MAAM;GAClB,iBAAiB,MAAM;EACzB;CACF;;;;;;;;;;CAWA,kBAA0B,OAA+B;EACvD,KAAK,WAAW,CAAC,aAAa,CAAC;EAC/B,KAAK,uBAAuB,KAAK,IAAI,KAAK,sBAAsB,MAAM,UAAU;EAChF,KAAK,mBAAmB;EAExB,IAAI,CAAC,KAAK,eAAe;EACzB,IAAI,MAAM,cAAc,KAAK,cAAc,YAAY;EACvD,IAAI,MAAM,uBAAuB,KAAK,cAAc,YAAY;GAC9D,KAAK,gBAAgB;GACrB;EACF;EACA,KAAK,gBAAgB;GACnB,GAAG,KAAK;GACR,YAAY,MAAM;GAClB,oBAAoB,MAAM;EAC5B;CACF;CAEA,mBAA2B,MAAgE;EACzF,MAAM,OAAO,IAAI,gBAAgB;EACjC,MAAM,UAAU,KAAK,cAAc,KAAK,QAAQ,IAAI;EACpD,KAAK,mBAAmB;EACxB,QACG,MAAM,aAAa;GAClB,IACE,SAAS,cAAc,KAAK,yBAC3B,CAAC,KAAK,iBAAiB,SAAS,cAAc,KAAK,cAAc,aAElE,KAAK,gBAAgB;EAEzB,CAAC,CAAC,CACD,YAAY,KAAA,CAAS,CAAC,CACtB,cAAc;GACb,IAAI,KAAK,qBAAqB,SAC5B,KAAK,mBAAmB;EAE5B,CAAC;EACH,OAAO;CACT;CAEA,MAAc,cACZ,QACA,MAC2B;EAC3B,IAAI,KAAK,QACP,MAAM,IAAID,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,YAAY,KAAK,GAAG,WAAW;EAEnF,MAAM,OAAO,KAAK,mBAAmB,KAAK,mBAAmB,IAAI;EACjE,IAAI,MACF,IAAI;GACF,OAAO,MAAM,KAAK,qBAAqB,MAAM,MAAM;EACrD,SAAS,KAAK;GACZ,IAAI,CAACD,8BAAAA,YAAY,GAAG,KAAKC,8BAAAA,gBAAgB,QAAQ,GAAG,MAAM;EAI5D;EAMF,MAAM,YAAY,MAAM,KAAK,KAAK,QAChCE,2BAAAA,UAAU,UAAU,KAAK,IAAI,KAAK,SAAS,IAC1C,QAAQC,2BAAAA,mBAAmB,MAAM,GAAG,GACrC,MACF;EACA,OAAO,KAAK,qBAAqB,WAAW,MAAM;CACpD;CAEA,qBAAkD;EAChD,MAAM,OAAO,KAAK;EAClB,KAAK,qBAAqB;EAC1B,OAAO;CACT;CAEA,qBAA6B,MAAoB,QAAgD;EAC/F,OAAO,KAAK,KAAK,QACfD,2BAAAA,UAAU,cAAc,KAAK,IAAI,KAAK,WAAW,KAAK,UAAU,IAC/D,QAAQE,2BAAAA,uBAAuB,MAAM,GAAG,GACzC,MACF;CACF;CAEA,QAAgC;EAC9B,IAAI,KAAK,QACP,OAAON,8BAAAA,iBAAiB,aAAmB,KAAA,CAAS;EAEtD,KAAK,SAAS;EACd,KAAK,WAAW,MAAM;EACtB,KAAK,YAAY;EACjB,KAAK,gBAAgB;EACrB,KAAK,mBAAmB;EACxB,OAAOA,8BAAAA,iBAAiB,aAAmB,KAAA,CAAS;CACtD;CAEA,qBAAmC;EACjC,KAAK,kBAAkB;EACvB,IAAI,KAAK,iBAAiB,KAAK,KAAK,UAAU,KAAK,WAAW;EAC9D,KAAK,YAAY,IAAI,UAAU;GAC7B,MAAM,KAAK;GACX,MAAMI,2BAAAA,UAAU,YAAY,KAAK,IAAI,KAAK,SAAS;GAKnD,eAAe,KAAK,IAAI,aAAa,KAAK,KAAK,eAAe,aAAa;GAC3E,QAAQ,QAAQ;IACd,MAAM,QAAQ,gBAAgB,KAAK,KAAK,SAAS;IACjD,IAAI,CAAC,OAAO;IAGZ,KAAK,kBAAkB,KAAK;IAC5B,KAAK,IAAI,QAAQ,KAAK;GACxB;GACA,qBAAqB;IAEnB,KAAK,gBAAgB;IACrB,KAAK,mBAAmB;GAC1B;GACA,kBAAkB;IAIhB,KAAK,YAAY;GACnB;EACF,CAAC;EACD,KAAK,UAAU,KAAK;CACtB;CAEA,sBAAoC;EAClC,KAAK,iBAAiB,KAAK,IAAI,GAAG,KAAK,iBAAiB,CAAC;EACzD,IAAI,KAAK,mBAAmB,KAAK,KAAK,WAAW;GAC/C,KAAK,UAAU,MAAM;GACrB,KAAK,YAAY;EACnB;CACF;;;;CAKA,kBAA0B,OAA4B;EACpD,QAAQ,MAAM,MAAd;GACE,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;IACH,KAAK,eAAe,MAAM,MAAM,CAAC,aAAa,CAAC;IAC/C;GACF,KAAK;GACL,KAAK;IACH,IAAI,MAAM,OAAO,KAAK,oBAAoB,MAAM,KAAK;IACrD;GACF,KAAK;IACH,IAAI,MAAM,OAAO,KAAK,iBAAiB,MAAM,OAAO,MAAM,iBAAiB;IAC3E;GACF,KAAK;IACH,IAAI,MAAM,OAAO,KAAK,eAAe,MAAM,KAAK;IAChD;GACF,KAAK;GACL,KAAK;IACH,IAAI,MAAM,OAAO,KAAK,kBAAkB,MAAM,KAAK;IACnD;GACF,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;IAIH,KAAK,eAAe,MAAM,MAAM,CAAC,aAAa,CAAC;IAC/C;GACF,KAAK;IAGH,IAAI,MAAM,MAAM,KAAK,eAAe,MAAM,MAAM,CAAC,aAAa,CAAC;IAC/D;GACF,KAAK;IAEH,IAAI,MAAM,MAAM,KAAK,eAAe,MAAM,MAAM,CAAC,WAAW,aAAa,CAAC;IAC1E;GACF,KAAK;IAIH,IAAI,MAAM,MAAM,KAAK,eAAe,MAAM,MAAM,CAAC,WAAW,aAAa,CAAC;IAC1E;EACJ;CACF;AACF;AAEA,SAAS,oBAAoB,IAA0B;CACrD,OAAO;EACL;EACA,SAAS;EACT,kBAAkB;EAClB,YAAY;EACZ,OAAO;EACP,YAAY;GAAE,OAAO;GAAW,kBAAkB;EAAK;EACvD,aAAa;GACX,OAAO;GACP,MAAM;GACN,YAAY;GACZ,UAAU;GACV,yBAAyB;GACzB,mBAAmB;EACrB;EACA,QAAQ;GAAE,UAAU;GAAM,SAAS,CAAC,qBAAqB;GAAG,UAAUA,2BAAAA,UAAU;EAAO;CACzF;AACF;AAEA,SAAS,YAAe,SAAqB,QAAiC;CAC5E,IAAI,OAAO,SACT,OAAO,QAAQ,OAAO,IAAIG,8BAAAA,WAAW,OAAO,MAAM,CAAC;CAErD,OAAO,IAAI,SAAY,SAAS,WAAW;EACzC,MAAM,gBAAgB;GACpB,OAAO,IAAIA,8BAAAA,WAAW,OAAO,MAAM,CAAC;EACtC;EACA,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;EACxD,QAAQ,MACL,UAAU;GACT,OAAO,oBAAoB,SAAS,OAAO;GAC3C,QAAQ,KAAK;EACf,IACC,WAAW;GACV,OAAO,oBAAoB,SAAS,OAAO;GAC3C,OAAO,MAAM;EACf,CACF;CACF,CAAC;AACH;;;;;;;;;;AC/rBA,IAAa,qBAAb,cAAwC,MAAM;CAC5C,YACE,MACA,SACA,QACA;EACA,MAAM,OAAO;EAJJ,KAAA,OAAA;EAEA,KAAA,SAAA;EAGT,KAAK,OAAO;CACd;AACF;AAEA,eAAsB,mBACpB,SACA,YACA,OAA6B,CAAC,GACP;CAEvB,MAAM,MAAM,OADI,KAAK,SAAS,WAAW,MAAA,CACf,GAAG,QAAQ,QAAQ,OAAO,EAAE,EAAE,qBAAqB;EAC3E,QAAQ;EACR,SAAS,EAAE,gBAAgB,mBAAmB;EAC9C,MAAM,KAAK,UAAU;GACnB;GACA,GAAI,KAAK,aAAa,KAAA,IAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;EACnE,CAAC;CACH,CAAC;CACD,IAAI,CAAC,IAAI,IAAI;EACX,IAAI,OAAO;EACX,IAAI,UAAU,qCAAqC,IAAI;EACvD,IAAI;GACF,MAAM,UAAW,MAAM,IAAI,KAAK;GAChC,IAAI,QAAQ,OAAO,MAAM,OAAO,QAAQ,MAAM;GAC9C,IAAI,QAAQ,OAAO,SAAS,UAAU,QAAQ,MAAM;EACtD,QAAQ,CAER;EACA,MAAM,IAAI,mBAAmB,MAAM,SAAS,IAAI,MAAM;CACxD;CACA,OAAQ,MAAM,IAAI,KAAK;AACzB;;;;;;;;;;;;AAaA,SAAgB,6BAA6B,OAAwC;CAenF,OAAO,IAAIC,8BAAAA,YAbT,MAAM,SAAS,0BACXC,8BAAAA,gBAAgB,wBAChB,MAAM,SAAS,aACbA,8BAAAA,gBAAgB,WAChB,MAAM,SAAS,kBACb,MAAM,SAAS,sBACf,MAAM,SAAS,mBACfA,8BAAAA,gBAAgB,YAChB,MAAM,WAAW,MACfA,8BAAAA,gBAAgB,kBAChB,MAAM,WAAW,MACfA,8BAAAA,gBAAgB,aAChBA,8BAAAA,gBAAgB,SACD,0BAA0B,MAAM,WAAW;EACtE,SAAS;GAAE,WAAW,MAAM;GAAM,QAAQ,MAAM;EAAO;EACvD,OAAO;CACT,CAAC;AACH;;AAGA,MAAM,uBAAuB;;;;;;;;AAS7B,SAAgB,mBACd,SACA,YACA,OAA6B,CAAC,GACP;CACvB,IAAI,UAA+B;CACnC,IAAI,WAAmC;CACvC,OAAO,YAAY;EACjB,IAAI,WAAW,QAAQ,YAAY,KAAK,IAAI,IAAI,MAAO,sBACrD,OAAO,QAAQ;EAEjB,aAAA,WAAa,mBAAmB,SAAS,YAAY,IAAI,CAAC,CACvD,MAAM,SAAS;GACd,UAAU;GACV,OAAO,KAAK;EACd,CAAC,CAAC,CACD,cAAc;GACb,WAAW;EACb,CAAC;EACH,OAAO;CACT;AACF;;;ACnFA,IAAa,aAAb,MAAa,WAAW;CAOtB,YAAY,MAAyB;EANpB,gBAAA,MAAA,QAAA,KAAA,CAAA;EACA,gBAAA,MAAA,WAAA,KAAA,CAAA;EACA,gBAAA,MAAA,WAAA,KAAA,CAAA;EACA,gBAAA,MAAA,aAAA,KAAA,CAAA;EACT,gBAAA,MAAA,cAAgC,IAAA;EAGtC,KAAK,OAAO,KAAK,QAAQ,QAAQ,OAAO,EAAE;EAC1C,MAAM,QAAQ,KAAK;EACnB,KAAK,UAAU,UAAU,KAAA,IAAY,OAAO,OAAO,UAAU,aAAa,cAAc;EACxF,KAAK,YAAY,KAAK,aAAa;EACnC,KAAK,UAAU,KAAK,SAAS,WAAW,MAAM,KAAK,UAAU;CAC/D;;CAGA,IAAI,UAAkB;EACpB,OAAO,KAAK;CACd;;;;;;;CAQA,IAAI,YAAqC;EACvC,OAAO,KAAK;CACd;;;;;;;;CASA,UAAU,OAA8D;EACtE,OAAO,IAAI,WAAW;GACpB,SAAS,KAAK;GACd;GACA,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;GACtD,OAAO,KAAK;EACd,CAAC;CACH;;;;;CAMA,MAAM,OACJ,MACA,SACA,QACmB;EACnB,OAAO,KAAK,QAAQ,MAAM;GACxB,QAAQ;GACR,SAAS,IAAI,QAAQ;IAAE,QAAQ;IAAqB,GAAG;GAAQ,CAAC;GAChE;EACF,CAAC;CACH;;;;;;;;;;;;;;CAeA,aAAa,SAAkC;EAC7C,KAAK,aAAa;EAClB,IAAI,SAAS,KAAK,iBAAiB,OAAO,WAAW,aAAa,aAChE,KAAK,MAAM,UAAU,QAAQ,IAAI,eAAe;GAC9C,MAAM,QAAQ,CAAC,GAAG,OAAO,KAAK,GAAG,OAAO,OAAO;GAC/C,MAAM,KAAK,QAAQ,OAAO,QAAQ,KAAK;GACvC,IAAI,OAAO,QAAQ,MAAM,KAAK,UAAU,OAAO,QAAQ;GACvD,IAAI,OAAO,SAAS,MAAM,KAAK,4BAAW,IAAI,KAAK,OAAO,UAAU,GAAI,EAAA,CAAE,YAAY,GAAG;GACzF,MAAM,KAAK,iBAAiB,QAAQ;GACpC,WAAW,SAAS,SAAS,MAAM,KAAK,IAAI;EAC9C;CAEJ;;CAGA,IAAI,oBAAuC;EACzC,OAAO,KAAK;CACd;CAEA,YAAY,MAAsB;EAChC,OAAO,GAAG,KAAK,UAAU;CAC3B;CAEA,MAAM,QAAQ,MAAc,QAAoC;EAC9D,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM;GAAE,QAAQ;GAAO;EAAO,CAAC;EAC9D,IAAI,CAAC,IAAI,IAAI,MAAM,KAAK,cAAc,GAAG;EACzC,OAAO,MAAM,IAAI,KAAK;CACxB;CAEA,MAAM,SAAS,MAAc,QAA0C;EACrE,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM;GACnC,QAAQ;GACR,SAAS,IAAI,QAAQ,EAAE,QAAQ,kBAAkB,CAAC;GAClD;EACF,CAAC;EACD,IAAI,CAAC,IAAI,IAAI,MAAM,KAAK,cAAc,GAAG;EACzC,OAAO,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;CAC/C;;;;;;;;CASA,MAAM,eAAgC;EACpC,IAAI,CAAC,KAAK,SACR,MAAM,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,YAAY,qCAAqC;EAEzF,OAAO,MAAM,KAAK,QAAQ;CAC5B;CAEA,MAAM,QAAW,MAAc,QAA6B,QAAiC;EAC3F,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM;GAAE,QAAQ;GAAO;EAAO,CAAC;EAC9D,OAAO,MAAM,KAAK,kBAAkB,KAAK,MAAM;CACjD;;;;;;;;;;;;;;CAeA,MAAM,mBACJ,WACA,QACA,gBACA,QACY;EACZ,MAAM,cAAc,MAAM,UAAU,MAAM;EAC1C,IAAI;GACF,OAAO,MAAM,KAAK,QAAQ,aAAa,QAAQ,MAAM;EACvD,SAAS,KAAK;GACZ,IAAI,CAACD,8BAAAA,YAAY,GAAG,KAAKC,8BAAAA,gBAAgB,QAAQ,GAAG,MAAM;GAC1D,MAAM,eAAe,MAAM;GAC3B,MAAM,YAAY,MAAM,UAAU,MAAM;GACxC,OAAO,MAAM,KAAK,QAAQ,WAAW,QAAQ,MAAM;EACrD;CACF;;;;;;CAOA,MAAM,YAAY,MAAc,QAAwC;EACtE,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM;GACnC,QAAQ;GACR,SAAS,IAAI,QAAQ,EAAE,QAAQ,sBAAsB,CAAC;GACtD;EACF,CAAC;EACD,IAAI,CAAC,IAAI,IAAI,MAAM,KAAK,cAAc,GAAG;EACzC,OAAO,MAAM,IAAI,SAAS;CAC5B;;;;;;CAOA,MAAM,uBACJ,WACA,gBACA,QACmB;EACnB,MAAM,cAAc,MAAM,UAAU,MAAM;EAC1C,IAAI;GACF,OAAO,MAAM,KAAK,YAAY,aAAa,MAAM;EACnD,SAAS,KAAK;GACZ,IAAI,CAACD,8BAAAA,YAAY,GAAG,KAAKC,8BAAAA,gBAAgB,QAAQ,GAAG,MAAM;GAC1D,MAAM,eAAe,MAAM;GAC3B,MAAM,YAAY,MAAM,UAAU,MAAM;GACxC,OAAO,MAAM,KAAK,YAAY,WAAW,MAAM;EACjD;CACF;;;;;;;;CASA,MAAM,mBACJ,WACA,gBACA,QACe;EACf,MAAM,cAAc,MAAM,UAAU,MAAM;EAC1C,IAAI;GACF,OAAO,MAAM,KAAK,QAAQ,aAAa,MAAM;EAC/C,SAAS,KAAK;GACZ,IAAI,CAACD,8BAAAA,YAAY,GAAG,KAAKC,8BAAAA,gBAAgB,QAAQ,GAAG,MAAM;GAC1D,MAAM,eAAe,MAAM;GAC3B,MAAM,YAAY,MAAM,UAAU,MAAM;GACxC,OAAO,MAAM,KAAK,QAAQ,WAAW,MAAM;EAC7C;CACF;;CAGA,MAAM,QAAQ,MAAc,QAAgD;EAC1E,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM;GAAE,QAAQ;GAAO;EAAO,CAAC;EAC9D,IAAI,CAAC,IAAI,IAAI,MAAM,KAAK,cAAc,GAAG;EACzC,OAAO;GAAE,OAAO,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;GAAG,SAAS,IAAI;EAAQ;CAChF;;;;;;CAOA,MAAM,mBACJ,WACA,gBACA,QAC2B;EAC3B,MAAM,cAAc,MAAM,UAAU,MAAM;EAC1C,IAAI;GACF,OAAO,MAAM,KAAK,QAAQ,aAAa,MAAM;EAC/C,SAAS,KAAK;GACZ,IAAI,CAACD,8BAAAA,YAAY,GAAG,KAAKC,8BAAAA,gBAAgB,QAAQ,GAAG,MAAM;GAC1D,MAAM,eAAe,MAAM;GAC3B,MAAM,YAAY,MAAM,UAAU,MAAM;GACxC,OAAO,MAAM,KAAK,QAAQ,WAAW,MAAM;EAC7C;CACF;CAEA,MAAM,kBACJ,MACA,MACA,QACA,QACY;EACZ,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM;GAAE,QAAQ;GAAQ;GAAM;EAAO,CAAC;EACrE,OAAO,MAAM,KAAK,kBAAkB,KAAK,MAAM;CACjD;;CAGA,MAAM,mBACJ,MACA,MACA,QACA,QACY;EACZ,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM;GAAE,QAAQ;GAAS;GAAM;EAAO,CAAC;EACtE,OAAO,MAAM,KAAK,kBAAkB,KAAK,MAAM;CACjD;CAEA,MAAM,SACJ,MACA,MACA,QACA,QACY;EACZ,MAAM,MAAM,MAAM,KAAK,YAAY,MAAM,QAAQ,MAAM,MAAM;EAC7D,OAAO,MAAM,KAAK,kBAAkB,KAAK,MAAM;CACjD;;CAGA,MAAM,cACJ,MACA,OACA,aACA,QACA,QACY;EACZ,MAAM,UAAU,IAAI,QAAQ,EAAE,gBAAgB,YAAY,CAAC;EAG3D,MAAM,OAAO,IAAI,WAAW,KAAK,CAAC,CAAC;EACnC,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM;GAAE,QAAQ;GAAQ;GAAM;GAAS;EAAO,CAAC;EAC9E,OAAO,MAAM,KAAK,kBAAkB,KAAK,MAAM;CACjD;CAEA,MAAM,UACJ,MACA,MACA,QACA,QACY;EACZ,MAAM,MAAM,MAAM,KAAK,YAAY,MAAM,SAAS,MAAM,MAAM;EAC9D,OAAO,MAAM,KAAK,kBAAkB,KAAK,MAAM;CACjD;CAEA,MAAM,WAAc,MAAc,QAA6B,QAAiC;EAC9F,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM;GAAE,QAAQ;GAAU;EAAO,CAAC;EACjE,OAAO,MAAM,KAAK,kBAAkB,KAAK,MAAM;CACjD;CAEA,MAAM,YAAY,MAAc,QAAoC;EAClE,MAAM,MAAM,MAAM,KAAK,QAAQ,MAAM;GAAE,QAAQ;GAAU;EAAO,CAAC;EACjE,IAAI,IAAI,WAAW,KAAK;EACxB,IAAI,CAAC,IAAI,IAAI,MAAM,KAAK,cAAc,GAAG;CAC3C;CAEA,MAAM,UAAU,MAAc,MAAe,QAAoC;EAC/E,MAAM,MAAM,MAAM,KAAK,YAAY,MAAM,QAAQ,MAAM,MAAM;EAC7D,IAAI,IAAI,WAAW,KAAK;EACxB,IAAI,CAAC,IAAI,IAAI,MAAM,KAAK,cAAc,GAAG;CAC3C;CAEA,YACE,MACA,QACA,MACA,QACmB;EACnB,MAAM,UAAU,IAAI,QAAQ,EAAE,gBAAgB,mBAAmB,CAAC;EAClE,OAAO,KAAK,QAAQ,MAAM;GACxB;GACA,MAAM,KAAK,UAAU,QAAQ,CAAC,CAAC;GAC/B;GACA;EACF,CAAC;CACH;CAEA,MAAc,QAAQ,MAAc,MAAsC;EACxE,MAAM,EAAE,KAAK,gBAAgB,KAAK,gBAAgB,IAAI;EACtD,MAAM,UAAU,IAAI,QAAQ,KAAK,WAAW,CAAC,CAAC;EAC9C,IAAI,KAAK,SAAS;GAChB,MAAM,QAAQ,MAAM,KAAK,QAAQ;GACjC,QAAQ,IAAI,iBAAiB,UAAU,OAAO;EAChD;EACA,IAAI,CAAC,QAAQ,IAAI,QAAQ,GAAG,QAAQ,IAAI,UAAU,kBAAkB;EACpE,IAAI,KAAK,WAAW,QAAQ,IAAI,uBAAuB,KAAK,SAAS;EACrE,IAAI,aAAa,QAAQ,IAAI,YAAY,MAAM,YAAY,KAAK;EAChE,IAAI;GACF,OAAO,MAAM,KAAK,QAAQ,KAAK;IAAE,GAAG;IAAM;GAAQ,CAAC;EACrD,SAAS,KAAK;GAIZ,IAAI,KAAK,QAAQ,SACf,MAAM,IAAIC,8BAAAA,WAAW,KAAK,OAAO,UAAU,GAAG;GAEhD,IAAK,KAAkC,SAAS,cAC9C,MAAM,IAAIA,8BAAAA,WAAY,IAAc,OAAO;GAE7C,MAAM,IAAIF,8BAAAA,YACRC,8BAAAA,gBAAgB,SAChB,kBAAmB,KAAe,WAAW,OAC7C,EACE,OAAO,IACT,CACF;EACF;CACF;CAEA,MAAc,kBAAqB,KAAe,QAAyC;EACzF,IAAI,CAAC,IAAI,IAAI,MAAM,KAAK,cAAc,GAAG;EACzC,MAAM,OAAgB,MAAM,IAAI,KAAK,CAAC,CAAC,aAAa,CAAC,EAAE;EACvD,IAAI;GACF,OAAO,OAAO,IAAI;EACpB,SAAS,KAAK;GACZ,MAAM,IAAID,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,8BAA+B,KAAe,WAAW,OACzD,EACE,OAAO,IACT,CACF;EACF;CACF;;;;;;;;CASA,gBAAwB,MAGtB;EACA,IAAI,CAAC,KAAK,cAAc,CAAC,KAAK,WAAW,KACvC,OAAO;GAAE,KAAK,GAAG,KAAK,UAAU;GAAQ,aAAa;EAAK;EAE5D,MAAM,WAAA,GAAA,2BAAA,eAAA,CAAyB;GAC7B;GACA,WAAW,KAAK;GAChB,OAAO,KAAK,WAAW;GACvB,WAAW,KAAK,WAAW;GAC3B,KAAK,KAAK,WAAW;EACvB,CAAC;EACD,OAAO;GACL,KAAK,QAAQ;GACb,aAAa,QAAQ,eAAe,QAAQ,aAAa,QAAQ,aAAa;EAChF;CACF;CAEA,MAAc,cAAc,KAA+B;EACzD,IAAI;EACJ,IAAI;GACF,UAAU,MAAM,IAAI,KAAK;EAC3B,QAAQ;GACN,UAAU;EACZ;EACA,MAAM,OAAO,gBAAgB,IAAI,MAAM;EACvC,IAAI,WAAW,OAAO,YAAY,YAAY,WAAW,SAAS;GAChE,MAAM,QAAS,QAA+B;GAC9C,MAAM,SAAS,cAAc,KAAK;GAClC,IAAI,QAAQ,MAAM,IAAID,8BAAAA,YAAY,OAAO,MAAM,OAAO,SAAS,EAAE,SAAS,OAAO,QAAQ,CAAC;GAK1F,MAAM,IAAIA,8BAAAA,YAAY,MAHpB,OAAO,UAAU,YAAY,SAAS,aAAa,QAC/C,OAAQ,MAA+B,OAAO,IAC9C,QAAQ,IAAI,UACe,EAAE,SAAS,EAAE,QAAQ,IAAI,OAAO,EAAE,CAAC;EACtE;EACA,MAAM,IAAIA,8BAAAA,YAAY,MAAM,QAAQ,IAAI,UAAU,EAAE,SAAS,EAAE,QAAQ,IAAI,OAAO,EAAE,CAAC;CACvF;AACF;AAEA,SAAS,gBAAgB,QAAiC;CACxD,IAAI,WAAW,KAAK,OAAOC,8BAAAA,gBAAgB;CAC3C,IAAI,WAAW,KAAK,OAAOA,8BAAAA,gBAAgB;CAC3C,IAAI,WAAW,KAAK,OAAOA,8BAAAA,gBAAgB;CAC3C,IAAI,WAAW,KAAK,OAAOA,8BAAAA,gBAAgB;CAC3C,IAAI,WAAW,KAAK,OAAOA,8BAAAA,gBAAgB;CAC3C,IAAI,WAAW,KAAK,OAAOA,8BAAAA,gBAAgB;CAC3C,IAAI,WAAW,KAAK,OAAOA,8BAAAA,gBAAgB;CAC3C,OAAOA,8BAAAA,gBAAgB;AACzB;AAEA,SAAS,cAAc,OAA8C;CACnE,MAAM,SAASE,2BAAAA,yBAAyB,UAAU,KAAK;CACvD,OAAO,OAAO,UAAU,OAAO,OAAO;AACxC;;;;;;;;ACreA,IAAa,cAAb,MAAa,YAA8B;CACzC,OAAO,YAAY,MAAuC;EAIxD,MAAM,YAAY,UAAA,GAAA,0BAAA,aAAA,CAAsB;EACxC,OAAO,IAAI,YAAY,IAAI,WAAW;GAAE,GAAG;GAAM;EAAU,CAAC,GAAG,SAAS;CAC1E;CAIA,YACE,MAEA,WACA;EAHiB,KAAA,OAAA;EAEA,KAAA,YAAA;EALX,gBAAA,MAAA,aAAY,KAAA;CAMjB;CAEH,KAAK,OAAkB,SAAyD;EAC9E,IAAI,KAAK,WACP,OAAOC,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YAAYC,8BAAAA,gBAAgB,oBAAoB,kBAAkB,CACxE;EAMF,SAAc;EACd,SAAc;EAMd,MAAM,oBACJ,WAAW,cAAc,UAAW,QAAQ,YAAY,OAAS,MAAM,YAAY;EAErF,IAAI,MAAM,SAAS,SAAS;GAS1B,MAAM,MAAM,mBAAmB,KAAK,KAAK,SAAS,MAAM,YAAY;IAClE,GAAI,MAAM,kBAAkB,KAAA,IAAY,EAAE,UAAU,MAAM,cAAc,IAAI,CAAC;IAC7E,OAAO,KAAK,KAAK;GACnB,CAAC;GACD,MAAM,QAAQ,YAAY;IACxB,IAAI;KACF,OAAO,MAAM,IAAI;IACnB,SAAS,OAAO;KACd,MAAM,iBAAiB,qBAAqB,6BAA6B,KAAK,IAAI;IACpF;GACF;GACA,OAAO,KAAK,KAAK;IAAE,MAAM;IAAS;IAAO,UAAU,MAAM,YAAY;GAAK,GAAG,OAAO;EACtF;EAEA,IAAI,MAAM,SAAS,SAAS;GAQ1B,MAAM,cAAc,MAAM;GAC1B,OAAOF,8BAAAA,iBAAiB,IAAoB,OAAO,WAAW;IAC5D,MAAM,UAAU,KAAK,KAAK,UAAU,WAAW;IAC/C,MAAM,QAAQ,MAAM,QAAQ,aAAa;IACzC,MAAM,SAAS,uBAAuB,KAAK;IAC3C,MAAM,QAAQ,OAAO;IACrB,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAChD,MAAM,IAAIC,8BAAAA,YACRC,8BAAAA,gBAAgB,YAChB,iEACF;IAEF,MAAM,YACJ,OAAO,OAAO,eAAe,YAAY,OAAO,WAAW,SAAS,IAChE,OAAO,aACPC,2BAAAA;IACN,MAAM,OAAO,MAAM,QAAQ,QACzBC,2BAAAA,UAAU,UAAU,OAAO,SAAS,IACnC,QAAQC,2BAAAA,mBAAmB,MAAM,GAAG,GACrC,MACF;IACA,MAAM,SAAS,IAAI,oBACjB,SACA,KAAK,IACL,WACA,MACA,OACA,KAAK,SACP;IACA,MAAM,yBAAyB,QAAQ,MAAM,QAAQ,iBAAiB;IACtE,OAAO;GACT,CAAC;EACH;EAEA,IAAI,MAAM,SAAS,MAAM;GAKvB,MAAM,KAAK,MAAM;GACjB,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK,UAAU,MAAM,KAAK,IAAI,KAAK;GACtE,OAAOL,8BAAAA,iBAAiB,IAAoB,OAAO,WAAW;IAC5D,IAAI,YAAY,MAAM,aAAaG,2BAAAA;IAKnC,IAAI,gBAA+B;IACnC,IAAI;KACF,gBAAgB,MAAM,QAAQ,aAAa;IAC7C,QAAQ;KACN,gBAAgB;IAClB;IACA,IAAI,CAAC,MAAM,aAAa,eAAe;KACrC,MAAM,SAAS,uBAAuB,aAAa;KACnD,IAAI,OAAO,OAAO,eAAe,YAAY,OAAO,WAAW,SAAS,GACtE,YAAY,OAAO;IAEvB;IACA,MAAM,OAAO,MAAM,QAAQ,QACzBC,2BAAAA,UAAU,UAAU,IAAI,SAAS,IAChC,QAAQC,2BAAAA,mBAAmB,MAAM,GAAG,GACrC,MACF;IACA,MAAM,SAAS,IAAI,oBACjB,SACA,KAAK,IACL,WACA,MACA,eACA,KAAK,SACP;IACA,MAAM,yBAAyB,QAAQ,MAAM,QAAQ,iBAAiB;IACtE,OAAO;GACT,CAAC;EACH;EAGA,OAAOL,8BAAAA,iBAAiB,aACtB,IAAIC,8BAAAA,YACFC,8BAAAA,gBAAgB,YAChB,4EAA6E,MAA4B,KAAK,GAChH,CACF;CACF;CAEA,UAAkC;EAChC,IAAI,KAAK,WAAW,OAAOF,8BAAAA,iBAAiB,aAAmB,KAAA,CAAS;EACxE,KAAK,YAAY;EACjB,OAAOA,8BAAAA,iBAAiB,aAAmB,KAAA,CAAS;CACtD;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,eAAe,yBACb,QACA,MAIA,QACA,UACe;CACf,MAAM,UAAU,IAAI,IAAI,KAAK,OAAO,OAAO;CAK3C,MAAM,WAAW,OAAO;CAIxB,IADE,YAAY,SAAS,QAAQ,IAAI,UAAU,KAAK,KAAK,YAAY,oBAClD;EAEf,IAAI,MADmB,aAAa,SAAS,OAAO;GAAE;GAAU,MAAM;EAAM,CAAC,GAAG,MAAM,GACxE;EAKd,IAAI,QAAQ,IAAI,UAAU,GAAG;CAC/B;CAEA,IAAI,CAAC,KAAK,OAAO,UAAU;CAC3B,IAAI,QAAQ,IAAI,UAAU,GAAG;CAC7B,IAAI,CAAC,QAAQ,IAAI,KAAK,GAAG;CACzB,MAAM,aAAa,SAAS,gBAAgB,GAAG,MAAM;AACvD;;;AAIA,eAAe,aACb,SACA,QACkB;CAClB,MAAM,gBAAgB,QAAQ,MAAM,OAAO,0BAAU,IAAI,MAAM,SAAS,CAAC;CACzE,IAAI,OAAO,SAAS,QAAQ;MACvB,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;CAC7D,IAAI;EACF,MAAM;EACN,OAAO;CACT,QAAQ;EACN,OAAO;CACT,UAAU;EACR,OAAO,oBAAoB,SAAS,OAAO;CAC7C;AACF;;;ACzOA,SAAgB,kBAAkB,MAAuC;CACvE,OAAO,YAAY,YAAY,IAAI;AACrC;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,YAAY,MAAuC;CACjE,OAAO,YAAY,YAAY,IAAI;AACrC"}
|