@jeffusion/bungee-core 5.11.0 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +150 -51
- package/dist/plugins/chatgpt-oauth/control.js +338 -47
- package/dist/plugins/chatgpt-oauth/control.js.map +8 -7
- package/dist/plugins/chatgpt-oauth/index.js +181 -13
- package/dist/plugins/chatgpt-oauth/index.js.map +4 -4
- package/dist/plugins/chatgpt-oauth/manifest.json +98 -7
- package/dist/plugins/chatgpt-oauth/ui/AccountsPage.svelte +25 -15
- package/dist/plugins/chatgpt-oauth/ui/ChatgptQuotaWidget.svelte +7 -4
- package/dist/plugins/chatgpt-oauth/ui/account-model.js +16 -7
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/plugin-services/host-rpc.ts", "../../../src/plugin-services/wire-contract.ts", "../../../src/plugin-services/rpc-runtime.ts", "../../../src/plugin-services/peer-channel-protocol.ts", "../../../src/plugin-services/peer-channel-hub.ts", "../../../src/plugin-services/snapshot-store.ts", "../../../src/plugin-services.ts", "../../../../../plugins/chatgpt-oauth/server/rpc.ts", "../../../../../plugins/chatgpt-oauth/server/control.ts", "../../../../../plugins/chatgpt-oauth/server/oauth.ts", "../../../../../plugins/chatgpt-oauth/server/accounts.ts", "../../../../../plugins/chatgpt-oauth/server/sessions.ts", "../../../../../plugins/chatgpt-oauth/server/usage.ts", "../../../../../plugins/chatgpt-oauth/server/auto-reset.ts"],
|
|
3
|
+
"sources": ["../../../src/plugin-services/host-rpc.ts", "../../../src/plugin-services/wire-contract.ts", "../../../src/plugin-services/rpc-runtime.ts", "../../../src/plugin-services/peer-channel-protocol.ts", "../../../src/plugin-services/peer-channel-hub.ts", "../../../src/plugin-services/snapshot-store.ts", "../../../src/plugin-services.ts", "../../../../../plugins/chatgpt-oauth/server/rpc.ts", "../../../../../plugins/chatgpt-oauth/server/control.ts", "../../../../../plugins/chatgpt-oauth/server/oauth.ts", "../../../../../plugins/chatgpt-oauth/server/siwc.ts", "../../../../../plugins/chatgpt-oauth/server/accounts.ts", "../../../../../plugins/chatgpt-oauth/server/sessions.ts", "../../../../../plugins/chatgpt-oauth/server/usage.ts", "../../../../../plugins/chatgpt-oauth/server/auto-reset.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/**\n * Same-process host RPC adapter (P4): lets the canonical `PluginServiceHost`\n * lifecycle own RPC publications/consumption without a second plugin framework\n * and without faking a wire transport.\n *\n * The parent injects the trusted owner token, endpoint identity, required\n * placement/callee/journal callbacks, and the real host lease callback. Real\n * cross-process transport is NOT implemented: the required placement resolver\n * returns an exact endpoint registered in the exposed runtime, `ambiguous`, or\n * `null` meaning \"use the explicit local channel\". Commands run only through the\n * accepted runtime kernel. Journal-backed policies require `CommandJournal`;\n * application-owned `none` commands may execute without a journal and expose no\n * journal result/reconciliation capability. Caller identity, purpose, scope,\n * leases, and deadlines are host decisions; plugin call options may only carry\n * `signal`/`timeoutMs`/`operationId`, snapshotted without invoking accessors.\n *\n * Command binding errors are mapped once by the kernel to its fixed-code\n * `RpcInvocationError` (own `code`, no cause/message/raw operation id); the\n * client rebuilds a fresh public `RpcServiceError` from that code and the\n * validated operation id of the current call. No error instance is reused.\n */\nimport { assertSupportedServiceDeclarations, isCrossProcessSelfService } from './contracts';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { isProxy } from 'node:util/types';\nimport type {\n PluginServiceConsumption,\n PluginServiceDeclarations,\n PluginServiceProcess,\n PluginServicePublication,\n PluginServiceScope,\n} from './contracts';\nimport {\n RpcServiceRuntime,\n type RpcAdmissionGrant,\n type RpcAdmissionRequest,\n type RpcCaller,\n type RpcCommandAction,\n type RpcCommandExecution,\n type RpcCommandExecutor,\n type RpcDrainResult,\n type RpcEndpointBinding,\n type RpcEndpointHandle,\n type RpcHandlerContext,\n type RpcHandlerMap,\n type RpcInvocationErrorCode,\n type RpcInvokeRequest,\n type RpcRuntimeLimits,\n type RpcRuntimeStatus,\n} from './rpc-runtime';\nimport {\n type CommandAtomicPlanner,\n type CommandExternalExecutor,\n type CommandJournal,\n} from './command-journal';\nimport {\n defineRpcService,\n assertRpcData,\n encodeRpcJson,\n decodeRpcJson,\n RPC_JSON_MAX_BYTES,\n type RpcCallPurpose,\n type InferRpcData,\n type RpcCommandPolicy,\n type RpcJson,\n type RpcMethodDefinition,\n} from './wire-contract';\n\n/* -------------------------------------------------------------------------- */\n/* Fixed-code public errors */\n/* -------------------------------------------------------------------------- */\n\nexport type RpcServiceErrorCode =\n | RpcInvocationErrorCode\n | 'undeclared'\n | 'unavailable'\n | 'ambiguous_placement'\n | 'invalid_registration';\n\nconst SERVICE_ERROR_MESSAGES: Record<RpcServiceErrorCode, string> = {\n unauthorized: 'RPC call is not authorized',\n not_ready: 'RPC endpoint is not ready',\n retired: 'RPC endpoint is retiring',\n revoked: 'RPC endpoint generation was revoked',\n unsupported_method: 'RPC method is not published',\n wrong_purpose: 'RPC method is not published for this purpose',\n invalid_input: 'RPC input is not valid',\n invalid_output: 'RPC output is not valid',\n invalid_operation_id: 'RPC command operation id is invalid',\n overloaded: 'RPC runtime is at capacity',\n cancelled: 'RPC call was cancelled',\n timeout: 'RPC call deadline exceeded',\n unknown: 'RPC command outcome is unknown',\n capability_unavailable: 'RPC command execution is unavailable',\n closed: 'RPC runtime is closed',\n failed: 'RPC call failed',\n conflict: 'RPC command identity conflicts with an existing record',\n expired: 'RPC command result has expired',\n pending: 'RPC command is still pending',\n rejected: 'RPC command was rejected',\n missing: 'RPC command has no stored result',\n storage_failure: 'RPC command storage failed',\n deadlock: 'RPC call chain would deadlock',\n call_depth_exceeded: 'RPC call depth exceeded',\n undeclared: 'RPC service is not declared by the manifest',\n unavailable: 'RPC service is unavailable',\n ambiguous_placement: 'RPC service placement is ambiguous',\n invalid_registration: 'RPC registration is invalid',\n};\n\nconst SERVICE_ERROR_CODES = new Set<RpcServiceErrorCode>(Object.keys(SERVICE_ERROR_MESSAGES) as RpcServiceErrorCode[]);\n\n/** Fixed-code error. It never carries a provider cause, message, or payload. */\nexport class RpcServiceError extends Error {\n readonly name = 'RpcServiceError';\n readonly code: RpcServiceErrorCode;\n readonly operationId: string | null;\n\n constructor(code: RpcServiceErrorCode, operationId: string | null = null) {\n super(SERVICE_ERROR_MESSAGES[code]);\n this.code = code;\n this.operationId = operationId;\n }\n}\n\nfunction ownStringProperty(target: unknown, name: string): string | null {\n if (target === null || (typeof target !== 'object' && typeof target !== 'function')) return null;\n let descriptor: PropertyDescriptor | undefined;\n try { descriptor = Object.getOwnPropertyDescriptor(target, name); } catch { return null; }\n if (descriptor === undefined || !('value' in descriptor) || typeof descriptor.value !== 'string') return null;\n return descriptor.value;\n}\n\n/**\n * Rebuilds a fresh public error from the kernel's fixed code and the validated\n * operation id of THIS call. It never reuses the incoming instance, never reads\n * its operation id, and never reads a cause or message.\n */\nexport function toRpcServiceError(error: unknown, operationId: string | null): RpcServiceError {\n const raw = ownStringProperty(error, 'code');\n const code = raw !== null && SERVICE_ERROR_CODES.has(raw as RpcServiceErrorCode)\n ? raw as RpcServiceErrorCode\n : 'failed';\n return new RpcServiceError(code, operationId);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Public types */\n/* -------------------------------------------------------------------------- */\n\nexport interface RpcCallOptions {\n readonly signal?: AbortSignal;\n readonly timeoutMs?: number;\n readonly operationId?: string;\n}\n\nexport type RpcCommandClientExtras<D extends RpcMethodDefinition> = D extends { readonly command: RpcCommandPolicy }\n ? {\n /** Durable committed result query; runs through the same runtime lease/deadline as execute. */\n queryResult(operationId: string): Promise<InferRpcData<D['output']>>;\n /** Explicit host-authorized reconciliation for an unknown command outcome. */\n reconcile(operationId: string, input: InferRpcData<D['input']>): Promise<InferRpcData<D['output']>>;\n }\n : Record<never, never>;\n\nexport type RpcMethodClient<D extends RpcMethodDefinition> =\n ((input: InferRpcData<D['input']>, options?: RpcCallOptions) => Promise<InferRpcData<D['output']>>)\n & RpcCommandClientExtras<D>;\n\n/** Public plugin-facing RPC client derived from a literal contract. */\nexport type AsyncRpcClient<M extends Record<string, RpcMethodDefinition>> = {\n readonly [K in keyof M]: RpcMethodClient<M[K]>;\n};\n\n/** Logical placement identity, independent of any physical address or generation. */\nexport interface HostRpcServiceDescriptor {\n readonly provider: string;\n readonly service: string;\n readonly major: number;\n readonly kind: 'rpc';\n readonly process: PluginServiceProcess;\n readonly scope: PluginServiceScope;\n}\n\n/** Physical endpoint identity supplied by the trusted host for one owner instance. */\nexport interface HostRpcLifecycleIdentity {\n readonly endpoint: string;\n readonly instance: string;\n readonly generation: number;\n readonly catalog: string;\n /** Trusted callee subject; never derived from plugin input. */\n readonly subject: string;\n}\n\n/** Canonical owner lifecycle view; the adapter never keeps a second copy. */\nexport interface HostRpcLifecycleState {\n readonly ready: boolean;\n readonly retiring: boolean;\n readonly revoked: boolean;\n}\n\n/** Host-minted invocation frame; the real principal lives in the host callee frame. */\nexport interface HostRpcInvocationContext {\n readonly purpose: RpcCallPurpose;\n /** Opaque host correlation token; the leaf only trusts the required resolver. */\n readonly token: object;\n readonly signal?: AbortSignal;\n readonly deadlineAt?: number;\n}\n\nexport interface HostRpcLeaseRequest {\n readonly role: 'caller' | 'callee';\n readonly plugin: string;\n readonly scope: string;\n readonly state: HostRpcLifecycleState;\n readonly purpose: RpcCallPurpose;\n readonly operationId: string | null;\n /** Logical target provider. */\n readonly provider: string;\n}\n\nexport interface HostRpcLeaseGrant {\n readonly release: () => void;\n /** Host-verified existing request lease; only honored for request/attempt. */\n readonly allowRetired?: boolean;\n}\n\nexport type HostRpcAcquireLease = (request: HostRpcLeaseRequest) => HostRpcLeaseGrant;\n\nexport interface HostRpcMethodCapability {\n /** Synchronous private-state CAS planner for a `local-transaction` command. */\n readonly atomic?: CommandAtomicPlanner;\n /** Reconcile capability for an `external-contract` command. */\n readonly external?: CommandExternalExecutor;\n}\n\nexport type HostRpcCommandCapabilities<M extends Record<string, RpcMethodDefinition>> = {\n readonly [K in keyof M]?: HostRpcMethodCapability;\n};\n\n/** Everything the canonical host exposes for one owner to use RPC services. */\nexport interface HostRpcOwnerInput {\n readonly token: object;\n readonly plugin: string;\n /** Canonical owner scope: `'global'` or a trusted binding scope key. */\n readonly scope: string;\n readonly declarations: PluginServiceDeclarations;\n readonly dependencies: Readonly<Record<string, string>>;\n readonly lifecycle: HostRpcLifecycleIdentity;\n /** Canonical lifecycle source of truth; the adapter copies nothing. */\n readonly getLifecycleState: () => HostRpcLifecycleState;\n readonly acquireLease: HostRpcAcquireLease;\n readonly registerPublication?: (publication: PluginServicePublication) => void;\n readonly registerConsumption?: (consumption: PluginServiceConsumption, localProviderToken?: object) => void;\n readonly onDispose?: (cleanup: () => void) => void;\n readonly canCall?: (target: { readonly provider: string; readonly service: string; readonly major: number; readonly method: string }) => boolean;\n /** Required host invocation-frame resolver; null for plain plugin background calls. */\n readonly resolveInvocationContext: () => HostRpcInvocationContext | null;\n}\n\n/** Trusted peer broker input. This capability is never part of PluginServices. */\nexport interface HostRpcRemoteCallerInput extends HostRpcOwnerInput {\n readonly process: PluginServiceProcess;\n /** Must verify the current authenticated peer frame and logical caller authority. */\n readonly authorizeIncoming: (request: RpcAdmissionRequest, endpoint: NonNullable<ReturnType<RpcServiceRuntime['endpointInfo']>>) => boolean;\n}\n\nexport interface HostRpcRemoteCallerHandle {\n invokeTracked(request: Omit<RpcInvokeRequest, 'caller' | 'callerToken'>): ReturnType<RpcServiceRuntime['invokeTracked']>;\n dispose(): Promise<RpcDrainResult>;\n}\n\n/** Exact placement delegated to the host. `null` means \"use the explicit local channel\". */\nexport type HostRpcPlacementResolution =\n | { readonly kind: 'endpoint'; readonly endpoint: RpcEndpointHandle }\n | { readonly kind: 'ambiguous' }\n | null\n | undefined;\n\nexport interface HostRpcPlacementRequest {\n readonly provider: string;\n readonly service: string;\n readonly major: number;\n readonly method: string;\n readonly scope: PluginServiceScope;\n readonly bindingScope?: string;\n readonly caller: RpcCaller;\n readonly purpose?: RpcCallPurpose;\n}\n\nexport type HostRpcPlacementResolver = (request: HostRpcPlacementRequest) => HostRpcPlacementResolution;\n\nexport interface HostRpcJournalRequest {\n readonly provider: string;\n readonly service: string;\n readonly major: number;\n readonly method: string;\n readonly scope: PluginServiceScope;\n /** Binding scope key when `scope` is `binding`; keeps two bindings apart. */\n readonly bindingScope?: string;\n readonly policy: RpcCommandPolicy;\n readonly atomic?: CommandAtomicPlanner;\n readonly external?: CommandExternalExecutor;\n}\n\n/** Host-owned durable journal factory; `null` refuses commands for this key. */\nexport type HostRpcJournalResolver = (request: HostRpcJournalRequest) => CommandJournal | null;\n\n/** Trusted opaque callee context resolver. */\nexport type HostRpcCalleeResolver = (request: RpcAdmissionRequest, publication: HostRpcServiceDescriptor) => unknown;\n\n/**\n * Host-provided frame for one admitted native RPC handler. It lets the SAME\n * `PluginServiceHost` invocation store the real purpose/deadline/cancellation\n * for the duration of the handler, bound to the exact published owner, so a\n * channel operation started inside a native handler is authorized by the real\n * frame (never downgraded to `background`, never given a forged purpose).\n */\nexport interface HostRpcHandlerFrame {\n readonly purpose: RpcCallPurpose;\n readonly deadlineAt?: number;\n readonly signal?: AbortSignal;\n /** Exact published owner the call targets; `null` for a remote (peer) route. */\n readonly ownerToken: object | null;\n readonly operationId: string | null;\n}\n\nexport interface HostRpcAdapterOptions {\n readonly process: PluginServiceProcess;\n readonly limits?: RpcRuntimeLimits;\n readonly hostLifetime?: AbortSignal;\n readonly maxCallDepth?: number;\n /** Required host placement authority. */\n readonly resolvePlacement: HostRpcPlacementResolver;\n /** Required host journal authority. */\n readonly resolveJournal: HostRpcJournalResolver;\n /** Required trusted opaque callee frame authority. */\n readonly resolveCallee: HostRpcCalleeResolver;\n /**\n * Host callback that enters the exact published owner's trusted invocation\n * frame for one native handler call. The canonical `PluginServiceHost` wires\n * it to its OWN invocation store, so a native RPC handler shares one\n * purpose/deadline/cancel resolver with local dispatch and channel work.\n */\n readonly enterHostHandlerFrame?: (frame: HostRpcHandlerFrame, run: () => unknown) => unknown;\n}\n\nexport interface HostRpcPublication {\n readonly descriptor: HostRpcServiceDescriptor;\n}\n\n/** Host-only readonly directory entry for one real registered publication. */\nexport interface HostRpcPublicationView {\n readonly provider: string;\n readonly service: string;\n readonly major: number;\n readonly scope: PluginServiceScope;\n readonly scopeKey: string;\n readonly ready: boolean;\n readonly lifecycle: HostRpcLifecycleIdentity;\n /** The kernel-selected binding of the exact endpoint handle; never re-derived. */\n readonly binding: RpcEndpointBinding;\n}\n\nexport interface HostRpcOwnerHandle {\n readonly owner: HostRpcOwnerInput;\n publish<const M extends Record<string, RpcMethodDefinition>>(\n contract: { readonly id: string; readonly version: number; readonly methods: M },\n handlers: RpcHandlerMap<M, unknown>,\n capabilities?: HostRpcCommandCapabilities<M>,\n ): HostRpcPublication;\n consume<const M extends Record<string, RpcMethodDefinition>>(\n provider: string,\n contract: { readonly id: string; readonly version: number; readonly methods: M },\n ): AsyncRpcClient<M>;\n /** Canonical host hook: ready maps to kernel `markReady`. */\n markReady(): void;\n /** Canonical host hook: retirement maps to kernel `retire`. */\n retire(): void;\n /**\n * Canonical host hook: disposal maps to kernel `revoke` + bounded `drain`.\n * Returns the REAL drain verdict; `drained: false` is reported, never hidden.\n */\n dispose(): Promise<RpcDrainResult>;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Internal helpers */\n/* -------------------------------------------------------------------------- */\n\nconst SEP = '\\0';\nconst DEFAULT_MAX_CALL_DEPTH = 32;\nconst CALL_OPTION_KEYS = ['signal', 'timeoutMs', 'operationId'] as const;\nconst EMPTY_OPTIONS: RpcCallOptions = Object.freeze({});\n\ninterface ActiveFrame {\n readonly purpose: RpcCallPurpose;\n readonly depth: number;\n readonly chain: readonly string[];\n readonly deadlineAt: number;\n readonly signal: AbortSignal;\n}\n\n/** Host frame inheritance only: purpose, call chain, deadline, and cancellation. */\nconst FRAME_STORE = new AsyncLocalStorage<ActiveFrame>();\n\ninterface RegisteredPublication {\n readonly key: string;\n readonly handle: RpcEndpointHandle;\n readonly provider: string;\n readonly scopeKey: string;\n readonly scope: PluginServiceScope;\n readonly contractId: string;\n readonly contractVersion: number;\n readonly ownerState: OwnerState;\n}\n\ninterface OwnerState {\n readonly owner: HostRpcOwnerInput;\n readonly plugin: string;\n readonly scope: string;\n readonly scopeKind: PluginServiceScope;\n readonly callerSubject: string;\n readonly lifecycle: HostRpcLifecycleIdentity;\n readonly publications: Set<RegisteredPublication>;\n readonly process: PluginServiceProcess;\n readonly local: boolean;\n readonly authorizeIncoming?: HostRpcRemoteCallerInput['authorizeIncoming'];\n /** RPC capability revocation, independent of eventual resource reclamation. */\n revoked: boolean;\n released: boolean;\n}\n\ninterface CalleeInfo {\n readonly provider: string;\n readonly scopeKey: string;\n readonly scope: PluginServiceScope;\n readonly frame: unknown;\n /** Exact published owner token, or `null` for a remote (peer) route. */\n readonly ownerToken: object | null;\n}\n\ntype Handler = (input: unknown, context: RpcHandlerContext<unknown>) => unknown;\n\ntype RouteResolution =\n | { readonly kind: 'publication'; readonly publication: RegisteredPublication }\n | { readonly kind: 'remote'; readonly handle: RpcEndpointHandle }\n | { readonly kind: 'ambiguous' }\n | { readonly kind: 'missing' };\n\nconst CALLEE_INFO = new WeakMap<object, CalleeInfo>();\n\n/** Reads the trusted opaque callee frame the host resolver produced for an admitted call. */\nexport function readHostRpcCalleeFrame(callee: unknown): unknown {\n if (callee === null || typeof callee !== 'object') return null;\n return CALLEE_INFO.get(callee as object)?.frame ?? null;\n}\n\nfunction publicationKey(provider: string, scopeKey: string, service: string, major: number): string {\n return `${provider}${SEP}${scopeKey}${SEP}${service}${SEP}${major}`;\n}\n\nfunction scopeKindOf(scope: string): PluginServiceScope {\n return scope === 'global' ? 'global' : 'binding';\n}\n\nfunction callerSubjectFor(plugin: string, scope: string): string {\n return scope === 'global' ? plugin : `${plugin}@${scope}`;\n}\n\nfunction normalizeOperationId(operationId: unknown): string {\n if (typeof operationId !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(operationId)) {\n throw new RpcServiceError('invalid_operation_id');\n }\n return operationId;\n}\n\n/** Combines cancellation signals without depending on `AbortSignal.any` being present. */\nfunction anySignal(signals: readonly AbortSignal[]): AbortSignal {\n if (signals.length === 1) return signals[0];\n const native = (AbortSignal as unknown as { any?: (values: AbortSignal[]) => AbortSignal }).any;\n if (typeof native === 'function') return native.call(AbortSignal, [...signals]);\n const controller = new AbortController();\n const abort = (): void => controller.abort();\n for (const signal of signals) {\n if (signal.aborted) { abort(); break; }\n signal.addEventListener('abort', abort, { once: true });\n }\n return controller.signal;\n}\n\nfunction requirePurpose(definition: RpcMethodDefinition, purpose: RpcCallPurpose): RpcCallPurpose {\n if (!definition.purposes.includes(purpose)) throw new RpcServiceError('wrong_purpose');\n return purpose;\n}\n\n/** Own-descriptor snapshot of the trusted lifecycle identity; no accessor ever runs. */\nfunction snapshotLifecycle(value: unknown): HostRpcLifecycleIdentity {\n if (value === null || typeof value !== 'object' || isProxy(value)) throw new RpcServiceError('invalid_registration');\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) throw new RpcServiceError('invalid_registration');\n const read = (name: string): unknown => {\n const descriptor = Object.getOwnPropertyDescriptor(value, name);\n if (descriptor === undefined || !descriptor.enumerable || !('value' in descriptor)) {\n throw new RpcServiceError('invalid_registration');\n }\n return descriptor.value;\n };\n const allowed = new Set(['endpoint', 'instance', 'generation', 'catalog', 'subject']);\n for (const key of Reflect.ownKeys(value)) {\n if (typeof key !== 'string' || !allowed.has(key)) throw new RpcServiceError('invalid_registration');\n }\n const endpoint = read('endpoint');\n const instance = read('instance');\n const generation = read('generation');\n const catalog = read('catalog');\n const subject = read('subject');\n if (typeof endpoint !== 'string' || !endpoint || typeof instance !== 'string' || !instance\n || !Number.isSafeInteger(generation) || (generation as number) < 1\n || typeof catalog !== 'string' || typeof subject !== 'string' || !subject) {\n throw new RpcServiceError('invalid_registration');\n }\n return Object.freeze({ endpoint, instance, generation: generation as number, catalog, subject });\n}\n\n/** Own-descriptor snapshot of a dependencies record; accessors are rejected, never invoked. */\nfunction snapshotDependencies(value: unknown): Readonly<Record<string, string>> {\n if (value === undefined) return Object.freeze({});\n if (value === null || typeof value !== 'object' || isProxy(value)) throw new RpcServiceError('invalid_registration');\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) throw new RpcServiceError('invalid_registration');\n const result: Record<string, string> = {};\n for (const key of Reflect.ownKeys(value)) {\n if (typeof key !== 'string') throw new RpcServiceError('invalid_registration');\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (descriptor === undefined || !descriptor.enumerable || !('value' in descriptor) || typeof descriptor.value !== 'string') {\n throw new RpcServiceError('invalid_registration');\n }\n result[key] = descriptor.value;\n }\n return Object.freeze(result);\n}\n\n/**\n * Copies own enumerable data-function properties only. Accessors, proxies,\n * prototype methods, symbol keys, and unknown keys are rejected before any value\n * is read, so no plugin getter ever runs.\n */\nfunction snapshotHandlers(methods: Record<string, RpcMethodDefinition>, handler: unknown): Map<string, Handler> {\n if (handler === null || typeof handler !== 'object' || isProxy(handler)) throw new RpcServiceError('invalid_registration');\n const prototype = Object.getPrototypeOf(handler);\n if (prototype !== Object.prototype && prototype !== null) throw new RpcServiceError('invalid_registration');\n const allowed = new Set(Object.keys(methods));\n const collected = new Map<string, Handler>();\n for (const key of Reflect.ownKeys(handler)) {\n if (typeof key !== 'string' || !allowed.has(key)) throw new RpcServiceError('invalid_registration');\n const descriptor = Object.getOwnPropertyDescriptor(handler, key);\n if (descriptor === undefined || !descriptor.enumerable || !('value' in descriptor) || typeof descriptor.value !== 'function') {\n throw new RpcServiceError('invalid_registration');\n }\n collected.set(key, descriptor.value as Handler);\n }\n for (const name of allowed) if (!collected.has(name)) throw new RpcServiceError('invalid_registration');\n return collected;\n}\n\n/**\n * Snapshots one command capability through own descriptors only. Proxies, accessors,\n * unknown keys, and non-function planner/reconcile values are rejected before any\n * value is read, so no plugin getter ever runs and no mutable capability object is\n * retained.\n */\nfunction snapshotCapability(value: unknown): HostRpcMethodCapability {\n if (value === null || typeof value !== 'object' || isProxy(value)) throw new RpcServiceError('invalid_registration');\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) throw new RpcServiceError('invalid_registration');\n let atomic: CommandAtomicPlanner | undefined;\n let external: CommandExternalExecutor | undefined;\n for (const key of Reflect.ownKeys(value)) {\n if (typeof key !== 'string' || (key !== 'atomic' && key !== 'external')) throw new RpcServiceError('invalid_registration');\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (descriptor === undefined || !descriptor.enumerable || !('value' in descriptor)) {\n throw new RpcServiceError('invalid_registration');\n }\n if (key === 'atomic') {\n if (typeof descriptor.value !== 'function') throw new RpcServiceError('invalid_registration');\n atomic = descriptor.value as CommandAtomicPlanner;\n } else {\n external = snapshotExternal(descriptor.value);\n }\n }\n const record: { atomic?: CommandAtomicPlanner; external?: CommandExternalExecutor } = {};\n if (atomic !== undefined) record.atomic = atomic;\n if (external !== undefined) record.external = external;\n return Object.freeze(record);\n}\n\n/** Snapshots the `external.reconcile` function without retaining the plugin's object. */\nfunction snapshotExternal(value: unknown): CommandExternalExecutor {\n if (value === null || typeof value !== 'object' || isProxy(value)) throw new RpcServiceError('invalid_registration');\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) throw new RpcServiceError('invalid_registration');\n for (const key of Reflect.ownKeys(value)) {\n if (key !== 'reconcile') throw new RpcServiceError('invalid_registration');\n }\n const descriptor = Object.getOwnPropertyDescriptor(value, 'reconcile');\n if (descriptor === undefined || !descriptor.enumerable || !('value' in descriptor) || typeof descriptor.value !== 'function') {\n throw new RpcServiceError('invalid_registration');\n }\n return Object.freeze({ reconcile: descriptor.value as CommandExternalExecutor['reconcile'] });\n}\n\n/**\n * Descriptor-safe snapshot of the command capabilities record. Every key must name a\n * declared command method; accessors, proxies, symbol keys, unknown/non-command\n * methods, and unknown capability fields are rejected before `register`, so a failed\n * snapshot can never leave a ghost endpoint. The snapshot is frozen and independent\n * of the plugin's mutable objects.\n */\nfunction snapshotCapabilities(\n methodTable: Record<string, RpcMethodDefinition>,\n value: unknown,\n): Readonly<Record<string, HostRpcMethodCapability>> | null {\n if (value === undefined) return null;\n if (value === null || typeof value !== 'object' || isProxy(value)) throw new RpcServiceError('invalid_registration');\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) throw new RpcServiceError('invalid_registration');\n const record: Record<string, HostRpcMethodCapability> = {};\n for (const key of Reflect.ownKeys(value)) {\n if (typeof key !== 'string' || !Object.hasOwn(methodTable, key)) throw new RpcServiceError('invalid_registration');\n const definition = methodTable[key];\n if (definition === undefined || definition.kind !== 'command') throw new RpcServiceError('invalid_registration');\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (descriptor === undefined || !descriptor.enumerable || !('value' in descriptor)) {\n throw new RpcServiceError('invalid_registration');\n }\n if (descriptor.value === undefined) continue;\n record[key] = snapshotCapability(descriptor.value);\n }\n return Object.freeze(record);\n}\n\n/** Snapshots plugin call options without invoking accessors or accepting unknown keys. */\nfunction snapshotCallOptions(options: RpcCallOptions | undefined): RpcCallOptions {\n if (options === undefined) return EMPTY_OPTIONS;\n if (options === null || typeof options !== 'object' || isProxy(options)) throw new RpcServiceError('invalid_input');\n const prototype = Object.getPrototypeOf(options);\n if (prototype !== Object.prototype && prototype !== null) throw new RpcServiceError('invalid_input');\n const result: { signal?: AbortSignal; timeoutMs?: number; operationId?: string } = {};\n for (const key of Reflect.ownKeys(options)) {\n if (typeof key !== 'string' || !(CALL_OPTION_KEYS as readonly string[]).includes(key)) {\n throw new RpcServiceError('invalid_input');\n }\n const descriptor = Object.getOwnPropertyDescriptor(options, key);\n if (descriptor === undefined || !descriptor.enumerable || !('value' in descriptor)) {\n throw new RpcServiceError('invalid_input');\n }\n (result as Record<string, unknown>)[key] = descriptor.value;\n }\n if (result.signal !== undefined && !(result.signal instanceof AbortSignal)) throw new RpcServiceError('invalid_input');\n if (result.timeoutMs !== undefined\n && (typeof result.timeoutMs !== 'number' || !Number.isSafeInteger(result.timeoutMs) || result.timeoutMs < 0)) {\n throw new RpcServiceError('invalid_input');\n }\n if (result.operationId !== undefined && typeof result.operationId !== 'string') throw new RpcServiceError('invalid_input');\n return Object.freeze(result);\n}\n\nfunction defineContract<const M extends Record<string, RpcMethodDefinition>>(\n contract: { readonly id: string; readonly version: number; readonly methods: M },\n): { readonly id: string; readonly version: number; readonly methods: M } {\n try {\n return defineRpcService(contract) as unknown as { readonly id: string; readonly version: number; readonly methods: M };\n } catch {\n throw new RpcServiceError('invalid_registration');\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Adapter */\n/* -------------------------------------------------------------------------- */\n\nexport class HostRpcAdapter {\n readonly runtime: RpcServiceRuntime<unknown>;\n readonly #options: HostRpcAdapterOptions;\n readonly #process: PluginServiceProcess;\n readonly #maxCallDepth: number;\n readonly #ownersByToken = new WeakMap<object, OwnerState>();\n readonly #ownersByCaller = new Map<string, OwnerState>();\n readonly #publications = new Map<string, RegisteredPublication>();\n readonly #capabilities = new Map<string, Readonly<Record<string, HostRpcMethodCapability>>>();\n #closed = false;\n\n constructor(options: HostRpcAdapterOptions) {\n if (options === null || typeof options !== 'object' || typeof options.process !== 'string') {\n throw new RpcServiceError('invalid_registration');\n }\n if (typeof options.resolvePlacement !== 'function' || typeof options.resolveJournal !== 'function'\n || typeof options.resolveCallee !== 'function') {\n throw new RpcServiceError('invalid_registration');\n }\n this.#options = options;\n this.#process = options.process;\n this.#maxCallDepth = Number.isSafeInteger(options.maxCallDepth) && (options.maxCallDepth as number) > 0\n ? options.maxCallDepth as number : DEFAULT_MAX_CALL_DEPTH;\n this.runtime = new RpcServiceRuntime<unknown>({\n admit: (request) => this.#admit(request),\n commandExecutor: this.#commandExecutor(),\n hostLifetime: options.hostLifetime,\n limits: options.limits,\n });\n }\n\n status(): RpcRuntimeStatus {\n return this.runtime.status();\n }\n\n /**\n * Host-only readonly directory of this adapter's *real* registered\n * publications: the kernel-selected binding (endpoint/process/instance/\n * generation/catalog/scope/subject) of the exact endpoint handle, its owner\n * lifecycle identity and its current readiness. It is a plain snapshot for\n * host decision making (peer routing/validation); it grants nothing, exposes\n * no SDK surface and is never exposed through `PluginServices`.\n */\n publicationView(): readonly HostRpcPublicationView[] {\n const view: HostRpcPublicationView[] = [];\n for (const publication of this.#publications.values()) {\n const info = this.runtime.endpointInfo(publication.handle);\n if (info === null) continue;\n const lifecycle = publication.ownerState.lifecycle;\n const state = publication.ownerState.owner.getLifecycleState();\n view.push(Object.freeze({\n provider: publication.provider,\n service: publication.contractId,\n major: publication.contractVersion,\n scope: publication.scope,\n scopeKey: publication.scopeKey,\n ready: state.ready && !state.retiring && !state.revoked,\n lifecycle: Object.freeze({\n endpoint: lifecycle.endpoint, instance: lifecycle.instance,\n generation: lifecycle.generation, catalog: lifecycle.catalog, subject: lifecycle.subject,\n }),\n binding: info.binding,\n }));\n }\n return Object.freeze(view);\n }\n\n /** Closes the process runtime; the parent awaits this in the canonical shutdown. */\n async dispose(options: { readonly timeoutMs?: number } = {}) {\n this.#closed = true;\n return this.runtime.dispose(options);\n }\n\n /* ------------------------------ owners ---------------------------------- */\n\n createOwner(input: HostRpcOwnerInput): HostRpcOwnerHandle {\n return this.#ownerHandle(this.#createOwnerState(input, this.#process, true));\n }\n\n /** Imports an authenticated concrete caller, not a plugin instance or SDK facade. */\n createRemoteCaller(input: HostRpcRemoteCallerInput): HostRpcRemoteCallerHandle {\n if (!['control', 'worker', 'ingress'].includes(input?.process) || typeof input?.authorizeIncoming !== 'function') {\n throw new RpcServiceError('invalid_registration');\n }\n const authorize = input.authorizeIncoming;\n const state = this.#createOwnerState(input, input.process, false, authorize);\n return Object.freeze({\n invokeTracked: (request: Omit<RpcInvokeRequest, 'caller' | 'callerToken'>) => this.runtime.invokeTracked({\n ...request, caller: Object.freeze({ subject: state.callerSubject, scope: state.scopeKind }), callerToken: state.owner.token,\n }),\n dispose: () => this.#disposeOwner(state),\n });\n }\n\n #createOwnerState(input: HostRpcOwnerInput, process: PluginServiceProcess, local: boolean,\n authorizeIncoming?: HostRpcRemoteCallerInput['authorizeIncoming']): OwnerState {\n if (this.#closed) throw new RpcServiceError('closed');\n if (input === null || typeof input !== 'object' || input.token === null || typeof input.token !== 'object') {\n throw new RpcServiceError('invalid_registration');\n }\n if (typeof input.plugin !== 'string' || !input.plugin || typeof input.scope !== 'string' || !input.scope) {\n throw new RpcServiceError('invalid_registration');\n }\n if (typeof input.getLifecycleState !== 'function' || typeof input.acquireLease !== 'function'\n || typeof input.resolveInvocationContext !== 'function') {\n throw new RpcServiceError('invalid_registration');\n }\n if (this.#ownersByToken.has(input.token)) throw new RpcServiceError('invalid_registration');\n const callerSubject = callerSubjectFor(input.plugin, input.scope);\n if (local && this.#ownersByCaller.has(callerSubject)) throw new RpcServiceError('invalid_registration');\n const state: OwnerState = {\n owner: input,\n plugin: input.plugin,\n scope: input.scope,\n scopeKind: scopeKindOf(input.scope),\n callerSubject,\n lifecycle: snapshotLifecycle(input.lifecycle),\n publications: new Set(),\n process, local, authorizeIncoming,\n revoked: false,\n released: false,\n };\n // Fail closed before any publication: dependency records must be snapshot-clean.\n snapshotDependencies(input.dependencies);\n if (Object.hasOwn(input, 'optionalDependencies')) throw new RpcServiceError('invalid_registration');\n try { assertSupportedServiceDeclarations(input.declarations); } catch { throw new RpcServiceError('invalid_registration'); }\n this.#ownersByToken.set(input.token, state);\n if (local) this.#ownersByCaller.set(callerSubject, state);\n return state;\n }\n\n #ownerHandle(state: OwnerState): HostRpcOwnerHandle {\n return Object.freeze({\n owner: state.owner,\n publish: <const M extends Record<string, RpcMethodDefinition>>(\n contract: { readonly id: string; readonly version: number; readonly methods: M },\n handlers: RpcHandlerMap<M, unknown>,\n capabilities?: HostRpcCommandCapabilities<M>,\n ) => this.#publish(state, contract, handlers, capabilities),\n consume: <const M extends Record<string, RpcMethodDefinition>>(\n provider: string,\n contract: { readonly id: string; readonly version: number; readonly methods: M },\n ) => this.#consume(state, provider, contract),\n markReady: () => { this.#markReady(state); },\n retire: () => { this.#retire(state); },\n dispose: () => this.#disposeOwner(state),\n });\n }\n\n #markReady(state: OwnerState): void {\n if (state.revoked || state.released || this.#closed) throw new RpcServiceError('closed');\n for (const publication of state.publications) this.runtime.markReady(publication.handle);\n }\n\n #retire(state: OwnerState): void {\n if (state.released) return;\n for (const publication of state.publications) this.runtime.retire(publication.handle);\n }\n\n /** Revoke + REAL bounded drain. Resources are dropped only after a drained verdict. */\n async #disposeOwner(state: OwnerState): Promise<RpcDrainResult> {\n if (state.released) return Object.freeze({ drained: true, active: 0 });\n state.revoked = true;\n this.runtime.revokeCaller(state.callerSubject, state.owner.token);\n for (const publication of state.publications) this.runtime.revoke(publication.handle);\n const result = await this.runtime.drainOwner(state.callerSubject, [...state.publications].map(publication => publication.handle), { callerToken: state.owner.token });\n if (result.drained) this.#releaseOwner(state);\n return result;\n }\n\n /** Drops publication/capability/owner mapping so the same logical owner can be recreated. */\n #releaseOwner(state: OwnerState): void {\n for (const publication of state.publications) {\n this.#publications.delete(publication.key);\n this.#capabilities.delete(publication.key);\n }\n state.publications.clear();\n state.released = true;\n if (this.#ownersByCaller.get(state.callerSubject) === state) this.#ownersByCaller.delete(state.callerSubject);\n }\n\n /* ---------------------------- publications ------------------------------ */\n\n #publish<const M extends Record<string, RpcMethodDefinition>>(\n state: OwnerState,\n contractInput: { readonly id: string; readonly version: number; readonly methods: M },\n handlers: RpcHandlerMap<M, unknown>,\n capabilities?: HostRpcCommandCapabilities<M>,\n ): HostRpcPublication {\n const lifecycleState = state.owner.getLifecycleState();\n if (state.revoked || state.released || this.#closed || lifecycleState.revoked || lifecycleState.retiring) {\n throw new RpcServiceError('closed');\n }\n const contract = defineContract(contractInput);\n if (this.#matchPublication(state, contract.id, contract.version) === null) throw new RpcServiceError('undeclared');\n const key = publicationKey(state.plugin, state.scope, contract.id, contract.version);\n // Duplicate detection happens BEFORE register so no ghost endpoint is created.\n if (this.#publications.has(key)) throw new RpcServiceError('invalid_registration');\n const methodTable = contract.methods as Record<string, RpcMethodDefinition>;\n const collected = snapshotHandlers(methodTable, handlers);\n // Snapshot capabilities BEFORE `register`: a hostile accessor must fail closed with\n // zero endpoints and no parent publication callback, never leave a ghost endpoint.\n const capabilityRecord = snapshotCapabilities(methodTable, capabilities);\n const wrapped: Record<string, Handler> = {};\n for (const [name, definition] of Object.entries(methodTable)) {\n const chainKey = `${state.plugin}${SEP}${state.scope}${SEP}${contract.id}${SEP}${contract.version}${SEP}${name}`;\n wrapped[name] = this.#wrapHandler(collected.get(name) as Handler, definition, chainKey);\n }\n const binding: RpcEndpointBinding = {\n endpoint: state.lifecycle.endpoint,\n process: this.#process,\n instance: state.lifecycle.instance,\n generation: state.lifecycle.generation,\n catalog: state.lifecycle.catalog,\n scope: state.scopeKind,\n subject: state.lifecycle.subject,\n };\n let handle: RpcEndpointHandle;\n try {\n handle = this.runtime.register({\n provider: state.plugin,\n binding,\n contract,\n handler: wrapped as unknown as RpcHandlerMap<M, unknown>,\n });\n } catch {\n throw new RpcServiceError('invalid_registration');\n }\n const descriptor: HostRpcServiceDescriptor = Object.freeze({\n provider: state.plugin, service: contract.id, major: contract.version, kind: 'rpc',\n process: this.#process, scope: state.scopeKind,\n });\n const publication: RegisteredPublication = {\n key, handle, provider: state.plugin, scopeKey: state.scope, scope: state.scopeKind,\n contractId: contract.id, contractVersion: contract.version, ownerState: state,\n };\n this.#publications.set(key, publication);\n state.publications.add(publication);\n if (capabilityRecord !== null && Object.keys(capabilityRecord).length > 0) {\n this.#capabilities.set(key, capabilityRecord);\n }\n try {\n state.owner.registerPublication?.({\n id: contract.id, version: contract.version, kind: 'rpc', process: this.#process, scope: 'global',\n });\n } catch {\n // Roll back completely: no ghost endpoint, no reservation, no capability.\n this.runtime.revoke(handle);\n this.#publications.delete(key);\n this.#capabilities.delete(key);\n state.publications.delete(publication);\n throw new RpcServiceError('invalid_registration');\n }\n return Object.freeze({ descriptor });\n }\n\n #wrapHandler(original: Handler, definition: RpcMethodDefinition, chainKey: string): Handler {\n // Commands are framed once by `#commandExecutor` for the whole journal capability\n // (execute/query/reconcile); framing the business handler again here would inflate\n // depth and could manufacture false same-method cycles.\n if (definition.kind === 'command') return original;\n return (input, context) => this.#runInFrame(context, chainKey, () => original(input, context));\n }\n\n /** Runs `run` inside one inherited host frame: purpose, chain, deadline, cancellation. */\n #runInFrame(context: RpcHandlerContext<unknown>, chainKey: string, run: () => unknown): unknown {\n const parent = FRAME_STORE.getStore() ?? null;\n const depth = (parent?.depth ?? 0) + 1;\n if (depth > this.#maxCallDepth) throw new RpcServiceError('call_depth_exceeded', context.operationId);\n const actualDeadline = typeof context.deadlineAt === 'number' ? context.deadlineAt : Number.POSITIVE_INFINITY;\n const frame: ActiveFrame = Object.freeze({\n purpose: context.purpose,\n depth,\n chain: Object.freeze([...(parent?.chain ?? []), chainKey]),\n deadlineAt: parent === null ? actualDeadline : Math.min(parent.deadlineAt, actualDeadline),\n // A nested call must also abort when the parent call is cancelled.\n signal: parent === null ? context.signal : anySignal([parent.signal, context.signal]),\n });\n const enter = this.#options.enterHostHandlerFrame;\n if (enter === undefined) return FRAME_STORE.run(frame, run);\n // The canonical host enters its OWN live invocation frame for the exact\n // published owner, so channel work and nested local dispatch inside this\n // handler inherit the real purpose/deadline/cancel and the exact owner\n // authority instead of being re-interpreted as an unauthenticated background\n // task. `ownerToken` is host-private (`CALLEE_INFO`), never a payload field.\n const info = context.callee !== null && typeof context.callee === 'object'\n ? CALLEE_INFO.get(context.callee as object)\n : undefined;\n const hostFrame: HostRpcHandlerFrame = {\n purpose: frame.purpose,\n ...(Number.isFinite(frame.deadlineAt) ? { deadlineAt: frame.deadlineAt } : {}),\n signal: frame.signal,\n ownerToken: info?.ownerToken ?? null,\n operationId: context.operationId ?? null,\n };\n return FRAME_STORE.run(frame, () => enter(hostFrame, run));\n }\n\n /* ----------------------------- consumption ------------------------------ */\n\n #consume<const M extends Record<string, RpcMethodDefinition>>(\n state: OwnerState,\n provider: string,\n contractInput: { readonly id: string; readonly version: number; readonly methods: M },\n ): AsyncRpcClient<M> {\n if (state.released || this.#closed) throw new RpcServiceError('closed');\n if (typeof provider !== 'string' || !provider) throw new RpcServiceError('invalid_registration');\n const contract = defineContract(contractInput);\n const declaration = this.#matchConsumption(state, provider, contract.id, contract.version);\n if (declaration === null) throw new RpcServiceError('undeclared');\n if (!isCrossProcessSelfService(state.plugin, declaration, state.owner.declarations) && (provider === state.plugin || !Object.hasOwn(state.owner.dependencies, provider))) throw new RpcServiceError('undeclared');\n const scopeKey = 'global';\n const firstMethod = Object.keys(contract.methods as Record<string, RpcMethodDefinition>)[0];\n const route = this.#resolveRoute(state, { provider, service: contract.id, major: contract.version, method: firstMethod }, scopeKey);\n if (route.kind === 'ambiguous') throw new RpcServiceError('ambiguous_placement');\n if (route.kind === 'missing') {\n throw new RpcServiceError('unavailable');\n }\n state.owner.registerConsumption?.(declaration, route.kind === 'publication' ? route.publication.ownerState.owner.token : undefined);\n const methodTable = contract.methods as Record<string, RpcMethodDefinition>;\n const client: Record<string, unknown> = {};\n for (const [method, definition] of Object.entries(methodTable)) {\n client[method] = this.#makeMethodClient(state, provider, contract, method, definition);\n }\n return Object.freeze(client) as AsyncRpcClient<M>;\n }\n\n #makeMethodClient<const M extends Record<string, RpcMethodDefinition>>(\n state: OwnerState,\n provider: string,\n contract: { readonly id: string; readonly version: number; readonly methods: M },\n method: string,\n definition: RpcMethodDefinition,\n ): unknown {\n const target = { provider, service: contract.id, major: contract.version, method };\n const invoke = (action: RpcCommandAction | undefined, input: unknown, operationId: string | null, options: RpcCallOptions) =>\n this.#invokeAction(state, target, definition, action, input, operationId, options);\n const call = async (input: unknown, options?: RpcCallOptions): Promise<unknown> => {\n const snapshot = snapshotCallOptions(options);\n const operationId = this.#operationId(definition, snapshot);\n return invoke(definition.kind === 'command' ? 'execute' : undefined, input, operationId, snapshot);\n };\n if (definition.kind !== 'command') return call;\n const queryResult = (operationId: string): Promise<unknown> =>\n invoke('query-result', null, normalizeOperationId(operationId), EMPTY_OPTIONS);\n const reconcile = (operationId: string, input: unknown): Promise<unknown> =>\n invoke('reconcile', input, normalizeOperationId(operationId), EMPTY_OPTIONS);\n return Object.assign(call, { queryResult, reconcile });\n }\n\n #operationId(definition: RpcMethodDefinition, options: RpcCallOptions): string | null {\n const raw = options.operationId;\n if (definition.kind === 'query') {\n if (raw !== undefined) throw new RpcServiceError('invalid_operation_id');\n return null;\n }\n if (raw === undefined) throw new RpcServiceError('invalid_operation_id');\n return normalizeOperationId(raw);\n }\n\n async #invokeAction(\n state: OwnerState,\n target: { readonly provider: string; readonly service: string; readonly major: number; readonly method: string },\n definition: RpcMethodDefinition,\n action: RpcCommandAction | undefined,\n input: unknown,\n operationId: string | null,\n options: RpcCallOptions,\n ): Promise<RpcJson> {\n if (state.revoked || state.released || this.#closed) throw new RpcServiceError('closed', operationId);\n // The manifest consumption and its canonical dependency record are re-validated on\n // every call: a removed declaration or dependency is refused.\n const scopeKey = this.#targetScope(state, target);\n if (scopeKey === null) throw new RpcServiceError('undeclared', operationId);\n const parent = FRAME_STORE.getStore() ?? null;\n if (parent !== null && parent.chain.includes(`${target.provider}${SEP}${scopeKey}${SEP}${target.service}${SEP}${target.major}${SEP}${target.method}`)) {\n throw new RpcServiceError('deadlock');\n }\n // Enforce the consumer contract's own input schema/byte bound before the provider\n // sees the call. `query-result` carries only the null control DTO, never business input.\n if (action !== 'query-result') {\n try {\n const limit = definition.maxInputBytes ?? RPC_JSON_MAX_BYTES;\n input = decodeRpcJson(encodeRpcJson(input, limit), limit);\n assertRpcData(definition.input, input, limit);\n } catch {\n throw new RpcServiceError('invalid_input', operationId);\n }\n }\n const caller = Object.freeze({ subject: state.callerSubject, scope: state.scopeKind });\n // Resolve the host invocation frame exactly once; purpose and request share that snapshot.\n const invocation = state.owner.resolveInvocationContext();\n const purpose = this.#selectPurpose(state, definition, invocation);\n const route = this.#resolveRoute(state, target, scopeKey, purpose);\n if (route.kind === 'ambiguous') throw new RpcServiceError('ambiguous_placement');\n if (route.kind === 'missing') throw new RpcServiceError('unavailable');\n const request = this.#buildRequest(target, caller, purpose, input, operationId, action, options, parent, invocation, state.owner.token);\n try {\n const result = await this.runtime.invoke(request);\n try { assertRpcData(definition.output, result, definition.maxOutputBytes); }\n catch { throw new RpcServiceError('invalid_output', operationId); }\n return result;\n } catch (error) {\n throw toRpcServiceError(error, operationId);\n }\n }\n\n /** Purpose is inherited, never rank-converted; the method must explicitly allow it. */\n #selectPurpose(state: OwnerState, definition: RpcMethodDefinition, invocation: HostRpcInvocationContext | null): RpcCallPurpose {\n const parent = FRAME_STORE.getStore() ?? null;\n if (parent !== null) return requirePurpose(definition, parent.purpose);\n if (invocation !== null) return requirePurpose(definition, invocation.purpose);\n const ready = state.owner.getLifecycleState().ready;\n return requirePurpose(definition, ready ? 'background' : 'bootstrap');\n }\n\n #buildRequest(\n target: { readonly provider: string; readonly service: string; readonly major: number; readonly method: string },\n caller: RpcCaller,\n purpose: RpcCallPurpose,\n input: unknown,\n operationId: string | null,\n action: RpcCommandAction | undefined,\n options: RpcCallOptions,\n parent: ActiveFrame | null,\n invocation: HostRpcInvocationContext | null,\n callerToken: object,\n ) {\n let timeoutMs = options.timeoutMs;\n const deadlineAt = Math.min(parent?.deadlineAt ?? Infinity, invocation?.deadlineAt ?? Infinity);\n if (parent !== null && Number.isFinite(parent.deadlineAt)) {\n const remaining = Math.floor(parent.deadlineAt - Date.now());\n timeoutMs = timeoutMs === undefined ? remaining : Math.min(timeoutMs, remaining);\n }\n if (invocation?.deadlineAt !== undefined) {\n const remaining = Math.floor(invocation.deadlineAt - Date.now());\n timeoutMs = timeoutMs === undefined ? remaining : Math.min(timeoutMs, remaining);\n }\n if (timeoutMs !== undefined && (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0)) {\n throw new RpcServiceError('timeout', operationId);\n }\n const explicitSignal = options.signal;\n const parentSignal = parent?.signal;\n let signal = explicitSignal === undefined\n ? parentSignal\n : parentSignal === undefined ? explicitSignal : anySignal([explicitSignal, parentSignal]);\n if (invocation?.signal !== undefined) signal = signal === undefined ? invocation.signal : anySignal([signal, invocation.signal]);\n const request: {\n target: { provider: string; service: string; major: number; method: string };\n caller: RpcCaller;\n callerToken: object;\n purpose: RpcCallPurpose;\n input: unknown;\n operationId?: string;\n commandAction?: RpcCommandAction;\n signal?: AbortSignal;\n timeoutMs?: number;\n deadlineAt?: number;\n } = {\n target: { provider: target.provider, service: target.service, major: target.major, method: target.method },\n caller,\n callerToken,\n purpose,\n input,\n };\n if (operationId !== null) request.operationId = operationId;\n if (action !== undefined) request.commandAction = action;\n if (signal !== undefined) request.signal = signal;\n if (timeoutMs !== undefined) request.timeoutMs = timeoutMs;\n if (Number.isFinite(deadlineAt)) request.deadlineAt = deadlineAt;\n return request;\n }\n\n /* ------------------------------- routing -------------------------------- */\n\n #matchPublication(state: OwnerState, id: string, version: number): PluginServicePublication | null {\n return state.owner.declarations.provides?.find((value) =>\n value.id === id && value.version === version\n && (value.kind ?? 'local') === 'rpc'\n && value.process === this.#process\n && (value.scope ?? 'global') === 'global' && state.scope === 'global') ?? null;\n }\n\n #matchConsumption(state: OwnerState, provider: string, id: string, version: number): PluginServiceConsumption | null {\n return state.owner.declarations.consumes?.find((value) =>\n value.plugin === provider && value.id === id && value.version === version\n && (value.kind ?? 'local') === 'rpc'\n && value.process === state.process) ?? null;\n }\n\n #targetScope(\n state: OwnerState,\n target: { readonly provider: string; readonly service: string; readonly major: number },\n ): string | null {\n const consumption = state.owner.declarations.consumes?.find((value) =>\n value.plugin === target.provider && value.id === target.service && value.version === target.major\n && (value.kind ?? 'local') === 'rpc' && value.process === state.process) ?? null;\n if (consumption === null) return null;\n if (!isCrossProcessSelfService(state.plugin, consumption, state.owner.declarations) && (target.provider === state.plugin || !Object.hasOwn(state.owner.dependencies, target.provider))) return null;\n return 'global';\n }\n\n /** Host placement authority runs first; `null` opts into the explicit local channel. */\n #resolveRoute(\n state: OwnerState,\n target: { readonly provider: string; readonly service: string; readonly major: number; readonly method: string },\n scopeKey: string,\n purpose?: RpcCallPurpose,\n ): RouteResolution {\n let placement: HostRpcPlacementResolution;\n try {\n placement = this.#options.resolvePlacement({\n provider: target.provider,\n service: target.service,\n major: target.major,\n method: target.method,\n scope: scopeKey === 'global' ? 'global' : 'binding',\n ...(scopeKey === 'global' ? {} : { bindingScope: scopeKey }),\n caller: Object.freeze({ subject: state.callerSubject, scope: state.scopeKind }),\n purpose,\n });\n } catch {\n return { kind: 'missing' };\n }\n if (placement !== null && placement !== undefined) {\n if (placement.kind === 'ambiguous') return { kind: 'ambiguous' };\n return { kind: 'remote', handle: placement.endpoint };\n }\n const publication = this.#publications.get(publicationKey(target.provider, scopeKey, target.service, target.major));\n return publication === undefined ? { kind: 'missing' } : { kind: 'publication', publication };\n }\n\n /* ----------------------------- admission -------------------------------- */\n\n #admit(request: RpcAdmissionRequest): RpcAdmissionGrant<unknown> | null {\n if (this.#closed) return null;\n const state = request.callerToken === undefined ? this.#ownersByCaller.get(request.caller.subject)\n : this.#ownersByToken.get(request.callerToken);\n if (state === undefined || state.revoked || state.released) return null;\n if (state.callerSubject !== request.caller.subject\n || (request.caller.scope !== undefined && state.scopeKind !== request.caller.scope)) return null;\n const callerState = state.owner.getLifecycleState();\n if (callerState.revoked) return null;\n if (state.owner.canCall !== undefined && !state.owner.canCall({ ...request.target })) return null;\n if (!callerState.ready && request.purpose !== 'bootstrap') return null;\n const target = { ...request.target };\n const scopeKey = this.#targetScope(state, target);\n if (scopeKey === null) return null;\n const route = this.#resolveRoute(state, target, scopeKey, request.purpose);\n if (route.kind === 'ambiguous' || route.kind === 'missing') return null;\n const publication = route.kind === 'publication' ? route.publication : null;\n const endpoint = route.kind === 'publication' ? route.publication.handle : route.handle;\n // The callee publication is built from the REAL kernel-bound endpoint identity, never\n // from the adapter process or a plugin-supplied location. A foreign/unconfirmable\n // endpoint, or one whose provider/service/major/scope disagrees with the requested\n // target, is refused before any lease or callee frame is produced.\n const info = this.runtime.endpointInfo(endpoint);\n if (info === null) return null;\n if (info.provider !== target.provider || info.contract.id !== target.service || info.contract.version !== target.major) {\n return null;\n }\n const scope = info.binding.scope;\n if ((scopeKey === 'global') !== (scope === 'global')) return null;\n if (!state.local) {\n try { if (state.authorizeIncoming?.(request, info) !== true) return null; }\n catch { return null; }\n if (state.revoked || state.released || this.#closed) return null;\n }\n const provider = info.provider;\n // Logical clients can be relocated without retaining an unrelated local provider.\n const consumption = this.#matchConsumption(state, target.provider, target.service, target.major)!;\n state.owner.registerConsumption?.(consumption, publication?.ownerState.owner.token);\n // Resolve the trusted callee frame before any lease so a throwing host\n // resolver cannot leak leases.\n const hostFrame = this.#options.resolveCallee(\n request,\n Object.freeze({ provider, service: target.service, major: target.major, kind: 'rpc', process: info.binding.process, scope }),\n );\n // Caller lease holds the issuing owner for the whole call lifespan.\n let callerRelease: () => void = () => undefined;\n try {\n const lease = state.owner.acquireLease({\n role: 'caller', plugin: state.plugin, scope: state.scope, state: callerState,\n purpose: request.purpose, operationId: request.operationId, provider: target.provider,\n });\n if (lease === null || typeof lease !== 'object' || typeof lease.release !== 'function') return null;\n callerRelease = once(() => { try { lease.release(); } catch { /* host-owned */ } });\n } catch { return null; }\n // Callee lease holds the provider (local only). A callee the kernel will refuse\n // (revoked / retiring without an existing-lease proof / unready non-bootstrap)\n // is NOT leased here, so the kernel reports the exact state instead of a lease error.\n let calleeRelease: (() => void) | null = null;\n let allowRetired = false;\n if (publication !== null) {\n const calleeState = publication.ownerState.owner.getLifecycleState();\n const runnable = calleeState.revoked ? false\n : calleeState.retiring ? (request.purpose === 'request' || request.purpose === 'attempt')\n : (calleeState.ready || request.purpose === 'bootstrap');\n if (runnable) {\n try {\n const lease = publication.ownerState.owner.acquireLease({\n role: 'callee', plugin: publication.provider, scope: publication.scopeKey, state: calleeState,\n purpose: request.purpose, operationId: request.operationId, provider: target.provider,\n });\n if (lease === null || typeof lease !== 'object' || typeof lease.release !== 'function') {\n callerRelease();\n return null;\n }\n calleeRelease = once(() => { try { lease.release(); } catch { /* host-owned */ } });\n allowRetired = lease.allowRetired === true\n && (request.purpose === 'request' || request.purpose === 'attempt');\n } catch { callerRelease(); return null; }\n }\n }\n const callee = Object.freeze({});\n CALLEE_INFO.set(callee, { provider, scopeKey, scope, frame: hostFrame, ownerToken: publication?.ownerState.owner.token ?? null });\n const release = once(() => {\n try { calleeRelease?.(); } catch { /* host-owned */ }\n try { callerRelease(); } catch { /* host-owned */ }\n });\n // A host callback can synchronously dispose this capability before a task exists.\n // Recheck after every admission callback has returned, before handing the kernel a grant.\n if (state.revoked || state.released || this.#closed) { release(); return null; }\n return {\n endpoint, callee, release, callerToken: state.owner.token,\n allowUnready: request.purpose === 'bootstrap',\n allowRetired,\n };\n }\n\n /* ------------------------------ commands -------------------------------- */\n\n #commandExecutor(): RpcCommandExecutor<unknown> {\n const run = async (\n execution: Omit<RpcCommandExecution<unknown>, 'executeBusiness'>,\n action: RpcCommandAction,\n ): Promise<unknown> => {\n const callee = execution.context.callee;\n const info = callee !== null && typeof callee === 'object' ? CALLEE_INFO.get(callee as object) : undefined;\n if (info === undefined) throw new RpcServiceError('capability_unavailable', execution.operationId);\n const chainKey = `${info.provider}${SEP}${info.scopeKey}${SEP}${execution.contract.id}${SEP}${execution.contract.version}${SEP}${execution.method}`;\n const journal = this.#journalFor(info, execution);\n // Application-owned CAS/idempotency (e.g. a budget ledger or credential\n // version fence) has one transaction authority. No parallel journal is\n // created for an explicitly non-deduplicated command.\n if (journal === null && execution.definition.command?.deduplication === 'none') {\n if (action !== 'execute') throw new RpcServiceError('capability_unavailable', execution.operationId);\n return this.#runInFrame(execution.context, chainKey, () => (execution as RpcCommandExecution<unknown>).executeBusiness());\n }\n if (journal === null) throw new RpcServiceError('capability_unavailable', execution.operationId);\n // Every journal action (execute/query/reconcile) runs inside the real RPC frame so\n // the business handler and any nested external-reconcile RPC inherit purpose,\n // chain, deadline, and cancellation. Commands are framed once here, not in #wrapHandler.\n return this.#runInFrame(execution.context, chainKey, () => {\n if (action === 'execute') return journal.execute(execution as RpcCommandExecution<unknown>);\n if (action === 'query-result') return journal.query(execution.operationId, execution.context.caller);\n return journal.reconcile(execution);\n });\n };\n return {\n execute: (execution) => run(execution, 'execute'),\n queryResult: (execution) => run(execution, 'query-result'),\n reconcile: (execution) => run(execution, 'reconcile'),\n };\n }\n\n #journalFor(\n info: CalleeInfo,\n execution: Omit<RpcCommandExecution<unknown>, 'executeBusiness'>,\n ): CommandJournal | null {\n const policy = execution.definition.command;\n if (policy === undefined) throw new RpcServiceError('capability_unavailable', execution.operationId);\n const capability = this.#capabilities.get(\n publicationKey(info.provider, info.scopeKey, execution.contract.id, execution.contract.version),\n )?.[execution.method];\n try {\n return this.#options.resolveJournal({\n provider: info.provider,\n service: execution.contract.id,\n major: execution.contract.version,\n method: execution.method,\n scope: info.scope,\n ...(info.scope === 'binding' ? { bindingScope: info.scopeKey } : {}),\n policy,\n ...(capability?.atomic === undefined ? {} : { atomic: capability.atomic }),\n ...(capability?.external === undefined ? {} : { external: capability.external }),\n }) ?? null;\n } catch {\n throw new RpcServiceError('capability_unavailable', execution.operationId);\n }\n }\n}\n\nfunction once(action: () => void): () => void {\n let done = false;\n return () => { if (done) return; done = true; action(); };\n}\n",
|
|
6
6
|
"/**\n * Plugin service RPC data contract (P1/P4): a dependency-free schema DSL, a\n * bounded strict-JSON codec, and service/method contract validation.\n *\n * Scope boundary: this module validates *data shapes only*. It deliberately\n * grants no wire authorization — host identity, generation, scope/lease, call\n * context, and permissions must be enforced by the host RPC adapter, never by a\n * schema check here. In particular `command.deduplication` is a declared intent;\n * real local transactions and any cross-system exactly-once behavior belong to\n * the host and to the external contract, not to this file.\n *\n * Everything that reaches validation is first cloned from own property\n * descriptors into bounded pure JSON, so no getter, proxy trap, or `toJSON` is\n * ever invoked and no non-JSON shape is silently accepted.\n */\nimport { isProxy } from 'node:util/types';\n\nexport type RpcCallKind = 'query' | 'command';\nexport type RpcCallPurpose = 'bootstrap' | 'background' | 'management' | 'request' | 'attempt';\nexport type RpcCommandDeduplication = 'local-transaction' | 'external-contract' | 'none';\n\n/** Declared intent only; the host owns the actual transaction and retention. */\nexport interface RpcCommandPolicy {\n readonly deduplication: RpcCommandDeduplication;\n /**\n * `null` means the result is retained permanently and durably: it survives a\n * restart and is never recomputed. A positive number is a retention window in\n * milliseconds. Retention is a host/storage concern; this is declaration only.\n */\n readonly resultRetentionMs: number | null;\n readonly quotaBytes: number;\n readonly maxResultBytes: number;\n}\n\n/** Pure JSON: null, boolean, finite number, string, arrays, and plain records. */\nexport type RpcJson =\n | null\n | boolean\n | number\n | string\n | readonly RpcJson[]\n | { readonly [key: string]: RpcJson };\n\n/**\n * Data schema DSL. `object` rejects unknown fields, `optional` lists real\n * optional keys, and `json` carries an optional explicit byte bound (default:\n * the RPC envelope).\n */\nexport type RpcDataSchema =\n | { readonly type: 'string'; readonly minLength?: number; readonly maxLength?: number }\n | { readonly type: 'number'; readonly integer?: boolean; readonly minimum?: number; readonly maximum?: number }\n | { readonly type: 'boolean' }\n | { readonly type: 'null' }\n | { readonly type: 'literal'; readonly value: RpcJson }\n | { readonly type: 'array'; readonly items: RpcDataSchema; readonly maxItems?: number }\n | {\n readonly type: 'object';\n readonly properties: { readonly [key: string]: RpcDataSchema };\n readonly optional?: readonly string[];\n }\n | { readonly type: 'record'; readonly values: RpcDataSchema; readonly maxEntries?: number }\n | { readonly type: 'union'; readonly variants: readonly RpcDataSchema[] }\n | { readonly type: 'json'; readonly maxBytes?: number };\n\n/** Flattens intersections so optional modifiers survive as real optional keys. */\ntype Simplify<T> = { [K in keyof T]: T[K] };\n\ntype OptionalNames<S> = S extends { readonly optional: readonly (infer K extends string)[] } ? K : never;\n\ntype InferObject<P extends Record<string, RpcDataSchema>, O extends string> = Simplify<\n { [K in keyof P as K extends O ? never : K]: InferRpcData<P[K]> } &\n { [K in Extract<keyof P, O>]?: InferRpcData<P[K]> }\n>;\n\n/** Derives the TypeScript type described by a `RpcDataSchema`. */\nexport type InferRpcData<S> =\n RpcDataSchema extends S ? RpcJson : S extends { readonly type: 'string' }\n ? string\n : S extends { readonly type: 'number' }\n ? number\n : S extends { readonly type: 'boolean' }\n ? boolean\n : S extends { readonly type: 'null' }\n ? null\n : S extends { readonly type: 'literal'; readonly value: infer V extends RpcJson }\n ? V\n : S extends { readonly type: 'json' }\n ? RpcJson\n : S extends { readonly type: 'array'; readonly items: infer I extends RpcDataSchema }\n ? InferRpcData<I>[]\n : S extends { readonly type: 'record'; readonly values: infer V extends RpcDataSchema }\n ? { [key: string]: InferRpcData<V> }\n : S extends { readonly type: 'union'; readonly variants: infer VS }\n ? VS extends readonly (infer V extends RpcDataSchema)[]\n ? InferRpcData<V>\n : never\n : S extends { readonly type: 'object'; readonly properties: infer P extends Record<string, RpcDataSchema> }\n ? InferObject<P, OptionalNames<S>>\n : never;\n\nexport interface RpcMethodDefinition {\n readonly kind: RpcCallKind;\n readonly input: RpcDataSchema;\n readonly output: RpcDataSchema;\n readonly purposes: readonly RpcCallPurpose[];\n readonly timeoutMs?: number;\n readonly maxInputBytes?: number;\n readonly maxOutputBytes?: number;\n readonly command?: RpcCommandPolicy;\n}\n\nexport interface RpcServiceContract<\n M extends Record<string, RpcMethodDefinition> = Record<string, RpcMethodDefinition>,\n> {\n readonly id: string;\n readonly version: number;\n readonly methods: M;\n}\n\nexport const RPC_JSON_MAX_BYTES = 64 * 1024;\n/** Metadata contract/schema inputs are pure JSON and bounded well below the envelope. */\nexport const RPC_CONTRACT_MAX_BYTES = 256 * 1024;\n\nconst JSON_MAX_DEPTH = 64;\nconst SCHEMA_MAX_DEPTH = 64;\nconst RPC_MAX_TIMEOUT_MS = 300_000;\nconst RPC_MAX_METHODS = 128;\nconst RPC_SERVICE_ID = /^[a-z][a-z0-9.-]{0,127}$/;\nconst RPC_METHOD_NAME = /^[A-Za-z_][A-Za-z0-9_.-]{0,127}$/;\nconst RPC_CALL_PURPOSES = new Set<RpcCallPurpose>(['bootstrap', 'background', 'management', 'request', 'attempt']);\nconst RPC_COMMAND_DEDUPLICATION = new Set<RpcCommandDeduplication>(['local-transaction', 'external-contract', 'none']);\nconst RPC_COMMAND_POLICY_KEYS = new Set(['deduplication', 'resultRetentionMs', 'quotaBytes', 'maxResultBytes']);\nconst CONTRACT_KEYS = ['id', 'version', 'methods'] as const;\nconst METHOD_KEYS = [\n 'kind',\n 'input',\n 'output',\n 'purposes',\n 'timeoutMs',\n 'maxInputBytes',\n 'maxOutputBytes',\n 'command',\n] as const;\n\nexport type RpcProtocolErrorCode = 'invalid_data' | 'size_limit' | 'invalid_contract';\n\n/** Fixed-code error. It never carries payload, secrets, keys, or arbitrary objects. */\nexport class RpcProtocolError extends Error {\n readonly name = 'RpcProtocolError';\n\n constructor(\n readonly code: RpcProtocolErrorCode,\n message: string,\n ) {\n super(message);\n }\n}\n\n/** Reports a fixed schema category only — never a user property name or value. */\nfunction failData(category: string): never {\n throw new RpcProtocolError('invalid_data', `invalid_data in ${category}`);\n}\n\nfunction failSize(): never {\n throw new RpcProtocolError('size_limit', 'size_limit: JSON value exceeds the byte limit');\n}\n\nfunction failContract(reason: string): never {\n throw new RpcProtocolError('invalid_contract', `invalid_contract: ${reason}`);\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n if (isProxy(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction isPositiveSafeInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;\n}\n\nfunction isNonNegativeSafeInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;\n}\n\nfunction hasLoneSurrogate(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code >= 0xd800 && code <= 0xdbff) {\n if (index + 1 >= value.length) return true;\n const next = value.charCodeAt(index + 1);\n if (next < 0xdc00 || next > 0xdfff) return true;\n index += 1;\n } else if (code >= 0xdc00 && code <= 0xdfff) {\n return true;\n }\n }\n return false;\n}\n\nfunction isArrayIndex(key: string, length: number): boolean {\n if (!/^(?:0|[1-9]\\d*)$/.test(key)) return false;\n const index = Number(key);\n return Number.isSafeInteger(index) && index >= 0 && index < length;\n}\n\nfunction assertKnownKeys(input: Record<string, unknown>, allowed: readonly string[], category: string): void {\n for (const key of Object.keys(input)) {\n if (!allowed.includes(key)) failContract(`unknown ${category} field`);\n }\n}\n\n/**\n * Running lower bound of the JSON byte size, used to reject oversized input\n * before it is fully cloned or stringified. Every accounting term is an\n * underestimate (escapes only ever add bytes), so a positive budget never\n * rejects a value that would actually fit.\n */\ninterface SnapshotBudget {\n left: number;\n}\n\nfunction spend(budget: SnapshotBudget, bytes: number): void {\n budget.left -= bytes;\n if (budget.left < 0) failSize();\n}\n\n/**\n * Validates and deep-clones a value into a plain pure-JSON graph. Object\n * descriptors are inspected before any value is read, so accessors and `toJSON`\n * are never invoked. Cycles, holes, non-plain objects, non-enumerable or symbol\n * keys, non-finite numbers, lone surrogates, and over-deep nesting are rejected;\n * the budget rejects oversized values early.\n */\nfunction snapshot(value: unknown, depth: number, ancestors: Set<object>, budget: SnapshotBudget): RpcJson {\n if (value === null) {\n spend(budget, 4);\n return null;\n }\n if (typeof value === 'boolean') {\n spend(budget, value ? 4 : 5);\n return value;\n }\n if (typeof value === 'string') {\n if (hasLoneSurrogate(value)) failData('string');\n spend(budget, Buffer.byteLength(value, 'utf8') + 2);\n return value;\n }\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) failData('number');\n spend(budget, 1);\n return value;\n }\n if (typeof value !== 'object') failData('json');\n const object = value as object;\n if (isProxy(object)) failData('json');\n if (ancestors.has(object)) failData('json');\n const nextDepth = depth + 1;\n if (nextDepth > JSON_MAX_DEPTH) failData('json');\n if (Array.isArray(object)) {\n if (Object.getPrototypeOf(object) !== Array.prototype) failData('array');\n const lengthDescriptor = Object.getOwnPropertyDescriptor(object, 'length');\n if (!lengthDescriptor || !('value' in lengthDescriptor) || typeof lengthDescriptor.value !== 'number') {\n failData('array');\n }\n const length = lengthDescriptor.value;\n if (!Number.isSafeInteger(length) || length < 0) failData('array');\n if (length > budget.left) failSize();\n spend(budget, 2);\n if (length > 1) spend(budget, length - 1);\n ancestors.add(object);\n const items: RpcJson[] = new Array(length);\n let count = 0;\n for (const key of Reflect.ownKeys(object)) {\n if (key === 'length') continue;\n if (typeof key !== 'string' || !isArrayIndex(key, length)) failData('array');\n const descriptor = Object.getOwnPropertyDescriptor(object, key);\n if (!descriptor || !descriptor.enumerable || !('value' in descriptor)) failData('array');\n items[Number(key)] = snapshot(descriptor.value, nextDepth, ancestors, budget);\n count += 1;\n }\n if (count !== length) failData('array');\n ancestors.delete(object);\n return items;\n }\n const prototype = Object.getPrototypeOf(object);\n if (prototype !== Object.prototype && prototype !== null) failData('object');\n const keys = Reflect.ownKeys(object);\n if (keys.length > budget.left) failSize();\n spend(budget, 2);\n if (keys.length > 1) spend(budget, keys.length - 1);\n ancestors.add(object);\n const result: Record<string, RpcJson> = {};\n for (const key of keys) {\n if (typeof key !== 'string') failData('object');\n if (hasLoneSurrogate(key)) failData('object');\n const descriptor = Object.getOwnPropertyDescriptor(object, key);\n if (!descriptor || !descriptor.enumerable || !('value' in descriptor)) failData('object');\n spend(budget, Buffer.byteLength(key, 'utf8') + 3);\n // defineProperty keeps a literal `__proto__` key an own data property instead of polluting the prototype.\n Object.defineProperty(result, key, {\n value: snapshot(descriptor.value, nextDepth, ancestors, budget),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n ancestors.delete(object);\n return result;\n}\n\n/** Clones a contract/schema input as bounded pure JSON, mapping pure-JSON errors to invalid_contract. */\nfunction snapshotPureInput(input: unknown): RpcJson {\n try {\n const pure = snapshot(input, 0, new Set(), { left: RPC_CONTRACT_MAX_BYTES });\n if (Buffer.byteLength(JSON.stringify(pure), 'utf8') > RPC_CONTRACT_MAX_BYTES) failContract('input must be bounded pure JSON data');\n return pure;\n } catch (error) {\n if (error instanceof RpcProtocolError && (error.code === 'invalid_data' || error.code === 'size_limit')) {\n failContract('input must be bounded pure JSON data');\n }\n throw error;\n }\n}\n\n/** Strict scanner: rejects duplicate keys, trailing content, and deep nesting. */\nfunction scanJson(text: string): void {\n let index = 0;\n const numberPattern = /-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/y;\n const fail = (): never => {\n throw new RpcProtocolError('invalid_data', 'invalid JSON text');\n };\n const whitespace = (): void => {\n while (index < text.length) {\n const character = text[index];\n if (character === ' ' || character === '\\t' || character === '\\n' || character === '\\r') index += 1;\n else break;\n }\n };\n const string = (): string => {\n if (text[index] !== '\"') return fail();\n const start = index;\n index += 1;\n while (index < text.length) {\n const character = text[index];\n if (character === '\"') {\n index += 1;\n try {\n const value: unknown = JSON.parse(text.slice(start, index));\n if (typeof value !== 'string') return fail();\n return value;\n } catch (error) {\n if (error instanceof RpcProtocolError) throw error;\n return fail();\n }\n }\n if (character === undefined) return fail();\n if (character.charCodeAt(0) < 0x20) return fail();\n if (character === '\\\\') {\n index += 1;\n const escape = text[index];\n if (escape === 'u') {\n if (!/^[0-9a-fA-F]{4}$/.test(text.slice(index + 1, index + 5))) return fail();\n index += 5;\n continue;\n }\n if (escape === undefined || !'\"\\\\/bfnrt'.includes(escape)) return fail();\n index += 1;\n continue;\n }\n index += 1;\n }\n return fail();\n };\n const value = (depth: number): void => {\n whitespace();\n const character = text[index];\n if (character === '{') {\n if (depth >= JSON_MAX_DEPTH) return fail();\n index += 1;\n whitespace();\n const keys = new Set<string>();\n if (text[index] === '}') {\n index += 1;\n return;\n }\n while (true) {\n whitespace();\n const key = string();\n if (keys.has(key)) return fail();\n keys.add(key);\n whitespace();\n if (text[index] !== ':') return fail();\n index += 1;\n value(depth + 1);\n whitespace();\n if (text[index] === '}') {\n index += 1;\n return;\n }\n if (text[index] !== ',') return fail();\n index += 1;\n }\n }\n if (character === '[') {\n if (depth >= JSON_MAX_DEPTH) return fail();\n index += 1;\n whitespace();\n if (text[index] === ']') {\n index += 1;\n return;\n }\n while (true) {\n value(depth + 1);\n whitespace();\n if (text[index] === ']') {\n index += 1;\n return;\n }\n if (text[index] !== ',') return fail();\n index += 1;\n }\n }\n if (character === '\"') {\n string();\n return;\n }\n if (text.startsWith('true', index)) {\n index += 4;\n return;\n }\n if (text.startsWith('false', index)) {\n index += 5;\n return;\n }\n if (text.startsWith('null', index)) {\n index += 4;\n return;\n }\n numberPattern.lastIndex = index;\n const match = numberPattern.exec(text);\n if (match === null) return fail();\n index = numberPattern.lastIndex;\n };\n value(0);\n whitespace();\n if (index !== text.length) fail();\n}\n\n/** Rejects numbers that overflowed to Infinity and lone surrogates after parsing. */\nfunction assertJsonGraph(value: unknown): void {\n const stack: unknown[] = [value];\n while (stack.length > 0) {\n const current = stack.pop();\n if (typeof current === 'number') {\n if (!Number.isFinite(current)) failData('json');\n continue;\n }\n if (typeof current === 'string') {\n if (hasLoneSurrogate(current)) failData('string');\n continue;\n }\n if (Array.isArray(current)) {\n for (const item of current) stack.push(item);\n continue;\n }\n if (current !== null && typeof current === 'object') {\n for (const key of Object.keys(current)) {\n if (hasLoneSurrogate(key)) failData('object');\n stack.push((current as Record<string, unknown>)[key]);\n }\n }\n }\n}\n\n/**\n * Serializes a pure-JSON value under a UTF-8 byte bound. Oversized values are\n * rejected by the running budget before a large clone is built. `maxBytes` may\n * be raised for independent, larger data channels; the default stays the control\n * envelope limit.\n */\nexport function encodeRpcJson(value: unknown, maxBytes: number = RPC_JSON_MAX_BYTES): string {\n assertByteLimit(maxBytes);\n const clone = snapshot(value, 0, new Set(), { left: maxBytes });\n const text = JSON.stringify(clone);\n if (typeof text !== 'string') failData('json');\n if (Buffer.byteLength(text, 'utf8') > maxBytes) failSize();\n return text;\n}\n\n/** Deterministic encoding for signed RPC metadata, retaining every legal JSON key. */\nexport function encodeCanonicalRpcJson(value: unknown, maxBytes: number = RPC_JSON_MAX_BYTES): string {\n assertByteLimit(maxBytes);\n const clone = snapshot(value, 0, new Set(), { left: maxBytes });\n const canonical = (item: RpcJson): string => {\n if (item === null || typeof item !== 'object') return JSON.stringify(item);\n if (Array.isArray(item)) return `[${item.map(canonical).join(',')}]`;\n const record = item as Readonly<Record<string, RpcJson>>;\n return `{${Object.keys(record).sort().map(key => `${JSON.stringify(key)}:${canonical(record[key])}`).join(',')}}`;\n };\n const text = canonical(clone);\n if (Buffer.byteLength(text, 'utf8') > maxBytes) failSize();\n return text;\n}\n\n/** Parses strict, bounded pure JSON. Non-finite numbers and lone surrogates are rejected. */\nexport function decodeRpcJson(text: string, maxBytes: number = RPC_JSON_MAX_BYTES): RpcJson {\n assertByteLimit(maxBytes);\n if (typeof text !== 'string') failData('json');\n if (Buffer.byteLength(text, 'utf8') > maxBytes) failSize();\n scanJson(text);\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw new RpcProtocolError('invalid_data', 'invalid JSON text');\n }\n assertJsonGraph(parsed);\n return parsed as RpcJson;\n}\n\nfunction jsonEquals(left: RpcJson, right: RpcJson): boolean {\n if (left === right) return true;\n if (typeof left !== typeof right) return false;\n if (Array.isArray(left) !== Array.isArray(right)) return false;\n if (Array.isArray(left)) {\n if (!Array.isArray(right) || left.length !== right.length) return false;\n for (let index = 0; index < left.length; index += 1) {\n if (!jsonEquals(left[index], right[index])) return false;\n }\n return true;\n }\n if (typeof left === 'object' && left !== null && right !== null && typeof right === 'object') {\n const leftRecord = left as Record<string, RpcJson>;\n const rightRecord = right as Record<string, RpcJson>;\n const keys = Object.keys(leftRecord);\n if (keys.length !== Object.keys(rightRecord).length) return false;\n for (const key of keys) {\n if (!Object.prototype.hasOwnProperty.call(rightRecord, key)) return false;\n if (!jsonEquals(leftRecord[key], rightRecord[key])) return false;\n }\n return true;\n }\n return false;\n}\n\nfunction checkOptionalNonNegative(value: unknown, field: string): number | undefined {\n if (value === undefined) return undefined;\n if (!isNonNegativeSafeInteger(value)) failContract(`${field} must be a non-negative safe integer`);\n return value;\n}\n\nfunction checkOptionalFinite(value: unknown, field: string): number | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'number' || !Number.isFinite(value)) failContract(`${field} must be a finite number`);\n return value;\n}\n\nfunction checkSchema(input: unknown, depth: number, seen: Set<object>): void {\n if (depth > SCHEMA_MAX_DEPTH) failContract('schema nesting exceeds the limit');\n if (!isPlainObject(input)) failContract('schema must be a plain object');\n if (seen.has(input)) failContract('schema must not contain cycles');\n seen.add(input);\n const type = input.type;\n if (type === 'string') {\n assertKnownKeys(input, ['type', 'minLength', 'maxLength'], 'schema');\n const min = checkOptionalNonNegative(input.minLength, 'minLength');\n const max = checkOptionalNonNegative(input.maxLength, 'maxLength');\n if (min !== undefined && max !== undefined && min > max) failContract('string minLength must not exceed maxLength');\n } else if (type === 'number') {\n assertKnownKeys(input, ['type', 'integer', 'minimum', 'maximum'], 'schema');\n if (input.integer !== undefined && typeof input.integer !== 'boolean') failContract('number integer flag must be boolean');\n const min = checkOptionalFinite(input.minimum, 'minimum');\n const max = checkOptionalFinite(input.maximum, 'maximum');\n if (min !== undefined && max !== undefined && min > max) failContract('number minimum must not exceed maximum');\n } else if (type === 'boolean') {\n assertKnownKeys(input, ['type'], 'schema');\n } else if (type === 'null') {\n assertKnownKeys(input, ['type'], 'schema');\n } else if (type === 'literal') {\n assertKnownKeys(input, ['type', 'value'], 'schema');\n if (!Object.prototype.hasOwnProperty.call(input, 'value')) failContract('literal schema requires a value');\n try {\n snapshot(input.value, 0, new Set(), { left: Infinity });\n } catch (error) {\n if (error instanceof RpcProtocolError && error.code === 'invalid_data') {\n failContract('literal value must be pure JSON');\n }\n throw error;\n }\n } else if (type === 'array') {\n assertKnownKeys(input, ['type', 'items', 'maxItems'], 'schema');\n if (!Object.prototype.hasOwnProperty.call(input, 'items')) failContract('array schema requires items');\n checkSchema(input.items, depth + 1, seen);\n checkOptionalNonNegative(input.maxItems, 'maxItems');\n } else if (type === 'object') {\n assertKnownKeys(input, ['type', 'properties', 'optional'], 'schema');\n const properties = input.properties;\n if (!isPlainObject(properties)) failContract('object schema requires a properties record');\n for (const key of Object.keys(properties)) checkSchema(properties[key], depth + 1, seen);\n const optional = input.optional;\n if (optional !== undefined) {\n if (!Array.isArray(optional)) failContract('object optional must be an array of field names');\n const names = new Set<string>();\n for (const name of optional) {\n if (typeof name !== 'string') failContract('object optional entries must be strings');\n if (names.has(name)) failContract('object optional entries must be unique');\n names.add(name);\n if (!Object.prototype.hasOwnProperty.call(properties, name)) {\n failContract('object optional names must exist in properties');\n }\n }\n }\n } else if (type === 'record') {\n assertKnownKeys(input, ['type', 'values', 'maxEntries'], 'schema');\n if (!Object.prototype.hasOwnProperty.call(input, 'values')) failContract('record schema requires values');\n checkSchema(input.values, depth + 1, seen);\n checkOptionalNonNegative(input.maxEntries, 'maxEntries');\n } else if (type === 'union') {\n assertKnownKeys(input, ['type', 'variants'], 'schema');\n const variants = input.variants;\n if (!Array.isArray(variants) || variants.length === 0) {\n failContract('union schema requires a non-empty variants array');\n }\n for (const variant of variants) checkSchema(variant, depth + 1, seen);\n } else if (type === 'json') {\n assertKnownKeys(input, ['type', 'maxBytes'], 'schema');\n if (input.maxBytes !== undefined && !isPositiveSafeInteger(input.maxBytes)) {\n failContract('json schema maxBytes must be a positive safe integer');\n }\n } else {\n failContract('unknown schema type');\n }\n seen.delete(input);\n}\n\nfunction validateValue(schema: RpcDataSchema, value: unknown): void {\n switch (schema.type) {\n case 'string': {\n if (typeof value !== 'string') failData('string');\n if (schema.minLength !== undefined && value.length < schema.minLength) failData('string');\n if (schema.maxLength !== undefined && value.length > schema.maxLength) failData('string');\n return;\n }\n case 'number': {\n if (typeof value !== 'number' || !Number.isFinite(value)) failData('number');\n if (schema.integer === true && !Number.isInteger(value)) failData('number');\n if (schema.minimum !== undefined && value < schema.minimum) failData('number');\n if (schema.maximum !== undefined && value > schema.maximum) failData('number');\n return;\n }\n case 'boolean': {\n if (typeof value !== 'boolean') failData('boolean');\n return;\n }\n case 'null': {\n if (value !== null) failData('null');\n return;\n }\n case 'literal': {\n if (!jsonEquals(schema.value, value as RpcJson)) failData('literal');\n return;\n }\n case 'array': {\n if (!Array.isArray(value)) failData('array');\n if (schema.maxItems !== undefined && value.length > schema.maxItems) failData('array');\n for (const item of value) validateValue(schema.items, item);\n return;\n }\n case 'object': {\n if (!isPlainObject(value)) failData('object');\n const optional = new Set(schema.optional ?? []);\n for (const key of Object.keys(value)) {\n if (!Object.prototype.hasOwnProperty.call(schema.properties, key)) failData('object');\n }\n for (const key of Object.keys(schema.properties)) {\n if (!Object.prototype.hasOwnProperty.call(value, key)) {\n if (!optional.has(key)) failData('object');\n continue;\n }\n validateValue(schema.properties[key], value[key]);\n }\n return;\n }\n case 'record': {\n if (!isPlainObject(value)) failData('record');\n const keys = Object.keys(value);\n if (schema.maxEntries !== undefined && keys.length > schema.maxEntries) failData('record');\n for (const key of keys) validateValue(schema.values, value[key]);\n return;\n }\n case 'union': {\n for (const variant of schema.variants) {\n try {\n validateValue(variant, value);\n return;\n } catch (error) {\n if (!(error instanceof RpcProtocolError) || error.code !== 'invalid_data') throw error;\n }\n }\n failData('union');\n }\n case 'json': {\n const maxBytes = schema.maxBytes ?? RPC_JSON_MAX_BYTES;\n const text = JSON.stringify(value);\n if (typeof text !== 'string' || Buffer.byteLength(text, 'utf8') > maxBytes) failData('json');\n return;\n }\n }\n}\n\n/**\n * Asserts a runtime value matches the schema. The whole value is first cloned\n * into bounded pure JSON without invoking accessors, then validated. Throws\n * `RpcProtocolError` with `invalid_data` (value) or `invalid_contract` (malformed\n * schema).\n */\n/** Validates a standalone data schema (lane contract registration) without a value. */\nexport function assertRpcDataSchema(schema: RpcDataSchema): void {\n const pure = snapshotPureInput(schema);\n checkSchema(pure, 0, new Set());\n}\n\nexport function assertRpcData<S extends RpcDataSchema>(\n schema: S,\n value: unknown,\n maxBytes?: number,\n): asserts value is InferRpcData<S> { const pureSchema = snapshotPureInput(schema);\n checkSchema(pureSchema, 0, new Set());\n const checkedSchema = pureSchema as unknown as RpcDataSchema;\n const limit = maxBytes ?? (checkedSchema.type === 'json' ? checkedSchema.maxBytes ?? RPC_JSON_MAX_BYTES : RPC_JSON_MAX_BYTES);\n assertByteLimit(limit);\n let pureValue: RpcJson;\n try { pureValue = snapshot(value, 0, new Set(), { left: limit }); }\n catch (error) {\n if (error instanceof RpcProtocolError && error.code === 'size_limit') failData('json');\n throw error;\n }\n if (Buffer.byteLength(JSON.stringify(pureValue), 'utf8') > limit) failData('json');\n validateValue(checkedSchema, pureValue);\n}\n\nfunction assertByteLimit(maxBytes: number): void {\n if (!isPositiveSafeInteger(maxBytes)) failContract('maxBytes must be a positive safe integer');\n}\n\nfunction checkByteLimit(value: unknown, field: string): number | undefined {\n if (value === undefined) return undefined;\n if (!isPositiveSafeInteger(value) || value > RPC_JSON_MAX_BYTES) {\n failContract(`${field} must be a positive integer no larger than the RPC envelope`);\n }\n return value;\n}\n\nfunction checkCommandPolicy(policy: Record<string, unknown>, maxOutputBytes: number): void {\n const keys = Object.keys(policy);\n if (keys.length !== RPC_COMMAND_POLICY_KEYS.size || keys.some((key) => !RPC_COMMAND_POLICY_KEYS.has(key))) {\n failContract('command policy fields are fixed');\n }\n const deduplication = policy.deduplication;\n if (typeof deduplication !== 'string' || !RPC_COMMAND_DEDUPLICATION.has(deduplication as RpcCommandDeduplication)) {\n failContract('invalid command deduplication');\n }\n const retention = policy.resultRetentionMs;\n if (retention !== null && !isPositiveSafeInteger(retention)) {\n failContract('resultRetentionMs must be a positive integer or null');\n }\n const maxResultBytes = policy.maxResultBytes;\n if (!isPositiveSafeInteger(maxResultBytes)) failContract('maxResultBytes must be a positive safe integer');\n if (maxResultBytes > maxOutputBytes) failContract('maxResultBytes must not exceed maxOutputBytes');\n const quotaBytes = policy.quotaBytes;\n if (!isPositiveSafeInteger(quotaBytes)) failContract('quotaBytes must be a positive safe integer');\n if (quotaBytes < maxResultBytes) failContract('quotaBytes must be able to hold maxResultBytes');\n}\n\nfunction checkMethod(definition: Record<string, unknown>): void {\n assertKnownKeys(definition, METHOD_KEYS, 'method');\n const kind = definition.kind;\n if (kind !== 'query' && kind !== 'command') failContract('method kind must be query or command');\n checkSchema(definition.input, 0, new Set());\n checkSchema(definition.output, 0, new Set());\n const purposes = definition.purposes;\n if (!Array.isArray(purposes) || purposes.length === 0) failContract('purposes must be a non-empty array');\n const seenPurposes = new Set<string>();\n for (const purpose of purposes) {\n if (typeof purpose !== 'string' || !RPC_CALL_PURPOSES.has(purpose as RpcCallPurpose)) failContract('invalid purpose');\n if (seenPurposes.has(purpose)) failContract('purposes must be unique');\n seenPurposes.add(purpose);\n }\n if (definition.timeoutMs !== undefined) {\n if (!isPositiveSafeInteger(definition.timeoutMs) || definition.timeoutMs > RPC_MAX_TIMEOUT_MS) {\n failContract('timeoutMs must be a positive integer no larger than the timeout bound');\n }\n }\n checkByteLimit(definition.maxInputBytes, 'maxInputBytes');\n const maxOutputBytes = checkByteLimit(definition.maxOutputBytes, 'maxOutputBytes');\n const command = definition.command;\n if (kind === 'command') {\n if (!isPlainObject(command)) failContract('command methods require an explicit command policy');\n checkCommandPolicy(command, maxOutputBytes ?? RPC_JSON_MAX_BYTES);\n } else if (command !== undefined) {\n failContract('query methods must not declare a command policy');\n }\n}\n\nfunction checkContract(contract: unknown): void {\n if (!isPlainObject(contract)) failContract('contract must be a plain object');\n assertKnownKeys(contract, CONTRACT_KEYS, 'contract');\n if (typeof contract.id !== 'string' || !RPC_SERVICE_ID.test(contract.id)) failContract('invalid service id');\n if (!isPositiveSafeInteger(contract.version)) failContract('service version must be a positive safe integer');\n const methods = contract.methods;\n if (!isPlainObject(methods)) failContract('methods must be a plain object');\n const names = Object.keys(methods);\n if (names.length === 0) failContract('service must declare at least one method');\n if (names.length > RPC_MAX_METHODS) failContract('service declares too many methods');\n for (const name of names) {\n if (!RPC_METHOD_NAME.test(name)) failContract('invalid method name');\n const definition = methods[name];\n if (!isPlainObject(definition)) failContract('method definition must be a plain object');\n checkMethod(definition);\n }\n}\n\nfunction deepFreeze(value: unknown): unknown {\n if (Array.isArray(value)) {\n for (const item of value) deepFreeze(item);\n return Object.freeze(value);\n }\n if (isPlainObject(value)) {\n for (const key of Object.keys(value)) deepFreeze(value[key]);\n return Object.freeze(value);\n }\n return value;\n}\n\n/**\n * Validates a service contract and returns a deep-frozen pure clone. The caller's\n * objects are never read through accessors, never frozen, and never modified;\n * `methods` keeps its literal types so clients can derive call signatures.\n */\nexport function defineRpcService<const M extends Record<string, RpcMethodDefinition>>(contract: {\n readonly id: string;\n readonly version: number;\n readonly methods: M;\n}): RpcServiceContract<M> {\n const pure = snapshotPureInput(contract);\n checkContract(pure);\n return deepFreeze(pure) as unknown as RpcServiceContract<M>;\n}\n",
|
|
@@ -10,14 +10,15 @@
|
|
|
10
10
|
"/**\n * Host-managed persistent atomic snapshot version store.\n *\n * A provider plugin (e.g. the future models-dev directory) gets versioned,\n * immutable, digest-addressed snapshot bodies with bounded retention WITHOUT\n * inventing its own chunking or widening the 1 MiB durable-command limit: the\n * body is stored as bounded chunks in the host `plugin_communication_records`\n * table (the audited v14 schema; no new table, no runtime DDL), and the version\n * becomes visible atomically by flipping its meta + the current pointer.\n *\n * Durability/atomicity contract:\n * - chunks are written first; a version is INVISIBLE until its meta row exists,\n * so a crash mid-write leaves only unreachable chunks (reclaimed by `collect`);\n * - the current pointer is flipped last, so a reader never observes a half-written\n * body as current;\n * - a returned source keeps the exact descriptor fixed and can `retain()`/`release()`\n * the version; a retained version is never reclaimed, so an in-flight whole-body\n * read can never have its bytes swapped or freed underneath it;\n * - retention is explicit and bounded (`maxVersions`, `maxBytes`), and GC never\n * touches the current version, a retained version, or a version whose chunks\n * are still referenced.\n */\n\nimport { createHash } from 'node:crypto';\nimport type { ChannelSnapshotDescriptor } from './peer-channel-protocol';\nimport type { PluginChannelSnapshotSource } from './peer-channel-hub';\nimport { CHANNEL_MAX_CHUNK_BYTES } from './peer-channel-protocol';\nimport { CHANNEL_SNAPSHOT_MAX_BYTES } from './peer-channel-hub';\nimport type { CommunicationNamespaceStore } from './persistence';\nimport { encodeRpcJson } from './wire-contract';\n\nconst DEFAULT_MAX_VERSIONS = 3;\nconst DEFAULT_CHUNK_BYTES = 60 * 1024;\n\n/**\n * Retained-version refcounts shared by ALL store instances of one version family.\n * Two `store()` calls for the same (namespace, owner, family id) must share pin\n * management: otherwise one instance's GC could reclaim a version another instance\n * still has retained for an in-flight whole-body read.\n */\nconst SNAPSHOT_FAMILY_REFS = new Map<string, Map<number, number>>();\n\nfunction familyRefs(prefix: string): Map<number, number> {\n let refs = SNAPSHOT_FAMILY_REFS.get(prefix);\n if (refs === undefined) { refs = new Map(); SNAPSHOT_FAMILY_REFS.set(prefix, refs); }\n return refs;\n}\n\n/** Minimal read surface shared by the namespace store and its transaction mutator. */\ninterface SnapshotRecordReader {\n get(key: string): { readonly payload: Uint8Array } | null;\n}\n\nexport interface HostSnapshotStoreOptions {\n /** Descriptor owner identity (usually the providing plugin name). */\n readonly owner: string;\n /**\n * Immutable version-family id declared by the provider. Two `store()` calls\n * with the same id share ONE durable family (current pointer, version index,\n * retention, pins); a different id is a completely separate family. It is part\n * of the persistent identity, so the same family is readable again after a\n * process restart.\n */\n readonly id?: string;\n /** Runtime generation of the owner; part of the immutable descriptor. */\n readonly epoch?: number;\n readonly schemaVersion: number;\n readonly chunkBytes?: number;\n /** Retained versions, including the current one. */\n readonly maxVersions?: number;\n /** Bounded total retained body bytes. */\n readonly maxBytes?: number;\n}\n\ninterface VersionMeta {\n readonly owner: string;\n readonly epoch: number;\n readonly version: number;\n readonly schemaVersion: number;\n readonly digest: `sha256:${string}`;\n readonly size: number;\n readonly chunkBytes: number;\n readonly chunks: number;\n}\n\n/**\n * One namespace-isolated, atomically published version family. The store never\n * exposes its keys, connection, or any other namespace.\n */\nexport class HostSnapshotStore {\n readonly #store: CommunicationNamespaceStore;\n readonly #owner: string;\n readonly #epoch: number;\n readonly #schemaVersion: number;\n readonly #chunkBytes: number;\n readonly #maxVersions: number;\n readonly #maxBytes: number;\n readonly #prefix: string;\n #maintenanceError: string | null = null;\n\n constructor(store: CommunicationNamespaceStore, options: HostSnapshotStoreOptions) {\n const chunkBytes = options.chunkBytes ?? DEFAULT_CHUNK_BYTES;\n const maxVersions = options.maxVersions ?? DEFAULT_MAX_VERSIONS;\n const maxBytes = options.maxBytes ?? CHANNEL_SNAPSHOT_MAX_BYTES;\n if (typeof options.owner !== 'string' || options.owner.length === 0) throw new Error('snapshot store requires an owner identity');\n if (!Number.isSafeInteger(options.schemaVersion) || options.schemaVersion < 1) throw new Error('snapshot store schema version is invalid');\n if (!Number.isSafeInteger(chunkBytes) || chunkBytes < 1 || chunkBytes > CHANNEL_MAX_CHUNK_BYTES) throw new Error('snapshot store chunk size is invalid');\n if (!Number.isSafeInteger(maxVersions) || maxVersions < 1) throw new Error('snapshot store version retention is invalid');\n if (!Number.isSafeInteger(maxBytes) || maxBytes < 1 || maxBytes > CHANNEL_SNAPSHOT_MAX_BYTES) throw new Error('snapshot store byte retention is invalid');\n const familyId = options.id ?? '';\n if (options.id !== undefined && (typeof options.id !== 'string' || options.id.length === 0 || options.id.length > 256)) {\n throw new Error('snapshot store family id is invalid');\n }\n this.#store = store;\n this.#owner = options.owner;\n this.#epoch = options.epoch ?? 1;\n this.#schemaVersion = options.schemaVersion;\n this.#chunkBytes = chunkBytes;\n this.#maxVersions = maxVersions;\n this.#maxBytes = maxBytes;\n // The family id is part of the persistent identity: two declared families of\n // one provider never share a current pointer, version index or pins.\n const identity = familyId === '' ? `${store.namespace}/${options.owner}` : `${store.namespace}/${options.owner}/${familyId}`;\n this.#prefix = `hs:${createHash('sha256').update(identity).digest('hex').slice(0, 16)}`;\n }\n\n #chunkKey(version: number, index: number): string {\n return `${this.#prefix}:${version}:c${String(index).padStart(8, '0')}`;\n }\n\n #metaKey(version: number): string { return `${this.#prefix}:${version}:m`; }\n\n #currentKey(): string { return `${this.#prefix}:cur`; }\n\n #digest(bytes: Uint8Array): `sha256:${string}` {\n return `sha256:${createHash('sha256').update(bytes).digest('hex')}`;\n }\n\n #readMeta(version: number, reader: SnapshotRecordReader = this.#store): VersionMeta | null {\n const record = reader.get(this.#metaKey(version));\n if (record === null) return null;\n let parsed: unknown;\n try { parsed = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(record.payload)); }\n catch { throw new Error('snapshot store meta is unreadable'); }\n if (parsed === null || typeof parsed !== 'object') throw new Error('snapshot store meta is invalid');\n const meta = parsed as Partial<VersionMeta>;\n if (meta.owner !== this.#owner || meta.version !== version\n || !Number.isSafeInteger(meta.epoch) || !Number.isSafeInteger(meta.schemaVersion)\n || !Number.isSafeInteger(meta.size) || !Number.isSafeInteger(meta.chunkBytes)\n || !Number.isSafeInteger(meta.chunks) || typeof meta.digest !== 'string') {\n throw new Error('snapshot store meta is invalid');\n }\n return Object.freeze({\n owner: meta.owner, epoch: meta.epoch as number, version, schemaVersion: meta.schemaVersion as number,\n digest: meta.digest as `sha256:${string}`, size: meta.size as number,\n chunkBytes: meta.chunkBytes as number, chunks: meta.chunks as number,\n });\n }\n\n #descriptor(meta: VersionMeta): ChannelSnapshotDescriptor {\n return Object.freeze({\n owner: meta.owner, epoch: meta.epoch, version: meta.version, schemaVersion: meta.schemaVersion,\n digest: meta.digest, size: meta.size, chunkBytes: meta.chunkBytes,\n });\n }\n\n /**\n * Atomically publishes one immutable version. Returns the fixed descriptor, or\n * throws (quota/corruption) — a partially written version is never visible.\n */\n publish(version: number, body: unknown | Uint8Array): ChannelSnapshotDescriptor {\n if (!Number.isSafeInteger(version) || version < 1) throw new Error('snapshot store version is invalid');\n const bytes = body instanceof Uint8Array ? new Uint8Array(body) : new TextEncoder().encode(encodeRpcJson(body, this.#maxBytes));\n if (bytes.byteLength === 0 || bytes.byteLength > this.#maxBytes) throw new Error('snapshot store body exceeds the bounded retention budget');\n const chunks = Math.ceil(bytes.byteLength / this.#chunkBytes);\n const prior = this.#readMeta(version);\n if (prior !== null) {\n // Republishing the SAME immutable version must be idempotent; different\n // content under an existing version is refused.\n if (prior.digest !== this.#digest(bytes) || prior.size !== bytes.byteLength) throw new Error('snapshot store version already exists with different content');\n return this.#descriptor(prior);\n }\n const digest = this.#digest(bytes);\n const meta: VersionMeta = Object.freeze({\n owner: this.#owner, epoch: this.#epoch, version, schemaVersion: this.#schemaVersion,\n digest, size: bytes.byteLength, chunkBytes: this.#chunkBytes, chunks,\n });\n const versions = this.#publishedVersions(this.#store);\n const nextVersions = versions.includes(version) ? versions : [...versions, version].sort((left, right) => left - right);\n const encoder = new TextEncoder();\n // ONE immediate transaction for the whole version: chunks, meta, version index\n // and the visibility flip commit together. This both makes a partial version\n // impossible and pays exactly ONE durable commit instead of one per chunk\n // (per-chunk commits blocked the host event loop for seconds on a large body).\n this.#store.transact((mutator) => {\n for (let index = 0; index < chunks; index += 1) {\n const offset = index * this.#chunkBytes;\n const chunk = bytes.subarray(offset, Math.min(offset + this.#chunkBytes, bytes.byteLength));\n mutator.put(this.#chunkKey(version, index), chunk, { required: false, expiresAt: null });\n }\n mutator.put(this.#metaKey(version), encoder.encode(JSON.stringify(meta)), { required: false, expiresAt: null });\n mutator.put(this.#versionsKey(), encoder.encode(JSON.stringify({ versions: nextVersions })), { required: false, expiresAt: null });\n // Visibility flip is LAST, inside the same commit: a reader never observes a\n // half-written body as current, and a crash leaves only unreachable chunks.\n // A monotonic fence makes the flip safe under out-of-order publishes: a new\n // but LOWER version is still durable/retained, yet it can never move the\n // current pointer backwards. (Re-publishing an already-existing version\n // returned above without touching the pointer.)\n const current = this.#currentVersion(mutator);\n if (current === null || version > current) {\n mutator.put(this.#currentKey(), encoder.encode(String(version)), { required: false, expiresAt: null });\n }\n });\n this.maintain();\n return this.#descriptor(meta);\n }\n\n /** Post-commit GC failure cannot turn a durable publication into a failed publish. */\n maintain(): { readonly removed: number; readonly error: string | null } {\n try {\n const removed = this.collect();\n this.#maintenanceError = null;\n return Object.freeze({ removed, error: null });\n } catch {\n this.#maintenanceError = 'storage_failure';\n return Object.freeze({ removed: 0, error: this.#maintenanceError });\n }\n }\n\n maintenanceStatus(): { readonly pending: boolean; readonly error: string | null } {\n return Object.freeze({ pending: this.#maintenanceError !== null, error: this.#maintenanceError });\n }\n\n /** Source for the current version, or `null` when none was published. */\n current(): PluginChannelSnapshotSource | null {\n const pointer = this.#store.get(this.#currentKey());\n if (pointer === null) return null;\n let text: string;\n try { text = new TextDecoder('utf-8', { fatal: true }).decode(pointer.payload); }\n catch { throw new Error('snapshot store current pointer is unreadable'); }\n const version = Number(text);\n if (!Number.isSafeInteger(version) || version < 1) throw new Error('snapshot store current pointer is invalid');\n return this.version(version);\n }\n\n /** Source for one explicitly named, still-retained version. */\n version(version: number): PluginChannelSnapshotSource | null {\n if (!Number.isSafeInteger(version) || version < 1) return null;\n // A present-but-corrupt meta/version index record is CORRUPTION, not\n // \"absent\": reporting `null` would let a reader believe the version never\n // existed. `#readMeta` throws on corruption and is intentionally not caught.\n const meta = this.#readMeta(version);\n if (meta === null) return null;\n const store = this.#store;\n const digest = meta.digest;\n const size = meta.size;\n const chunkBytes = meta.chunkBytes;\n const chunks = meta.chunks;\n const prefix = this.#prefix;\n const refs = familyRefs(prefix);\n let retained = false;\n const source: PluginChannelSnapshotSource = {\n descriptor: this.#descriptor(meta),\n retain: () => {\n if (retained) return;\n retained = true;\n refs.set(version, (refs.get(version) ?? 0) + 1);\n },\n release: () => {\n if (!retained) return;\n retained = false;\n const count = (refs.get(version) ?? 1) - 1;\n if (count <= 0) refs.delete(version);\n else refs.set(version, count);\n },\n read: async (offset: number, length: number): Promise<Uint8Array> => {\n if (!Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(length) || length < 0 || offset + length > size) {\n throw new Error('snapshot store read is out of range');\n }\n const out = new Uint8Array(length);\n let at = offset;\n let written = 0;\n while (written < length) {\n const index = Math.floor(at / chunkBytes);\n if (index >= chunks) throw new Error('snapshot store chunk is missing');\n const record = store.get(`${prefix}:${version}:c${String(index).padStart(8, '0')}`);\n if (record === null) throw new Error('snapshot store chunk is missing');\n const chunk = record.payload;\n const within = at - index * chunkBytes;\n const take = Math.min(chunk.byteLength - within, length - written);\n if (take <= 0) throw new Error('snapshot store chunk is truncated');\n out.set(chunk.subarray(within, within + take), written);\n written += take;\n at += take;\n }\n // Integrity is re-verified on every read: a tampered chunk is refused.\n if (this.#digest(out) !== digest && length === size && offset === 0) {\n // Full-body reads re-check the whole digest; partial reads rely on the\n // chunked layout plus the session's whole-body verification.\n throw new Error('snapshot store digest mismatch');\n }\n return out;\n },\n };\n return Object.freeze(source);\n }\n\n #currentVersion(reader: SnapshotRecordReader = this.#store): number | null {\n const pointer = reader.get(this.#currentKey());\n if (pointer === null) return null;\n let text: string;\n try { text = new TextDecoder('utf-8', { fatal: true }).decode(pointer.payload); }\n catch { throw new Error('snapshot store current pointer is unreadable'); }\n const version = Number(text);\n if (!Number.isSafeInteger(version) || version < 1) throw new Error('snapshot store current pointer is invalid');\n return version;\n }\n\n #totalBytes(reader: SnapshotRecordReader): number {\n let total = 0;\n for (const version of this.#publishedVersions(reader)) {\n const meta = this.#readMeta(version, reader);\n if (meta !== null) total += meta.size;\n }\n return total;\n }\n\n /**\n * Durable published-version index. `list()` cannot be used here: it returns the\n * first N rows by key order, so a large body's chunk rows would push later\n * version metas out of view and GC would never run.\n */\n #versionsKey(): string { return `${this.#prefix}:versions`; }\n\n #publishedVersions(reader: SnapshotRecordReader): number[] {\n const record = reader.get(this.#versionsKey());\n if (record === null) return [];\n let parsed: unknown;\n try { parsed = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(record.payload)); }\n catch { throw new Error('snapshot store version index is unreadable'); }\n if (parsed === null || typeof parsed !== 'object') throw new Error('snapshot store version index is invalid');\n const list = (parsed as { versions?: unknown }).versions;\n if (!Array.isArray(list)) throw new Error('snapshot store version index is invalid');\n return list.filter((value): value is number => Number.isSafeInteger(value) && value >= 1).sort((left, right) => left - right);\n }\n\n /**\n * Bounded GC in ONE transaction: drops the oldest unreferenced, non-current\n * versions until both the version count and the total byte budget fit. Never\n * touches a version a live read has retained, and never the current version.\n */\n collect(): number {\n const encoder = new TextEncoder();\n return this.#store.transact((mutator) => {\n let removed = 0;\n for (;;) {\n const versions = this.#publishedVersions(mutator);\n const total = this.#totalBytes(mutator);\n if (versions.length <= this.#maxVersions && total <= this.#maxBytes) break;\n const current = this.#currentVersion(mutator);\n const oldest = versions.find((version) => version !== current && (familyRefs(this.#prefix).get(version) ?? 0) === 0);\n if (oldest === undefined) break;\n const meta = this.#readMeta(oldest, mutator);\n if (meta === null) break;\n for (let index = 0; index < meta.chunks; index += 1) mutator.ack(this.#chunkKey(oldest, index));\n mutator.ack(this.#metaKey(oldest));\n mutator.put(this.#versionsKey(), encoder.encode(JSON.stringify({ versions: versions.filter((version) => version !== oldest) })), { required: false, expiresAt: null });\n removed += 1;\n }\n return removed;\n });\n }\n}\n",
|
|
11
11
|
"/** Public same-process plugin services. Cross-process callers require the host RPC adapter. */\nimport type { PluginServiceDeclarations, PluginServiceProcess } from './plugin-services/contracts';\nimport { assertSupportedServiceDeclarations, isCrossProcessSelfSnapshot } from './plugin-services/contracts';\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { HostRpcAdapter, RpcServiceError, type HostRpcAdapterOptions, type HostRpcLifecycleIdentity, type HostRpcOwnerHandle, type HostRpcInvocationContext, type HostRpcLeaseRequest, type HostRpcLeaseGrant, type HostRpcHandlerFrame } from './plugin-services/host-rpc';\nimport type { RpcCallPurpose, RpcMethodDefinition } from './plugin-services/wire-contract';\nimport type { HostChannelOperation, HostChannelOwnerHandle, PluginChannelCapabilities, PluginChannelOwnerInput, PluginEventServices, PluginSnapshotServices, PluginStreamServices } from './plugin-services/channels';\nexport { defineRpcService } from './plugin-services/wire-contract';\nexport { RpcServiceError } from './plugin-services/host-rpc';\nexport { HostSnapshotStore, type HostSnapshotStoreOptions } from './plugin-services/snapshot-store';\nexport type { AsyncRpcClient, HostRpcCommandCapabilities, RpcCallOptions, RpcServiceErrorCode } from './plugin-services/host-rpc';\nexport type { RpcHandlerMap, RpcHandlerContext } from './plugin-services/rpc-runtime';\nexport type { RpcDataSchema, RpcMethodDefinition, InferRpcData } from './plugin-services/wire-contract';\nexport type { PluginServiceDeclarations, PluginServicePublication, PluginServiceConsumption, PluginServiceProcess, PluginServiceKind, PluginServiceScope } from './plugin-services/contracts';\nexport type {\n PluginStreamServices, PluginSnapshotServices, PluginEventServices, PluginStreamContract, PluginSnapshotContract,\n PluginEventContract, PluginChannelPublication, PluginStreamReadInput, PluginStreamWriteInput, PluginStreamDuplexInput,\n PluginSnapshotView, PluginSnapshotStatus, PluginEventPublisher, PluginChannelCapabilities, HostChannelPublicationView,\n PluginSnapshotVersionSource, HostSnapshotStoreOptionsView,\n} from './plugin-services/channels';\nexport type { PluginChannelDuplexSession, PluginChannelDuplexResult } from './plugin-services/peer-channel-hub';\n\nconst CHANNEL_KINDS = new Set(['events', 'snapshot', 'stream']);\n\nexport interface PluginServices {\n /** Explicit owner-bound background invocation; never inherits a stale/request frame. */\n runBackground?<T>(run: () => T): T;\n onDispose(cleanup: () => void): void;\n publish<T extends object>(serviceId: string, contractVersion: number, implementation: T): void;\n consume<T extends object>(provider: string, serviceId: string, contractVersion: number): Readonly<T>;\n /** Typed asynchronous data-only services, when the host communication runtime is configured. */\n readonly rpc?: Pick<HostRpcOwnerHandle, 'publish' | 'consume'>;\n /** Bounded, cancelable chunked byte channels over the authenticated peer link. */\n readonly stream?: PluginStreamServices;\n /** Transient notifications and durable at-least-once topics. */\n readonly events?: PluginEventServices;\n /** Versioned immutable snapshots with digest verification. */\n readonly snapshot?: PluginSnapshotServices;\n /** Explicit deployment capabilities for the channel lanes (checked before declaring work). */\n readonly channelCapabilities?: PluginChannelCapabilities;\n}\n\nexport interface PluginServiceCommunications extends Omit<HostRpcAdapterOptions, 'process' | 'enterHostHandlerFrame'> {\n /** Real process/owner identity supplied by the runtime, never invented by the plugin. */\n readonly identity: (plugin: string, scope: string) => HostRpcLifecycleIdentity;\n /**\n * Trusted host hook, called for one declared RPC consumption before the\n * adapter resolves its route. It lets the host register the native remote\n * proxy for the consumer's own contract so `resolvePlacement` can select it.\n * A host that does not implement remote routing simply omits it.\n */\n readonly ensureRemoteRoute?: (input: {\n readonly plugin: string;\n readonly scope: string;\n readonly provider: string;\n readonly contract: { readonly id: string; readonly version: number; readonly methods: Record<string, RpcMethodDefinition> };\n }) => void;\n /**\n * Host-owned event/snapshot/stream adapter. It is created by the same process\n * composition that owns the peer link, so channel work rides the one\n * authenticated transport and the canonical owner lifecycle.\n */\n readonly channels?: (input: PluginChannelOwnerInput) => HostChannelOwnerHandle;\n}\nexport interface PluginServiceInvocation {\n readonly purpose: RpcCallPurpose;\n /** Exact pre-admission lease returned by this host; request/attempt require it. */\n readonly lease?: () => void;\n readonly callee?: unknown;\n readonly signal?: AbortSignal;\n readonly deadlineAt?: number;\n}\ninterface LeaseProof { readonly retained: ReadonlySet<Owner>; released: boolean }\ninterface InvocationFrame extends HostRpcInvocationContext { readonly proof?: LeaseProof; readonly callee?: unknown; readonly ownerAuthority?: Owner; readonly peerAuthenticated?: boolean }\ninterface RpcReference { readonly owner: Owner }\n\ntype Owner = {\n plugin: string; scope: string; dependencies: Readonly<Record<string, string>>;\n ready: boolean; retiring: boolean; revoked: boolean; cleaning: boolean; leases: number;\n pending: Set<Promise<unknown>>; waiters: Array<() => void>; cleanups: Set<() => void>;\n consumed: Set<Owner>;\n rpcConsumed: Map<string, RpcReference>;\n rpc?: HostRpcOwnerHandle;\n channels?: HostChannelOwnerHandle;\n};\ntype Publication = { owner: Owner; id: string; version: number; kind: 'local' | 'rpc'; implementation?: object };\n\n/** Cleanup failed after the context was fully revoked; runtime teardown must still run. */\nexport class PluginServiceCleanupError extends AggregateError {\n constructor(failures: readonly unknown[]) { super(failures, 'Plugin service cleanup failed'); }\n}\n\nexport class PluginServiceHost {\n readonly rpc?: HostRpcAdapter;\n private readonly frames = new AsyncLocalStorage<InvocationFrame>();\n private readonly leaseProofs = new WeakMap<() => void, LeaseProof>();\n private readonly liveInvocations = new WeakSet<object>();\n private readonly ownerTokens = new WeakSet<object>();\n private readonly disposals = new WeakMap<Owner, Promise<void>>();\n private readonly communications?: PluginServiceCommunications;\n constructor(readonly process: PluginServiceProcess = 'worker', communications?: PluginServiceCommunications) {\n this.communications = communications;\n if (communications) this.rpc = new HostRpcAdapter({\n ...communications, process,\n enterHostHandlerFrame: (hostFrame, run) => this.runHostHandlerFrame(hostFrame, run),\n });\n }\n private contracts?: ReadonlyMap<string, PluginServiceDeclarations>;\n setDeclarations(contracts: ReadonlyMap<string, PluginServiceDeclarations>): void {\n for (const declarations of contracts.values()) assertSupportedServiceDeclarations(declarations);\n this.contracts = new Map(contracts);\n }\n /** Trusted host view of the declared service graph; never exposed to plugins. */\n serviceDeclarations(): ReadonlyMap<string, PluginServiceDeclarations> { return this.contracts ?? new Map(); }\n private owners = new Map<string, Owner>();\n private contexts = new WeakMap<PluginServices, Owner>();\n private publications = new Map<string, Publication>();\n private key(plugin: string, scope: string): string { return `${plugin}\\0${scope}`; }\n private publicationKey(plugin: string, scope: string, id: string, version: number): string {\n return `${plugin}\\0${scope}\\0${id}\\0${version}`;\n }\n isReady(plugin: string, scope = 'global'): boolean {\n const owner = this.owners.get(this.key(plugin, scope));\n return !!owner?.ready && !owner.retiring && !owner.revoked;\n }\n /** Trusted runtime entry; not exposed through PluginServices. */\n runInInvocation<T>(context: PluginServices, invocation: PluginServiceInvocation, run: () => T): T {\n const owner = this.contexts.get(context);\n if (!owner || owner.revoked || this.owners.get(this.key(owner.plugin, owner.scope)) !== owner) throw new RpcServiceError('unauthorized');\n const proof = invocation.lease === undefined ? undefined : this.leaseProofs.get(invocation.lease);\n if (invocation.purpose === 'request' || invocation.purpose === 'attempt') {\n if (!proof || proof.released || !proof.retained.has(owner)) throw new RpcServiceError('unauthorized');\n } else if (owner.retiring) throw new RpcServiceError('retired');\n const frame: InvocationFrame = Object.freeze({ ...invocation, proof, token: Object.freeze({}) });\n this.liveInvocations.add(frame.token);\n return this.frames.run(frame, () => {\n try {\n const result = run();\n if (result && (typeof result === 'object' || typeof result === 'function') && typeof (result as { then?: unknown }).then === 'function') {\n return Promise.resolve(result).finally(() => this.liveInvocations.delete(frame.token)) as T;\n }\n this.liveInvocations.delete(frame.token);\n return result;\n } catch (error) { this.liveInvocations.delete(frame.token); throw error; }\n });\n }\n /** Broker-only entry after physical-peer and per-call identity projection. */\n runPeerInvocation<T>(purpose: 'request' | 'attempt', callee: unknown, run: () => T): T {\n const frame: InvocationFrame = Object.freeze({purpose, callee, peerAuthenticated: true, token: Object.freeze({})});\n this.liveInvocations.add(frame.token);\n return this.frames.run(frame, () => {\n try {\n const result = run();\n if (result && typeof (result as any).then === 'function') return Promise.resolve(result).finally(() => this.liveInvocations.delete(frame.token)) as T;\n this.liveInvocations.delete(frame.token); return result;\n } catch (error) { this.liveInvocations.delete(frame.token); throw error; }\n });\n }\n /** Read by the trusted callee resolver to carry management/request authority. */\n currentInvocation(): Readonly<HostRpcInvocationContext & { readonly callee?: unknown }> | null {\n const frame = this.frames.getStore();\n return frame === undefined || !this.liveInvocations.has(frame.token) ? null : Object.freeze({ purpose: frame.purpose, token: frame.token, signal: frame.signal, deadlineAt: frame.deadlineAt, callee: frame.callee });\n }\n /**\n * Enters one live host-handler frame bound to the exact published owner, so a\n * native RPC handler shares the SAME trusted invocation store as local\n * dispatch. The frame is live only for the handler's real duration; a stale\n * (settled) frame is therefore never observable.\n */\n private runHostHandlerFrame(host: HostRpcHandlerFrame, run: () => unknown): unknown {\n const owner = host.ownerToken !== null && this.ownerTokens.has(host.ownerToken) ? host.ownerToken as Owner : undefined;\n const frame: InvocationFrame = Object.freeze({\n purpose: host.purpose,\n token: Object.freeze({}),\n ...(host.signal === undefined ? {} : { signal: host.signal }),\n ...(host.deadlineAt === undefined ? {} : { deadlineAt: host.deadlineAt }),\n ...(owner === undefined ? {} : { ownerAuthority: owner }),\n });\n this.liveInvocations.add(frame.token);\n const settle = (): void => { this.liveInvocations.delete(frame.token); };\n return this.frames.run(frame, () => {\n try {\n const result = run();\n if (result !== null && (typeof result === 'object' || typeof result === 'function') && typeof (result as { then?: unknown }).then === 'function') {\n return Promise.resolve(result).finally(settle);\n }\n settle();\n return result;\n } catch (error) { settle(); throw error; }\n });\n }\n createContext(plugin: string, scope = 'global', dependencies: Readonly<Record<string, string>> = {}): PluginServices {\n const key = this.key(plugin, scope);\n if (this.owners.has(key)) throw new Error(`Service context already exists: ${plugin}/${scope}`);\n const declarations = this.contracts?.get(plugin);\n if (!this.rpc && (declarations?.provides?.some(service => service.process === this.process && service.kind === 'rpc')\n || declarations?.consumes?.some(service => service.process === this.process && service.kind === 'rpc'))) {\n throw new RpcServiceError('capability_unavailable');\n }\n const channelProvider = declarations?.provides?.some(service => service.process === this.process && CHANNEL_KINDS.has(service.kind ?? 'local')) === true;\n const channelConsumer = declarations?.consumes?.some(service => service.process === this.process && CHANNEL_KINDS.has(service.kind ?? 'local')) === true;\n // A declared channel provider or required consumer without the host channel\n // adapter is refused here (capability_unavailable), never silently degraded.\n if ((channelProvider || channelConsumer) && this.communications?.channels === undefined) {\n throw new RpcServiceError('capability_unavailable');\n }\n const owner: Owner = { plugin, scope, dependencies: Object.freeze({ ...dependencies }), consumed: new Set(), rpcConsumed: new Map(), ready: false, retiring: false, revoked: false, cleaning: false, leases: 0, pending: new Set(), waiters: [], cleanups: new Set() };\n this.owners.set(key, owner);\n this.ownerTokens.add(owner);\n try {\n if (this.rpc) {\n owner.rpc = this.rpc.createOwner({\n token: owner, plugin, scope, dependencies: owner.dependencies,\n declarations: this.contracts?.get(plugin) ?? {}, lifecycle: this.communications!.identity(plugin, scope),\n getLifecycleState: () => ({ ready: owner.ready, retiring: owner.retiring, revoked: owner.revoked }),\n acquireLease: request => this.acquireRpcLease(owner, request),\n resolveInvocationContext: () => this.currentInvocation(),\n registerPublication: publication => {\n const publicationKey = this.publicationKey(plugin, scope, publication.id, publication.version);\n if (this.publications.has(publicationKey)) throw new RpcServiceError('invalid_registration');\n this.publications.set(publicationKey, { owner, id: publication.id, version: publication.version, kind: 'rpc' });\n },\n registerConsumption: (declaration, providerToken) => {\n const referenceKey = this.publicationKey(declaration.plugin, 'global', declaration.id, declaration.version);\n if (providerToken) {\n const provider = [...this.owners.values()].find(candidate => candidate === providerToken);\n if (!provider || provider.revoked) throw new RpcServiceError('unavailable');\n owner.rpcConsumed.set(referenceKey, { owner: provider });\n } else owner.rpcConsumed.delete(referenceKey);\n },\n });\n }\n if (this.communications?.channels !== undefined && (channelProvider || channelConsumer)) {\n owner.channels = this.communications.channels({\n plugin, scope, declarations: this.contracts?.get(plugin) ?? {},\n dependencies: owner.dependencies,\n lifecycle: this.communications.identity(plugin, scope),\n getLifecycleState: () => ({ ready: owner.ready, retiring: owner.retiring, revoked: owner.revoked }),\n trackPending: (pending: Promise<unknown>) => {\n owner.pending.add(pending);\n void pending.finally(() => { owner.pending.delete(pending); this.notify(owner); }).catch(() => {});\n },\n beginOperation: (options) => this.beginChannelOperation(plugin, scope, options),\n });\n }\n } catch (error) { this.owners.delete(key); throw error; }\n const assertActive = (target = owner) => {\n if (target.revoked || (target.retiring && !target.cleaning && !owner.cleaning && target.leases === 0 && target.pending.size === 0)) throw new Error(`Plugin service handle revoked: ${target.plugin}`);\n };\n const wrap = (value: unknown, provider: Owner, receiver?: object): any => {\n if (typeof value === 'function') return (...args: unknown[]) => {\n assertActive(); assertActive(provider);\n const guardArgument = (arg: unknown): unknown => {\n if (typeof arg === 'function') return (...callbackArgs: unknown[]) => {\n assertActive(); assertActive(provider);\n const result = Reflect.apply(arg, undefined, callbackArgs);\n if (result && typeof result.then === 'function') {\n const pending = Promise.resolve(result);\n owner.pending.add(pending); provider.pending.add(pending);\n void pending.finally(() => { owner.pending.delete(pending); provider.pending.delete(pending); this.notify(owner); this.notify(provider); }).catch(() => {});\n return pending;\n }\n return result;\n };\n if (Array.isArray(arg)) return Object.freeze(arg.map(guardArgument));\n if (arg && typeof arg === 'object') return Object.freeze(Object.fromEntries(Object.entries(arg).map(([key, value]) => [key, guardArgument(value)])));\n return arg;\n };\n const guarded = args.map(guardArgument);\n const result = Reflect.apply(value, receiver, guarded);\n if (result && typeof result.then === 'function') {\n const pending = Promise.resolve(result).then(output => { assertActive(); assertActive(provider); return wrap(output, provider); });\n owner.pending.add(pending); provider.pending.add(pending);\n void pending.finally(() => { owner.pending.delete(pending); provider.pending.delete(pending); this.notify(owner); this.notify(provider); }).catch(() => {});\n return pending;\n }\n return wrap(result, provider);\n };\n if (Array.isArray(value)) return Object.freeze(value.map(item => wrap(item, provider)));\n if (value && typeof value === 'object') {\n // A fresh facade prevents access to implementation identity or mutable provider fields.\n const facade: Record<string, unknown> = {};\n for (const key of Object.keys(value)) Object.defineProperty(facade, key, {\n enumerable: true, get: () => { assertActive(); assertActive(provider); return wrap((value as any)[key], provider, value as object); },\n });\n return Object.freeze(facade);\n }\n return value;\n };\n const consume = <T extends object>(provider: string, id: string, version: number): Readonly<T> => {\n assertActive();\n const declaration = this.contracts?.get(plugin)?.consumes?.find(value => value.plugin === provider && value.id === id && value.version === version && value.process === this.process);\n if (this.contracts && !declaration) throw new Error(`Undeclared plugin service consumption: ${plugin} -> ${provider}/${id}`);\n if (declaration?.kind && declaration.kind !== 'local') throw new Error('Non-local services require their asynchronous host adapter');\n if (provider === plugin || !Object.hasOwn(owner.dependencies, provider)) throw new Error(`Undeclared plugin service dependency: ${plugin} -> ${provider}`);\n const targetScope = 'global';\n const publication = this.publications.get(this.publicationKey(provider, targetScope, id, version));\n if (!publication || !publication.owner.ready || publication.owner.retiring || publication.owner.revoked) {\n if ([...this.publications.values()].some(value => value.owner.plugin === provider && value.owner.scope === targetScope && value.id === id && value.version !== version)) throw new Error(`Plugin service contract mismatch: ${provider}/${id}`);\n throw new Error(`Plugin service not ready: ${provider}/${id}`);\n }\n owner.consumed.add(publication.owner);\n return wrap(publication.implementation, publication.owner);\n };\n const context: PluginServices = Object.freeze({\n runBackground: <T>(run: () => T): T => {\n if (this.contexts.get(context) !== owner || this.owners.get(key) !== owner\n || !owner.ready || owner.retiring || owner.revoked) throw new RpcServiceError('retired');\n const release = this.acquireLease(plugin, scope);\n try {\n const result = this.runInInvocation(context, { purpose: 'background' }, run);\n if (result && (typeof result === 'object' || typeof result === 'function') && typeof (result as { then?: unknown }).then === 'function') {\n return Promise.resolve(result).finally(release) as T;\n }\n release();\n return result;\n } catch (error) { release(); throw error; }\n },\n onDispose: (cleanup: () => void) => { assertActive(); owner.cleanups.add(cleanup); },\n publish: <T extends object>(id: string, version: number, implementation: T) => {\n assertActive();\n const candidates = this.contracts?.get(plugin)?.provides?.filter(value => value.id === id && value.version === version && value.process === this.process);\n const declaration = candidates?.[0];\n if (this.contracts && !declaration) throw new Error(`Undeclared plugin service publication: ${plugin}/${id}`);\n if (declaration?.kind && declaration.kind !== 'local') throw new Error('Non-local services require their asynchronous host adapter');\n if (owner.scope !== 'global') throw new Error('Only global providers may publish global services');\n if (!Number.isSafeInteger(version) || version < 1) throw new Error('Invalid service contract version');\n const publicationKey = this.publicationKey(plugin, owner.scope, id, version);\n if (this.publications.has(publicationKey)) throw new Error(`Service already published: ${plugin}/${id}`);\n this.publications.set(publicationKey, { owner, id, version, implementation, kind: 'local' });\n },\n consume: <T extends object>(provider: string, id: string, version: number): Readonly<T> => consume<T>(provider, id, version),\n rpc: owner.rpc === undefined ? undefined : (() => {\n const ownerHandle = owner.rpc!;\n const prepare = (provider: string, contract: { readonly id: string; readonly version: number; readonly methods: Record<string, RpcMethodDefinition> }): void => {\n try { this.communications?.ensureRemoteRoute?.({ plugin, scope: owner.scope, provider, contract }); }\n catch { /* an unroutable remote declaration stays unavailable, never guessed */ }\n };\n return Object.freeze({\n publish: ownerHandle.publish,\n consume: <const M extends Record<string, RpcMethodDefinition>>(provider: string, contract: { readonly id: string; readonly version: number; readonly methods: M }) => {\n prepare(provider, contract);\n return ownerHandle.consume(provider, contract);\n },\n });\n })(),\n stream: owner.channels?.stream,\n events: owner.channels?.events,\n snapshot: owner.channels?.snapshot,\n channelCapabilities: owner.channels?.capabilities,\n });\n this.contexts.set(context, owner);\n return context;\n }\n markReady(plugin: string, scope = 'global', expectedContext?: PluginServices): void {\n const owner = this.requireOwner(plugin, scope, expectedContext);\n if (owner.retiring || owner.revoked) throw new Error(`Plugin service disposed: ${plugin}`);\n for (const publication of this.contracts?.get(plugin)?.provides ?? []) {\n if (publication.kind === 'rpc' && publication.process === this.process && (publication.scope ?? 'global') === (scope === 'global' ? 'global' : 'binding')\n && this.publications.get(this.publicationKey(plugin, scope, publication.id, publication.version))?.kind !== 'rpc') throw new RpcServiceError('not_ready');\n }\n owner.rpc?.markReady();\n owner.channels?.markReady();\n owner.ready = true;\n }\n retire(plugin: string, scope = 'global', expectedContext?: PluginServices): void {\n const owner = this.requireOwner(plugin, scope, expectedContext);\n owner.retiring = true;\n owner.rpc?.retire();\n try { owner.channels?.retire(); } catch { /* host-owned */ }\n }\n /**\n * Host-only: retires admission for EVERY live owner at once. It is wired to\n * the real drain admission point, so after it no new bootstrap/background work\n * is admitted while every already-accepted lease, result and terminal keeps\n * draining normally (nothing is revoked here).\n */\n retireAll(): void {\n for (const owner of this.owners.values()) {\n if (owner.revoked) continue;\n owner.retiring = true;\n try { owner.rpc?.retire(); } catch { /* host-owned */ }\n try { owner.channels?.retire(); } catch { /* host-owned */ }\n }\n }\n /**\n * Host-only: begins ONE channel operation for an owner. It applies the exact\n * same invocation-frame rules as an RPC call (management only from a\n * management frame, request/attempt only with a live retained lease proof, no\n * new work while retiring, bootstrap-only before ready) and holds a real\n * owner lease for the operation's whole lifetime, so owner disposal can never\n * race a live lane task. `null` refuses the operation.\n */\n beginChannelOperation(\n plugin: string,\n scope = 'global',\n incoming?: {\n readonly purpose?: RpcCallPurpose;\n readonly deadlineAt?: number;\n readonly signal?: AbortSignal;\n readonly authenticated?: boolean;\n /**\n * Host-managed background work: the operation runs in an EXPLICIT\n * independent background context and deliberately ignores any frame the\n * caller happens to be inside (typically a closed bootstrap/init closure).\n */\n readonly background?: boolean;\n },\n ): HostChannelOperation | null {\n const owner = this.owners.get(this.key(plugin, scope));\n if (!owner || owner.revoked) return null;\n if (this.owners.get(this.key(plugin, scope)) !== owner) return null;\n const stored = this.frames.getStore();\n let frame: InvocationFrame | undefined;\n if (incoming?.background === true) {\n // Explicit Host background context: no inherited purpose/deadline/signal.\n frame = undefined;\n } else {\n // A stale (already settled) frame is REFUSED: a finished invocation must\n // never be reused as fresh authority nor laundered into another purpose.\n // Legitimate background work either runs outside a frame or asks for the\n // explicit Host background context above.\n if (stored !== undefined && !this.liveInvocations.has(stored.token)) return null;\n frame = stored;\n }\n const leaseBound = frame !== undefined\n && (frame.purpose === 'request' || frame.purpose === 'attempt')\n && ((frame.proof !== undefined && !frame.proof.released && frame.proof.retained.has(owner))\n || frame.ownerAuthority === owner);\n if (frame !== undefined && (frame.purpose === 'request' || frame.purpose === 'attempt') && !leaseBound) return null;\n // A peer-authenticated inbound channel request carries the caller host's real\n // purpose, but only request/attempt/background may cross that boundary: a peer\n // may never claim management or bootstrap authority for a provider lease.\n const peerPurpose = frame === undefined && incoming?.authenticated === true\n && (incoming.purpose === 'request' || incoming.purpose === 'attempt' || incoming.purpose === 'background')\n ? incoming.purpose\n : undefined;\n const purpose = frame?.purpose ?? peerPurpose ?? 'background';\n const requestBound = leaseBound || peerPurpose === 'request' || peerPurpose === 'attempt';\n // Retirement refuses NEW work; already-accepted request/attempt work finishes.\n if (owner.retiring && !requestBound) return null;\n if (!owner.ready && !requestBound && purpose !== 'bootstrap') return null;\n const deadlineAt = minDefined(frame?.deadlineAt, incoming?.deadlineAt);\n const signal = combineAbortSignals(frame?.signal, incoming?.signal);\n owner.leases += 1;\n let released = false;\n const release = () => { if (released) return; released = true; owner.leases -= 1; this.notify(owner); };\n return Object.freeze({\n purpose,\n ...(signal === undefined ? {} : { signal }),\n ...(deadlineAt === undefined ? {} : { deadlineAt }),\n release,\n });\n }\n\n /** Capture before admission; release only after all consumers finish old-request processing. */\n acquireLease(plugin: string, scope = 'global'): () => void {\n const owner = this.requireOwner(plugin, scope);\n if (!owner.ready || owner.retiring || owner.revoked) throw new Error(`Plugin service not ready: ${plugin}`);\n const retained = new Set<Owner>();\n const retain = (target: Owner): void => {\n if (retained.has(target)) return;\n if (!target.ready || target.retiring || target.revoked) throw new Error(`Plugin service not ready: ${target.plugin}`);\n retained.add(target);\n for (const provider of this.dependencyOwners(target)) retain(provider);\n for (const provider of target.consumed) if (provider.ready && !provider.retiring && !provider.revoked) retain(provider);\n // A declared in-process channel provider is an exact required\n // reference too, and its ready provider owner enters the lease proof so a\n // request/attempt frame can authorize real channel work on it.\n for (const provider of this.channelDependencyOwners(target)) {\n if (provider.ready && !provider.retiring && !provider.revoked) retain(provider);\n }\n for (const reference of target.rpcConsumed.values()) retain(reference.owner);\n };\n retain(owner);\n for (const target of retained) target.leases++;\n let released = false;\n const proof: LeaseProof = { retained, released: false };\n const release = () => { if (released) return; released = true; proof.released = true; for (const target of retained) { target.leases--; this.notify(target); } };\n this.leaseProofs.set(release, proof);\n return release;\n }\n\n references(plugin: string): ReadonlyArray<{ plugin: string; scope: string; leases: number }> {\n return [...this.owners.values()].filter(o => !o.revoked && (o.plugin === plugin || [...this.dependencyOwners(o), ...this.consumedOwners(o)].some(provider => provider.plugin === plugin)))\n .map(o => Object.freeze({ plugin: o.plugin, scope: o.scope, leases: o.leases }));\n }\n /** Stop admission immediately, preserve acquired handles until leases and calls drain. */\n dispose(plugin: string, scope = 'global', expectedContext?: PluginServices): Promise<void> {\n let owner: Owner;\n try { owner = this.requireOwner(plugin, scope, expectedContext); } catch (error) { return Promise.reject(error); }\n const existing = this.disposals.get(owner);\n if (existing) return existing;\n let resolve!: () => void;\n let reject!: (error: unknown) => void;\n const task = new Promise<void>((accept, fail) => { resolve = accept; reject = fail; });\n // Install before cleanup can synchronously re-enter disposal.\n this.disposals.set(owner, task);\n void this.disposeOwner(owner).then(() => {\n this.disposals.delete(owner); resolve();\n }, error => { this.disposals.delete(owner); reject(error); });\n return task;\n }\n private async disposeOwner(owner: Owner): Promise<void> {\n const { plugin, scope } = owner;\n const hasPublications = [...this.publications.values()].some(publication => publication.owner === owner);\n if (hasPublications) {\n const dependents = [...this.owners.values()].filter(candidate => candidate !== owner && !candidate.revoked && (this.dependencyOwners(candidate).includes(owner) || this.consumedOwners(candidate).includes(owner)));\n if (dependents.length) throw new Error(`Plugin service provider is referenced: ${plugin} <- ${dependents.map(candidate => `${candidate.plugin}/${candidate.scope}`).join(', ')}`);\n }\n owner.retiring = true;\n owner.rpc?.retire();\n try { owner.channels?.retire(); } catch { /* host-owned */ }\n if (owner.leases || owner.pending.size) await new Promise<void>(resolve => owner.waiters.push(resolve));\n if (owner.channels) {\n try { await owner.channels.dispose(); } catch { /* provider release is best-effort here */ }\n }\n if (owner.rpc) {\n const result = await owner.rpc.dispose();\n if (!result.drained) throw new RpcServiceError('timeout');\n }\n // Cleanup may invoke its cached unsubscribe handle after drain, before final revocation.\n owner.cleaning = true;\n const failures: unknown[] = [];\n try {\n for (const cleanup of owner.cleanups) { try { cleanup(); } catch (error) { failures.push(error); } }\n } finally {\n owner.cleanups.clear(); owner.consumed.clear(); owner.rpcConsumed.clear(); owner.cleaning = false;\n owner.revoked = true; owner.ready = false;\n for (const [key, publication] of this.publications) if (publication.owner === owner) this.publications.delete(key);\n if (this.owners.get(this.key(plugin, scope)) === owner) this.owners.delete(this.key(plugin, scope));\n }\n if (failures.length) throw new PluginServiceCleanupError(failures);\n }\n /** Actual local provider owners, not activation edges to another process/binding. */\n private dependencyOwners(owner: Owner): Owner[] {\n const result = new Set<Owner>();\n for (const dependency of Object.keys(owner.dependencies)) {\n const declarations = this.contracts?.get(owner.plugin)?.consumes?.filter(service => service.plugin === dependency && service.process === this.process);\n if (declarations?.length) {\n for (const service of declarations) {\n // RPC providers are retained through `rpcConsumed`/`acquireRpcLease`,\n // never here. A local channel provider (events/snapshot/stream) IS a\n // real provider owner, so a request/attempt lease must retain it too,\n // or `beginChannelOperation` would refuse exact in-process channel work.\n if ((service.kind ?? 'local') === 'rpc') continue;\n const provider = this.owners.get(this.key(dependency, 'global'));\n if (provider) result.add(provider);\n }\n } else {\n const provider = this.owners.get(this.key(dependency, 'global'));\n if (provider) result.add(provider);\n }\n }\n return [...result];\n }\n /** Local providers of this owner's declared channel consumptions. */\n private channelDependencyOwners(owner: Owner): Owner[] {\n const result = new Set<Owner>();\n for (const service of this.contracts?.get(owner.plugin)?.consumes ?? []) {\n if (service.process !== this.process) continue;\n if (!CHANNEL_KINDS.has(service.kind ?? 'local')) continue;\n if (typeof service.plugin !== 'string' || !service.plugin) continue;\n if (isCrossProcessSelfSnapshot(owner.plugin, service, this.contracts?.get(owner.plugin) ?? {})) continue;\n if (!Object.hasOwn(owner.dependencies, service.plugin)) continue;\n const provider = this.owners.get(this.key(service.plugin, 'global'));\n if (provider) result.add(provider);\n }\n return [...result];\n }\n /** Consumers release all actual references before providers. */\n disposalOrder(): ReadonlyArray<{ plugin: string; scope: string }> {\n const visited = new Set<Owner>(), visiting = new Set<Owner>(), ordered: Owner[] = [];\n const visit = (owner: Owner): void => {\n if (visited.has(owner)) return;\n if (visiting.has(owner)) throw new Error('Plugin service reference cycle during disposal');\n visiting.add(owner);\n for (const provider of [...this.dependencyOwners(owner), ...this.consumedOwners(owner)]) if (!provider.revoked) visit(provider);\n visiting.delete(owner); visited.add(owner); ordered.push(owner);\n };\n for (const owner of this.owners.values()) visit(owner);\n return ordered.reverse().map(owner => Object.freeze({ plugin: owner.plugin, scope: owner.scope }));\n }\n private requireOwner(plugin: string, scope: string, expectedContext?: PluginServices): Owner {\n const owner = this.owners.get(this.key(plugin, scope));\n if (!owner) throw new Error(`Missing plugin service context: ${plugin}/${scope}`);\n if (expectedContext && this.contexts.get(expectedContext) !== owner) throw new Error(`Stale plugin service context: ${plugin}/${scope}`);\n return owner;\n }\n private notify(owner: Owner): void {\n if (!owner.leases && !owner.pending.size) for (const resolve of owner.waiters.splice(0)) resolve();\n }\n private consumedOwners(owner: Owner): Owner[] {\n return [...new Set([...owner.consumed, ...[...owner.rpcConsumed.values()].map(reference => reference.owner)])];\n }\n /** Each real RPC task borrows the canonical owner until actual business work settles. */\n private acquireRpcLease(owner: Owner, request: HostRpcLeaseRequest): HostRpcLeaseGrant {\n if (owner.revoked || this.owners.get(this.key(owner.plugin, owner.scope)) !== owner) throw new RpcServiceError('revoked');\n const frame = this.frames.getStore();\n if (frame && !this.liveInvocations.has(frame.token)) throw new RpcServiceError('unauthorized');\n if (request.purpose === 'management' && frame?.purpose !== 'management') throw new RpcServiceError('unauthorized');\n const existing = (request.purpose === 'request' || request.purpose === 'attempt')\n && frame?.purpose === request.purpose && ((frame.proof !== undefined && !frame.proof.released && frame.proof.retained.has(owner)) || (request.role === 'callee' && frame.peerAuthenticated === true));\n if ((request.purpose === 'request' || request.purpose === 'attempt') && !existing) throw new RpcServiceError('unauthorized');\n if (owner.retiring && !existing) throw new RpcServiceError('retired');\n if (!owner.ready && request.purpose !== 'bootstrap') throw new RpcServiceError('not_ready');\n owner.leases++;\n let released = false;\n return { allowRetired: existing, release: () => { if (released) return; released = true; owner.leases--; this.notify(owner); } };\n }\n}\n\n/** Smallest defined deadline, or undefined when neither side has one. */\nfunction minDefined(left: number | undefined, right: number | undefined): number | undefined {\n if (left === undefined) return right;\n if (right === undefined) return left;\n return Math.min(left, right);\n}\n\n/** Combines local and peer-provided abort signals without dropping either. */\nfunction combineAbortSignals(...signals: ReadonlyArray<AbortSignal | undefined>): AbortSignal | undefined {\n const present = signals.filter((signal): signal is AbortSignal => signal !== undefined);\n if (present.length === 0) return undefined;\n if (present.length === 1) return present[0];\n const any = (AbortSignal as unknown as { any?: (list: readonly AbortSignal[]) => AbortSignal }).any;\n if (typeof any === 'function') return any.call(AbortSignal, present);\n const controller = new AbortController();\n const abort = (signal: AbortSignal) => { if (!controller.signal.aborted) controller.abort(signal.reason); };\n for (const signal of present) {\n if (signal.aborted) { abort(signal); break; }\n signal.addEventListener('abort', () => abort(signal), { once: true });\n }\n return controller.signal;\n}\n\nexport const TOKEN_METERING_SERVICE_ID = 'token-metering.v1';\nexport const TOKEN_METERING_CONTRACT_VERSION = 1;\nexport type TokenMeteringSource = 'official' | 'estimated' | 'partial' | 'none';\nexport type TokenMeteringAuthority = 'official' | 'local' | 'heuristic' | 'partial' | 'none';\nexport interface TokenMeteringResult {\n readonly requestId: string; readonly attemptId: string; readonly routeId: string; readonly upstreamId: string;\n readonly keyId?: string | null;\n readonly provider: string; readonly model?: string; readonly pricingProvider?: string;\n readonly inputTokens?: number; readonly outputTokens?: number; readonly cacheReadTokens?: number; readonly cacheWriteTokens?: number;\n readonly inputSource: TokenMeteringSource; readonly outputSource: TokenMeteringSource;\n readonly inputAuthority: TokenMeteringAuthority; readonly outputAuthority: TokenMeteringAuthority;\n readonly complete: boolean; readonly observationIncomplete: boolean;\n readonly outcome: 'completed' | 'failed' | 'aborted'; readonly finishedAtMs: number; readonly settlementVersion: number;\n}\nexport interface TokenMeteringSubscription {\n /** Omit for degradable all-request reporting; required consumers bind their admitted request. */\n readonly requestId?: string;\n readonly required?: boolean;\n readonly onResult: (result: TokenMeteringResult) => void | Promise<void>;\n readonly onFailure?: (error: unknown, result: TokenMeteringResult) => void | Promise<void>;\n}\nexport interface TokenMeteringService {\n /** Final completion boundary: await this request's required settlement/failure callbacks before releasing its host lease. */\n drainRequest(requestId: string): Promise<void>;\n subscribe(subscription: TokenMeteringSubscription): () => void;\n prepareAttempt(input: Readonly<{ requestId: string; attemptId: string; routeId: string; upstreamId: string; url: string; body: unknown }>): Readonly<{ supported: boolean; provider?: string; model?: string; pricingProvider?: string }>;\n /** Consumer calls before request admission to pin demand; framework init also captures report subscriptions. */\n prepareRequest(requestId: string): boolean;\n}\n\nexport const TOKEN_PRICING_SERVICE_ID = 'token-stats.pricing.v1';\nexport const TOKEN_PRICING_CONTRACT_VERSION = 1;\n/** Costs are quantized to safe integer nanoUSD (1 USD = 1e9 nanoUSD); unknown remains null. */\nexport interface TokenPricingService {\n canPrice(input: Readonly<{ model?: string; pricingProvider?: string }>): Promise<boolean>;\n price(result: TokenMeteringResult): Promise<Readonly<{ costUsd: number | null; costNanoUsd: number | null }>>;\n}\n",
|
|
12
12
|
"import { defineRpcService } from '../../../packages/core/src/plugin-services';\n\nconst command = { deduplication: 'none', resultRetentionMs: null, quotaBytes: 65536, maxResultBytes: 65536 } as const;\nexport const businessRpc = defineRpcService({id: 'chatgpt-oauth.credentials.v1', version: 1, methods: {\n getCredential: {kind: 'command', input: {type: 'object', properties: {}}, output: {type: 'object', properties: {version: {type: 'number', integer: true, minimum: 1}, expiresAt: {type: 'number'}, headers: {type: 'record', values: {type: 'string'}, maxEntries: 16}}}, purposes: ['attempt'], command, timeoutMs: 15000},\n rejectAccess: {kind: 'command', input: {type: 'object', properties: {version: {type: 'number', integer: true, minimum: 1}}}, output: {type: 'object', properties: {rejected: {type: 'boolean'}}}, purposes: ['attempt'], command, timeoutMs: 15000},\n}});\n",
|
|
13
|
-
"import { businessRpc } from './rpc';\nimport { randomUUID } from 'node:crypto';\nimport type {\n ControlApiDeclaration,\n ControlApiHandlerContext,\n ControlHostContext,\n ControlPlugin,\n ControlRpcContext,\n CredentialLease,\n PluginControl,\n UpstreamDraft,\n} from '../../../packages/core/src/plugin-control/contracts';\nimport type { FetchLike, CodexTokenSet } from './oauth';\nimport { refreshCodexToken } from './oauth';\nimport { AccountControlError, AccountStore, accountListItem, type AccountListItem, type StoredAccount } from './accounts';\nimport { LoginSessionError, LoginSessionManager, type LoginCommitInfo, type LoginFence, type LoginSessionDependencies } from './sessions';\nimport { UsageError, UsageService } from './usage';\nimport { AutoResetScheduler, type AutoResetTimer } from './auto-reset';\n\nexport const CHATGPT_TARGET = 'https://chatgpt.com';\nexport const CONTROL_HOST_CONTRACT_GAP = 'ControlRpcContext.binding.bindingOptions.accountRef is required and host-resolved; RPC payload is never used as a fallback.';\n\nexport interface ControlDependencies extends LoginSessionDependencies { now?: () => number; timeoutMs?: number; autoResetTimer?: AutoResetTimer }\n\nexport class ControlError extends Error {\n readonly name = 'ControlError';\n constructor(readonly code: ControlErrorCode) { super(code); }\n}\n\nexport type ControlErrorCode =\n | 'invalid_input' | 'body_limit' | 'request_cancelled' | 'not_found' | 'disabled' | 'revoked'\n | 'reauth_required' | 'identity_missing' | 'identity_mismatch' | 'invalid_identity'\n | 'refresh_failed' | 'refresh_in_progress' | 'stale_refresh' | 'binding_options_unavailable' | 'disposed'\n | 'expired' | 'cancelled' | 'busy' | 'login_failed' | 'session_error'\n | 'reset_in_progress' | 'credits_unavailable' | 'credit_unavailable' | 'upstream_unavailable';\n\nconst REFRESH_SAFETY_WINDOW_MS = 60_000;\nconst REFRESH_LOCK_MS = 90_000;\nconst MAX_BODY_BYTES = 64 * 1024;\n\nfunction safeError(error: unknown): ControlError {\n if (error instanceof ControlError) return error;\n if (error instanceof AccountControlError) {\n const map: Record<string, ControlErrorCode> = {\n invalid_input: 'invalid_input',\n not_found: 'not_found', disabled: 'disabled', revoked: 'revoked', reauth_required: 'reauth_required',\n identity_mismatch: 'identity_mismatch', invalid_identity: 'invalid_identity', disposed: 'disposed',\n stale_refresh: 'stale_refresh',\n };\n return new ControlError(map[error.code] ?? 'refresh_failed');\n }\n if (error instanceof LoginSessionError) {\n const known: Record<string, ControlErrorCode> = { invalid_input: 'invalid_input', not_found: 'not_found', expired: 'expired', cancelled: 'cancelled', already_consumed: 'busy', busy: 'busy', failed: 'login_failed', disposed: 'disposed' };\n return new ControlError(known[error.code] ?? 'session_error');\n }\n if (error instanceof UsageError) {\n const known: Record<string, ControlErrorCode> = {\n reauth_required: 'reauth_required', disposed: 'disposed', cancelled: 'request_cancelled',\n reset_in_progress: 'reset_in_progress', credits_unavailable: 'credits_unavailable', credit_unavailable: 'credit_unavailable',\n stale_generation: 'upstream_unavailable', upstream_unavailable: 'upstream_unavailable',\n };\n return new ControlError(known[error.code] ?? 'refresh_failed');\n }\n const kind = (error as { kind?: string }).kind;\n if (kind === 'refresh_token_reused') return new ControlError('reauth_required');\n if (typeof kind === 'string') return new ControlError('login_failed');\n return new ControlError('refresh_failed');\n}\n\nfunction jsonResponse(value: unknown, status = 200): Response {\n return new Response(JSON.stringify(value), { status, headers: { 'content-type': 'application/json; charset=utf-8' } });\n}\n\nfunction errorResponse(error: unknown): Response {\n const safe = safeError(error);\n const status = safe.code === 'not_found' ? 404 : safe.code === 'invalid_input' || safe.code === 'request_cancelled' ? 400 : safe.code === 'body_limit' ? 413 : safe.code === 'binding_options_unavailable' ? 501 : 409;\n return jsonResponse({ error: safe.code }, status);\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new ControlError('invalid_input');\n return value as Record<string, unknown>;\n}\n\nfunction exactKeys(value: Record<string, unknown>, keys: readonly string[]): void {\n const allowed = new Set(keys);\n if (Object.keys(value).some((key) => !allowed.has(key))) throw new ControlError('invalid_input');\n}\n\nfunction requiredText(value: unknown, max = 512): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > max || value.trim() !== value) throw new ControlError('invalid_input');\n return value;\n}\n\nfunction optionalText(value: unknown, max = 512): string | undefined { return value === undefined ? undefined : requiredText(value, max); }\nfunction requiredVersion(value: unknown): number {\n if (!Number.isSafeInteger(value) || (value as number) < 1) throw new ControlError('invalid_input');\n return value as number;\n}\n\nfunction abortable<T>(promise: Promise<T>, signal: AbortSignal, hostSignal?: AbortSignal, lifetimeSignal?: AbortSignal): Promise<T> {\n if (hostSignal?.aborted || lifetimeSignal?.aborted) return Promise.reject(new ControlError('disposed'));\n if (signal.aborted) return Promise.reject(new ControlError('request_cancelled'));\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n const cleanup = () => { signal.removeEventListener('abort', onRequestAbort); hostSignal?.removeEventListener('abort', onHostAbort); lifetimeSignal?.removeEventListener('abort', onLifetimeAbort); };\n const onRequestAbort = () => { if (!settled) { settled = true; cleanup(); reject(new ControlError('request_cancelled')); } };\n const onHostAbort = () => { if (!settled) { settled = true; cleanup(); reject(new ControlError('disposed')); } };\n const onLifetimeAbort = () => { if (!settled) { settled = true; cleanup(); reject(new ControlError('disposed')); } };\n signal.addEventListener('abort', onRequestAbort, { once: true });\n hostSignal?.addEventListener('abort', onHostAbort, { once: true });\n lifetimeSignal?.addEventListener('abort', onLifetimeAbort, { once: true });\n promise.then((value) => { if (!settled) { settled = true; cleanup(); resolve(value); } }, (error) => { if (!settled) { settled = true; cleanup(); reject(error); } });\n });\n}\n\nasync function readRequestJson(request: Request, requestSignal: AbortSignal, hostSignal: AbortSignal, lifetimeSignal = hostSignal): Promise<Record<string, unknown>> {\n if (hostSignal.aborted || lifetimeSignal.aborted) throw new ControlError('disposed');\n if (requestSignal.aborted) throw new ControlError('request_cancelled');\n if (!request.body) return {};\n const reader = request.body.getReader();\n const decoder = new TextDecoder();\n let text = '';\n let total = 0;\n try {\n for (;;) {\n const next = await abortable(reader.read(), requestSignal, hostSignal, lifetimeSignal);\n if (next.done) break;\n total += next.value.byteLength;\n if (total > MAX_BODY_BYTES) {\n void reader.cancel().catch(() => undefined);\n throw new ControlError('body_limit');\n }\n text += decoder.decode(next.value, { stream: true });\n }\n text += decoder.decode();\n } catch (error) {\n void reader.cancel().catch(() => undefined);\n if (error instanceof ControlError) throw error;\n throw new ControlError('invalid_input');\n } finally { reader.releaseLock(); }\n if (!text) return {};\n try { return record(JSON.parse(text)); } catch { throw new ControlError('invalid_input'); }\n}\n\nfunction accountRefFromBinding(context: ControlRpcContext): string {\n const value = context.binding.bindingOptions?.accountRef;\n if (typeof value !== 'string' || value.length < 1 || value.length > 128 || value.trim() !== value) throw new ControlError('binding_options_unavailable');\n return value;\n}\n\nfunction lease(account: StoredAccount): CredentialLease {\n if (account.status !== 'active') throw new ControlError(account.status);\n if (!account.accessToken) throw new ControlError('reauth_required');\n if (!account.identity?.accountId) throw new ControlError('identity_missing');\n if (!Number.isFinite(account.expiresAt)) throw new ControlError('reauth_required');\n return { version: account.generation, expiresAt: account.expiresAt as number, headers: { Authorization: `Bearer ${account.accessToken}`, 'Chatgpt-Account-Id': account.identity.accountId } };\n}\n\nfunction isRefreshable(account: StoredAccount, now: number): boolean {\n return account.expiresAt === undefined || account.expiresAt <= now + REFRESH_SAFETY_WINDOW_MS;\n}\n\nclass ChatgptControl implements PluginControl {\n readonly api: readonly ControlApiDeclaration[];\n readonly rpc: readonly { name: string; handler: string; invoke: (payload: unknown, context: ControlRpcContext) => unknown | Promise<unknown> }[];\n private readonly accounts: AccountStore;\n private readonly sessions: LoginSessionManager;\n private readonly now: () => number;\n private readonly workerOwner = `chatgpt-control-${randomUUID()}`;\n private readonly inFlight = new Map<string, Promise<StoredAccount>>();\n private readonly refreshControllers = new Map<string, AbortController>();\n private readonly apiLifetime = new AbortController();\n private readonly usage: UsageService;\n private readonly autoReset: AutoResetScheduler;\n private disposed = false;\n private readonly abortListener: () => void;\n\n constructor(private readonly host: ControlHostContext, private readonly deps: ControlDependencies = {}) {\n this.now = deps.now ?? Date.now;\n this.accounts = new AccountStore(host.secretStore, () => !this.disposed && !host.signal.aborted);\n this.sessions = new LoginSessionManager(host.signal, deps);\n this.usage = new UsageService({\n fetchImpl: deps.fetchImpl,\n now: this.now,\n timeoutMs: deps.timeoutMs,\n hostSignal: this.apiLifetime.signal,\n credential: (id, signal) => this.credential(id, signal),\n rejectAccess: (id, version) => this.accounts.rejectAccess(id, version),\n });\n this.autoReset = new AutoResetScheduler(this.accounts, this.usage, this.apiLifetime.signal, this.now, deps.autoResetTimer);\n this.abortListener = () => { void this.dispose(); };\n if (host.signal.aborted) this.disposed = true;\n else host.signal.addEventListener('abort', this.abortListener, { once: true });\n this.api = this.buildApi();\n this.rpc = this.buildRpc();\n host.services?.rpc?.publish(businessRpc, Object.fromEntries(this.rpc.map(declaration => [declaration.name, (payload: unknown, context: any) => {\n const frame = host.resolveRpcCallee?.(context.callee) as {binding?: ControlRpcContext['binding']; attempt?: ControlRpcContext['attempt']} | null;\n if (!frame?.binding || !frame.attempt || frame.binding.plugin !== 'chatgpt-oauth') throw new ControlError('binding_options_unavailable');\n return declaration.invoke(payload, {...host, binding: frame.binding, attempt: {...frame.attempt, signal: AbortSignal.any([frame.attempt.signal, context.signal])}});\n }])) as any);\n }\n\n private assertAlive(signal?: AbortSignal): void {\n if (this.disposed || this.host.signal.aborted) throw new ControlError('disposed');\n if (signal?.aborted) throw new ControlError('request_cancelled');\n }\n\n async start(): Promise<void> {\n this.assertAlive();\n await this.accounts.read();\n this.assertAlive();\n this.autoReset.start();\n }\n\n private async refresh(id: string, signal: AbortSignal): Promise<StoredAccount> {\n for (let attempt = 0; attempt < 120; attempt++) {\n this.assertAlive(signal);\n const current = await this.accounts.get(id);\n this.assertAlive(signal);\n if (current.status !== 'active') throw new ControlError(current.status);\n if (!isRefreshable(current, this.now())) return current;\n if (!current.refreshToken) throw new ControlError('reauth_required');\n const lock = await this.accounts.acquireRefresh(id, this.workerOwner, this.now() + REFRESH_LOCK_MS);\n this.assertAlive(signal);\n if (!lock.acquired) {\n await abortable(new Promise<void>((resolve) => setTimeout(resolve, 25)), signal, this.host.signal);\n continue;\n }\n const generation = lock.account.generation;\n try {\n const token = await refreshCodexToken(lock.account.refreshToken as string, { fetchImpl: this.deps.fetchImpl, signal });\n this.assertAlive(signal);\n const updated = await this.accounts.replaceCredentials(id, token, { owner: this.workerOwner, generation });\n this.assertAlive(signal);\n return updated;\n } catch (error) {\n if (this.disposed || this.host.signal.aborted) throw new ControlError('disposed');\n const oauthCode = (error as { kind?: string }).kind;\n if (oauthCode === 'refresh_token_reused') {\n const fenced = await this.accounts.failRefreshReauth(id, this.workerOwner, generation).catch(() => false);\n if (!fenced) {\n const latest = await this.accounts.get(id).catch(() => undefined);\n if (latest?.status === 'revoked') throw new ControlError('revoked');\n if (latest?.status === 'disabled') throw new ControlError('disabled');\n }\n throw new ControlError('reauth_required');\n }\n if (error instanceof AccountControlError) {\n await this.accounts.releaseRefresh(id, this.workerOwner, generation);\n throw safeError(error);\n }\n const released = await this.accounts.releaseRefresh(id, this.workerOwner, generation);\n if (!released) {\n const latest = await this.accounts.get(id).catch(() => undefined);\n if (latest?.status === 'revoked') throw new ControlError('revoked');\n if (latest?.status === 'disabled') throw new ControlError('disabled');\n if (latest?.generation !== generation) throw new ControlError('stale_refresh');\n }\n if (error instanceof ControlError) throw error;\n throw new ControlError('refresh_failed');\n }\n }\n throw new ControlError('refresh_in_progress');\n }\n\n private async credential(id: string, signal: AbortSignal): Promise<CredentialLease> {\n this.assertAlive(signal);\n const account = await this.accounts.get(id);\n this.assertAlive(signal);\n if (account.status !== 'active') throw new ControlError(account.status);\n if (!isRefreshable(account, this.now())) { this.assertAlive(signal); return lease(account); }\n let shared = this.inFlight.get(id);\n if (!shared) {\n const controller = new AbortController();\n const onHostAbort = () => controller.abort('disposed');\n this.host.signal.addEventListener('abort', onHostAbort, { once: true });\n this.refreshControllers.set(id, controller);\n shared = this.refresh(id, controller.signal).finally(() => {\n this.host.signal.removeEventListener('abort', onHostAbort);\n this.refreshControllers.delete(id);\n this.inFlight.delete(id);\n });\n this.inFlight.set(id, shared);\n }\n const updated = await abortable(shared, signal, this.host.signal);\n this.assertAlive(signal);\n return lease(updated);\n }\n\n private async commitLogin(token: CodexTokenSet, info: LoginCommitInfo, canCommit: () => boolean): Promise<AccountListItem> {\n this.assertAlive();\n if (!canCommit()) throw new ControlError('session_error');\n const account = info.accountRef === undefined\n ? await this.accounts.create(token.identity?.email ?? 'ChatGPT', token, () => canCommit())\n : await this.accounts.relogin(info.accountRef, token, info.fence as LoginFence, () => canCommit());\n if (!canCommit()) throw new ControlError('session_error');\n this.usage.invalidateAccount(account.id);\n return accountListItem(account);\n }\n\n private async loginFence(accountRef: string | undefined): Promise<LoginFence | undefined> {\n return accountRef === undefined ? undefined : await this.accounts.reserveRelogin(accountRef);\n }\n\n private readJson(context: ControlApiHandlerContext): Promise<Record<string, unknown>> {\n return readRequestJson(context.request, context.requestSignal, context.signal, this.apiLifetime.signal);\n }\n\n private async startDevice(accountRef: string | undefined): Promise<unknown> {\n const started = await this.sessions.startDevice(accountRef, () => this.loginFence(accountRef));\n void this.sessions.completeDevice(started.sessionId, (token, info, guard) => this.commitLogin(token, info, guard)).catch(() => undefined);\n return started;\n }\n\n private accountRefQuery(request: Request): string {\n const url = new URL(request.url);\n const entries = [...url.searchParams.entries()];\n if (entries.length !== 1 || entries[0]?.[0] !== 'accountRef') throw new ControlError('invalid_input');\n return requiredText(entries[0][1], 128);\n }\n\n private buildApi(): readonly ControlApiDeclaration[] {\n const invoke = (handler: (context: ControlApiHandlerContext) => Promise<Response> | Response) => async (context: ControlApiHandlerContext) => {\n try { this.assertAlive(context.requestSignal); return await handler(context); } catch (error) { return errorResponse(error); }\n };\n return [\n { path: '/accounts', methods: ['GET'], handler: 'listAccounts', invoke: invoke(async () => jsonResponse({ accounts: await this.accounts.list() })) },\n { path: '/accounts/usage', methods: ['GET'], handler: 'getAccountUsage', invoke: invoke(async (context) => jsonResponse(await this.usage.get(this.accountRefQuery(context.request), context.requestSignal))) },\n { path: '/accounts/usage/reset', methods: ['POST'], handler: 'resetAccountUsage', invoke: invoke(async (context) => {\n const body = await this.readJson(context);\n exactKeys(body, ['accountRef', 'redeemRequestId', 'creditId']);\n const accountRef = requiredText(body.accountRef, 128);\n const redeemRequestId = requiredText(body.redeemRequestId, 128);\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(redeemRequestId)) throw new ControlError('invalid_input');\n const creditId = requiredText(body.creditId, 512);\n if (/[\\0\\r\\n]/.test(creditId)) throw new ControlError('invalid_input');\n const pending = accountListItem(await this.accounts.get(accountRef)).pendingAutoReset;\n if (pending) {\n if (pending.redeemRequestId !== redeemRequestId || pending.creditId !== creditId) throw new ControlError('reset_in_progress');\n this.usage.restorePendingReset(accountRef, redeemRequestId, creditId);\n }\n const result = await this.usage.consume(accountRef, redeemRequestId, creditId, context.requestSignal, {\n beforeConsume: selected => this.accounts.recordResetAttempt(accountRef, redeemRequestId, selected, this.now()),\n });\n if (result.outcome !== 'reset_outcome_unknown') await this.accounts.finishAutoReset(accountRef, redeemRequestId);\n return jsonResponse(result);\n }) },\n { path: '/accounts/auto-reset', methods: ['POST'], handler: 'setAutoResetCredits', invoke: invoke(async context => {\n const body = await this.readJson(context);\n exactKeys(body, ['accountRef', 'enabled']);\n if (typeof body.enabled !== 'boolean') throw new ControlError('invalid_input');\n return jsonResponse({ account: accountListItem(await this.accounts.setAutoResetCredits(requiredText(body.accountRef, 128), body.enabled)) });\n }) },\n { path: '/accounts/draft', methods: ['POST'], handler: 'createDraft', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const account = await this.accounts.get(requiredText(body.accountRef, 128));\n if (!accountListItem(account).available) throw new ControlError(account.status === 'active' ? 'reauth_required' : account.status);\n const draft: UpstreamDraft = { target: CHATGPT_TARGET, bindingOptions: { accountRef: account.id } };\n return jsonResponse(draft);\n }) },\n { path: '/login/device', methods: ['POST'], handler: 'startDeviceLogin', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n return jsonResponse(await this.startDevice(optionalText(body.accountRef, 128)));\n }) },\n { path: '/login/pkce', methods: ['POST'], handler: 'startPkceLogin', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const accountRef = optionalText(body.accountRef, 128);\n const started = this.sessions.startPkce(accountRef);\n try { if (accountRef !== undefined) this.sessions.setFence(started.sessionId, await this.loginFence(accountRef) as LoginFence); }\n catch (error) { this.sessions.cancel(started.sessionId); throw error; }\n return jsonResponse(started);\n }) },\n { path: '/login/status', methods: ['GET'], handler: 'getLoginStatus', invoke: invoke(async (context) => {\n const url = new URL(context.request.url);\n const values = url.searchParams.getAll('sessionId');\n if (values.length !== 1) throw new ControlError('invalid_input');\n return jsonResponse(this.sessions.status(requiredText(values[0], 128)));\n }) },\n { path: '/login/callback', methods: ['POST'], handler: 'completePkceLogin', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['sessionId', 'callbackUrl']);\n const sessionId = requiredText(body.sessionId, 128);\n const status = this.sessions.status(sessionId);\n if (status.state !== 'pending') return jsonResponse(status);\n const result = await this.sessions.completePkce(sessionId, requiredText(body.callbackUrl, 4096), (token, info, guard) => this.commitLogin(token, info, guard));\n return jsonResponse({ account: result.result });\n }) },\n { path: '/login/device/complete', methods: ['POST'], handler: 'completeDeviceLogin', invoke: invoke(async (context) => {\n const body = await this.readJson(context);\n exactKeys(body, ['sessionId']);\n const status = this.sessions.status(requiredText(body.sessionId, 128));\n if (status.state !== 'pending') return jsonResponse(status);\n const result = await this.sessions.completeDevice(requiredText(body.sessionId, 128), (token, info, guard) => this.commitLogin(token, info, guard));\n return jsonResponse({ account: result.result });\n }) },\n { path: '/login/cancel', methods: ['POST'], handler: 'cancelLogin', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['sessionId']);\n return jsonResponse({ cancelled: this.sessions.cancel(requiredText(body.sessionId, 128)) });\n }) },\n { path: '/accounts/disable', methods: ['POST'], handler: 'disableAccount', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const accountRef = requiredText(body.accountRef, 128);\n const account = await this.accounts.setStatus(accountRef, 'disabled');\n this.usage.invalidateAccount(accountRef);\n return jsonResponse({ account: accountListItem(account) });\n }) },\n { path: '/accounts/enable', methods: ['POST'], handler: 'enableAccount', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const accountRef = requiredText(body.accountRef, 128);\n const account = await this.accounts.enable(accountRef);\n this.usage.invalidateAccount(accountRef);\n return jsonResponse({ account: accountListItem(account) });\n }) },\n { path: '/accounts/rename', methods: ['POST'], handler: 'updateAccount', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef', 'label']);\n return jsonResponse({ account: accountListItem(await this.accounts.rename(requiredText(body.accountRef, 128), requiredText(body.label))) });\n }) },\n { path: '/accounts/delete', methods: ['POST'], handler: 'deleteAccount', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const accountRef = requiredText(body.accountRef, 128);\n const account = await this.accounts.setStatus(accountRef, 'revoked');\n this.usage.invalidateAccount(accountRef);\n return jsonResponse({ account: accountListItem(account) });\n }) },\n ];\n }\n\n private buildRpc(): readonly { name: string; handler: string; invoke: (payload: unknown, context: ControlRpcContext) => unknown | Promise<unknown> }[] {\n return [\n { name: 'getCredential', handler: 'getCredential', invoke: async (_payload, context) => {\n try { this.assertAlive(context.attempt.signal); return await this.credential(accountRefFromBinding(context), context.attempt.signal); } catch (error) { throw safeError(error); }\n } },\n { name: 'rejectAccess', handler: 'rejectAccess', invoke: async (payload, context) => {\n try {\n this.assertAlive(context.attempt.signal);\n const body = record(payload); exactKeys(body, ['version']);\n return { rejected: await this.accounts.rejectAccess(accountRefFromBinding(context), requiredVersion(body.version)) };\n } catch (error) { throw safeError(error); }\n } },\n ];\n }\n\n async dispose(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n this.apiLifetime.abort('disposed');\n this.host.signal.removeEventListener('abort', this.abortListener);\n for (const controller of this.refreshControllers.values()) controller.abort('disposed');\n this.sessions.dispose();\n this.autoReset.dispose();\n this.usage.dispose();\n this.inFlight.clear();\n }\n}\n\nexport function createControl(context: ControlHostContext, dependencies: ControlDependencies = {}): PluginControl { return new ChatgptControl(context, dependencies); }\n\nexport const api = Object.freeze([\n { path: '/accounts', methods: ['GET'], handler: 'listAccounts' },\n { path: '/accounts/usage', methods: ['GET'], handler: 'getAccountUsage' },\n { path: '/accounts/usage/reset', methods: ['POST'], handler: 'resetAccountUsage' },\n { path: '/accounts/auto-reset', methods: ['POST'], handler: 'setAutoResetCredits' },\n { path: '/accounts/draft', methods: ['POST'], handler: 'createDraft' },\n { path: '/login/device', methods: ['POST'], handler: 'startDeviceLogin' },\n { path: '/login/pkce', methods: ['POST'], handler: 'startPkceLogin' },\n { path: '/login/status', methods: ['GET'], handler: 'getLoginStatus' },\n { path: '/login/callback', methods: ['POST'], handler: 'completePkceLogin' },\n { path: '/login/device/complete', methods: ['POST'], handler: 'completeDeviceLogin' },\n { path: '/login/cancel', methods: ['POST'], handler: 'cancelLogin' },\n { path: '/accounts/disable', methods: ['POST'], handler: 'disableAccount' },\n { path: '/accounts/enable', methods: ['POST'], handler: 'enableAccount' },\n { path: '/accounts/rename', methods: ['POST'], handler: 'updateAccount' },\n { path: '/accounts/delete', methods: ['POST'], handler: 'deleteAccount' },\n] as const);\nexport const rpc = Object.freeze([{ name: 'getCredential', handler: 'getCredential' }, { name: 'rejectAccess', handler: 'rejectAccess' }] as const);\nexport const controlApi = api;\nexport const controlRpc = rpc;\nexport default { createControl } satisfies ControlPlugin;\n",
|
|
14
|
-
"import { createHash, randomBytes } from 'node:crypto';\n\nexport const CODEX_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann';\nexport const CODEX_AUTH_URL = 'https://auth.openai.com/oauth/authorize';\nexport const CODEX_TOKEN_URL = 'https://auth.openai.com/oauth/token';\nexport const CODEX_DEVICE_USER_CODE_URL = 'https://auth.openai.com/api/accounts/deviceauth/usercode';\nexport const CODEX_DEVICE_TOKEN_URL = 'https://auth.openai.com/api/accounts/deviceauth/token';\nexport const CODEX_DEVICE_EXCHANGE_REDIRECT_URI = 'https://auth.openai.com/deviceauth/callback';\nexport const CODEX_REDIRECT_URI = 'http://localhost:1455/auth/callback';\nexport const CODEX_DEVICE_URL = 'https://auth.openai.com/codex/device';\nexport const CODEX_DEVICE_TIMEOUT_MS = 15 * 60 * 1000;\nexport const CODEX_CALLBACK_TTL_MS = 5 * 60 * 1000;\n\nexport type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport type OAuthErrorKind =\n | 'cancelled'\n | 'timeout'\n | 'network'\n | 'http'\n | 'invalid_response'\n | 'invalid_callback'\n | 'refresh_token_reused'\n | 'body_limit';\n\nexport class CodexOAuthError extends Error {\n readonly kind: OAuthErrorKind;\n readonly status?: number;\n readonly upstreamCode?: string;\n readonly retryable: boolean;\n\n constructor(kind: OAuthErrorKind, message: string, options: { status?: number; upstreamCode?: string; retryable?: boolean } = {}) {\n super(message);\n this.name = 'CodexOAuthError';\n this.kind = kind;\n this.status = options.status;\n this.upstreamCode = options.upstreamCode;\n this.retryable = options.retryable ?? (kind === 'network' || kind === 'timeout');\n }\n}\n\nexport interface DeviceCode {\n deviceAuthId: string;\n userCode: string;\n intervalMs: number;\n}\n\nexport interface DeviceTokenResponse {\n authorizationCode: string;\n codeVerifier: string;\n codeChallenge?: string;\n}\n\nexport interface OAuthRequestOptions {\n fetchImpl?: FetchLike;\n signal?: AbortSignal;\n timeoutMs?: number;\n maxBodyBytes?: number;\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_BODY_BYTES = 256 * 1024;\n\nfunction fetchOf(fetchImpl?: FetchLike): FetchLike {\n return fetchImpl ?? fetch;\n}\n\nfunction safeMessage(kind: OAuthErrorKind, status?: number): string {\n if (kind === 'cancelled') return 'Codex OAuth operation was cancelled';\n if (kind === 'timeout') return 'Codex OAuth operation timed out';\n if (kind === 'network') return 'Codex OAuth network request failed';\n if (kind === 'body_limit') return 'Codex OAuth response exceeded the body limit';\n if (kind === 'refresh_token_reused') return 'Codex refresh token was already used and cannot be retried';\n if (kind === 'invalid_callback') return 'Codex OAuth callback is invalid';\n if (kind === 'invalid_response') return 'Codex OAuth returned an invalid response';\n return `Codex OAuth request failed${status === undefined ? '' : ` (HTTP ${status})`}`;\n}\n\nfunction abortError(signal?: AbortSignal): CodexOAuthError {\n return new CodexOAuthError(signal?.reason === 'timeout' ? 'timeout' : 'cancelled', safeMessage(signal?.reason === 'timeout' ? 'timeout' : 'cancelled'));\n}\n\nfunction safeRequestError(error: unknown, signal?: AbortSignal): CodexOAuthError {\n if (error instanceof CodexOAuthError) return error;\n if (signal?.aborted) return abortError(signal);\n return new CodexOAuthError('network', safeMessage('network'), { retryable: true });\n}\n\ntype ReadChunkResult = Awaited<ReturnType<ReadableStreamDefaultReader<Uint8Array>['read']>>;\n\nfunction readChunk(reader: ReadableStreamDefaultReader<Uint8Array>, signal?: AbortSignal): Promise<ReadChunkResult> {\n if (!signal) return reader.read();\n if (signal.aborted) return Promise.reject(abortError(signal));\n return new Promise((resolve, reject) => {\n let settled = false;\n const cleanup = () => signal.removeEventListener('abort', onAbort);\n const onAbort = () => {\n if (settled) return;\n settled = true;\n cleanup();\n void reader.cancel().catch(() => undefined);\n reject(abortError(signal));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n reader.read().then(\n (value) => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(value);\n },\n (error) => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(error);\n }\n );\n });\n}\n\nfunction awaitWithSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) return promise;\n if (signal.aborted) return Promise.reject(abortError(signal));\n return new Promise((resolve, reject) => {\n let settled = false;\n const cleanup = () => signal.removeEventListener('abort', onAbort);\n const onAbort = () => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(abortError(signal));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n (value) => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(value);\n },\n (error) => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(error);\n }\n );\n });\n}\n\nfunction combinedSignal(signal: AbortSignal | undefined, timeoutMs: number): { signal: AbortSignal; dispose: () => void } {\n const controller = new AbortController();\n const onAbort = () => controller.abort(signal?.reason ?? new DOMException('Aborted', 'AbortError'));\n if (signal?.aborted) onAbort();\n else signal?.addEventListener('abort', onAbort, { once: true });\n const timer = setTimeout(() => controller.abort('timeout'), timeoutMs);\n return {\n signal: controller.signal,\n dispose: () => {\n clearTimeout(timer);\n signal?.removeEventListener('abort', onAbort);\n }\n };\n}\n\nasync function readBounded(response: Response, maxBodyBytes: number, signal?: AbortSignal): Promise<string> {\n try {\n if (!response.body) {\n const text = await awaitWithSignal(response.text(), signal);\n if (new TextEncoder().encode(text).byteLength > maxBodyBytes) {\n throw new CodexOAuthError('body_limit', safeMessage('body_limit'), { retryable: false });\n }\n return text;\n }\n const reader = response.body.getReader();\n try {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for (;;) {\n const next = await readChunk(reader, signal);\n if (next.done) break;\n total += next.value.byteLength;\n if (total > maxBodyBytes) {\n void reader.cancel().catch(() => undefined);\n throw new CodexOAuthError('body_limit', safeMessage('body_limit'), { retryable: false });\n }\n chunks.push(next.value);\n }\n const bytes = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return new TextDecoder().decode(bytes);\n } finally {\n reader.releaseLock();\n }\n } catch (error) {\n throw safeRequestError(error, signal);\n }\n}\n\nfunction jsonRecord(text: string): Record<string, unknown> {\n try {\n const value: unknown = JSON.parse(text);\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) return value as Record<string, unknown>;\n } catch {\n // Deliberately hide malformed upstream body contents.\n }\n throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n}\n\nfunction safeUpstreamCode(text: string): string | undefined {\n const safeCodes = new Set(['refresh_token_reused', 'invalid_grant', 'authorization_pending', 'slow_down', 'access_denied', 'expired_token', 'invalid_request']);\n const find = (value: unknown, depth: number): string | undefined => {\n if (depth > 2 || value === null || typeof value !== 'object') return undefined;\n if (Array.isArray(value)) {\n for (const item of value) {\n const found = find(item, depth + 1);\n if (found) return found;\n }\n return undefined;\n }\n for (const [key, item] of Object.entries(value)) {\n if (['error', 'error_code', 'code'].includes(key) && typeof item === 'string' && safeCodes.has(item.toLowerCase())) return item.toLowerCase();\n const found = find(item, depth + 1);\n if (found) return found;\n }\n return undefined;\n };\n try {\n const value: unknown = JSON.parse(text);\n return find(value, 0);\n } catch {\n // Do not expose or inspect arbitrary response text.\n }\n return undefined;\n}\n\nfunction responseError(status: number, body: string, refresh = false): CodexOAuthError {\n const code = safeUpstreamCode(body);\n if (refresh && code?.toLowerCase() === 'refresh_token_reused') {\n return new CodexOAuthError('refresh_token_reused', safeMessage('refresh_token_reused'), {\n status,\n upstreamCode: 'refresh_token_reused',\n retryable: false\n });\n }\n return new CodexOAuthError('http', safeMessage('http', status), {\n status,\n upstreamCode: code,\n retryable: status >= 500 || status === 408 || status === 429\n });\n}\n\nasync function requestJson(url: string, init: RequestInit, options: OAuthRequestOptions, refresh = false): Promise<Record<string, unknown>> {\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const combined = combinedSignal(options.signal, timeoutMs);\n try {\n if (combined.signal.aborted) throw abortError(combined.signal);\n let response: Response;\n try {\n response = await fetchOf(options.fetchImpl)(url, { ...init, redirect: 'error', signal: combined.signal });\n } catch (error) {\n throw safeRequestError(error, combined.signal);\n }\n const body = await readBounded(response, options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES, combined.signal);\n if (!response.ok) throw responseError(response.status, body, refresh);\n return jsonRecord(body);\n } catch (error) {\n throw safeRequestError(error, combined.signal);\n } finally {\n combined.dispose();\n }\n}\n\nfunction stringField(record: Record<string, unknown>, ...names: string[]): string | undefined {\n for (const name of names) {\n if (typeof record[name] === 'string' && record[name].trim()) return record[name].trim();\n }\n return undefined;\n}\n\nfunction positiveNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value) && value > 0) return value;\n if (typeof value === 'string' && /^\\d+(?:\\.\\d+)?$/.test(value.trim())) {\n const parsed = Number(value);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n }\n return undefined;\n}\n\nexport async function requestDeviceCode(options: OAuthRequestOptions = {}): Promise<DeviceCode> {\n const body = await requestJson(CODEX_DEVICE_USER_CODE_URL, {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/json' },\n body: JSON.stringify({ client_id: CODEX_CLIENT_ID })\n }, options);\n const deviceAuthId = stringField(body, 'device_auth_id');\n const userCode = stringField(body, 'user_code', 'usercode');\n if (!deviceAuthId || !userCode) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n const seconds = positiveNumber(body.interval) ?? 5;\n return { deviceAuthId, userCode, intervalMs: Math.max(250, Math.round(seconds * 1000)) };\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) return reject(abortError(signal));\n let settled = false;\n const cleanup = () => signal?.removeEventListener('abort', onAbort);\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve();\n }, ms);\n const onAbort = () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n cleanup();\n reject(abortError(signal));\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nexport async function pollDeviceToken(\n device: Pick<DeviceCode, 'deviceAuthId' | 'userCode' | 'intervalMs'>,\n options: OAuthRequestOptions & { maxDurationMs?: number } = {}\n): Promise<DeviceTokenResponse> {\n if (!device.deviceAuthId.trim() || !device.userCode.trim()) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n const maxDurationMs = Math.min(options.maxDurationMs ?? CODEX_DEVICE_TIMEOUT_MS, CODEX_DEVICE_TIMEOUT_MS);\n const deadline = Date.now() + Math.max(1, maxDurationMs);\n const intervalMs = Math.max(250, device.intervalMs || 5000);\n for (;;) {\n if (Date.now() >= deadline) throw new CodexOAuthError('timeout', 'Codex device authentication timed out after 15 minutes', { retryable: false });\n const remaining = deadline - Date.now();\n const body = JSON.stringify({ device_auth_id: device.deviceAuthId, user_code: device.userCode });\n let response: Response;\n const combined = combinedSignal(options.signal, Math.min(options.timeoutMs ?? DEFAULT_TIMEOUT_MS, remaining));\n try {\n try {\n response = await fetchOf(options.fetchImpl)(CODEX_DEVICE_TOKEN_URL, {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/json' },\n body,\n redirect: 'error',\n signal: combined.signal\n });\n } catch (error) {\n throw safeRequestError(error, combined.signal);\n }\n const text = await readBounded(response, options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES, combined.signal);\n if (response.status === 403 || response.status === 404) {\n // OpenAI uses both statuses for a still-pending device authorization. Any\n // other non-2xx status is a terminal protocol error, not a polling state.\n if (Date.now() >= deadline) throw new CodexOAuthError('timeout', 'Codex device authentication timed out after 15 minutes', { retryable: false });\n await sleep(Math.min(intervalMs, deadline - Date.now()), options.signal);\n continue;\n }\n if (!response.ok) throw responseError(response.status, text);\n const parsed = jsonRecord(text);\n const authorizationCode = stringField(parsed, 'authorization_code');\n const codeVerifier = stringField(parsed, 'code_verifier');\n if (!authorizationCode || !codeVerifier) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n return { authorizationCode, codeVerifier, codeChallenge: stringField(parsed, 'code_challenge') };\n } catch (error) {\n throw safeRequestError(error, combined.signal);\n } finally {\n combined.dispose();\n }\n }\n}\n\nexport interface PKCE {\n state: string;\n codeVerifier: string;\n codeChallenge: string;\n}\n\nexport function base64Url(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString('base64url');\n}\n\nexport function createPKCE(random?: (size: number) => Uint8Array): PKCE {\n const bytes = random ?? ((size) => randomBytes(size));\n const codeVerifier = base64Url(bytes(32));\n const state = base64Url(bytes(32));\n const codeChallenge = base64Url(new Uint8Array(createHash('sha256').update(codeVerifier).digest()));\n return { state, codeVerifier, codeChallenge };\n}\n\nexport function buildCodexAuthorizationUrl(pkce: Pick<PKCE, 'state' | 'codeChallenge'>): string {\n const url = new URL(CODEX_AUTH_URL);\n url.search = new URLSearchParams({\n client_id: CODEX_CLIENT_ID,\n response_type: 'code',\n redirect_uri: CODEX_REDIRECT_URI,\n scope: 'openid email profile offline_access',\n state: pkce.state,\n code_challenge: pkce.codeChallenge,\n code_challenge_method: 'S256',\n prompt: 'login',\n id_token_add_organizations: 'true',\n codex_cli_simplified_flow: 'true'\n }).toString();\n return url.toString();\n}\n\nexport interface CallbackParseOptions {\n expectedState: string;\n issuedAt?: number;\n now?: number;\n ttlMs?: number;\n expectedOrigin?: string;\n expectedPath?: string;\n}\n\nexport interface OAuthCallback {\n code?: string;\n state: string;\n error?: string;\n errorDescription?: { present: true };\n}\n\nconst SAFE_CALLBACK_ERRORS = new Set([\n 'access_denied',\n 'invalid_request',\n 'unauthorized_client',\n 'unsupported_response_type',\n 'invalid_scope',\n 'server_error',\n 'temporarily_unavailable'\n]);\n\nexport function parseCodexCallbackUrl(raw: string, options: CallbackParseOptions): OAuthCallback {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const expectedUrl = new URL(CODEX_REDIRECT_URI);\n if (\n (options.expectedOrigin !== undefined && options.expectedOrigin !== expectedUrl.origin) ||\n (options.expectedPath !== undefined && options.expectedPath !== expectedUrl.pathname) ||\n url.origin !== expectedUrl.origin ||\n url.pathname !== expectedUrl.pathname ||\n url.username ||\n url.password ||\n url.hash\n ) {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const duplicate = ['state', 'code', 'error', 'error_description'].some((name) => url.searchParams.getAll(name).length > 1);\n if (duplicate || url.searchParams.has('userinfo')) {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const state = url.searchParams.get('state') ?? '';\n if (!state || state !== options.expectedState) throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n const now = options.now ?? Date.now();\n const ttl = options.ttlMs ?? CODEX_CALLBACK_TTL_MS;\n if (!Number.isFinite(now) || !Number.isFinite(ttl) || ttl <= 0 || (options.issuedAt !== undefined && (!Number.isFinite(options.issuedAt) || options.issuedAt < 0 || now < options.issuedAt || now - options.issuedAt > ttl))) {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const hasCode = url.searchParams.has('code');\n const hasError = url.searchParams.has('error');\n if (hasCode && hasError) throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n const code = url.searchParams.get('code')?.trim() || undefined;\n const rawError = url.searchParams.get('error')?.trim() || undefined;\n if ((hasCode && !code) || (hasError && !rawError)) {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const error = rawError ? (SAFE_CALLBACK_ERRORS.has(rawError) ? rawError : 'unknown_error') : undefined;\n const hasErrorDescription = rawError !== undefined && url.searchParams.has('error_description');\n if (rawError === undefined && url.searchParams.has('error_description')) {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const result: OAuthCallback = {\n state,\n code,\n error,\n errorDescription: hasErrorDescription ? { present: true } : undefined\n };\n if (!result.code && !result.error) throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n return result;\n}\n\nexport interface CodexTokenSet {\n accessToken: string;\n refreshToken: string;\n idToken?: string;\n tokenType?: string;\n expiresIn?: number;\n expiresAt?: number;\n identity?: CodexIdentity;\n identityStatus: 'missing' | 'parsed' | 'invalid';\n}\n\nfunction tokenSet(record: Record<string, unknown>, previousRefreshToken?: string): CodexTokenSet {\n const accessToken = stringField(record, 'access_token');\n const refreshToken = stringField(record, 'refresh_token') ?? previousRefreshToken;\n if (!accessToken || !refreshToken) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n const expiresIn = positiveNumber(record.expires_in);\n const idToken = stringField(record, 'id_token');\n let identity: CodexIdentity | undefined;\n let identityStatus: CodexTokenSet['identityStatus'] = 'missing';\n if (idToken) {\n try {\n identity = extractCodexIdentity(idToken);\n identityStatus = 'parsed';\n } catch {\n // Identity is optional metadata. Never discard newly rotated credentials.\n identityStatus = 'invalid';\n }\n }\n return {\n accessToken,\n refreshToken,\n idToken,\n tokenType: stringField(record, 'token_type'),\n expiresIn,\n expiresAt: expiresIn === undefined ? undefined : Date.now() + expiresIn * 1000,\n identity,\n identityStatus\n };\n}\n\nexport async function exchangeCodexCode(\n code: string,\n codeVerifier: string,\n options: OAuthRequestOptions & { redirectUri?: string } = {}\n): Promise<CodexTokenSet> {\n if (!code.trim() || !codeVerifier.trim()) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n const redirectUri = options.redirectUri ?? CODEX_REDIRECT_URI;\n const body = new URLSearchParams({ grant_type: 'authorization_code', client_id: CODEX_CLIENT_ID, code, redirect_uri: redirectUri, code_verifier: codeVerifier });\n const response = await requestJson(CODEX_TOKEN_URL, {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/x-www-form-urlencoded' },\n body: body.toString()\n }, options);\n return tokenSet(response);\n}\n\nexport async function exchangeCodexDeviceAuthorization(\n deviceToken: Pick<DeviceTokenResponse, 'authorizationCode' | 'codeVerifier'>,\n options: OAuthRequestOptions = {}\n): Promise<CodexTokenSet> {\n return exchangeCodexCode(deviceToken.authorizationCode, deviceToken.codeVerifier, {\n ...options,\n redirectUri: CODEX_DEVICE_EXCHANGE_REDIRECT_URI\n });\n}\n\nexport async function refreshCodexToken(\n refreshToken: string,\n options: OAuthRequestOptions = {}\n): Promise<CodexTokenSet> {\n if (!refreshToken.trim()) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n const body = new URLSearchParams({ client_id: CODEX_CLIENT_ID, grant_type: 'refresh_token', refresh_token: refreshToken, scope: 'openid profile email' });\n const response = await requestJson(CODEX_TOKEN_URL, {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/x-www-form-urlencoded' },\n body: body.toString()\n }, { ...options }, true);\n return tokenSet(response, refreshToken);\n}\n\nexport interface CodexIdentity {\n email?: string;\n accountId?: string;\n planType?: string;\n userId?: string;\n}\n\nexport interface CodexJwtPayload {\n email?: unknown;\n exp?: unknown;\n sub?: unknown;\n [key: string]: unknown;\n}\n\nexport function parseJwtPayload(idToken: string): CodexJwtPayload {\n const parts = idToken.split('.');\n if (parts.length !== 3 || !parts[1]) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n try {\n const payload: unknown = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));\n if (typeof payload !== 'object' || payload === null || Array.isArray(payload)) throw new Error('not an object');\n return payload as CodexJwtPayload;\n } catch {\n throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n }\n}\n\nexport function extractCodexIdentity(idToken: string): CodexIdentity {\n const payload = parseJwtPayload(idToken);\n const auth = payload['https://api.openai.com/auth'];\n const authRecord = typeof auth === 'object' && auth !== null && !Array.isArray(auth) ? auth as Record<string, unknown> : {};\n return {\n email: typeof payload.email === 'string' ? payload.email : undefined,\n accountId: typeof authRecord.chatgpt_account_id === 'string' ? authRecord.chatgpt_account_id : undefined,\n planType: typeof authRecord.chatgpt_plan_type === 'string' ? authRecord.chatgpt_plan_type : undefined,\n userId: typeof authRecord.user_id === 'string' ? authRecord.user_id : undefined\n };\n}\n",
|
|
15
|
-
"import { randomUUID } from 'node:crypto';\nimport type { SecretStore } from '../../../packages/core/src/plugin-control/contracts';\nimport type { CodexIdentity, CodexTokenSet } from './oauth';\nimport type { ResetCredit } from './usage';\n\nexport interface AutoResetAttempt {\n creditId: string;\n redeemRequestId: string;\n expiresAt?: number;\n completed: boolean;\n}\n\nexport const ACCOUNT_STORE_KEY = 'accounts.v1';\nexport const ACCOUNT_SCHEMA_VERSION = 1;\n\nexport type AccountStatus = 'active' | 'disabled' | 'reauth_required' | 'revoked';\n\nexport interface StoredAccount {\n id: string;\n label: string;\n status: AccountStatus;\n generation: number;\n createdAt: number;\n updatedAt: number;\n expiresAt?: number;\n accessToken?: string;\n refreshToken?: string;\n idToken?: string;\n identity?: CodexIdentity;\n refreshLock?: { owner: string; until: number };\n loginFence: number;\n credentialValid: boolean;\n autoResetCredits?: boolean;\n autoResetAttempts?: AutoResetAttempt[];\n}\n\ninterface AccountAggregate {\n schema: typeof ACCOUNT_SCHEMA_VERSION;\n accounts: StoredAccount[];\n}\n\nexport interface AccountListItem {\n readonly id: string;\n readonly label: string;\n readonly status: AccountStatus;\n readonly available: boolean;\n readonly reason?: string;\n readonly expiresAt?: number;\n readonly identity?: Readonly<CodexIdentity>;\n readonly autoResetCredits: boolean;\n readonly pendingAutoReset?: Readonly<AutoResetAttempt>;\n}\n\nexport class AccountControlError extends Error {\n readonly name = 'AccountControlError';\n constructor(readonly code: AccountErrorCode) {\n super(code);\n }\n}\n\nexport type AccountErrorCode =\n | 'invalid_input'\n | 'not_found'\n | 'version_conflict'\n | 'identity_mismatch'\n | 'disabled'\n | 'revoked'\n | 'reauth_required'\n | 'stale_refresh'\n | 'invalid_identity'\n | 'disposed';\n\nconst MAX_ACCOUNTS = 128;\nconst MAX_TEXT = 512;\nconst MAX_TOKEN = 32_768;\nconst MAX_AUTO_RESET_ATTEMPTS = 256;\n\nfunction text(value: unknown, max = MAX_TEXT): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > max || value.trim() !== value) {\n throw new AccountControlError('invalid_input');\n }\n return value;\n}\n\nfunction optionalText(value: unknown, max = MAX_TEXT): string | undefined {\n if (value === undefined) return undefined;\n return text(value, max);\n}\n\nfunction identity(value: unknown): CodexIdentity | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new AccountControlError('invalid_input');\n const input = value as Record<string, unknown>;\n const keys = new Set(['email', 'accountId', 'planType', 'userId']);\n if (Object.keys(input).some((key) => !keys.has(key))) throw new AccountControlError('invalid_input');\n const result: CodexIdentity = {};\n for (const key of keys) {\n const value = input[key];\n if (value !== undefined) (result as Record<string, string>)[key] = text(value);\n }\n return Object.keys(result).length === 0 ? undefined : result;\n}\n\nfunction copyIdentity(value: CodexIdentity | undefined): CodexIdentity | undefined {\n return value === undefined ? undefined : { ...value };\n}\n\nfunction copyAccount(value: StoredAccount): StoredAccount {\n return { ...value, identity: copyIdentity(value.identity), refreshLock: value.refreshLock && { ...value.refreshLock },\n autoResetAttempts: value.autoResetAttempts?.map(item => ({ ...item })) };\n}\n\nfunction validAutoResetAttempts(value: unknown): boolean {\n return value === undefined || (Array.isArray(value) && value.length <= MAX_AUTO_RESET_ATTEMPTS && value.every(item =>\n item && typeof item.creditId === 'string' && item.creditId.length > 0 && item.creditId.length <= MAX_TEXT &&\n !/[\\u0000-\\u001f\\u007f]/.test(item.creditId) &&\n typeof item.redeemRequestId === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(item.redeemRequestId) &&\n (item.expiresAt === undefined || (Number.isFinite(item.expiresAt) && item.expiresAt >= 0)) && typeof item.completed === 'boolean'));\n}\n\nfunction validStoredAccount(value: unknown): value is StoredAccount {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const account = value as Record<string, unknown>;\n return typeof account.id === 'string' && account.id.length > 0 && account.id.length <= 128 &&\n typeof account.label === 'string' && account.label.length > 0 && account.label.length <= MAX_TEXT &&\n ['active', 'disabled', 'reauth_required', 'revoked'].includes(account.status as string) &&\n Number.isSafeInteger(account.generation) && (account.generation as number) > 0 &&\n (account.loginFence === undefined || (Number.isSafeInteger(account.loginFence) && (account.loginFence as number) > 0)) &&\n (account.credentialValid === undefined || typeof account.credentialValid === 'boolean') &&\n (account.autoResetCredits === undefined || typeof account.autoResetCredits === 'boolean') &&\n validAutoResetAttempts(account.autoResetAttempts) &&\n Number.isFinite(account.createdAt) && Number.isFinite(account.updatedAt);\n}\n\nfunction decode(value: string | undefined): AccountAggregate {\n if (value === undefined) return { schema: ACCOUNT_SCHEMA_VERSION, accounts: [] };\n try {\n const parsed: unknown = JSON.parse(value);\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) throw new Error();\n const aggregate = parsed as Record<string, unknown>;\n if (aggregate.schema !== ACCOUNT_SCHEMA_VERSION || !Array.isArray(aggregate.accounts) || aggregate.accounts.length > MAX_ACCOUNTS ||\n !aggregate.accounts.every(validStoredAccount)) throw new Error();\n return { schema: ACCOUNT_SCHEMA_VERSION, accounts: aggregate.accounts.map((item) => ({\n ...copyAccount(item), loginFence: item.loginFence ?? 1,\n credentialValid: item.credentialValid ?? item.status !== 'reauth_required',\n })) };\n } catch {\n throw new AccountControlError('invalid_input');\n }\n}\n\nfunction encode(value: AccountAggregate): string {\n return JSON.stringify(value);\n}\n\nfunction statusReason(account: StoredAccount): string | undefined {\n if (account.status === 'disabled') return 'disabled';\n if (account.status === 'reauth_required') return 'reauth_required';\n if (account.status === 'revoked') return 'revoked';\n return undefined;\n}\n\nexport function accountListItem(account: StoredAccount): AccountListItem {\n const pending = account.autoResetAttempts?.find(item => !item.completed);\n return {\n id: account.id,\n label: account.label,\n status: account.status,\n available: account.status === 'active' && account.credentialValid && Boolean(account.accessToken && account.refreshToken && Number.isFinite(account.expiresAt)),\n reason: statusReason(account),\n expiresAt: account.expiresAt,\n identity: copyIdentity(account.identity),\n autoResetCredits: account.autoResetCredits === true,\n pendingAutoReset: pending && { ...pending },\n };\n}\n\nexport class AccountStore {\n constructor(private readonly secretStore: SecretStore, private readonly canWrite: () => boolean = () => true) {}\n\n async read(): Promise<{ aggregate: AccountAggregate; version: number | null }> {\n const value = await this.secretStore.get(ACCOUNT_STORE_KEY);\n return { aggregate: decode(value?.value), version: value?.version ?? null };\n }\n\n private async mutate<T>(mutator: (aggregate: AccountAggregate) => T, canCommit: () => boolean = () => true): Promise<T> {\n for (let attempt = 0; attempt < 12; attempt++) {\n if (!this.canWrite() || !canCommit()) throw new AccountControlError('disposed');\n const current = await this.read();\n const next: AccountAggregate = { schema: ACCOUNT_SCHEMA_VERSION, accounts: current.aggregate.accounts.map(copyAccount) };\n const result = mutator(next);\n if (!this.canWrite() || !canCommit()) throw new AccountControlError('disposed');\n try {\n await this.secretStore.compareAndSet(ACCOUNT_STORE_KEY, current.version, encode(next));\n return result;\n } catch (error) {\n if ((error as { code?: string }).code !== 'version_conflict') throw error;\n }\n }\n throw new AccountControlError('version_conflict');\n }\n\n async list(): Promise<AccountListItem[]> {\n return (await this.read()).aggregate.accounts.map(accountListItem);\n }\n\n async get(id: string): Promise<StoredAccount> {\n const account = (await this.read()).aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n return copyAccount(account);\n }\n\n async create(label: string, token: CodexTokenSet, canCommit: () => boolean = () => true): Promise<StoredAccount> {\n text(label);\n if (token.identityStatus !== 'parsed' || !token.identity?.accountId) throw new AccountControlError('invalid_identity');\n return this.mutate((aggregate) => {\n if (aggregate.accounts.length >= MAX_ACCOUNTS) throw new AccountControlError('invalid_input');\n const now = Date.now();\n const account: StoredAccount = {\n id: randomUUID(), label, status: token.expiresAt === undefined ? 'reauth_required' : 'active', generation: 1, loginFence: 1,\n credentialValid: token.expiresAt !== undefined, createdAt: now, updatedAt: now,\n accessToken: text(token.accessToken, MAX_TOKEN), refreshToken: text(token.refreshToken, MAX_TOKEN),\n idToken: optionalText(token.idToken, MAX_TOKEN), expiresAt: token.expiresAt,\n identity: copyIdentity(token.identity),\n };\n aggregate.accounts.push(account);\n return copyAccount(account);\n }, canCommit);\n }\n\n async replaceCredentials(\n id: string,\n token: CodexTokenSet,\n options: { owner?: string; generation?: number } = {},\n ): Promise<StoredAccount> {\n if (options.owner === undefined || options.generation === undefined) throw new AccountControlError('stale_refresh');\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.generation !== options.generation) throw new AccountControlError('stale_refresh');\n if (account.refreshLock?.owner !== options.owner) throw new AccountControlError('stale_refresh');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n if (account.status === 'disabled') throw new AccountControlError('disabled');\n if (token.identity?.accountId && account.identity?.accountId && token.identity.accountId !== account.identity.accountId) {\n throw new AccountControlError('identity_mismatch');\n }\n const now = Date.now();\n account.accessToken = text(token.accessToken, MAX_TOKEN);\n account.refreshToken = text(token.refreshToken, MAX_TOKEN);\n if (token.idToken !== undefined && token.identityStatus !== 'invalid') account.idToken = text(token.idToken, MAX_TOKEN);\n if (token.expiresAt !== undefined) account.expiresAt = token.expiresAt;\n else delete account.expiresAt;\n // A refresh response may omit the account id. Never let that optional\n // metadata silently replace an already-bound identity.\n if (token.identityStatus !== 'invalid' && token.identity !== undefined &&\n (account.identity?.accountId === undefined || token.identity.accountId !== undefined)) {\n account.identity = copyIdentity(token.identity);\n }\n account.credentialValid = token.expiresAt !== undefined;\n account.status = token.expiresAt === undefined ? 'reauth_required' : 'active';\n account.generation += 1;\n account.updatedAt = now;\n delete account.refreshLock;\n return copyAccount(account);\n });\n }\n\n async reserveRelogin(id: string): Promise<{ generation: number; loginFence: number }> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n account.loginFence += 1;\n account.updatedAt = Date.now();\n return { generation: account.generation, loginFence: account.loginFence };\n });\n }\n\n async relogin(\n id: string,\n token: CodexTokenSet,\n expected: { generation: number; loginFence: number },\n canCommit: () => boolean = () => true,\n ): Promise<StoredAccount> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n if (account.generation !== expected.generation || account.loginFence !== expected.loginFence) {\n throw new AccountControlError('stale_refresh');\n }\n if (token.identityStatus !== 'parsed' || !token.identity?.accountId) throw new AccountControlError('invalid_identity');\n if (account.identity?.accountId && token.identity.accountId !== account.identity.accountId) {\n throw new AccountControlError('identity_mismatch');\n }\n account.accessToken = text(token.accessToken, MAX_TOKEN);\n account.refreshToken = text(token.refreshToken, MAX_TOKEN);\n if (token.idToken !== undefined) account.idToken = text(token.idToken, MAX_TOKEN);\n if (token.expiresAt === undefined) {\n delete account.expiresAt;\n account.credentialValid = false;\n account.status = 'reauth_required';\n } else {\n account.expiresAt = token.expiresAt;\n account.credentialValid = true;\n account.status = 'active';\n }\n account.identity = copyIdentity(token.identity);\n account.generation += 1;\n account.updatedAt = Date.now();\n delete account.refreshLock;\n return copyAccount(account);\n }, canCommit);\n }\n\n async setStatus(id: string, status: Exclude<AccountStatus, 'active'>): Promise<StoredAccount> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') {\n if (status === 'revoked') return copyAccount(account);\n throw new AccountControlError('revoked');\n }\n account.status = status;\n account.generation += 1;\n account.updatedAt = Date.now();\n delete account.refreshLock;\n if (status === 'revoked') {\n delete account.accessToken;\n delete account.refreshToken;\n delete account.idToken;\n delete account.expiresAt;\n account.credentialValid = false;\n }\n return copyAccount(account);\n });\n }\n\n async rename(id: string, label: string): Promise<StoredAccount> {\n text(label);\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n account.label = label;\n account.updatedAt = Date.now();\n return copyAccount(account);\n });\n }\n\n async setAutoResetCredits(id: string, enabled: boolean): Promise<StoredAccount> {\n if (typeof enabled !== 'boolean') throw new AccountControlError('invalid_input');\n return this.mutate(aggregate => {\n const account = aggregate.accounts.find(item => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n account.autoResetCredits = enabled;\n account.updatedAt = Date.now();\n return copyAccount(account);\n });\n }\n\n /** Persist before POST: a crash or unknown outcome must never create a new automatic request. */\n async claimAutoReset(id: string, credit: ResetCredit, now: number): Promise<AutoResetAttempt | undefined> {\n return this.mutate(aggregate => {\n const account = aggregate.accounts.find(item => item.id === id);\n if (!account || !accountListItem(account).available || account.autoResetCredits !== true) return undefined;\n const attempts = account.autoResetAttempts ?? [];\n if (attempts.some(item => !item.completed || item.creditId === credit.id)) return undefined;\n account.autoResetAttempts = attempts.filter(item => !item.completed || item.expiresAt === undefined || item.expiresAt > now);\n if (account.autoResetAttempts.length >= MAX_AUTO_RESET_ATTEMPTS || credit.expiresAt === undefined || credit.expiresAt <= now) return undefined;\n const attempt: AutoResetAttempt = { creditId: credit.id, redeemRequestId: randomUUID(), expiresAt: credit.expiresAt, completed: false };\n account.autoResetAttempts.push(attempt);\n account.updatedAt = Date.now();\n return { ...attempt };\n });\n }\n\n /** Manual and automatic requests share the same durable fence against automatic retries. */\n async recordResetAttempt(id: string, redeemRequestId: string, credit: ResetCredit, now: number): Promise<void> {\n await this.mutate(aggregate => {\n const account = aggregate.accounts.find(item => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n const attempts = account.autoResetAttempts ?? [];\n const pending = attempts.find(item => !item.completed);\n if (pending) {\n if (pending.redeemRequestId !== redeemRequestId || pending.creditId !== credit.id) throw new AccountControlError('version_conflict');\n return;\n }\n account.autoResetAttempts = attempts.filter(item => item.creditId !== credit.id && (item.expiresAt === undefined || item.expiresAt > now));\n if (account.autoResetAttempts.length >= MAX_AUTO_RESET_ATTEMPTS) throw new AccountControlError('invalid_input');\n account.autoResetAttempts.push({ creditId: credit.id, redeemRequestId, expiresAt: credit.expiresAt, completed: false });\n account.updatedAt = Date.now();\n });\n }\n\n async finishAutoReset(id: string, redeemRequestId: string, cancel = false): Promise<void> {\n await this.mutate(aggregate => {\n const account = aggregate.accounts.find(item => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (cancel) account.autoResetAttempts = account.autoResetAttempts?.filter(item => item.redeemRequestId !== redeemRequestId);\n else {\n const attempt = account.autoResetAttempts?.find(item => item.redeemRequestId === redeemRequestId);\n if (attempt) attempt.completed = true;\n }\n account.updatedAt = Date.now();\n });\n }\n\n async enable(id: string): Promise<StoredAccount> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n if (account.status !== 'disabled') throw new AccountControlError('reauth_required');\n if (!account.accessToken || !account.credentialValid) throw new AccountControlError('reauth_required');\n account.status = 'active';\n account.generation += 1;\n account.updatedAt = Date.now();\n return copyAccount(account);\n });\n }\n\n async rejectAccess(id: string, generation: number): Promise<boolean> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.generation !== generation || account.status !== 'active') return false;\n account.status = 'reauth_required';\n account.credentialValid = false;\n account.generation += 1;\n account.updatedAt = Date.now();\n delete account.refreshLock;\n return true;\n });\n }\n\n async acquireRefresh(id: string, owner: string, until: number): Promise<{ acquired: boolean; account: StoredAccount }> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status !== 'active') throw new AccountControlError(account.status);\n if (account.refreshLock && account.refreshLock.owner !== owner && account.refreshLock.until > Date.now()) {\n return { acquired: false, account: copyAccount(account) };\n }\n account.refreshLock = { owner, until };\n account.updatedAt = Date.now();\n return { acquired: true, account: copyAccount(account) };\n });\n }\n\n async releaseRefresh(id: string, owner: string, generation: number): Promise<boolean> {\n try {\n return await this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (account?.generation === generation && account.refreshLock?.owner === owner && account.status === 'active') {\n delete account.refreshLock;\n account.updatedAt = Date.now();\n return true;\n }\n return false;\n });\n } catch (error) {\n if ((error as { code?: string }).code !== 'not_found' && (error as { code?: string }).code !== 'disposed') throw error;\n return false;\n }\n }\n\n async failRefreshReauth(id: string, owner: string, generation: number): Promise<boolean> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account || account.status !== 'active' || account.generation !== generation || account.refreshLock?.owner !== owner) return false;\n account.status = 'reauth_required';\n account.generation += 1;\n account.updatedAt = Date.now();\n delete account.refreshLock;\n return true;\n });\n }\n}\n",
|
|
16
|
-
"import { randomUUID } from 'node:crypto';\nimport {\n CODEX_CALLBACK_TTL_MS,\n CODEX_DEVICE_TIMEOUT_MS,\n CODEX_DEVICE_URL,\n type FetchLike,\n type CodexTokenSet,\n buildCodexAuthorizationUrl,\n createPKCE,\n exchangeCodexCode,\n exchangeCodexDeviceAuthorization,\n parseCodexCallbackUrl,\n pollDeviceToken,\n requestDeviceCode,\n type OAuthRequestOptions,\n} from './oauth';\n\nexport type LoginKind = 'device' | 'pkce';\nexport type LoginState = 'pending' | 'polling' | 'exchanging' | 'committing' | 'cancelled' | 'failed' | 'success';\n\nexport interface DeviceLoginStart {\n readonly sessionId: string;\n readonly userCode: string;\n readonly verificationUri: string;\n readonly expiresAt: number;\n}\n\nexport interface PkceLoginStart {\n readonly sessionId: string;\n readonly authorizationUrl: string;\n readonly expiresAt: number;\n}\n\nexport interface LoginStatus {\n readonly sessionId: string;\n readonly kind: LoginKind;\n readonly state: LoginState | 'expired';\n readonly issuedAt: number;\n readonly expiresAt: number;\n readonly accountRef?: string;\n readonly errorCode?: 'login_failed' | 'cancelled' | 'expired';\n readonly account?: { readonly id: string; readonly label: string; readonly status: string; readonly available: boolean; readonly accountId?: string };\n}\n\nexport interface LoginFence {\n readonly generation: number;\n readonly loginFence: number;\n}\n\nexport class LoginSessionError extends Error {\n readonly name = 'LoginSessionError';\n constructor(readonly code: LoginSessionErrorCode) {\n super(code);\n }\n}\n\nexport type LoginSessionErrorCode =\n | 'invalid_input'\n | 'not_found'\n | 'expired'\n | 'cancelled'\n | 'already_consumed'\n | 'busy'\n | 'failed'\n | 'disposed';\n\ninterface LoginSession {\n id: string;\n kind: LoginKind;\n state: LoginState;\n issuedAt: number;\n expiresAt: number;\n accountRef?: string;\n fence?: LoginFence;\n stateValue?: string;\n codeVerifier?: string;\n device?: { deviceAuthId: string; userCode: string; intervalMs: number };\n controller: AbortController;\n unlinkHost: () => void;\n expiryTimer: ReturnType<typeof setTimeout>;\n errorCode?: 'login_failed' | 'cancelled' | 'expired';\n account?: LoginStatus['account'];\n expiredDuringCommit?: boolean;\n}\n\nexport interface LoginSessionDependencies {\n fetchImpl?: FetchLike;\n now?: () => number;\n random?: (size: number) => Uint8Array;\n maxSessions?: number;\n}\n\nexport interface LoginCommitInfo {\n readonly accountRef?: string;\n readonly fence?: LoginFence;\n}\n\nexport type LoginCommit<TResult = unknown> = (\n token: CodexTokenSet,\n info: LoginCommitInfo,\n canCommit: () => boolean,\n) => Promise<TResult>;\n\nfunction safeOptions(deps: LoginSessionDependencies, signal: AbortSignal): OAuthRequestOptions {\n return { fetchImpl: deps.fetchImpl, signal };\n}\n\nexport class LoginSessionManager {\n private readonly sessions = new Map<string, LoginSession>();\n private readonly now: () => number;\n private readonly maxSessions: number;\n private disposed = false;\n private readonly onHostAbort: () => void;\n\n constructor(private readonly hostSignal: AbortSignal, private readonly deps: LoginSessionDependencies = {}) {\n this.now = deps.now ?? Date.now;\n this.maxSessions = Math.min(128, Math.max(1, deps.maxSessions ?? 64));\n this.onHostAbort = () => this.dispose();\n if (hostSignal.aborted) this.dispose();\n else hostSignal.addEventListener('abort', this.onHostAbort, { once: true });\n }\n\n private newSession(kind: LoginKind, accountRef: string | undefined, fence: LoginFence | undefined, ttl: number): LoginSession {\n if (this.disposed || this.hostSignal.aborted) throw new LoginSessionError('disposed');\n this.cleanup();\n if (this.sessions.size >= this.maxSessions) throw new LoginSessionError('busy');\n const controller = new AbortController();\n const onHostAbort = () => controller.abort(this.hostSignal.reason);\n this.hostSignal.addEventListener('abort', onHostAbort, { once: true });\n const issuedAt = this.now();\n const session: LoginSession = {\n id: randomUUID(), kind, state: 'pending', issuedAt, expiresAt: issuedAt + ttl,\n accountRef, fence, controller, unlinkHost: () => this.hostSignal.removeEventListener('abort', onHostAbort),\n expiryTimer: setTimeout(() => this.expire(session.id), Math.max(1, ttl)),\n };\n this.sessions.set(session.id, session);\n return session;\n }\n\n private expire(id: string): void {\n const session = this.sessions.get(id);\n if (!session) return;\n if (session.state === 'success' || session.state === 'failed') { this.remove(id); return; }\n if (session.state === 'cancelled') return;\n if (session.state === 'committing') { session.expiredDuringCommit = true; return; }\n session.state = 'cancelled';\n session.controller.abort('expired');\n }\n\n private cleanup(): void {\n const now = this.now();\n for (const [id, session] of this.sessions) {\n if ((session.state === 'cancelled' || session.state === 'success' || session.state === 'failed') && session.expiresAt <= now) this.remove(id);\n }\n }\n\n private remove(id: string): void {\n const session = this.sessions.get(id);\n if (!session) return;\n clearTimeout(session.expiryTimer);\n session.unlinkHost();\n this.sessions.delete(id);\n }\n\n private get(id: string): LoginSession {\n if (typeof id !== 'string' || id.length < 1 || id.length > 128) throw new LoginSessionError('invalid_input');\n const session = this.sessions.get(id);\n if (!session) throw new LoginSessionError('not_found');\n if (session.expiresAt <= this.now() && session.state !== 'committing') {\n this.expire(id);\n throw new LoginSessionError('expired');\n }\n return session;\n }\n\n async startDevice(accountRef?: string, fenceOrProvider?: LoginFence | (() => Promise<LoginFence | undefined>)): Promise<DeviceLoginStart> {\n if (accountRef !== undefined && (typeof accountRef !== 'string' || accountRef.length < 1 || accountRef.length > 128)) {\n throw new LoginSessionError('invalid_input');\n }\n const session = this.newSession('device', accountRef, typeof fenceOrProvider === 'function' ? undefined : fenceOrProvider, CODEX_DEVICE_TIMEOUT_MS);\n try {\n if (typeof fenceOrProvider === 'function') session.fence = await fenceOrProvider();\n const device = await requestDeviceCode(safeOptions(this.deps, session.controller.signal));\n if (!this.canCommit(session)) throw new LoginSessionError('cancelled');\n session.device = device;\n return { sessionId: session.id, userCode: device.userCode, verificationUri: CODEX_DEVICE_URL, expiresAt: session.expiresAt };\n } catch (error) {\n session.state = 'cancelled';\n session.controller.abort();\n this.remove(session.id);\n throw error;\n }\n }\n\n startPkce(accountRef?: string, fence?: LoginFence): PkceLoginStart {\n if (accountRef !== undefined && (typeof accountRef !== 'string' || accountRef.length < 1 || accountRef.length > 128)) {\n throw new LoginSessionError('invalid_input');\n }\n const pkce = createPKCE(this.deps.random);\n const session = this.newSession('pkce', accountRef, fence, CODEX_CALLBACK_TTL_MS);\n session.stateValue = pkce.state;\n session.codeVerifier = pkce.codeVerifier;\n return { sessionId: session.id, authorizationUrl: buildCodexAuthorizationUrl(pkce), expiresAt: session.expiresAt };\n }\n\n setFence(id: string, fence: LoginFence): void {\n const session = this.get(id);\n if (session.state !== 'pending') throw new LoginSessionError('busy');\n session.fence = fence;\n }\n\n status(id: string): LoginStatus {\n const session = this.sessions.get(id);\n if (!session) throw new LoginSessionError('not_found');\n return {\n sessionId: session.id, kind: session.kind,\n state: session.state === 'committing' ? 'committing' : session.expiresAt <= this.now() ? 'expired' : session.state,\n issuedAt: session.issuedAt, expiresAt: session.expiresAt, accountRef: session.accountRef,\n errorCode: session.state === 'committing' ? undefined : session.expiresAt <= this.now() ? 'expired' : session.errorCode,\n account: session.account,\n };\n }\n\n private canCommit(session: LoginSession): boolean {\n return !this.disposed && !this.hostSignal.aborted && !session.controller.signal.aborted &&\n session.state !== 'cancelled' && session.state !== 'failed' && session.state !== 'committing' && session.expiresAt > this.now();\n }\n\n private claim(id: string, kind: LoginKind): LoginSession {\n const session = this.get(id);\n if (session.kind !== kind) throw new LoginSessionError('invalid_input');\n if (session.state === 'cancelled') throw new LoginSessionError(session.expiresAt <= this.now() ? 'expired' : 'cancelled');\n if (session.state === 'success') throw new LoginSessionError('already_consumed');\n if (session.state === 'failed') throw new LoginSessionError('failed');\n if (session.state === 'polling' || session.state === 'exchanging' || session.state === 'committing') throw new LoginSessionError('busy');\n session.state = kind === 'device' ? 'polling' : 'exchanging';\n return session;\n }\n\n private async finish<TResult>(session: LoginSession, token: CodexTokenSet, commit?: LoginCommit<TResult>): Promise<{ token: CodexTokenSet; accountRef?: string; result?: TResult }> {\n if (!this.canCommit(session)) throw new LoginSessionError('cancelled');\n // This is the linearization point. Cancellation/TTL/dispose cannot claim\n // that an in-flight CAS was rolled back after this synchronous transition.\n session.state = 'committing';\n let result: TResult | undefined;\n try {\n result = commit === undefined ? undefined : await commit(token, { accountRef: session.accountRef, fence: session.fence }, () => session.state === 'committing');\n } catch (error) {\n session.state = 'failed';\n session.errorCode = 'login_failed';\n throw error;\n }\n session.account = this.accountSummary(result);\n session.state = 'success';\n if (session.expiredDuringCommit || session.expiresAt <= this.now()) this.remove(session.id);\n return { token, accountRef: session.accountRef, result };\n }\n\n private accountSummary(value: unknown): LoginStatus['account'] {\n if (typeof value !== 'object' || value === null) return undefined;\n const item = value as Record<string, unknown>;\n if (typeof item.id !== 'string' || typeof item.label !== 'string' || typeof item.status !== 'string' || typeof item.available !== 'boolean') return undefined;\n const identity = typeof item.identity === 'object' && item.identity !== null ? item.identity as Record<string, unknown> : undefined;\n return { id: item.id, label: item.label, status: item.status, available: item.available, accountId: typeof identity?.accountId === 'string' ? identity.accountId : undefined };\n }\n\n async completeDevice<TResult = unknown>(id: string, commit?: LoginCommit<TResult>): Promise<{ token: CodexTokenSet; accountRef?: string; result?: TResult }> {\n const session = this.claim(id, 'device');\n try {\n const device = session.device;\n if (!device) throw new LoginSessionError('busy');\n const token = await pollDeviceToken(device, { ...safeOptions(this.deps, session.controller.signal), maxDurationMs: Math.max(1, session.expiresAt - this.now()) });\n if (!this.canCommit(session)) throw new LoginSessionError('cancelled');\n session.state = 'exchanging';\n const exchanged = await exchangeCodexDeviceAuthorization(token, safeOptions(this.deps, session.controller.signal));\n return await this.finish(session, exchanged, commit);\n } catch (error) {\n if (session.controller.signal.aborted && session.state === 'cancelled') throw new LoginSessionError('cancelled');\n if (session.state === 'polling' || session.state === 'exchanging') {\n session.state = session.controller.signal.aborted ? 'cancelled' : 'failed';\n session.errorCode = session.controller.signal.aborted ? 'cancelled' : 'login_failed';\n if (session.state === 'failed') throw new LoginSessionError('failed');\n }\n throw error;\n }\n }\n\n async completePkce<TResult = unknown>(id: string, callbackUrl: string, commit?: LoginCommit<TResult>): Promise<{ token: CodexTokenSet; accountRef?: string; result?: TResult }> {\n const session = this.claim(id, 'pkce');\n try {\n if (typeof callbackUrl !== 'string' || callbackUrl.length > 4096) throw new LoginSessionError('invalid_input');\n const callback = parseCodexCallbackUrl(callbackUrl, { expectedState: session.stateValue as string, issuedAt: session.issuedAt, now: this.now(), ttlMs: CODEX_CALLBACK_TTL_MS });\n if (!callback.code) throw new LoginSessionError('cancelled');\n const token = await exchangeCodexCode(callback.code, session.codeVerifier as string, safeOptions(this.deps, session.controller.signal));\n return await this.finish(session, token, commit);\n } catch (error) {\n if (session.controller.signal.aborted && session.state === 'cancelled') throw new LoginSessionError('cancelled');\n if (session.state === 'exchanging') {\n session.state = session.controller.signal.aborted ? 'cancelled' : 'failed';\n session.errorCode = session.controller.signal.aborted ? 'cancelled' : 'login_failed';\n if (session.state === 'failed') throw new LoginSessionError('failed');\n }\n throw error;\n }\n }\n\n cancel(id: string): boolean {\n const session = this.get(id);\n if (session.state === 'success' || session.state === 'cancelled' || session.state === 'failed' || session.state === 'committing') return false;\n session.state = 'cancelled';\n session.controller.abort('cancelled');\n return true;\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n this.hostSignal.removeEventListener('abort', this.onHostAbort);\n for (const session of this.sessions.values()) {\n if (session.state !== 'committing') session.state = 'cancelled';\n if (session.state !== 'committing') session.controller.abort('disposed');\n session.unlinkHost();\n clearTimeout(session.expiryTimer);\n }\n for (const [id, session] of this.sessions) if (session.state !== 'committing') this.remove(id);\n }\n}\n",
|
|
13
|
+
"import { businessRpc } from './rpc';\nimport { randomUUID } from 'node:crypto';\nimport type {\n ControlApiDeclaration,\n ControlApiHandlerContext,\n ControlHostContext,\n ControlPlugin,\n ControlRpcContext,\n CredentialLease,\n PluginControl,\n UpstreamDraft,\n} from '../../../packages/core/src/plugin-control/contracts';\nimport type { FetchLike, CodexTokenSet } from './oauth';\nimport { refreshCodexToken } from './oauth';\nimport { getSiwcHostId, refreshSiwcToken, validSiwcMetadata } from './siwc';\nimport { AccountControlError, AccountStore, accountListItem, type AccountListItem, type StoredAccount } from './accounts';\nimport { LoginSessionError, LoginSessionManager, type LoginCommitInfo, type LoginFence, type LoginSessionDependencies } from './sessions';\nimport { UsageError, UsageService } from './usage';\nimport { AutoResetScheduler, type AutoResetTimer } from './auto-reset';\n\nexport const CHATGPT_TARGET = 'https://chatgpt.com';\nexport const SIWC_TARGET = 'https://api.openai.com';\nexport const CONTROL_HOST_CONTRACT_GAP = 'ControlRpcContext.binding.bindingOptions.accountRef is required and host-resolved; RPC payload is never used as a fallback.';\n\nexport interface ControlDependencies extends LoginSessionDependencies { now?: () => number; timeoutMs?: number; autoResetTimer?: AutoResetTimer }\n\nexport class ControlError extends Error {\n readonly name = 'ControlError';\n constructor(readonly code: ControlErrorCode) { super(code); }\n}\n\nexport type ControlErrorCode =\n | 'invalid_input' | 'body_limit' | 'request_cancelled' | 'not_found' | 'disabled' | 'revoked'\n | 'reauth_required' | 'identity_missing' | 'identity_mismatch' | 'invalid_identity'\n | 'refresh_failed' | 'refresh_in_progress' | 'stale_refresh' | 'binding_options_unavailable' | 'disposed'\n | 'expired' | 'cancelled' | 'busy' | 'login_failed' | 'session_error'\n | 'source_mismatch' | 'unsupported_operation'\n | 'reset_in_progress' | 'credits_unavailable' | 'credit_unavailable' | 'upstream_unavailable';\n\nconst REFRESH_SAFETY_WINDOW_MS = 60_000;\nconst REFRESH_LOCK_MS = 90_000;\nconst MAX_BODY_BYTES = 64 * 1024;\n\nfunction safeError(error: unknown): ControlError {\n if (error instanceof ControlError) return error;\n if (error instanceof AccountControlError) {\n const map: Record<string, ControlErrorCode> = {\n invalid_input: 'invalid_input',\n not_found: 'not_found', disabled: 'disabled', revoked: 'revoked', reauth_required: 'reauth_required',\n identity_mismatch: 'identity_mismatch', invalid_identity: 'invalid_identity', disposed: 'disposed',\n stale_refresh: 'stale_refresh', unsupported_operation: 'unsupported_operation',\n };\n return new ControlError(map[error.code] ?? 'refresh_failed');\n }\n if (error instanceof LoginSessionError) {\n const known: Record<string, ControlErrorCode> = { invalid_input: 'invalid_input', not_found: 'not_found', expired: 'expired', cancelled: 'cancelled', already_consumed: 'busy', busy: 'busy', failed: 'login_failed', disposed: 'disposed' };\n return new ControlError(known[error.code] ?? 'session_error');\n }\n if (error instanceof UsageError) {\n const known: Record<string, ControlErrorCode> = {\n reauth_required: 'reauth_required', disposed: 'disposed', cancelled: 'request_cancelled',\n reset_in_progress: 'reset_in_progress', credits_unavailable: 'credits_unavailable', credit_unavailable: 'credit_unavailable',\n stale_generation: 'upstream_unavailable', upstream_unavailable: 'upstream_unavailable',\n };\n return new ControlError(known[error.code] ?? 'refresh_failed');\n }\n const kind = (error as { kind?: string }).kind;\n if (kind === 'refresh_token_reused') return new ControlError('reauth_required');\n if (typeof kind === 'string') return new ControlError('login_failed');\n return new ControlError('refresh_failed');\n}\n\nfunction jsonResponse(value: unknown, status = 200): Response {\n return new Response(JSON.stringify(value), { status, headers: { 'content-type': 'application/json; charset=utf-8' } });\n}\n\nfunction errorResponse(error: unknown): Response {\n const safe = safeError(error);\n const status = safe.code === 'not_found' ? 404 : safe.code === 'invalid_input' || safe.code === 'request_cancelled' ? 400 : safe.code === 'body_limit' ? 413 : safe.code === 'binding_options_unavailable' ? 501 : 409;\n return jsonResponse({ error: safe.code }, status);\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new ControlError('invalid_input');\n return value as Record<string, unknown>;\n}\n\nfunction exactKeys(value: Record<string, unknown>, keys: readonly string[]): void {\n const allowed = new Set(keys);\n if (Object.keys(value).some((key) => !allowed.has(key))) throw new ControlError('invalid_input');\n}\n\nfunction requiredText(value: unknown, max = 512): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > max || value.trim() !== value) throw new ControlError('invalid_input');\n return value;\n}\n\nfunction optionalText(value: unknown, max = 512): string | undefined { return value === undefined ? undefined : requiredText(value, max); }\nfunction requiredVersion(value: unknown): number {\n if (!Number.isSafeInteger(value) || (value as number) < 1) throw new ControlError('invalid_input');\n return value as number;\n}\n\nfunction abortable<T>(promise: Promise<T>, signal: AbortSignal, hostSignal?: AbortSignal, lifetimeSignal?: AbortSignal): Promise<T> {\n if (hostSignal?.aborted || lifetimeSignal?.aborted) return Promise.reject(new ControlError('disposed'));\n if (signal.aborted) return Promise.reject(new ControlError('request_cancelled'));\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n const cleanup = () => { signal.removeEventListener('abort', onRequestAbort); hostSignal?.removeEventListener('abort', onHostAbort); lifetimeSignal?.removeEventListener('abort', onLifetimeAbort); };\n const onRequestAbort = () => { if (!settled) { settled = true; cleanup(); reject(new ControlError('request_cancelled')); } };\n const onHostAbort = () => { if (!settled) { settled = true; cleanup(); reject(new ControlError('disposed')); } };\n const onLifetimeAbort = () => { if (!settled) { settled = true; cleanup(); reject(new ControlError('disposed')); } };\n signal.addEventListener('abort', onRequestAbort, { once: true });\n hostSignal?.addEventListener('abort', onHostAbort, { once: true });\n lifetimeSignal?.addEventListener('abort', onLifetimeAbort, { once: true });\n promise.then((value) => { if (!settled) { settled = true; cleanup(); resolve(value); } }, (error) => { if (!settled) { settled = true; cleanup(); reject(error); } });\n });\n}\n\nasync function readRequestJson(request: Request, requestSignal: AbortSignal, hostSignal: AbortSignal, lifetimeSignal = hostSignal): Promise<Record<string, unknown>> {\n if (hostSignal.aborted || lifetimeSignal.aborted) throw new ControlError('disposed');\n if (requestSignal.aborted) throw new ControlError('request_cancelled');\n if (!request.body) return {};\n const reader = request.body.getReader();\n const decoder = new TextDecoder();\n let text = '';\n let total = 0;\n try {\n for (;;) {\n const next = await abortable(reader.read(), requestSignal, hostSignal, lifetimeSignal);\n if (next.done) break;\n total += next.value.byteLength;\n if (total > MAX_BODY_BYTES) {\n void reader.cancel().catch(() => undefined);\n throw new ControlError('body_limit');\n }\n text += decoder.decode(next.value, { stream: true });\n }\n text += decoder.decode();\n } catch (error) {\n void reader.cancel().catch(() => undefined);\n if (error instanceof ControlError) throw error;\n throw new ControlError('invalid_input');\n } finally { reader.releaseLock(); }\n if (!text) return {};\n try { return record(JSON.parse(text)); } catch { throw new ControlError('invalid_input'); }\n}\n\nfunction accountRefFromBinding(context: ControlRpcContext): string {\n const value = context.binding.bindingOptions?.accountRef;\n if (typeof value !== 'string' || value.length < 1 || value.length > 128 || value.trim() !== value) throw new ControlError('binding_options_unavailable');\n return value;\n}\n\nfunction lease(account: StoredAccount): CredentialLease {\n if (account.status !== 'active') throw new ControlError(account.status);\n if (!account.accessToken) throw new ControlError('reauth_required');\n if (account.siwc) {\n if (!validSiwcMetadata(account.siwc) || !Number.isFinite(account.expiresAt)) throw new ControlError('reauth_required');\n return { version: account.generation, expiresAt: account.expiresAt as number, headers: { Authorization: `Bearer ${account.accessToken}` } };\n }\n if (!account.identity?.accountId) throw new ControlError('identity_missing');\n if (!Number.isFinite(account.expiresAt)) throw new ControlError('reauth_required');\n return { version: account.generation, expiresAt: account.expiresAt as number, headers: { Authorization: `Bearer ${account.accessToken}`, 'Chatgpt-Account-Id': account.identity.accountId } };\n}\n\nfunction isRefreshable(account: StoredAccount, now: number): boolean {\n return account.expiresAt === undefined || account.expiresAt <= now + REFRESH_SAFETY_WINDOW_MS;\n}\n\nclass ChatgptControl implements PluginControl {\n readonly api: readonly ControlApiDeclaration[];\n readonly rpc: readonly { name: string; handler: string; invoke: (payload: unknown, context: ControlRpcContext) => unknown | Promise<unknown> }[];\n private readonly accounts: AccountStore;\n private readonly sessions: LoginSessionManager;\n private readonly now: () => number;\n private readonly workerOwner = `chatgpt-control-${randomUUID()}`;\n private readonly inFlight = new Map<string, Promise<StoredAccount>>();\n private readonly refreshControllers = new Map<string, AbortController>();\n private readonly apiLifetime = new AbortController();\n private readonly usage: UsageService;\n private readonly autoReset: AutoResetScheduler;\n private disposed = false;\n private readonly abortListener: () => void;\n\n constructor(private readonly host: ControlHostContext, private readonly deps: ControlDependencies = {}) {\n this.now = deps.now ?? Date.now;\n this.accounts = new AccountStore(host.secretStore, () => !this.disposed && !host.signal.aborted);\n this.sessions = new LoginSessionManager(host.signal, deps);\n this.usage = new UsageService({\n fetchImpl: deps.fetchImpl,\n now: this.now,\n timeoutMs: deps.timeoutMs,\n hostSignal: this.apiLifetime.signal,\n credential: (id, signal) => this.credential(id, signal, 'codex'),\n rejectAccess: (id, version) => this.accounts.rejectAccess(id, version),\n });\n this.autoReset = new AutoResetScheduler(this.accounts, this.usage, this.apiLifetime.signal, this.now, deps.autoResetTimer);\n this.abortListener = () => { void this.dispose(); };\n if (host.signal.aborted) this.disposed = true;\n else host.signal.addEventListener('abort', this.abortListener, { once: true });\n this.api = this.buildApi();\n this.rpc = this.buildRpc();\n host.services?.rpc?.publish(businessRpc, Object.fromEntries(this.rpc.map(declaration => [declaration.name, (payload: unknown, context: any) => {\n const frame = host.resolveRpcCallee?.(context.callee) as {binding?: ControlRpcContext['binding']; attempt?: ControlRpcContext['attempt']} | null;\n if (!frame?.binding || !frame.attempt || frame.binding.plugin !== 'chatgpt-oauth') throw new ControlError('binding_options_unavailable');\n return declaration.invoke(payload, {...host, binding: frame.binding, attempt: {...frame.attempt, signal: AbortSignal.any([frame.attempt.signal, context.signal])}});\n }])) as any);\n }\n\n private assertAlive(signal?: AbortSignal): void {\n if (this.disposed || this.host.signal.aborted) throw new ControlError('disposed');\n if (signal?.aborted) throw new ControlError('request_cancelled');\n }\n\n async start(): Promise<void> {\n this.assertAlive();\n await this.accounts.purgeRevoked();\n this.assertAlive();\n this.autoReset.start();\n }\n\n private async refresh(id: string, signal: AbortSignal): Promise<StoredAccount> {\n for (let attempt = 0; attempt < 120; attempt++) {\n this.assertAlive(signal);\n const current = await this.accounts.get(id);\n this.assertAlive(signal);\n if (current.status !== 'active') throw new ControlError(current.status);\n if (!isRefreshable(current, this.now())) return current;\n if (!current.refreshToken) throw new ControlError('reauth_required');\n const lock = await this.accounts.acquireRefresh(id, this.workerOwner, this.now() + REFRESH_LOCK_MS);\n this.assertAlive(signal);\n if (!lock.acquired) {\n await abortable(new Promise<void>((resolve) => setTimeout(resolve, 25)), signal, this.host.signal);\n continue;\n }\n const generation = lock.account.generation;\n try {\n const refreshOptions = { fetchImpl: this.deps.fetchImpl, signal, timeoutMs: this.deps.timeoutMs };\n const token = lock.account.siwc\n ? await refreshSiwcToken({ accessToken: lock.account.accessToken as string, refreshToken: lock.account.refreshToken as string, idToken: lock.account.idToken, identity: lock.account.identity, identityStatus: 'parsed', siwc: lock.account.siwc }, refreshOptions)\n : await refreshCodexToken(lock.account.refreshToken as string, refreshOptions);\n this.assertAlive(signal);\n const updated = await this.accounts.replaceCredentials(id, token, { owner: this.workerOwner, generation });\n this.assertAlive(signal);\n return updated;\n } catch (error) {\n if (this.disposed || this.host.signal.aborted) throw new ControlError('disposed');\n const oauthCode = (error as { kind?: string }).kind;\n if (oauthCode === 'refresh_token_reused' || (lock.account.siwc && ((error as { upstreamCode?: string }).upstreamCode === 'invalid_grant' || oauthCode === 'invalid_response' || (error instanceof AccountControlError && ['identity_mismatch', 'invalid_identity'].includes(error.code))))) {\n const fenced = await this.accounts.failRefreshReauth(id, this.workerOwner, generation).catch(() => false);\n if (!fenced) {\n const latest = await this.accounts.get(id).catch(() => undefined);\n if (!latest) throw new ControlError('not_found');\n if (latest?.status === 'revoked') throw new ControlError('revoked');\n if (latest?.status === 'disabled') throw new ControlError('disabled');\n }\n throw new ControlError('reauth_required');\n }\n if (error instanceof AccountControlError) {\n await this.accounts.releaseRefresh(id, this.workerOwner, generation);\n throw safeError(error);\n }\n const released = await this.accounts.releaseRefresh(id, this.workerOwner, generation);\n if (!released) {\n const latest = await this.accounts.get(id).catch(() => undefined);\n if (!latest) throw new ControlError('not_found');\n if (latest?.status === 'revoked') throw new ControlError('revoked');\n if (latest?.status === 'disabled') throw new ControlError('disabled');\n if (latest?.generation !== generation) throw new ControlError('stale_refresh');\n }\n if (error instanceof ControlError) throw error;\n throw new ControlError('refresh_failed');\n }\n }\n throw new ControlError('refresh_in_progress');\n }\n\n private async requireKind(id: string, kind: 'siwc' | 'codex', error: ControlErrorCode = 'source_mismatch'): Promise<StoredAccount> {\n const account = await this.accounts.get(id);\n if (Boolean(account.siwc) !== (kind === 'siwc')) throw new ControlError(error);\n return account;\n }\n\n private async bindingAccount(context: ControlRpcContext): Promise<string> {\n const id = accountRefFromBinding(context);\n const source = context.binding.contributionId;\n if (source === 'chatgpt-siwc') await this.requireKind(id, 'siwc');\n else if (source === 'chatgpt' || source === 'upstream') await this.requireKind(id, 'codex');\n else throw new ControlError('source_mismatch');\n return id;\n }\n\n private async draft(context: ControlApiHandlerContext, kind: 'siwc' | 'codex'): Promise<Response> {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const account = await this.requireKind(requiredText(body.accountRef, 128), kind);\n if (!accountListItem(account).available) throw new ControlError(account.status === 'active' ? 'reauth_required' : account.status);\n const draft: UpstreamDraft = { target: kind === 'siwc' ? SIWC_TARGET : CHATGPT_TARGET, bindingOptions: { accountRef: account.id } };\n return jsonResponse(draft);\n }\n\n private async credential(id: string, signal: AbortSignal, kind?: 'codex'): Promise<CredentialLease> {\n this.assertAlive(signal);\n const account = await this.accounts.get(id);\n this.assertAlive(signal);\n if (kind === 'codex' && account.siwc) throw new ControlError('unsupported_operation');\n if (account.status !== 'active') throw new ControlError(account.status);\n if (!isRefreshable(account, this.now())) { this.assertAlive(signal); return lease(account); }\n let shared = this.inFlight.get(id);\n if (!shared) {\n const controller = new AbortController();\n const onHostAbort = () => controller.abort('disposed');\n this.host.signal.addEventListener('abort', onHostAbort, { once: true });\n this.refreshControllers.set(id, controller);\n shared = this.refresh(id, controller.signal).finally(() => {\n this.host.signal.removeEventListener('abort', onHostAbort);\n this.refreshControllers.delete(id);\n this.inFlight.delete(id);\n });\n this.inFlight.set(id, shared);\n }\n const updated = await abortable(shared, signal, this.host.signal);\n this.assertAlive(signal);\n return lease(updated);\n }\n\n private async commitLogin(token: CodexTokenSet, info: LoginCommitInfo, canCommit: () => boolean): Promise<AccountListItem> {\n this.assertAlive();\n if (!canCommit()) throw new ControlError('session_error');\n const account = info.accountRef === undefined\n ? await this.accounts.create(token.identity?.email ?? 'ChatGPT', token, () => canCommit())\n : await this.accounts.relogin(info.accountRef, token, info.fence as LoginFence, () => canCommit());\n if (!canCommit()) throw new ControlError('session_error');\n this.usage.invalidateAccount(account.id);\n return accountListItem(account);\n }\n\n private async loginFence(accountRef: string | undefined): Promise<LoginFence | undefined> {\n return accountRef === undefined ? undefined : await this.accounts.reserveRelogin(accountRef);\n }\n\n private readJson(context: ControlApiHandlerContext): Promise<Record<string, unknown>> {\n return readRequestJson(context.request, context.requestSignal, context.signal, this.apiLifetime.signal);\n }\n\n private async startDevice(accountRef: string | undefined): Promise<unknown> {\n if (accountRef !== undefined) await this.requireKind(accountRef, 'codex');\n const started = await this.sessions.startDevice(accountRef, () => this.loginFence(accountRef));\n void this.sessions.completeDevice(started.sessionId, (token, info, guard) => this.commitLogin(token, info, guard)).catch(() => undefined);\n return started;\n }\n\n private accountRefQuery(request: Request): string {\n const url = new URL(request.url);\n const entries = [...url.searchParams.entries()];\n if (entries.length !== 1 || entries[0]?.[0] !== 'accountRef') throw new ControlError('invalid_input');\n return requiredText(entries[0][1], 128);\n }\n\n private buildApi(): readonly ControlApiDeclaration[] {\n const invoke = (handler: (context: ControlApiHandlerContext) => Promise<Response> | Response) => async (context: ControlApiHandlerContext) => {\n try { this.assertAlive(context.requestSignal); return await handler(context); } catch (error) { return errorResponse(error); }\n };\n return [\n { path: '/accounts', methods: ['GET'], handler: 'listAccounts', invoke: invoke(async () => jsonResponse({ accounts: await this.accounts.list() })) },\n { path: '/accounts/codex', methods: ['GET'], handler: 'listCodexAccounts', invoke: invoke(async () => jsonResponse({ accounts: (await this.accounts.list()).filter(account => account.authType === 'codex') })) },\n { path: '/accounts/siwc', methods: ['GET'], handler: 'listSiwcAccounts', invoke: invoke(async () => jsonResponse({ accounts: (await this.accounts.list()).filter(account => account.authType === 'siwc') })) },\n { path: '/accounts/usage', methods: ['GET'], handler: 'getAccountUsage', invoke: invoke(async (context) => {\n const id = this.accountRefQuery(context.request);\n return jsonResponse(await this.usage.get(id, context.requestSignal));\n }) },\n { path: '/accounts/usage/reset', methods: ['POST'], handler: 'resetAccountUsage', invoke: invoke(async (context) => {\n const body = await this.readJson(context);\n exactKeys(body, ['accountRef', 'redeemRequestId', 'creditId']);\n const accountRef = requiredText(body.accountRef, 128);\n await this.requireKind(accountRef, 'codex', 'unsupported_operation');\n const redeemRequestId = requiredText(body.redeemRequestId, 128);\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(redeemRequestId)) throw new ControlError('invalid_input');\n const creditId = requiredText(body.creditId, 512);\n if (/[\\0\\r\\n]/.test(creditId)) throw new ControlError('invalid_input');\n const pending = accountListItem(await this.accounts.get(accountRef)).pendingAutoReset;\n if (pending) {\n if (pending.redeemRequestId !== redeemRequestId || pending.creditId !== creditId) throw new ControlError('reset_in_progress');\n this.usage.restorePendingReset(accountRef, redeemRequestId, creditId);\n }\n const result = await this.usage.consume(accountRef, redeemRequestId, creditId, context.requestSignal, {\n beforeConsume: selected => this.accounts.recordResetAttempt(accountRef, redeemRequestId, selected, this.now()),\n });\n if (result.outcome !== 'reset_outcome_unknown') await this.accounts.finishAutoReset(accountRef, redeemRequestId);\n return jsonResponse(result);\n }) },\n { path: '/accounts/auto-reset', methods: ['POST'], handler: 'setAutoResetCredits', invoke: invoke(async context => {\n const body = await this.readJson(context);\n exactKeys(body, ['accountRef', 'enabled']);\n if (typeof body.enabled !== 'boolean') throw new ControlError('invalid_input');\n return jsonResponse({ account: accountListItem(await this.accounts.setAutoResetCredits(requiredText(body.accountRef, 128), body.enabled)) });\n }) },\n { path: '/accounts/draft', methods: ['POST'], handler: 'createDraft', invoke: invoke(context => this.draft(context, 'codex')) },\n { path: '/accounts/siwc/draft', methods: ['POST'], handler: 'createSiwcDraft', invoke: invoke(context => this.draft(context, 'siwc')) },\n { path: '/login/siwc', methods: ['POST'], handler: 'startSiwcLogin', invoke: invoke(async context => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const accountRef = optionalText(body.accountRef, 128);\n const account = accountRef === undefined ? undefined : await this.requireKind(accountRef, 'siwc');\n const hostId = await getSiwcHostId(this.host.secretStore, () => !this.disposed && !this.host.signal.aborted);\n this.assertAlive(context.requestSignal);\n const fence = await this.loginFence(accountRef);\n this.assertAlive(context.requestSignal);\n return jsonResponse(this.sessions.startSiwc(hostId, accountRef, account?.siwc?.clientId, fence));\n }) },\n { path: '/login/device', methods: ['POST'], handler: 'startDeviceLogin', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n return jsonResponse(await this.startDevice(optionalText(body.accountRef, 128)));\n }) },\n { path: '/login/pkce', methods: ['POST'], handler: 'startPkceLogin', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const accountRef = optionalText(body.accountRef, 128);\n if (accountRef !== undefined) await this.requireKind(accountRef, 'codex');\n const started = this.sessions.startPkce(accountRef);\n try { if (accountRef !== undefined) this.sessions.setFence(started.sessionId, await this.loginFence(accountRef) as LoginFence); }\n catch (error) { this.sessions.cancel(started.sessionId); throw error; }\n return jsonResponse(started);\n }) },\n { path: '/login/status', methods: ['GET'], handler: 'getLoginStatus', invoke: invoke(async (context) => {\n const url = new URL(context.request.url);\n const values = url.searchParams.getAll('sessionId');\n if (values.length !== 1) throw new ControlError('invalid_input');\n return jsonResponse(this.sessions.status(requiredText(values[0], 128)));\n }) },\n { path: '/login/callback', methods: ['POST'], handler: 'completePkceLogin', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['sessionId', 'callbackUrl']);\n const sessionId = requiredText(body.sessionId, 128);\n const status = this.sessions.status(sessionId);\n if (status.state !== 'pending') return jsonResponse(status);\n const complete = status.kind === 'siwc' ? this.sessions.completeSiwc.bind(this.sessions) : this.sessions.completePkce.bind(this.sessions);\n const result = await complete(sessionId, requiredText(body.callbackUrl, 4096), (token, info, guard) => this.commitLogin(token, info, guard));\n return jsonResponse({ account: result.result });\n }) },\n { path: '/login/device/complete', methods: ['POST'], handler: 'completeDeviceLogin', invoke: invoke(async (context) => {\n const body = await this.readJson(context);\n exactKeys(body, ['sessionId']);\n const status = this.sessions.status(requiredText(body.sessionId, 128));\n if (status.state !== 'pending') return jsonResponse(status);\n const result = await this.sessions.completeDevice(requiredText(body.sessionId, 128), (token, info, guard) => this.commitLogin(token, info, guard));\n return jsonResponse({ account: result.result });\n }) },\n { path: '/login/cancel', methods: ['POST'], handler: 'cancelLogin', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['sessionId']);\n return jsonResponse({ cancelled: this.sessions.cancel(requiredText(body.sessionId, 128)) });\n }) },\n { path: '/accounts/disable', methods: ['POST'], handler: 'disableAccount', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const accountRef = requiredText(body.accountRef, 128);\n const account = await this.accounts.setStatus(accountRef, 'disabled');\n this.usage.invalidateAccount(accountRef);\n return jsonResponse({ account: accountListItem(account) });\n }) },\n { path: '/accounts/enable', methods: ['POST'], handler: 'enableAccount', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const accountRef = requiredText(body.accountRef, 128);\n const account = await this.accounts.enable(accountRef);\n this.usage.invalidateAccount(accountRef);\n return jsonResponse({ account: accountListItem(account) });\n }) },\n { path: '/accounts/rename', methods: ['POST'], handler: 'updateAccount', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef', 'label']);\n return jsonResponse({ account: accountListItem(await this.accounts.rename(requiredText(body.accountRef, 128), requiredText(body.label))) });\n }) },\n { path: '/accounts/delete', methods: ['POST'], handler: 'deleteAccount', invoke: invoke(async (context) => {\n const body = await this.readJson(context); exactKeys(body, ['accountRef']);\n const accountRef = requiredText(body.accountRef, 128);\n await this.accounts.remove(accountRef);\n this.usage.invalidateAccount(accountRef);\n return jsonResponse({ deleted: true });\n }) },\n ];\n }\n\n private buildRpc(): readonly { name: string; handler: string; invoke: (payload: unknown, context: ControlRpcContext) => unknown | Promise<unknown> }[] {\n return [\n { name: 'getCredential', handler: 'getCredential', invoke: async (_payload, context) => {\n try { this.assertAlive(context.attempt.signal); return await this.credential(await this.bindingAccount(context), context.attempt.signal); } catch (error) { throw safeError(error); }\n } },\n { name: 'rejectAccess', handler: 'rejectAccess', invoke: async (payload, context) => {\n try {\n this.assertAlive(context.attempt.signal);\n const body = record(payload); exactKeys(body, ['version']);\n return { rejected: await this.accounts.rejectAccess(await this.bindingAccount(context), requiredVersion(body.version)) };\n } catch (error) { throw safeError(error); }\n } },\n ];\n }\n\n async dispose(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n this.apiLifetime.abort('disposed');\n this.host.signal.removeEventListener('abort', this.abortListener);\n for (const controller of this.refreshControllers.values()) controller.abort('disposed');\n this.sessions.dispose();\n this.autoReset.dispose();\n this.usage.dispose();\n this.inFlight.clear();\n }\n}\n\nexport function createControl(context: ControlHostContext, dependencies: ControlDependencies = {}): PluginControl { return new ChatgptControl(context, dependencies); }\n\nexport const api = Object.freeze([\n { path: '/accounts', methods: ['GET'], handler: 'listAccounts' },\n { path: '/accounts/codex', methods: ['GET'], handler: 'listCodexAccounts' },\n { path: '/accounts/siwc', methods: ['GET'], handler: 'listSiwcAccounts' },\n { path: '/accounts/usage', methods: ['GET'], handler: 'getAccountUsage' },\n { path: '/accounts/usage/reset', methods: ['POST'], handler: 'resetAccountUsage' },\n { path: '/accounts/auto-reset', methods: ['POST'], handler: 'setAutoResetCredits' },\n { path: '/accounts/draft', methods: ['POST'], handler: 'createDraft' },\n { path: '/accounts/siwc/draft', methods: ['POST'], handler: 'createSiwcDraft' },\n { path: '/login/siwc', methods: ['POST'], handler: 'startSiwcLogin' },\n { path: '/login/device', methods: ['POST'], handler: 'startDeviceLogin' },\n { path: '/login/pkce', methods: ['POST'], handler: 'startPkceLogin' },\n { path: '/login/status', methods: ['GET'], handler: 'getLoginStatus' },\n { path: '/login/callback', methods: ['POST'], handler: 'completePkceLogin' },\n { path: '/login/device/complete', methods: ['POST'], handler: 'completeDeviceLogin' },\n { path: '/login/cancel', methods: ['POST'], handler: 'cancelLogin' },\n { path: '/accounts/disable', methods: ['POST'], handler: 'disableAccount' },\n { path: '/accounts/enable', methods: ['POST'], handler: 'enableAccount' },\n { path: '/accounts/rename', methods: ['POST'], handler: 'updateAccount' },\n { path: '/accounts/delete', methods: ['POST'], handler: 'deleteAccount' },\n] as const);\nexport const rpc = Object.freeze([{ name: 'getCredential', handler: 'getCredential' }, { name: 'rejectAccess', handler: 'rejectAccess' }] as const);\nexport const controlApi = api;\nexport const controlRpc = rpc;\nexport default { createControl } satisfies ControlPlugin;\n",
|
|
14
|
+
"import { createHash, randomBytes } from 'node:crypto';\n\nexport const CODEX_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann';\nexport const CODEX_AUTH_URL = 'https://auth.openai.com/oauth/authorize';\nexport const CODEX_TOKEN_URL = 'https://auth.openai.com/oauth/token';\nexport const CODEX_DEVICE_USER_CODE_URL = 'https://auth.openai.com/api/accounts/deviceauth/usercode';\nexport const CODEX_DEVICE_TOKEN_URL = 'https://auth.openai.com/api/accounts/deviceauth/token';\nexport const CODEX_DEVICE_EXCHANGE_REDIRECT_URI = 'https://auth.openai.com/deviceauth/callback';\nexport const CODEX_REDIRECT_URI = 'http://localhost:1455/auth/callback';\nexport const CODEX_DEVICE_URL = 'https://auth.openai.com/codex/device';\nexport const CODEX_DEVICE_TIMEOUT_MS = 15 * 60 * 1000;\nexport const CODEX_CALLBACK_TTL_MS = 5 * 60 * 1000;\n\nexport type FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport type OAuthErrorKind =\n | 'cancelled'\n | 'timeout'\n | 'network'\n | 'http'\n | 'invalid_response'\n | 'invalid_callback'\n | 'refresh_token_reused'\n | 'body_limit';\n\nexport class CodexOAuthError extends Error {\n readonly kind: OAuthErrorKind;\n readonly status?: number;\n readonly upstreamCode?: string;\n readonly retryable: boolean;\n\n constructor(kind: OAuthErrorKind, message: string, options: { status?: number; upstreamCode?: string; retryable?: boolean } = {}) {\n super(message);\n this.name = 'CodexOAuthError';\n this.kind = kind;\n this.status = options.status;\n this.upstreamCode = options.upstreamCode;\n this.retryable = options.retryable ?? (kind === 'network' || kind === 'timeout');\n }\n}\n\nexport interface DeviceCode {\n deviceAuthId: string;\n userCode: string;\n intervalMs: number;\n}\n\nexport interface DeviceTokenResponse {\n authorizationCode: string;\n codeVerifier: string;\n codeChallenge?: string;\n}\n\nexport interface OAuthRequestOptions {\n fetchImpl?: FetchLike;\n signal?: AbortSignal;\n timeoutMs?: number;\n maxBodyBytes?: number;\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst DEFAULT_MAX_BODY_BYTES = 256 * 1024;\n\nfunction fetchOf(fetchImpl?: FetchLike): FetchLike {\n return fetchImpl ?? fetch;\n}\n\nfunction safeMessage(kind: OAuthErrorKind, status?: number): string {\n if (kind === 'cancelled') return 'Codex OAuth operation was cancelled';\n if (kind === 'timeout') return 'Codex OAuth operation timed out';\n if (kind === 'network') return 'Codex OAuth network request failed';\n if (kind === 'body_limit') return 'Codex OAuth response exceeded the body limit';\n if (kind === 'refresh_token_reused') return 'Codex refresh token was already used and cannot be retried';\n if (kind === 'invalid_callback') return 'Codex OAuth callback is invalid';\n if (kind === 'invalid_response') return 'Codex OAuth returned an invalid response';\n return `Codex OAuth request failed${status === undefined ? '' : ` (HTTP ${status})`}`;\n}\n\nfunction abortError(signal?: AbortSignal): CodexOAuthError {\n return new CodexOAuthError(signal?.reason === 'timeout' ? 'timeout' : 'cancelled', safeMessage(signal?.reason === 'timeout' ? 'timeout' : 'cancelled'));\n}\n\nfunction safeRequestError(error: unknown, signal?: AbortSignal): CodexOAuthError {\n if (error instanceof CodexOAuthError) return error;\n if (signal?.aborted) return abortError(signal);\n return new CodexOAuthError('network', safeMessage('network'), { retryable: true });\n}\n\ntype ReadChunkResult = Awaited<ReturnType<ReadableStreamDefaultReader<Uint8Array>['read']>>;\n\nfunction readChunk(reader: ReadableStreamDefaultReader<Uint8Array>, signal?: AbortSignal): Promise<ReadChunkResult> {\n if (!signal) return reader.read();\n if (signal.aborted) return Promise.reject(abortError(signal));\n return new Promise((resolve, reject) => {\n let settled = false;\n const cleanup = () => signal.removeEventListener('abort', onAbort);\n const onAbort = () => {\n if (settled) return;\n settled = true;\n cleanup();\n void reader.cancel().catch(() => undefined);\n reject(abortError(signal));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n reader.read().then(\n (value) => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(value);\n },\n (error) => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(error);\n }\n );\n });\n}\n\nfunction awaitWithSignal<T>(promise: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) return promise;\n if (signal.aborted) return Promise.reject(abortError(signal));\n return new Promise((resolve, reject) => {\n let settled = false;\n const cleanup = () => signal.removeEventListener('abort', onAbort);\n const onAbort = () => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(abortError(signal));\n };\n signal.addEventListener('abort', onAbort, { once: true });\n promise.then(\n (value) => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(value);\n },\n (error) => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(error);\n }\n );\n });\n}\n\nfunction combinedSignal(signal: AbortSignal | undefined, timeoutMs: number): { signal: AbortSignal; dispose: () => void } {\n const controller = new AbortController();\n const onAbort = () => controller.abort(signal?.reason ?? new DOMException('Aborted', 'AbortError'));\n if (signal?.aborted) onAbort();\n else signal?.addEventListener('abort', onAbort, { once: true });\n const timer = setTimeout(() => controller.abort('timeout'), timeoutMs);\n return {\n signal: controller.signal,\n dispose: () => {\n clearTimeout(timer);\n signal?.removeEventListener('abort', onAbort);\n }\n };\n}\n\nasync function readBounded(response: Response, maxBodyBytes: number, signal?: AbortSignal): Promise<string> {\n try {\n if (!response.body) {\n const text = await awaitWithSignal(response.text(), signal);\n if (new TextEncoder().encode(text).byteLength > maxBodyBytes) {\n throw new CodexOAuthError('body_limit', safeMessage('body_limit'), { retryable: false });\n }\n return text;\n }\n const reader = response.body.getReader();\n try {\n const chunks: Uint8Array[] = [];\n let total = 0;\n for (;;) {\n const next = await readChunk(reader, signal);\n if (next.done) break;\n total += next.value.byteLength;\n if (total > maxBodyBytes) {\n void reader.cancel().catch(() => undefined);\n throw new CodexOAuthError('body_limit', safeMessage('body_limit'), { retryable: false });\n }\n chunks.push(next.value);\n }\n const bytes = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return new TextDecoder().decode(bytes);\n } finally {\n reader.releaseLock();\n }\n } catch (error) {\n throw safeRequestError(error, signal);\n }\n}\n\nfunction jsonRecord(text: string): Record<string, unknown> {\n try {\n const value: unknown = JSON.parse(text);\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) return value as Record<string, unknown>;\n } catch {\n // Deliberately hide malformed upstream body contents.\n }\n throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n}\n\nfunction safeUpstreamCode(text: string): string | undefined {\n const safeCodes = new Set(['refresh_token_reused', 'invalid_grant', 'authorization_pending', 'slow_down', 'access_denied', 'expired_token', 'invalid_request']);\n const find = (value: unknown, depth: number): string | undefined => {\n if (depth > 2 || value === null || typeof value !== 'object') return undefined;\n if (Array.isArray(value)) {\n for (const item of value) {\n const found = find(item, depth + 1);\n if (found) return found;\n }\n return undefined;\n }\n for (const [key, item] of Object.entries(value)) {\n if (['error', 'error_code', 'code'].includes(key) && typeof item === 'string' && safeCodes.has(item.toLowerCase())) return item.toLowerCase();\n const found = find(item, depth + 1);\n if (found) return found;\n }\n return undefined;\n };\n try {\n const value: unknown = JSON.parse(text);\n return find(value, 0);\n } catch {\n // Do not expose or inspect arbitrary response text.\n }\n return undefined;\n}\n\nfunction responseError(status: number, body: string, refresh = false): CodexOAuthError {\n const code = safeUpstreamCode(body);\n if (refresh && code?.toLowerCase() === 'refresh_token_reused') {\n return new CodexOAuthError('refresh_token_reused', safeMessage('refresh_token_reused'), {\n status,\n upstreamCode: 'refresh_token_reused',\n retryable: false\n });\n }\n return new CodexOAuthError('http', safeMessage('http', status), {\n status,\n upstreamCode: code,\n retryable: status >= 500 || status === 408 || status === 429\n });\n}\n\nexport async function requestJson(url: string, init: RequestInit, options: OAuthRequestOptions, refresh = false): Promise<Record<string, unknown>> {\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const combined = combinedSignal(options.signal, timeoutMs);\n try {\n if (combined.signal.aborted) throw abortError(combined.signal);\n let response: Response;\n try {\n response = await fetchOf(options.fetchImpl)(url, { ...init, redirect: 'error', signal: combined.signal });\n } catch (error) {\n throw safeRequestError(error, combined.signal);\n }\n const body = await readBounded(response, options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES, combined.signal);\n if (!response.ok) throw responseError(response.status, body, refresh);\n return jsonRecord(body);\n } catch (error) {\n throw safeRequestError(error, combined.signal);\n } finally {\n combined.dispose();\n }\n}\n\nfunction stringField(record: Record<string, unknown>, ...names: string[]): string | undefined {\n for (const name of names) {\n if (typeof record[name] === 'string' && record[name].trim()) return record[name].trim();\n }\n return undefined;\n}\n\nfunction positiveNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value) && value > 0) return value;\n if (typeof value === 'string' && /^\\d+(?:\\.\\d+)?$/.test(value.trim())) {\n const parsed = Number(value);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n }\n return undefined;\n}\n\nexport async function requestDeviceCode(options: OAuthRequestOptions = {}): Promise<DeviceCode> {\n const body = await requestJson(CODEX_DEVICE_USER_CODE_URL, {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/json' },\n body: JSON.stringify({ client_id: CODEX_CLIENT_ID })\n }, options);\n const deviceAuthId = stringField(body, 'device_auth_id');\n const userCode = stringField(body, 'user_code', 'usercode');\n if (!deviceAuthId || !userCode) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n const seconds = positiveNumber(body.interval) ?? 5;\n return { deviceAuthId, userCode, intervalMs: Math.max(250, Math.round(seconds * 1000)) };\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) return reject(abortError(signal));\n let settled = false;\n const cleanup = () => signal?.removeEventListener('abort', onAbort);\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve();\n }, ms);\n const onAbort = () => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n cleanup();\n reject(abortError(signal));\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nexport async function pollDeviceToken(\n device: Pick<DeviceCode, 'deviceAuthId' | 'userCode' | 'intervalMs'>,\n options: OAuthRequestOptions & { maxDurationMs?: number } = {}\n): Promise<DeviceTokenResponse> {\n if (!device.deviceAuthId.trim() || !device.userCode.trim()) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n const maxDurationMs = Math.min(options.maxDurationMs ?? CODEX_DEVICE_TIMEOUT_MS, CODEX_DEVICE_TIMEOUT_MS);\n const deadline = Date.now() + Math.max(1, maxDurationMs);\n const intervalMs = Math.max(250, device.intervalMs || 5000);\n for (;;) {\n if (Date.now() >= deadline) throw new CodexOAuthError('timeout', 'Codex device authentication timed out after 15 minutes', { retryable: false });\n const remaining = deadline - Date.now();\n const body = JSON.stringify({ device_auth_id: device.deviceAuthId, user_code: device.userCode });\n let response: Response;\n const combined = combinedSignal(options.signal, Math.min(options.timeoutMs ?? DEFAULT_TIMEOUT_MS, remaining));\n try {\n try {\n response = await fetchOf(options.fetchImpl)(CODEX_DEVICE_TOKEN_URL, {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/json' },\n body,\n redirect: 'error',\n signal: combined.signal\n });\n } catch (error) {\n throw safeRequestError(error, combined.signal);\n }\n const text = await readBounded(response, options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES, combined.signal);\n if (response.status === 403 || response.status === 404) {\n // OpenAI uses both statuses for a still-pending device authorization. Any\n // other non-2xx status is a terminal protocol error, not a polling state.\n if (Date.now() >= deadline) throw new CodexOAuthError('timeout', 'Codex device authentication timed out after 15 minutes', { retryable: false });\n await sleep(Math.min(intervalMs, deadline - Date.now()), options.signal);\n continue;\n }\n if (!response.ok) throw responseError(response.status, text);\n const parsed = jsonRecord(text);\n const authorizationCode = stringField(parsed, 'authorization_code');\n const codeVerifier = stringField(parsed, 'code_verifier');\n if (!authorizationCode || !codeVerifier) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n return { authorizationCode, codeVerifier, codeChallenge: stringField(parsed, 'code_challenge') };\n } catch (error) {\n throw safeRequestError(error, combined.signal);\n } finally {\n combined.dispose();\n }\n }\n}\n\nexport interface PKCE {\n state: string;\n codeVerifier: string;\n codeChallenge: string;\n}\n\nexport function base64Url(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString('base64url');\n}\n\nexport function createPKCE(random?: (size: number) => Uint8Array): PKCE {\n const bytes = random ?? ((size) => randomBytes(size));\n const codeVerifier = base64Url(bytes(32));\n const state = base64Url(bytes(32));\n const codeChallenge = base64Url(new Uint8Array(createHash('sha256').update(codeVerifier).digest()));\n return { state, codeVerifier, codeChallenge };\n}\n\nexport function buildCodexAuthorizationUrl(pkce: Pick<PKCE, 'state' | 'codeChallenge'>): string {\n const url = new URL(CODEX_AUTH_URL);\n url.search = new URLSearchParams({\n client_id: CODEX_CLIENT_ID,\n response_type: 'code',\n redirect_uri: CODEX_REDIRECT_URI,\n scope: 'openid email profile offline_access',\n state: pkce.state,\n code_challenge: pkce.codeChallenge,\n code_challenge_method: 'S256',\n prompt: 'login',\n id_token_add_organizations: 'true',\n codex_cli_simplified_flow: 'true'\n }).toString();\n return url.toString();\n}\n\nexport interface CallbackParseOptions {\n expectedState: string;\n issuedAt?: number;\n now?: number;\n ttlMs?: number;\n expectedOrigin?: string;\n expectedPath?: string;\n}\n\nexport interface OAuthCallback {\n code?: string;\n state: string;\n error?: string;\n errorDescription?: { present: true };\n}\n\nconst SAFE_CALLBACK_ERRORS = new Set([\n 'access_denied',\n 'invalid_request',\n 'unauthorized_client',\n 'unsupported_response_type',\n 'invalid_scope',\n 'server_error',\n 'temporarily_unavailable'\n]);\n\nexport function parseCodexCallbackUrl(raw: string, options: CallbackParseOptions): OAuthCallback {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const expectedUrl = new URL(CODEX_REDIRECT_URI);\n if (\n (options.expectedOrigin !== undefined && options.expectedOrigin !== expectedUrl.origin) ||\n (options.expectedPath !== undefined && options.expectedPath !== expectedUrl.pathname) ||\n url.origin !== expectedUrl.origin ||\n url.pathname !== expectedUrl.pathname ||\n url.username ||\n url.password ||\n url.hash\n ) {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const duplicate = ['state', 'code', 'error', 'error_description'].some((name) => url.searchParams.getAll(name).length > 1);\n if (duplicate || url.searchParams.has('userinfo')) {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const state = url.searchParams.get('state') ?? '';\n if (!state || state !== options.expectedState) throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n const now = options.now ?? Date.now();\n const ttl = options.ttlMs ?? CODEX_CALLBACK_TTL_MS;\n if (!Number.isFinite(now) || !Number.isFinite(ttl) || ttl <= 0 || (options.issuedAt !== undefined && (!Number.isFinite(options.issuedAt) || options.issuedAt < 0 || now < options.issuedAt || now - options.issuedAt > ttl))) {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const hasCode = url.searchParams.has('code');\n const hasError = url.searchParams.has('error');\n if (hasCode && hasError) throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n const code = url.searchParams.get('code')?.trim() || undefined;\n const rawError = url.searchParams.get('error')?.trim() || undefined;\n if ((hasCode && !code) || (hasError && !rawError)) {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const error = rawError ? (SAFE_CALLBACK_ERRORS.has(rawError) ? rawError : 'unknown_error') : undefined;\n const hasErrorDescription = rawError !== undefined && url.searchParams.has('error_description');\n if (rawError === undefined && url.searchParams.has('error_description')) {\n throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n }\n const result: OAuthCallback = {\n state,\n code,\n error,\n errorDescription: hasErrorDescription ? { present: true } : undefined\n };\n if (!result.code && !result.error) throw new CodexOAuthError('invalid_callback', safeMessage('invalid_callback'), { retryable: false });\n return result;\n}\n\nexport interface CodexTokenSet {\n siwc?: { clientId: string; subject: string; scopes: string[] };\n accessToken: string;\n refreshToken: string;\n idToken?: string;\n tokenType?: string;\n expiresIn?: number;\n expiresAt?: number;\n identity?: CodexIdentity;\n identityStatus: 'missing' | 'parsed' | 'invalid';\n}\n\nfunction tokenSet(record: Record<string, unknown>, previousRefreshToken?: string): CodexTokenSet {\n const accessToken = stringField(record, 'access_token');\n const refreshToken = stringField(record, 'refresh_token') ?? previousRefreshToken;\n if (!accessToken || !refreshToken) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n const expiresIn = positiveNumber(record.expires_in);\n const idToken = stringField(record, 'id_token');\n let identity: CodexIdentity | undefined;\n let identityStatus: CodexTokenSet['identityStatus'] = 'missing';\n if (idToken) {\n try {\n identity = extractCodexIdentity(idToken);\n identityStatus = 'parsed';\n } catch {\n // Identity is optional metadata. Never discard newly rotated credentials.\n identityStatus = 'invalid';\n }\n }\n return {\n accessToken,\n refreshToken,\n idToken,\n tokenType: stringField(record, 'token_type'),\n expiresIn,\n expiresAt: expiresIn === undefined ? undefined : Date.now() + expiresIn * 1000,\n identity,\n identityStatus\n };\n}\n\nexport async function exchangeCodexCode(\n code: string,\n codeVerifier: string,\n options: OAuthRequestOptions & { redirectUri?: string } = {}\n): Promise<CodexTokenSet> {\n if (!code.trim() || !codeVerifier.trim()) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n const redirectUri = options.redirectUri ?? CODEX_REDIRECT_URI;\n const body = new URLSearchParams({ grant_type: 'authorization_code', client_id: CODEX_CLIENT_ID, code, redirect_uri: redirectUri, code_verifier: codeVerifier });\n const response = await requestJson(CODEX_TOKEN_URL, {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/x-www-form-urlencoded' },\n body: body.toString()\n }, options);\n return tokenSet(response);\n}\n\nexport async function exchangeCodexDeviceAuthorization(\n deviceToken: Pick<DeviceTokenResponse, 'authorizationCode' | 'codeVerifier'>,\n options: OAuthRequestOptions = {}\n): Promise<CodexTokenSet> {\n return exchangeCodexCode(deviceToken.authorizationCode, deviceToken.codeVerifier, {\n ...options,\n redirectUri: CODEX_DEVICE_EXCHANGE_REDIRECT_URI\n });\n}\n\nexport async function refreshCodexToken(\n refreshToken: string,\n options: OAuthRequestOptions = {}\n): Promise<CodexTokenSet> {\n if (!refreshToken.trim()) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n const body = new URLSearchParams({ client_id: CODEX_CLIENT_ID, grant_type: 'refresh_token', refresh_token: refreshToken, scope: 'openid profile email' });\n const response = await requestJson(CODEX_TOKEN_URL, {\n method: 'POST',\n headers: { accept: 'application/json', 'content-type': 'application/x-www-form-urlencoded' },\n body: body.toString()\n }, { ...options }, true);\n return tokenSet(response, refreshToken);\n}\n\nexport interface CodexIdentity {\n email?: string;\n accountId?: string;\n planType?: string;\n userId?: string;\n}\n\nexport interface CodexJwtPayload {\n email?: unknown;\n exp?: unknown;\n sub?: unknown;\n [key: string]: unknown;\n}\n\nexport function parseJwtPayload(idToken: string): CodexJwtPayload {\n const parts = idToken.split('.');\n if (parts.length !== 3 || !parts[1]) throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n try {\n const payload: unknown = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));\n if (typeof payload !== 'object' || payload === null || Array.isArray(payload)) throw new Error('not an object');\n return payload as CodexJwtPayload;\n } catch {\n throw new CodexOAuthError('invalid_response', safeMessage('invalid_response'), { retryable: false });\n }\n}\n\nexport function extractCodexIdentity(idToken: string): CodexIdentity {\n const payload = parseJwtPayload(idToken);\n const auth = payload['https://api.openai.com/auth'];\n const authRecord = typeof auth === 'object' && auth !== null && !Array.isArray(auth) ? auth as Record<string, unknown> : {};\n return {\n email: typeof payload.email === 'string' ? payload.email : undefined,\n accountId: typeof authRecord.chatgpt_account_id === 'string' ? authRecord.chatgpt_account_id : undefined,\n planType: typeof authRecord.chatgpt_plan_type === 'string' ? authRecord.chatgpt_plan_type : undefined,\n userId: typeof authRecord.user_id === 'string' ? authRecord.user_id : undefined\n };\n}\n",
|
|
15
|
+
"import { createPublicKey, randomBytes, randomUUID, verify, type JsonWebKey } from 'node:crypto';\nimport type { SecretStore } from '../../../packages/core/src/plugin-control/contracts';\nimport { CODEX_CALLBACK_TTL_MS, CodexOAuthError, requestJson, type CodexTokenSet, type OAuthRequestOptions, type PKCE } from './oauth';\n\nexport const SIWC_AUTH_URL = 'https://auth.openai.com/api/accounts/authorize';\nexport const SIWC_TOKEN_URL = 'https://auth.openai.com/api/accounts/oauth/token';\nexport const SIWC_JWKS_URL = 'https://auth.openai.com/.well-known/jwks.json';\nexport const SIWC_ISSUER = 'https://auth.openai.com';\nexport const SIWC_REDIRECT_URI = 'http://127.0.0.1:1455/auth/callback';\nexport const SIWC_RESOURCE = 'https://api.openai.com/v1';\nexport const SIWC_SCOPES = ['openid', 'profile', 'email', 'offline_access', 'resource.invoke', 'chatgpt.tokens.use.direct'] as const;\nexport const SIWC_REGISTRATION_KEY = 'siwc.registration.v1';\nconst CLIENT_ID = /^oaiapp_[A-Za-z0-9_-]{1,200}$/;\nconst HOST_ID = /^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;\n\nfunction invalid(kind: 'invalid_response' | 'invalid_callback' = 'invalid_response'): never {\n throw new CodexOAuthError(kind, `SIWC ${kind === 'invalid_callback' ? 'callback' : 'response'} is invalid`, { retryable: false });\n}\n\n/** Only installation identity is global. Issued client IDs belong to individual accounts. */\nexport async function getSiwcHostId(store: SecretStore, canWrite: () => boolean = () => true): Promise<string> {\n for (let attempt = 0; attempt < 12; attempt++) {\n if (!canWrite()) throw new CodexOAuthError('cancelled', 'SIWC operation was cancelled', { retryable: false });\n const current = await store.get(SIWC_REGISTRATION_KEY);\n if (current) {\n try {\n const record = JSON.parse(current.value);\n if (record?.schema === 1 && typeof record.hostId === 'string' && HOST_ID.test(record.hostId)) return record.hostId;\n } catch { /* Hide invalid secret-store contents. */ }\n return invalid();\n }\n const hostId = `urn:uuid:${randomUUID()}`;\n if (!canWrite()) throw new CodexOAuthError('cancelled', 'SIWC operation was cancelled', { retryable: false });\n try {\n await store.compareAndSet(SIWC_REGISTRATION_KEY, null, JSON.stringify({ schema: 1, hostId }));\n return hostId;\n } catch (error) {\n if ((error as { code?: string }).code !== 'version_conflict') throw error;\n }\n }\n return invalid();\n}\n\nexport function validSiwcMetadata(value: unknown): value is NonNullable<CodexTokenSet['siwc']> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return false;\n const item = value as Record<string, unknown>;\n return Object.keys(item).every(key => ['clientId', 'subject', 'scopes'].includes(key)) &&\n typeof item.clientId === 'string' && CLIENT_ID.test(item.clientId) &&\n typeof item.subject === 'string' && item.subject.length > 0 && item.subject.length <= 512 && item.subject.trim() === item.subject && !/[\\u0000-\\u001f\\u007f]/.test(item.subject) &&\n Array.isArray(item.scopes) && item.scopes.length <= 128 && item.scopes.every(scope => typeof scope === 'string' && /^[\\x21\\x23-\\x5b\\x5d-\\x7e]{1,128}$/.test(scope)) &&\n item.scopes.includes('resource.invoke') && item.scopes.includes('chatgpt.tokens.use.direct');\n}\n\nexport function createSiwcNonce(random: (size: number) => Uint8Array = randomBytes): string {\n return Buffer.from(random(32)).toString('base64url');\n}\n\nexport function buildSiwcAuthorizationUrl(pkce: Pick<PKCE, 'state' | 'codeChallenge'>, nonce: string, hostId: string, clientId?: string): string {\n if (!HOST_ID.test(hostId) || (clientId !== undefined && !CLIENT_ID.test(clientId)) || !nonce || !pkce.state || !pkce.codeChallenge) return invalid();\n const url = new URL(SIWC_AUTH_URL);\n url.search = new URLSearchParams({\n client_id: clientId ?? 'dynamic_agent_client', agent_name_hint: 'Bungee', ext_agent_host_id: hostId,\n response_type: 'code', redirect_uri: SIWC_REDIRECT_URI, resource: SIWC_RESOURCE, scope: SIWC_SCOPES.join(' '),\n state: pkce.state, nonce, code_challenge: pkce.codeChallenge, code_challenge_method: 'S256',\n }).toString();\n return url.toString();\n}\n\nexport function parseSiwcCallbackUrl(raw: string, options: { expectedState: string; expectedClientId?: string; issuedAt: number; now?: number }): { code: string; clientId: string } {\n let url: URL;\n try { url = new URL(raw); } catch { return invalid('invalid_callback'); }\n const expected = new URL(SIWC_REDIRECT_URI);\n const now = options.now ?? Date.now();\n if (raw.length > 4096 || raw.trim() !== raw || raw.split('?')[0] !== SIWC_REDIRECT_URI || url.origin !== expected.origin || url.pathname !== expected.pathname || url.username || url.password || url.hash ||\n !Number.isFinite(now) || !Number.isFinite(options.issuedAt) || options.issuedAt < 0 || now < options.issuedAt || now - options.issuedAt > CODEX_CALLBACK_TTL_MS ||\n [...url.searchParams.keys()].some(key => url.searchParams.getAll(key).length !== 1) || url.searchParams.has('userinfo') ||\n !options.expectedState || url.searchParams.get('state') !== options.expectedState || url.searchParams.has('error') || url.searchParams.has('error_description')) return invalid('invalid_callback');\n const code = url.searchParams.get('code');\n const clientId = url.searchParams.get('client_id');\n if (!code || code.trim() !== code || /[\\u0000-\\u001f\\u007f]/.test(code) || !clientId || !CLIENT_ID.test(clientId) || (options.expectedClientId !== undefined && clientId !== options.expectedClientId)) return invalid('invalid_callback');\n return { code, clientId };\n}\n\nfunction jwtObject(part: string): Record<string, unknown> {\n try {\n if (!/^[A-Za-z0-9_-]+$/.test(part)) return invalid();\n const value = JSON.parse(Buffer.from(part, 'base64url').toString('utf8'));\n if (value && typeof value === 'object' && !Array.isArray(value)) return value;\n } catch { /* Never expose token contents. */ }\n return invalid();\n}\n\nexport async function verifySiwcIdToken(idToken: string, expected: { clientId: string; nonce?: string; subject?: string; now?: number }, options: OAuthRequestOptions = {}): Promise<{ subject: string; email?: string }> {\n if (!CLIENT_ID.test(expected.clientId) || idToken.length > 32_768) return invalid();\n const parts = idToken.split('.');\n if (parts.length !== 3 || !/^[A-Za-z0-9_-]+$/.test(parts[2]!)) return invalid();\n const header = jwtObject(parts[0]!);\n const payload = jwtObject(parts[1]!);\n if (header.alg !== 'RS256' || typeof header.kid !== 'string' || !header.kid || header.crit !== undefined) return invalid();\n const jwks = await requestJson(SIWC_JWKS_URL, { method: 'GET', headers: { accept: 'application/json' } }, options);\n if (!Array.isArray(jwks.keys) || jwks.keys.length > 128) return invalid();\n const keys = jwks.keys.filter(key => key && typeof key === 'object' && key.kid === header.kid && key.kty === 'RSA' &&\n (key.alg === undefined || key.alg === 'RS256') && (key.use === undefined || key.use === 'sig') &&\n (key.key_ops === undefined || (Array.isArray(key.key_ops) && key.key_ops.includes('verify'))) && key.d === undefined);\n if (keys.length !== 1) return invalid();\n try {\n const publicKey = createPublicKey({ key: keys[0] as JsonWebKey, format: 'jwk' });\n if (!verify('RSA-SHA256', Buffer.from(`${parts[0]}.${parts[1]}`), publicKey, Buffer.from(parts[2]!, 'base64url'))) return invalid();\n } catch { return invalid(); }\n const aud = payload.aud;\n const now = expected.now ?? Date.now();\n if (payload.iss !== SIWC_ISSUER || !(aud === expected.clientId || (Array.isArray(aud) && aud.every(item => typeof item === 'string') && aud.includes(expected.clientId))) ||\n (Array.isArray(aud) && aud.length > 1 && payload.azp !== expected.clientId) || (payload.azp !== undefined && payload.azp !== expected.clientId) ||\n typeof payload.exp !== 'number' || !Number.isFinite(payload.exp) || !Number.isFinite(now) || payload.exp * 1000 <= now ||\n (payload.nbf !== undefined && (typeof payload.nbf !== 'number' || !Number.isFinite(payload.nbf) || payload.nbf * 1000 > now)) ||\n typeof payload.sub !== 'string' || !payload.sub || payload.sub.length > 512 || payload.sub.trim() !== payload.sub || /[\\u0000-\\u001f\\u007f]/.test(payload.sub) ||\n (expected.nonce !== undefined && payload.nonce !== expected.nonce) || (expected.subject !== undefined && payload.sub !== expected.subject)) return invalid();\n return { subject: payload.sub, email: typeof payload.email === 'string' && payload.email.length <= 512 && !/[\\u0000-\\u001f\\u007f]/.test(payload.email) ? payload.email : undefined };\n}\n\nfunction tokenString(record: Record<string, unknown>, key: string, fallback?: string): string {\n if (record[key] === undefined && fallback !== undefined) return fallback;\n const value = record[key];\n if (typeof value !== 'string' || !value || value.trim() !== value || value.length > 32_768 || /[\\r\\n\\0]/.test(value)) return invalid();\n return value;\n}\n\nasync function siwcTokenSet(record: Record<string, unknown>, expected: { clientId: string; nonce?: string; subject?: string }, options: OAuthRequestOptions, previous?: CodexTokenSet): Promise<CodexTokenSet> {\n const accessToken = tokenString(record, 'access_token');\n const refreshToken = tokenString(record, 'refresh_token', previous?.refreshToken);\n const idToken = tokenString(record, 'id_token', previous?.idToken);\n if (record.token_type !== undefined && (typeof record.token_type !== 'string' || record.token_type.toLowerCase() !== 'bearer')) return invalid();\n if (typeof record.expires_in !== 'number' || !Number.isFinite(record.expires_in) || record.expires_in <= 0 || record.expires_in * 1000 > Number.MAX_SAFE_INTEGER - Date.now()) return invalid();\n const scopes = record.scope === undefined && previous?.siwc ? [...previous.siwc.scopes] : tokenString(record, 'scope').split(/\\s+/);\n const verified = record.id_token === undefined && previous?.siwc\n ? { subject: previous.siwc.subject, email: previous.identity?.email }\n : await verifySiwcIdToken(idToken, expected, options);\n const siwc = { clientId: expected.clientId, subject: verified.subject, scopes };\n if (!validSiwcMetadata(siwc)) return invalid();\n return { accessToken, refreshToken, idToken, expiresIn: record.expires_in, expiresAt: Date.now() + record.expires_in * 1000,\n tokenType: 'Bearer', identity: { email: verified.email }, identityStatus: 'parsed', siwc };\n}\n\nexport async function exchangeSiwcCode(code: string, codeVerifier: string, clientId: string, nonce: string, options: OAuthRequestOptions = {}): Promise<CodexTokenSet> {\n if (!code || !codeVerifier || !nonce || !CLIENT_ID.test(clientId)) return invalid();\n const body = new URLSearchParams({ grant_type: 'authorization_code', client_id: clientId, code, code_verifier: codeVerifier, redirect_uri: SIWC_REDIRECT_URI, resource: SIWC_RESOURCE });\n const record = await requestJson(SIWC_TOKEN_URL, { method: 'POST', headers: { accept: 'application/json', 'content-type': 'application/x-www-form-urlencoded' }, body: body.toString() }, options);\n return siwcTokenSet(record, { clientId, nonce }, options);\n}\n\nexport async function refreshSiwcToken(previous: CodexTokenSet, options: OAuthRequestOptions = {}): Promise<CodexTokenSet> {\n if (!validSiwcMetadata(previous.siwc) || !previous.refreshToken) return invalid();\n const body = new URLSearchParams({ grant_type: 'refresh_token', client_id: previous.siwc.clientId, refresh_token: previous.refreshToken, resource: SIWC_RESOURCE });\n const record = await requestJson(SIWC_TOKEN_URL, { method: 'POST', headers: { accept: 'application/json', 'content-type': 'application/x-www-form-urlencoded' }, body: body.toString() }, options, true);\n return siwcTokenSet(record, { clientId: previous.siwc.clientId, subject: previous.siwc.subject }, options, previous);\n}\n",
|
|
16
|
+
"import { randomUUID } from 'node:crypto';\nimport type { SecretStore } from '../../../packages/core/src/plugin-control/contracts';\nimport type { CodexIdentity, CodexTokenSet } from './oauth';\nimport type { ResetCredit } from './usage';\nimport { validSiwcMetadata } from './siwc';\n\nexport interface AutoResetAttempt {\n creditId: string;\n redeemRequestId: string;\n expiresAt?: number;\n completed: boolean;\n}\n\nexport const ACCOUNT_STORE_KEY = 'accounts.v1';\nexport const ACCOUNT_SCHEMA_VERSION = 1;\n\nexport type AccountStatus = 'active' | 'disabled' | 'reauth_required' | 'revoked';\n\nexport interface StoredAccount {\n id: string;\n label: string;\n status: AccountStatus;\n generation: number;\n createdAt: number;\n updatedAt: number;\n expiresAt?: number;\n accessToken?: string;\n refreshToken?: string;\n idToken?: string;\n identity?: CodexIdentity;\n siwc?: CodexTokenSet['siwc'];\n refreshLock?: { owner: string; until: number };\n loginFence: number;\n credentialValid: boolean;\n autoResetCredits?: boolean;\n autoResetAttempts?: AutoResetAttempt[];\n}\n\ninterface AccountAggregate {\n schema: typeof ACCOUNT_SCHEMA_VERSION;\n accounts: StoredAccount[];\n}\n\nexport interface AccountListItem {\n readonly authType: 'siwc' | 'codex';\n readonly id: string;\n readonly label: string;\n readonly status: AccountStatus;\n readonly available: boolean;\n readonly reason?: string;\n readonly expiresAt?: number;\n readonly identity?: Readonly<CodexIdentity>;\n readonly autoResetCredits: boolean;\n readonly pendingAutoReset?: Readonly<AutoResetAttempt>;\n}\n\nexport class AccountControlError extends Error {\n readonly name = 'AccountControlError';\n constructor(readonly code: AccountErrorCode) {\n super(code);\n }\n}\n\nexport type AccountErrorCode =\n | 'invalid_input'\n | 'not_found'\n | 'version_conflict'\n | 'identity_mismatch'\n | 'disabled'\n | 'revoked'\n | 'reauth_required'\n | 'stale_refresh'\n | 'invalid_identity'\n | 'disposed'\n | 'unsupported_operation';\n\nconst MAX_ACCOUNTS = 128;\nconst MAX_TEXT = 512;\nconst MAX_TOKEN = 32_768;\nconst MAX_AUTO_RESET_ATTEMPTS = 256;\n\nfunction text(value: unknown, max = MAX_TEXT): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > max || value.trim() !== value) {\n throw new AccountControlError('invalid_input');\n }\n return value;\n}\n\nfunction optionalText(value: unknown, max = MAX_TEXT): string | undefined {\n if (value === undefined) return undefined;\n return text(value, max);\n}\n\nfunction identity(value: unknown): CodexIdentity | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new AccountControlError('invalid_input');\n const input = value as Record<string, unknown>;\n const keys = new Set(['email', 'accountId', 'planType', 'userId']);\n if (Object.keys(input).some((key) => !keys.has(key))) throw new AccountControlError('invalid_input');\n const result: CodexIdentity = {};\n for (const key of keys) {\n const value = input[key];\n if (value !== undefined) (result as Record<string, string>)[key] = text(value);\n }\n return Object.keys(result).length === 0 ? undefined : result;\n}\n\nfunction copyIdentity(value: CodexIdentity | undefined): CodexIdentity | undefined {\n return value === undefined ? undefined : { ...value };\n}\n\nfunction copyAccount(value: StoredAccount): StoredAccount {\n return { ...value, siwc: value.siwc && { ...value.siwc, scopes: [...value.siwc.scopes] }, identity: copyIdentity(value.identity), refreshLock: value.refreshLock && { ...value.refreshLock },\n autoResetAttempts: value.autoResetAttempts?.map(item => ({ ...item })) };\n}\n\nfunction validAutoResetAttempts(value: unknown): boolean {\n return value === undefined || (Array.isArray(value) && value.length <= MAX_AUTO_RESET_ATTEMPTS && value.every(item =>\n item && typeof item.creditId === 'string' && item.creditId.length > 0 && item.creditId.length <= MAX_TEXT &&\n !/[\\u0000-\\u001f\\u007f]/.test(item.creditId) &&\n typeof item.redeemRequestId === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(item.redeemRequestId) &&\n (item.expiresAt === undefined || (Number.isFinite(item.expiresAt) && item.expiresAt >= 0)) && typeof item.completed === 'boolean'));\n}\n\nfunction validStoredAccount(value: unknown): value is StoredAccount {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const account = value as Record<string, unknown>;\n return typeof account.id === 'string' && account.id.length > 0 && account.id.length <= 128 &&\n typeof account.label === 'string' && account.label.length > 0 && account.label.length <= MAX_TEXT &&\n ['active', 'disabled', 'reauth_required', 'revoked'].includes(account.status as string) &&\n Number.isSafeInteger(account.generation) && (account.generation as number) > 0 &&\n (account.loginFence === undefined || (Number.isSafeInteger(account.loginFence) && (account.loginFence as number) > 0)) &&\n (account.credentialValid === undefined || typeof account.credentialValid === 'boolean') &&\n (account.autoResetCredits === undefined || typeof account.autoResetCredits === 'boolean') &&\n (account.siwc === undefined || validSiwcMetadata(account.siwc)) &&\n validAutoResetAttempts(account.autoResetAttempts) &&\n Number.isFinite(account.createdAt) && Number.isFinite(account.updatedAt);\n}\n\nfunction decode(value: string | undefined): AccountAggregate {\n if (value === undefined) return { schema: ACCOUNT_SCHEMA_VERSION, accounts: [] };\n try {\n const parsed: unknown = JSON.parse(value);\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) throw new Error();\n const aggregate = parsed as Record<string, unknown>;\n if (aggregate.schema !== ACCOUNT_SCHEMA_VERSION || !Array.isArray(aggregate.accounts) || aggregate.accounts.length > MAX_ACCOUNTS ||\n !aggregate.accounts.every(validStoredAccount)) throw new Error();\n return { schema: ACCOUNT_SCHEMA_VERSION, accounts: aggregate.accounts.map((item) => ({\n ...copyAccount(item), loginFence: item.loginFence ?? 1,\n credentialValid: item.credentialValid ?? item.status !== 'reauth_required',\n })) };\n } catch {\n throw new AccountControlError('invalid_input');\n }\n}\n\nfunction encode(value: AccountAggregate): string {\n return JSON.stringify(value);\n}\n\nfunction statusReason(account: StoredAccount): string | undefined {\n if (account.status === 'disabled') return 'disabled';\n if (account.status === 'reauth_required') return 'reauth_required';\n if (account.status === 'revoked') return 'revoked';\n return undefined;\n}\n\nexport function accountListItem(account: StoredAccount): AccountListItem {\n const pending = account.autoResetAttempts?.find(item => !item.completed);\n return {\n authType: account.siwc ? 'siwc' : 'codex',\n id: account.id,\n label: account.label,\n status: account.status,\n available: account.status === 'active' && account.credentialValid && Boolean(account.accessToken && account.refreshToken && Number.isFinite(account.expiresAt)),\n reason: statusReason(account),\n expiresAt: account.expiresAt,\n identity: copyIdentity(account.identity),\n autoResetCredits: !account.siwc && account.autoResetCredits === true,\n pendingAutoReset: !account.siwc && pending ? { ...pending } : undefined,\n };\n}\n\nfunction validateTokenIdentity(token: CodexTokenSet): void {\n if (token.identityStatus !== 'parsed' || (token.siwc === undefined ? !token.identity?.accountId : !validSiwcMetadata(token.siwc))) {\n throw new AccountControlError('invalid_identity');\n }\n}\n\nfunction validateSiwcBinding(account: StoredAccount, token: CodexTokenSet): void {\n if (Boolean(account.siwc) !== Boolean(token.siwc)) throw new AccountControlError('identity_mismatch');\n if (account.siwc) {\n if (!validSiwcMetadata(token.siwc) || token.identityStatus !== 'parsed') throw new AccountControlError('invalid_identity');\n if (account.siwc.clientId !== token.siwc.clientId || account.siwc.subject !== token.siwc.subject) throw new AccountControlError('identity_mismatch');\n }\n}\n\nexport class AccountStore {\n constructor(private readonly secretStore: SecretStore, private readonly canWrite: () => boolean = () => true) {}\n\n async read(): Promise<{ aggregate: AccountAggregate; version: number | null }> {\n const value = await this.secretStore.get(ACCOUNT_STORE_KEY);\n return { aggregate: decode(value?.value), version: value?.version ?? null };\n }\n\n private async mutate<T>(mutator: (aggregate: AccountAggregate) => T, canCommit: () => boolean = () => true): Promise<T> {\n for (let attempt = 0; attempt < 12; attempt++) {\n if (!this.canWrite() || !canCommit()) throw new AccountControlError('disposed');\n const current = await this.read();\n const next: AccountAggregate = { schema: ACCOUNT_SCHEMA_VERSION, accounts: current.aggregate.accounts.map(copyAccount) };\n const result = mutator(next);\n if (!this.canWrite() || !canCommit()) throw new AccountControlError('disposed');\n try {\n await this.secretStore.compareAndSet(ACCOUNT_STORE_KEY, current.version, encode(next));\n return result;\n } catch (error) {\n if ((error as { code?: string }).code !== 'version_conflict') throw error;\n }\n }\n throw new AccountControlError('version_conflict');\n }\n\n async list(): Promise<AccountListItem[]> {\n return (await this.read()).aggregate.accounts.map(accountListItem);\n }\n\n async remove(id: string): Promise<void> {\n text(id, 128);\n await this.mutate(aggregate => {\n aggregate.accounts = aggregate.accounts.filter(account => account.id !== id);\n });\n }\n\n /** Migrate records retained by the former local deletion implementation. */\n async purgeRevoked(): Promise<void> {\n if (!(await this.read()).aggregate.accounts.some(account => account.status === 'revoked')) return;\n await this.mutate(aggregate => {\n aggregate.accounts = aggregate.accounts.filter(account => account.status !== 'revoked');\n });\n }\n\n async get(id: string): Promise<StoredAccount> {\n const account = (await this.read()).aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n return copyAccount(account);\n }\n\n async create(label: string, token: CodexTokenSet, canCommit: () => boolean = () => true): Promise<StoredAccount> {\n text(label);\n validateTokenIdentity(token);\n return this.mutate((aggregate) => {\n if (aggregate.accounts.length >= MAX_ACCOUNTS) throw new AccountControlError('invalid_input');\n const now = Date.now();\n const account: StoredAccount = {\n id: randomUUID(), label, status: token.expiresAt === undefined ? 'reauth_required' : 'active', generation: 1, loginFence: 1,\n credentialValid: token.expiresAt !== undefined, createdAt: now, updatedAt: now,\n accessToken: text(token.accessToken, MAX_TOKEN), refreshToken: text(token.refreshToken, MAX_TOKEN),\n idToken: optionalText(token.idToken, MAX_TOKEN), expiresAt: token.expiresAt,\n identity: copyIdentity(token.identity), siwc: token.siwc && { ...token.siwc, scopes: [...token.siwc.scopes] },\n };\n aggregate.accounts.push(account);\n return copyAccount(account);\n }, canCommit);\n }\n\n async replaceCredentials(\n id: string,\n token: CodexTokenSet,\n options: { owner?: string; generation?: number } = {},\n ): Promise<StoredAccount> {\n if (options.owner === undefined || options.generation === undefined) throw new AccountControlError('stale_refresh');\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.generation !== options.generation) throw new AccountControlError('stale_refresh');\n if (account.refreshLock?.owner !== options.owner) throw new AccountControlError('stale_refresh');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n if (account.status === 'disabled') throw new AccountControlError('disabled');\n if (token.identity?.accountId && account.identity?.accountId && token.identity.accountId !== account.identity.accountId) {\n throw new AccountControlError('identity_mismatch');\n }\n validateSiwcBinding(account, token);\n const now = Date.now();\n account.siwc = token.siwc && { ...token.siwc, scopes: [...token.siwc.scopes] };\n account.accessToken = text(token.accessToken, MAX_TOKEN);\n account.refreshToken = text(token.refreshToken, MAX_TOKEN);\n if (token.idToken !== undefined && token.identityStatus !== 'invalid') account.idToken = text(token.idToken, MAX_TOKEN);\n if (token.expiresAt !== undefined) account.expiresAt = token.expiresAt;\n else delete account.expiresAt;\n // A refresh response may omit the account id. Never let that optional\n // metadata silently replace an already-bound identity.\n if (token.identityStatus !== 'invalid' && token.identity !== undefined &&\n (account.identity?.accountId === undefined || token.identity.accountId !== undefined)) {\n account.identity = copyIdentity(token.identity);\n }\n account.credentialValid = token.expiresAt !== undefined;\n account.status = token.expiresAt === undefined ? 'reauth_required' : 'active';\n account.generation += 1;\n account.updatedAt = now;\n delete account.refreshLock;\n return copyAccount(account);\n });\n }\n\n async reserveRelogin(id: string): Promise<{ generation: number; loginFence: number }> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n account.loginFence += 1;\n account.updatedAt = Date.now();\n return { generation: account.generation, loginFence: account.loginFence };\n });\n }\n\n async relogin(\n id: string,\n token: CodexTokenSet,\n expected: { generation: number; loginFence: number },\n canCommit: () => boolean = () => true,\n ): Promise<StoredAccount> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n if (account.generation !== expected.generation || account.loginFence !== expected.loginFence) {\n throw new AccountControlError('stale_refresh');\n }\n validateTokenIdentity(token);\n validateSiwcBinding(account, token);\n if (account.identity?.accountId && token.identity?.accountId !== account.identity.accountId) {\n throw new AccountControlError('identity_mismatch');\n }\n account.accessToken = text(token.accessToken, MAX_TOKEN);\n account.refreshToken = text(token.refreshToken, MAX_TOKEN);\n if (token.idToken !== undefined) account.idToken = text(token.idToken, MAX_TOKEN);\n if (token.expiresAt === undefined) {\n delete account.expiresAt;\n account.credentialValid = false;\n account.status = 'reauth_required';\n } else {\n account.expiresAt = token.expiresAt;\n account.credentialValid = true;\n account.status = 'active';\n }\n account.identity = copyIdentity(token.identity);\n account.siwc = token.siwc && { ...token.siwc, scopes: [...token.siwc.scopes] };\n account.generation += 1;\n account.updatedAt = Date.now();\n delete account.refreshLock;\n return copyAccount(account);\n }, canCommit);\n }\n\n async setStatus(id: string, status: Exclude<AccountStatus, 'active' | 'revoked'>): Promise<StoredAccount> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n account.status = status;\n account.generation += 1;\n account.updatedAt = Date.now();\n delete account.refreshLock;\n return copyAccount(account);\n });\n }\n\n async rename(id: string, label: string): Promise<StoredAccount> {\n text(label);\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n account.label = label;\n account.updatedAt = Date.now();\n return copyAccount(account);\n });\n }\n\n async setAutoResetCredits(id: string, enabled: boolean): Promise<StoredAccount> {\n if (typeof enabled !== 'boolean') throw new AccountControlError('invalid_input');\n return this.mutate(aggregate => {\n const account = aggregate.accounts.find(item => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n if (account.siwc) throw new AccountControlError('unsupported_operation');\n account.autoResetCredits = enabled;\n account.updatedAt = Date.now();\n return copyAccount(account);\n });\n }\n\n /** Persist before POST: a crash or unknown outcome must never create a new automatic request. */\n async claimAutoReset(id: string, credit: ResetCredit, now: number): Promise<AutoResetAttempt | undefined> {\n return this.mutate(aggregate => {\n const account = aggregate.accounts.find(item => item.id === id);\n if (!account || account.siwc || !accountListItem(account).available || account.autoResetCredits !== true) return undefined;\n const attempts = account.autoResetAttempts ?? [];\n if (attempts.some(item => !item.completed || item.creditId === credit.id)) return undefined;\n account.autoResetAttempts = attempts.filter(item => !item.completed || item.expiresAt === undefined || item.expiresAt > now);\n if (account.autoResetAttempts.length >= MAX_AUTO_RESET_ATTEMPTS || credit.expiresAt === undefined || credit.expiresAt <= now) return undefined;\n const attempt: AutoResetAttempt = { creditId: credit.id, redeemRequestId: randomUUID(), expiresAt: credit.expiresAt, completed: false };\n account.autoResetAttempts.push(attempt);\n account.updatedAt = Date.now();\n return { ...attempt };\n });\n }\n\n /** Manual and automatic requests share the same durable fence against automatic retries. */\n async recordResetAttempt(id: string, redeemRequestId: string, credit: ResetCredit, now: number): Promise<void> {\n await this.mutate(aggregate => {\n const account = aggregate.accounts.find(item => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.siwc) throw new AccountControlError('unsupported_operation');\n const attempts = account.autoResetAttempts ?? [];\n const pending = attempts.find(item => !item.completed);\n if (pending) {\n if (pending.redeemRequestId !== redeemRequestId || pending.creditId !== credit.id) throw new AccountControlError('version_conflict');\n return;\n }\n account.autoResetAttempts = attempts.filter(item => item.creditId !== credit.id && (item.expiresAt === undefined || item.expiresAt > now));\n if (account.autoResetAttempts.length >= MAX_AUTO_RESET_ATTEMPTS) throw new AccountControlError('invalid_input');\n account.autoResetAttempts.push({ creditId: credit.id, redeemRequestId, expiresAt: credit.expiresAt, completed: false });\n account.updatedAt = Date.now();\n });\n }\n\n async finishAutoReset(id: string, redeemRequestId: string, cancel = false): Promise<void> {\n await this.mutate(aggregate => {\n const account = aggregate.accounts.find(item => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (cancel) account.autoResetAttempts = account.autoResetAttempts?.filter(item => item.redeemRequestId !== redeemRequestId);\n else {\n const attempt = account.autoResetAttempts?.find(item => item.redeemRequestId === redeemRequestId);\n if (attempt) attempt.completed = true;\n }\n account.updatedAt = Date.now();\n });\n }\n\n async enable(id: string): Promise<StoredAccount> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status === 'revoked') throw new AccountControlError('revoked');\n if (account.status !== 'disabled') throw new AccountControlError('reauth_required');\n if (!account.accessToken || !account.credentialValid) throw new AccountControlError('reauth_required');\n account.status = 'active';\n account.generation += 1;\n account.updatedAt = Date.now();\n return copyAccount(account);\n });\n }\n\n async rejectAccess(id: string, generation: number): Promise<boolean> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.generation !== generation || account.status !== 'active') return false;\n account.status = 'reauth_required';\n account.credentialValid = false;\n account.generation += 1;\n account.updatedAt = Date.now();\n delete account.refreshLock;\n return true;\n });\n }\n\n async acquireRefresh(id: string, owner: string, until: number): Promise<{ acquired: boolean; account: StoredAccount }> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account) throw new AccountControlError('not_found');\n if (account.status !== 'active') throw new AccountControlError(account.status);\n if (account.refreshLock && account.refreshLock.owner !== owner && account.refreshLock.until > Date.now()) {\n return { acquired: false, account: copyAccount(account) };\n }\n account.refreshLock = { owner, until };\n account.updatedAt = Date.now();\n return { acquired: true, account: copyAccount(account) };\n });\n }\n\n async releaseRefresh(id: string, owner: string, generation: number): Promise<boolean> {\n try {\n return await this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (account?.generation === generation && account.refreshLock?.owner === owner && account.status === 'active') {\n delete account.refreshLock;\n account.updatedAt = Date.now();\n return true;\n }\n return false;\n });\n } catch (error) {\n if ((error as { code?: string }).code !== 'not_found' && (error as { code?: string }).code !== 'disposed') throw error;\n return false;\n }\n }\n\n async failRefreshReauth(id: string, owner: string, generation: number): Promise<boolean> {\n return this.mutate((aggregate) => {\n const account = aggregate.accounts.find((item) => item.id === id);\n if (!account || account.status !== 'active' || account.generation !== generation || account.refreshLock?.owner !== owner) return false;\n account.status = 'reauth_required';\n account.generation += 1;\n account.updatedAt = Date.now();\n delete account.refreshLock;\n return true;\n });\n }\n}\n",
|
|
17
|
+
"import { randomUUID } from 'node:crypto';\nimport {\n CODEX_CALLBACK_TTL_MS,\n CODEX_DEVICE_TIMEOUT_MS,\n CODEX_DEVICE_URL,\n type FetchLike,\n type CodexTokenSet,\n buildCodexAuthorizationUrl,\n createPKCE,\n exchangeCodexCode,\n exchangeCodexDeviceAuthorization,\n parseCodexCallbackUrl,\n pollDeviceToken,\n requestDeviceCode,\n type OAuthRequestOptions,\n} from './oauth';\nimport { buildSiwcAuthorizationUrl, createSiwcNonce, exchangeSiwcCode, parseSiwcCallbackUrl } from './siwc';\n\nexport type LoginKind = 'device' | 'pkce' | 'siwc';\nexport type LoginState = 'pending' | 'polling' | 'exchanging' | 'committing' | 'cancelled' | 'failed' | 'success';\n\nexport interface DeviceLoginStart {\n readonly sessionId: string;\n readonly userCode: string;\n readonly verificationUri: string;\n readonly expiresAt: number;\n}\n\nexport interface PkceLoginStart {\n readonly sessionId: string;\n readonly authorizationUrl: string;\n readonly expiresAt: number;\n}\n\nexport interface LoginStatus {\n readonly sessionId: string;\n readonly kind: LoginKind;\n readonly state: LoginState | 'expired';\n readonly issuedAt: number;\n readonly expiresAt: number;\n readonly accountRef?: string;\n readonly errorCode?: 'login_failed' | 'cancelled' | 'expired';\n readonly account?: { readonly id: string; readonly label: string; readonly status: string; readonly available: boolean; readonly accountId?: string };\n}\n\nexport interface LoginFence {\n readonly generation: number;\n readonly loginFence: number;\n}\n\nexport class LoginSessionError extends Error {\n readonly name = 'LoginSessionError';\n constructor(readonly code: LoginSessionErrorCode) {\n super(code);\n }\n}\n\nexport type LoginSessionErrorCode =\n | 'invalid_input'\n | 'not_found'\n | 'expired'\n | 'cancelled'\n | 'already_consumed'\n | 'busy'\n | 'failed'\n | 'disposed';\n\ninterface LoginSession {\n id: string;\n kind: LoginKind;\n state: LoginState;\n issuedAt: number;\n expiresAt: number;\n accountRef?: string;\n fence?: LoginFence;\n stateValue?: string;\n codeVerifier?: string;\n nonce?: string;\n clientId?: string;\n device?: { deviceAuthId: string; userCode: string; intervalMs: number };\n controller: AbortController;\n unlinkHost: () => void;\n expiryTimer: ReturnType<typeof setTimeout>;\n errorCode?: 'login_failed' | 'cancelled' | 'expired';\n account?: LoginStatus['account'];\n expiredDuringCommit?: boolean;\n}\n\nexport interface LoginSessionDependencies {\n fetchImpl?: FetchLike;\n now?: () => number;\n random?: (size: number) => Uint8Array;\n maxSessions?: number;\n}\n\nexport interface LoginCommitInfo {\n readonly accountRef?: string;\n readonly fence?: LoginFence;\n}\n\nexport type LoginCommit<TResult = unknown> = (\n token: CodexTokenSet,\n info: LoginCommitInfo,\n canCommit: () => boolean,\n) => Promise<TResult>;\n\nfunction safeOptions(deps: LoginSessionDependencies, signal: AbortSignal): OAuthRequestOptions {\n return { fetchImpl: deps.fetchImpl, signal };\n}\n\nexport class LoginSessionManager {\n private readonly sessions = new Map<string, LoginSession>();\n private readonly now: () => number;\n private readonly maxSessions: number;\n private disposed = false;\n private readonly onHostAbort: () => void;\n\n constructor(private readonly hostSignal: AbortSignal, private readonly deps: LoginSessionDependencies = {}) {\n this.now = deps.now ?? Date.now;\n this.maxSessions = Math.min(128, Math.max(1, deps.maxSessions ?? 64));\n this.onHostAbort = () => this.dispose();\n if (hostSignal.aborted) this.dispose();\n else hostSignal.addEventListener('abort', this.onHostAbort, { once: true });\n }\n\n private newSession(kind: LoginKind, accountRef: string | undefined, fence: LoginFence | undefined, ttl: number): LoginSession {\n if (this.disposed || this.hostSignal.aborted) throw new LoginSessionError('disposed');\n this.cleanup();\n if (this.sessions.size >= this.maxSessions) throw new LoginSessionError('busy');\n const controller = new AbortController();\n const onHostAbort = () => controller.abort(this.hostSignal.reason);\n this.hostSignal.addEventListener('abort', onHostAbort, { once: true });\n const issuedAt = this.now();\n const session: LoginSession = {\n id: randomUUID(), kind, state: 'pending', issuedAt, expiresAt: issuedAt + ttl,\n accountRef, fence, controller, unlinkHost: () => this.hostSignal.removeEventListener('abort', onHostAbort),\n expiryTimer: setTimeout(() => this.expire(session.id), Math.max(1, ttl)),\n };\n this.sessions.set(session.id, session);\n return session;\n }\n\n private expire(id: string): void {\n const session = this.sessions.get(id);\n if (!session) return;\n if (session.state === 'success' || session.state === 'failed') { this.remove(id); return; }\n if (session.state === 'cancelled') return;\n if (session.state === 'committing') { session.expiredDuringCommit = true; return; }\n session.state = 'cancelled';\n session.controller.abort('expired');\n }\n\n private cleanup(): void {\n const now = this.now();\n for (const [id, session] of this.sessions) {\n if ((session.state === 'cancelled' || session.state === 'success' || session.state === 'failed') && session.expiresAt <= now) this.remove(id);\n }\n }\n\n private remove(id: string): void {\n const session = this.sessions.get(id);\n if (!session) return;\n clearTimeout(session.expiryTimer);\n session.unlinkHost();\n this.sessions.delete(id);\n }\n\n private get(id: string): LoginSession {\n if (typeof id !== 'string' || id.length < 1 || id.length > 128) throw new LoginSessionError('invalid_input');\n const session = this.sessions.get(id);\n if (!session) throw new LoginSessionError('not_found');\n if (session.expiresAt <= this.now() && session.state !== 'committing') {\n this.expire(id);\n throw new LoginSessionError('expired');\n }\n return session;\n }\n\n async startDevice(accountRef?: string, fenceOrProvider?: LoginFence | (() => Promise<LoginFence | undefined>)): Promise<DeviceLoginStart> {\n if (accountRef !== undefined && (typeof accountRef !== 'string' || accountRef.length < 1 || accountRef.length > 128)) {\n throw new LoginSessionError('invalid_input');\n }\n const session = this.newSession('device', accountRef, typeof fenceOrProvider === 'function' ? undefined : fenceOrProvider, CODEX_DEVICE_TIMEOUT_MS);\n try {\n if (typeof fenceOrProvider === 'function') session.fence = await fenceOrProvider();\n const device = await requestDeviceCode(safeOptions(this.deps, session.controller.signal));\n if (!this.canCommit(session)) throw new LoginSessionError('cancelled');\n session.device = device;\n return { sessionId: session.id, userCode: device.userCode, verificationUri: CODEX_DEVICE_URL, expiresAt: session.expiresAt };\n } catch (error) {\n session.state = 'cancelled';\n session.controller.abort();\n this.remove(session.id);\n throw error;\n }\n }\n\n startPkce(accountRef?: string, fence?: LoginFence): PkceLoginStart {\n if (accountRef !== undefined && (typeof accountRef !== 'string' || accountRef.length < 1 || accountRef.length > 128)) {\n throw new LoginSessionError('invalid_input');\n }\n const pkce = createPKCE(this.deps.random);\n const session = this.newSession('pkce', accountRef, fence, CODEX_CALLBACK_TTL_MS);\n session.stateValue = pkce.state;\n session.codeVerifier = pkce.codeVerifier;\n return { sessionId: session.id, authorizationUrl: buildCodexAuthorizationUrl(pkce), expiresAt: session.expiresAt };\n }\n\n startSiwc(hostId: string, accountRef?: string, clientId?: string, fence?: LoginFence): PkceLoginStart {\n if (accountRef !== undefined && (typeof accountRef !== 'string' || !accountRef || accountRef.length > 128)) throw new LoginSessionError('invalid_input');\n const pkce = createPKCE(this.deps.random);\n const nonce = createSiwcNonce(this.deps.random);\n const authorizationUrl = buildSiwcAuthorizationUrl(pkce, nonce, hostId, clientId);\n const session = this.newSession('siwc', accountRef, fence, CODEX_CALLBACK_TTL_MS);\n session.stateValue = pkce.state;\n session.codeVerifier = pkce.codeVerifier;\n session.nonce = nonce;\n session.clientId = clientId;\n return { sessionId: session.id, authorizationUrl, expiresAt: session.expiresAt };\n }\n\n setFence(id: string, fence: LoginFence): void {\n const session = this.get(id);\n if (session.state !== 'pending') throw new LoginSessionError('busy');\n session.fence = fence;\n }\n\n status(id: string): LoginStatus {\n const session = this.sessions.get(id);\n if (!session) throw new LoginSessionError('not_found');\n return {\n sessionId: session.id, kind: session.kind,\n state: session.state === 'committing' ? 'committing' : session.expiresAt <= this.now() ? 'expired' : session.state,\n issuedAt: session.issuedAt, expiresAt: session.expiresAt, accountRef: session.accountRef,\n errorCode: session.state === 'committing' ? undefined : session.expiresAt <= this.now() ? 'expired' : session.errorCode,\n account: session.account,\n };\n }\n\n private canCommit(session: LoginSession): boolean {\n return !this.disposed && !this.hostSignal.aborted && !session.controller.signal.aborted &&\n session.state !== 'cancelled' && session.state !== 'failed' && session.state !== 'committing' && session.expiresAt > this.now();\n }\n\n private claim(id: string, kind: LoginKind): LoginSession {\n const session = this.get(id);\n if (session.kind !== kind) throw new LoginSessionError('invalid_input');\n if (session.state === 'cancelled') throw new LoginSessionError(session.expiresAt <= this.now() ? 'expired' : 'cancelled');\n if (session.state === 'success') throw new LoginSessionError('already_consumed');\n if (session.state === 'failed') throw new LoginSessionError('failed');\n if (session.state === 'polling' || session.state === 'exchanging' || session.state === 'committing') throw new LoginSessionError('busy');\n session.state = kind === 'device' ? 'polling' : 'exchanging';\n return session;\n }\n\n private async finish<TResult>(session: LoginSession, token: CodexTokenSet, commit?: LoginCommit<TResult>): Promise<{ token: CodexTokenSet; accountRef?: string; result?: TResult }> {\n if (!this.canCommit(session)) throw new LoginSessionError('cancelled');\n // This is the linearization point. Cancellation/TTL/dispose cannot claim\n // that an in-flight CAS was rolled back after this synchronous transition.\n session.state = 'committing';\n let result: TResult | undefined;\n try {\n result = commit === undefined ? undefined : await commit(token, { accountRef: session.accountRef, fence: session.fence }, () => session.state === 'committing');\n } catch (error) {\n session.state = 'failed';\n session.errorCode = 'login_failed';\n throw error;\n }\n session.account = this.accountSummary(result);\n session.state = 'success';\n if (session.expiredDuringCommit || session.expiresAt <= this.now()) this.remove(session.id);\n return { token, accountRef: session.accountRef, result };\n }\n\n private accountSummary(value: unknown): LoginStatus['account'] {\n if (typeof value !== 'object' || value === null) return undefined;\n const item = value as Record<string, unknown>;\n if (typeof item.id !== 'string' || typeof item.label !== 'string' || typeof item.status !== 'string' || typeof item.available !== 'boolean') return undefined;\n const identity = typeof item.identity === 'object' && item.identity !== null ? item.identity as Record<string, unknown> : undefined;\n return { id: item.id, label: item.label, status: item.status, available: item.available, accountId: typeof identity?.accountId === 'string' ? identity.accountId : undefined };\n }\n\n async completeDevice<TResult = unknown>(id: string, commit?: LoginCommit<TResult>): Promise<{ token: CodexTokenSet; accountRef?: string; result?: TResult }> {\n const session = this.claim(id, 'device');\n try {\n const device = session.device;\n if (!device) throw new LoginSessionError('busy');\n const token = await pollDeviceToken(device, { ...safeOptions(this.deps, session.controller.signal), maxDurationMs: Math.max(1, session.expiresAt - this.now()) });\n if (!this.canCommit(session)) throw new LoginSessionError('cancelled');\n session.state = 'exchanging';\n const exchanged = await exchangeCodexDeviceAuthorization(token, safeOptions(this.deps, session.controller.signal));\n return await this.finish(session, exchanged, commit);\n } catch (error) {\n if (session.controller.signal.aborted && session.state === 'cancelled') throw new LoginSessionError('cancelled');\n if (session.state === 'polling' || session.state === 'exchanging') {\n session.state = session.controller.signal.aborted ? 'cancelled' : 'failed';\n session.errorCode = session.controller.signal.aborted ? 'cancelled' : 'login_failed';\n if (session.state === 'failed') throw new LoginSessionError('failed');\n }\n throw error;\n }\n }\n\n async completePkce<TResult = unknown>(id: string, callbackUrl: string, commit?: LoginCommit<TResult>): Promise<{ token: CodexTokenSet; accountRef?: string; result?: TResult }> {\n const session = this.claim(id, 'pkce');\n try {\n if (typeof callbackUrl !== 'string' || callbackUrl.length > 4096) throw new LoginSessionError('invalid_input');\n const callback = parseCodexCallbackUrl(callbackUrl, { expectedState: session.stateValue as string, issuedAt: session.issuedAt, now: this.now(), ttlMs: CODEX_CALLBACK_TTL_MS });\n if (!callback.code) throw new LoginSessionError('cancelled');\n const token = await exchangeCodexCode(callback.code, session.codeVerifier as string, safeOptions(this.deps, session.controller.signal));\n return await this.finish(session, token, commit);\n } catch (error) {\n if (session.controller.signal.aborted && session.state === 'cancelled') throw new LoginSessionError('cancelled');\n if (session.state === 'exchanging') {\n session.state = session.controller.signal.aborted ? 'cancelled' : 'failed';\n session.errorCode = session.controller.signal.aborted ? 'cancelled' : 'login_failed';\n if (session.state === 'failed') throw new LoginSessionError('failed');\n }\n throw error;\n }\n }\n\n async completeSiwc<TResult = unknown>(id: string, callbackUrl: string, commit?: LoginCommit<TResult>): Promise<{ token: CodexTokenSet; accountRef?: string; result?: TResult }> {\n const session = this.claim(id, 'siwc');\n try {\n const callback = parseSiwcCallbackUrl(callbackUrl, { expectedState: session.stateValue as string, expectedClientId: session.clientId, issuedAt: session.issuedAt, now: this.now() });\n const token = await exchangeSiwcCode(callback.code, session.codeVerifier as string, callback.clientId, session.nonce as string, safeOptions(this.deps, session.controller.signal));\n return await this.finish(session, token, commit);\n } catch (error) {\n if (session.controller.signal.aborted && session.state === 'cancelled') throw new LoginSessionError('cancelled');\n if (session.state === 'exchanging') {\n session.state = session.controller.signal.aborted ? 'cancelled' : 'failed';\n session.errorCode = session.controller.signal.aborted ? 'cancelled' : 'login_failed';\n if (session.state === 'failed') throw new LoginSessionError('failed');\n }\n throw error;\n }\n }\n\n cancel(id: string): boolean {\n const session = this.get(id);\n if (session.state === 'success' || session.state === 'cancelled' || session.state === 'failed' || session.state === 'committing') return false;\n session.state = 'cancelled';\n session.controller.abort('cancelled');\n return true;\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n this.hostSignal.removeEventListener('abort', this.onHostAbort);\n for (const session of this.sessions.values()) {\n if (session.state !== 'committing') session.state = 'cancelled';\n if (session.state !== 'committing') session.controller.abort('disposed');\n session.unlinkHost();\n clearTimeout(session.expiryTimer);\n }\n for (const [id, session] of this.sessions) if (session.state !== 'committing') this.remove(id);\n }\n}\n",
|
|
17
18
|
"import type { CredentialLease } from '../../../packages/core/src/plugin-control/contracts';\nimport type { FetchLike } from './oauth';\n\nexport const USAGE_PATH = '/backend-api/wham/usage';\nexport const RESET_CREDITS_PATH = '/backend-api/wham/rate-limit-reset-credits';\nexport const CONSUME_RESET_CREDITS_PATH = '/backend-api/wham/rate-limit-reset-credits/consume';\nexport const USAGE_ORIGIN = 'https://chatgpt.com';\nexport const USAGE_ACCEPT = 'application/json';\n\nconst MAX_USAGE_BODY_BYTES = 256 * 1024;\nconst MAX_CONSUME_BODY_BYTES = 64 * 1024;\nconst MAX_TEXT_BYTES = 512;\nconst MAX_CREDITS = 256;\nconst CACHE_TTL_MS = 30_000;\nconst DEFAULT_TIMEOUT_MS = 15_000;\n\nexport type ResourceState = 'fresh' | 'stale' | 'unavailable';\nexport type SafeUsageErrorCode =\n | 'timeout' | 'cancelled' | 'rate_limited' | 'upstream_forbidden'\n | 'upstream_unavailable' | 'invalid_response';\n\nexport interface UsageWindow {\n readonly usedPercent: number;\n readonly windowSeconds: number;\n readonly resetAfterSeconds: number;\n readonly resetAt: number;\n}\n\nexport interface UsageSummary {\n readonly state: ResourceState;\n readonly planType?: string;\n readonly allowed?: boolean;\n readonly limitReached?: boolean;\n readonly availableCount?: number;\n readonly primary?: UsageWindow;\n readonly secondary?: UsageWindow;\n readonly error?: UsageErrorBody;\n}\n\nexport interface ResetCredit {\n readonly id: string;\n readonly resetType: string;\n readonly status: 'available' | 'redeeming' | 'redeemed' | 'unknown';\n readonly grantedAt: number;\n readonly title?: string;\n readonly description?: string;\n readonly createdAt?: number;\n readonly expiresAt?: number;\n readonly redeemedAt?: number;\n}\n\nexport interface ResetCreditsSummary {\n readonly state: ResourceState;\n readonly availableCount?: number;\n readonly credits?: readonly ResetCredit[];\n readonly error?: UsageErrorBody;\n}\n\nexport interface UsageResult {\n readonly usage: UsageSummary;\n readonly resetCredits: ResetCreditsSummary;\n}\n\nexport type ResetOutcome = 'reset' | 'nothing_to_reset' | 'no_credit' | 'already_redeemed' | 'reset_outcome_unknown';\n\nexport interface ResetResult {\n readonly outcome: ResetOutcome;\n readonly windowsReset: number;\n readonly usage?: UsageResult;\n}\n\nexport interface UsageErrorBody {\n readonly code: SafeUsageErrorCode;\n readonly retryAfterSeconds?: number;\n}\n\nexport class UsageError extends Error {\n readonly name = 'UsageError';\n constructor(readonly code: SafeUsageErrorCode | 'reauth_required' | 'disposed' | 'reset_in_progress' | 'credits_unavailable' | 'credit_unavailable' | 'stale_generation' | 'cancelled') {\n super(code);\n }\n}\n\ninterface UsageDependencies {\n readonly fetchImpl?: FetchLike;\n readonly now?: () => number;\n readonly timeoutMs?: number;\n readonly hostSignal: AbortSignal;\n readonly credential: (accountRef: string, signal: AbortSignal) => Promise<CredentialLease>;\n readonly rejectAccess: (accountRef: string, version: number) => Promise<boolean>;\n}\n\ninterface ParsedResponse<T> {\n readonly value: T;\n readonly retryAfterSeconds?: number;\n}\n\nclass UpstreamError extends Error {\n constructor(readonly code: SafeUsageErrorCode, readonly retryAfterSeconds?: number) { super(code); }\n}\n\ninterface StoredSection<T> {\n readonly value?: T;\n readonly at?: number;\n readonly state: ResourceState;\n readonly error?: UsageErrorBody;\n}\n\ninterface CacheEntry {\n readonly generation: number;\n readonly usage: StoredSection<Omit<UsageSummary, 'state' | 'error'>>;\n readonly resetCredits: StoredSection<Omit<ResetCreditsSummary, 'state' | 'error'>>;\n}\n\ninterface GetOperation {\n readonly generation: number;\n readonly promise: Promise<UsageResult>;\n readonly controller: AbortController;\n}\n\ninterface ResetOperation {\n readonly key: string;\n readonly promise: Promise<ResetResult>;\n}\n\nfunction object(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new UpstreamError('invalid_response');\n return value as Record<string, unknown>;\n}\n\nfunction boundedString(value: unknown): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > MAX_TEXT_BYTES || /[\\u0000-\\u001f\\u007f]/.test(value)) {\n throw new UpstreamError('invalid_response');\n }\n return value;\n}\n\nfunction finiteNumber(value: unknown): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) throw new UpstreamError('invalid_response');\n return value;\n}\n\nfunction nonNegativeInteger(value: unknown, max = MAX_CREDITS): number {\n const number = finiteNumber(value);\n if (!Number.isSafeInteger(number) || number < 0 || number > max) throw new UpstreamError('invalid_response');\n return number;\n}\n\nfunction bool(value: unknown): boolean {\n if (typeof value !== 'boolean') throw new UpstreamError('invalid_response');\n return value;\n}\n\nfunction epochMs(value: unknown): number {\n const parsed = typeof value === 'number'\n ? value < 1_000_000_000_000 ? value * 1000 : value\n : typeof value === 'string' ? Date.parse(value) : NaN;\n if (!Number.isFinite(parsed) || parsed < 0 || parsed > 8_640_000_000_000_000) throw new UpstreamError('invalid_response');\n return parsed;\n}\n\nfunction optionalText(value: unknown): string | undefined {\n if (value === undefined || value === null || value === '') return undefined;\n return boundedString(value);\n}\n\nfunction optionalEpochMs(value: unknown): number | undefined {\n return value === undefined || value === null ? undefined : epochMs(value);\n}\n\nfunction safeRetryAfter(value: string | null, now: number): number | undefined {\n if (value === null || value.trim() !== value || value.length === 0) return undefined;\n const seconds = /^\\d+(?:\\.\\d+)?$/.test(value) ? Number(value) : (Date.parse(value) - now) / 1000;\n return Number.isFinite(seconds) && seconds >= 0 && seconds <= Number.MAX_SAFE_INTEGER ? seconds : undefined;\n}\n\nfunction sectionError(error: UpstreamError): UsageErrorBody {\n return error.retryAfterSeconds === undefined\n ? { code: error.code }\n : { code: error.code, retryAfterSeconds: error.retryAfterSeconds };\n}\n\nfunction cancelBody(response: Response): void {\n try { void response.body?.cancel().catch(() => undefined); } catch { /* body may already be locked or closed */ }\n}\n\nfunction parseWindow(value: unknown, now: number): UsageWindow {\n const input = object(value);\n const usedPercent = finiteNumber(input.used_percent);\n const windowSeconds = finiteNumber(input.limit_window_seconds ?? input.window_seconds);\n if (usedPercent < 0 || usedPercent > 100 || windowSeconds <= 0) throw new UpstreamError('invalid_response');\n const hasAfter = input.reset_after_seconds !== undefined;\n const hasAt = input.reset_at !== undefined;\n if (!hasAfter && !hasAt) throw new UpstreamError('invalid_response');\n const resetAfterSeconds = hasAfter ? finiteNumber(input.reset_after_seconds) : Math.max(0, (epochMs(input.reset_at) - now) / 1000);\n const resetAt = hasAt ? epochMs(input.reset_at) : now + resetAfterSeconds * 1000;\n if (resetAfterSeconds < 0 || !Number.isFinite(resetAfterSeconds) || !Number.isFinite(resetAt)) throw new UpstreamError('invalid_response');\n return { usedPercent, windowSeconds, resetAfterSeconds, resetAt };\n}\n\nfunction parseUsage(value: unknown, now: number): Omit<UsageSummary, 'state' | 'error'> {\n const input = object(value);\n const rate = input.rate_limit === undefined ? input : object(input.rate_limit);\n const result: { planType?: string; allowed?: boolean; limitReached?: boolean; availableCount?: number; primary?: UsageWindow; secondary?: UsageWindow } = {};\n if (input.plan_type !== undefined) result.planType = boundedString(input.plan_type);\n if (input.allowed !== undefined) result.allowed = bool(input.allowed);\n else if (rate.allowed !== undefined) result.allowed = bool(rate.allowed);\n if (input.limit_reached !== undefined) result.limitReached = bool(input.limit_reached);\n else if (rate.limit_reached !== undefined) result.limitReached = bool(rate.limit_reached);\n if (input.rate_limit_reset_credits !== undefined && input.rate_limit_reset_credits !== null) {\n const resetCredits = object(input.rate_limit_reset_credits);\n result.availableCount = nonNegativeInteger(resetCredits.available_count);\n }\n if (rate.primary_window !== undefined && rate.primary_window !== null) result.primary = parseWindow(rate.primary_window, now);\n if (rate.secondary_window !== undefined && rate.secondary_window !== null) result.secondary = parseWindow(rate.secondary_window, now);\n if (result.planType === undefined && result.allowed === undefined && result.limitReached === undefined && result.availableCount === undefined\n && result.primary === undefined && result.secondary === undefined) throw new UpstreamError('invalid_response');\n return result;\n}\n\nfunction parseCredit(value: unknown): ResetCredit {\n const input = object(value);\n const id = boundedString(input.id);\n const resetType = boundedString(input.reset_type);\n const grantedAt = epochMs(input.granted_at);\n const rawStatus = input.status;\n if (rawStatus !== undefined && typeof rawStatus !== 'string') throw new UpstreamError('invalid_response');\n if (rawStatus === undefined) throw new UpstreamError('invalid_response');\n const status = rawStatus === 'available' || rawStatus === 'redeeming' || rawStatus === 'redeemed' ? rawStatus : 'unknown';\n const result: ResetCredit = { id, resetType, status, grantedAt };\n for (const [source, target] of [['title', 'title'], ['description', 'description']] as const) {\n const text = optionalText(input[source]);\n if (text !== undefined) (result as unknown as Record<string, unknown>)[target] = text;\n }\n const expiresAt = optionalEpochMs(input.expires_at);\n if (expiresAt !== undefined) (result as unknown as Record<string, unknown>).expiresAt = expiresAt;\n return result;\n}\n\nfunction parseResetCredits(value: unknown): Omit<ResetCreditsSummary, 'state' | 'error'> {\n const input = object(value);\n const availableCount = nonNegativeInteger(input.available_count);\n if (!Array.isArray(input.credits) || input.credits.length > MAX_CREDITS) throw new UpstreamError('invalid_response');\n const credits = input.credits.map(parseCredit).sort((a, b) => (a.expiresAt ?? Number.MAX_SAFE_INTEGER) - (b.expiresAt ?? Number.MAX_SAFE_INTEGER));\n return { availableCount, credits };\n}\n\nasync function readJson(response: Response, signal: AbortSignal, maxBytes: number): Promise<unknown> {\n if (!response.body) return undefined;\n if (signal.aborted) throw new UsageError(signal.reason === 'timeout' ? 'timeout' : 'cancelled');\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let text = '';\n let total = 0;\n let onAbort!: () => void;\n const abort = new Promise<never>((_, reject) => {\n onAbort = () => reject(new UsageError(signal.reason === 'timeout' ? 'timeout' : 'cancelled'));\n signal.addEventListener('abort', onAbort, { once: true });\n });\n try {\n for (;;) {\n const next = await Promise.race([reader.read(), abort]);\n if (next.done) break;\n total += next.value.byteLength;\n if (total > maxBytes) throw new UpstreamError('invalid_response');\n text += decoder.decode(next.value, { stream: true });\n }\n text += decoder.decode();\n } catch (error) {\n void reader.cancel().catch(() => undefined);\n throw error;\n } finally {\n signal.removeEventListener('abort', onAbort);\n reader.releaseLock();\n }\n try { return JSON.parse(text); }\n catch { throw new UpstreamError('invalid_response'); }\n}\n\nfunction waitFor<T>(promise: Promise<T>, signal: AbortSignal, hostSignal: AbortSignal): Promise<T> {\n if (hostSignal.aborted) return Promise.reject(new UsageError('disposed'));\n if (signal.aborted) return Promise.reject(new UsageError('cancelled'));\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n const cleanup = () => { signal.removeEventListener('abort', onCancel); hostSignal.removeEventListener('abort', onDispose); };\n const onCancel = () => { if (!settled) { settled = true; cleanup(); reject(new UsageError('cancelled')); } };\n const onDispose = () => { if (!settled) { settled = true; cleanup(); reject(new UsageError('disposed')); } };\n signal.addEventListener('abort', onCancel, { once: true });\n hostSignal.addEventListener('abort', onDispose, { once: true });\n promise.then((value) => { if (!settled) { settled = true; cleanup(); resolve(value); } }, (error) => { if (!settled) { settled = true; cleanup(); reject(error); } });\n });\n}\n\nexport class UsageService {\n private readonly fetchImpl: FetchLike;\n private readonly now: () => number;\n private readonly timeoutMs: number;\n private readonly cache = new Map<string, CacheEntry>();\n private readonly gets = new Map<string, GetOperation>();\n private readonly resets = new Map<string, ResetOperation>();\n private readonly unknownReset = new Map<string, string>();\n private readonly epochs = new Map<string, number>();\n private readonly getControllers = new Map<string, AbortController>();\n private readonly hostAbortListener = () => this.dispose();\n\n constructor(private readonly deps: UsageDependencies) {\n this.fetchImpl = deps.fetchImpl ?? fetch;\n this.now = deps.now ?? Date.now;\n this.timeoutMs = Math.max(1, deps.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n if (deps.hostSignal.aborted) this.dispose();\n else deps.hostSignal.addEventListener('abort', this.hostAbortListener, { once: true });\n }\n\n private epoch(accountRef: string): number { return this.epochs.get(accountRef) ?? 0; }\n\n private operationKey(accountRef: string, generation: number): string { return `${accountRef}\\u0000${generation}`; }\n\n private invalidate(accountRef: string, abortGet = true): void {\n this.epochs.set(accountRef, this.epoch(accountRef) + 1);\n this.cache.delete(accountRef);\n for (const key of this.gets.keys()) {\n if (!key.startsWith(`${accountRef}\\u0000`)) continue;\n if (abortGet) this.getControllers.get(key)?.abort('invalidated');\n this.getControllers.delete(key);\n this.gets.delete(key);\n }\n }\n\n invalidateAccount(accountRef: string): void { this.invalidate(accountRef); }\n\n private async requestJson(\n url: string,\n lease: CredentialLease,\n operationSignal: AbortSignal,\n method: 'GET' | 'POST',\n body?: Record<string, string>,\n ): Promise<ParsedResponse<unknown>> {\n if (operationSignal.aborted) throw new UsageError(this.deps.hostSignal.aborted ? 'disposed' : 'cancelled');\n const controller = new AbortController();\n let timedOut = false;\n let abortReject!: (error: UsageError) => void;\n const aborted = new Promise<never>((_, reject) => { abortReject = reject; });\n const onAbort = () => {\n controller.abort(operationSignal.reason);\n abortReject(new UsageError(this.deps.hostSignal.aborted ? 'disposed' : 'cancelled'));\n };\n operationSignal.addEventListener('abort', onAbort, { once: true });\n let timeoutReject!: (error: UpstreamError) => void;\n const timeout = new Promise<never>((_, reject) => { timeoutReject = reject; });\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort('timeout');\n timeoutReject(new UpstreamError('timeout'));\n }, this.timeoutMs);\n try {\n const headers: Record<string, string> = {\n Authorization: lease.headers.Authorization,\n 'ChatGPT-Account-Id': lease.headers['Chatgpt-Account-Id'],\n 'OpenAI-Beta': 'codex-1',\n 'OAI-Language': 'zh-CN',\n Originator: 'Codex Desktop',\n Accept: USAGE_ACCEPT,\n 'Sec-Fetch-Site': 'none',\n 'Sec-Fetch-Mode': 'no-cors',\n 'Sec-Fetch-Dest': 'empty',\n Priority: 'u=4, i',\n };\n if (method === 'POST') headers['Content-Type'] = 'application/json';\n let response: Response;\n try {\n response = await Promise.race([this.fetchImpl(url, {\n method,\n headers,\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n redirect: 'manual',\n signal: controller.signal,\n }), timeout, aborted]);\n } catch {\n if (timedOut) throw new UpstreamError('timeout');\n if (operationSignal.aborted) throw new UsageError(this.deps.hostSignal.aborted ? 'disposed' : 'cancelled');\n throw new UpstreamError('upstream_unavailable');\n }\n const retryAfterSeconds = response.status === 429 ? safeRetryAfter(response.headers.get('retry-after'), this.now()) : undefined;\n if (response.status < 200 || response.status >= 300 || response.redirected) {\n cancelBody(response);\n if (response.status === 401) throw new UpstreamError('cancelled');\n if (response.status === 403) throw new UpstreamError('upstream_forbidden', retryAfterSeconds);\n if (response.status === 429) throw new UpstreamError('rate_limited', retryAfterSeconds);\n throw new UpstreamError('upstream_unavailable');\n }\n const parsed = await readJson(response, controller.signal, method === 'POST' ? MAX_CONSUME_BODY_BYTES : MAX_USAGE_BODY_BYTES);\n return { value: parsed, retryAfterSeconds };\n } catch (error) {\n if (timedOut && !(error instanceof UsageError)) throw new UpstreamError('timeout');\n throw error;\n } finally {\n clearTimeout(timer);\n operationSignal.removeEventListener('abort', onAbort);\n }\n }\n\n private async rejectOnce(accountRef: string, version: number): Promise<never> {\n this.invalidate(accountRef, false);\n let rejected: boolean;\n try { rejected = await this.deps.rejectAccess(accountRef, version); }\n catch { throw new UsageError('upstream_unavailable'); }\n throw new UsageError(rejected ? 'reauth_required' : 'stale_generation');\n }\n\n private async runGet(accountRef: string, lease: CredentialLease, signal: AbortSignal, operationEpoch: number): Promise<UsageResult> {\n const previous = this.cache.get(accountRef);\n const previousUsable = previous?.generation === lease.version && previous.usage.value !== undefined;\n const previousCreditsUsable = previous?.generation === lease.version && previous.resetCredits.value !== undefined;\n const [usage, credits] = await Promise.allSettled([\n this.requestJson(`${USAGE_ORIGIN}${USAGE_PATH}`, lease, signal, 'GET'),\n this.requestJson(`${USAGE_ORIGIN}${RESET_CREDITS_PATH}`, lease, signal, 'GET'),\n ]);\n if (this.deps.hostSignal.aborted) throw new UsageError('disposed');\n const unauthorized = [usage, credits].some((item) => item.status === 'rejected' && item.reason instanceof UpstreamError && item.reason.code === 'cancelled');\n if (unauthorized) return this.rejectOnce(accountRef, lease.version);\n let usageError = usage.status === 'rejected' ? usage.reason : undefined;\n let creditsError = credits.status === 'rejected' ? credits.reason : undefined;\n let usageValue: Omit<UsageSummary, 'state' | 'error'> | undefined;\n let creditsValue: Omit<ResetCreditsSummary, 'state' | 'error'> | undefined;\n let usageParseError: UpstreamError | undefined;\n let creditsParseError: UpstreamError | undefined;\n if (usage.status === 'fulfilled') {\n try { usageValue = parseUsage(usage.value.value, this.now()); }\n catch (error) { usageParseError = error instanceof UpstreamError ? error : new UpstreamError('invalid_response'); }\n }\n if (credits.status === 'fulfilled') {\n try { creditsValue = parseResetCredits(credits.value.value); }\n catch (error) { creditsParseError = error instanceof UpstreamError ? error : new UpstreamError('invalid_response'); }\n }\n if (usageParseError !== undefined) usageError = usageParseError;\n if (creditsParseError !== undefined) creditsError = creditsParseError;\n const usageFailure = usageError instanceof UpstreamError ? sectionError(usageError) : usageError instanceof UsageError ? { code: usageError.code === 'timeout' ? 'timeout' : 'cancelled' } as UsageErrorBody : { code: 'invalid_response' as const };\n const creditsFailure = creditsError instanceof UpstreamError ? sectionError(creditsError) : creditsError instanceof UsageError ? { code: creditsError.code === 'timeout' ? 'timeout' : 'cancelled' } as UsageErrorBody : { code: 'invalid_response' as const };\n const usageSection: UsageSummary = usageValue !== undefined\n ? { state: 'fresh', ...usageValue }\n : previousUsable && previous?.usage.value !== undefined\n ? { state: 'stale', ...previous.usage.value, error: usageFailure }\n : { state: 'unavailable', error: usageFailure };\n const creditsSection: ResetCreditsSummary = creditsValue !== undefined\n ? { state: 'fresh', ...creditsValue }\n : previousCreditsUsable && previous?.resetCredits.value !== undefined\n ? { state: 'stale', ...previous.resetCredits.value, error: creditsFailure }\n : { state: 'unavailable', error: creditsFailure };\n const result = { usage: usageSection, resetCredits: creditsSection };\n if (this.epoch(accountRef) === operationEpoch && !this.deps.hostSignal.aborted) {\n this.cache.set(accountRef, {\n generation: lease.version,\n usage: usageValue === undefined\n ? { state: usageSection.state, value: previousUsable ? previous?.usage.value : undefined, at: previousUsable ? previous?.usage.at : undefined, error: usageSection.error }\n : { state: 'fresh', value: usageValue, at: this.now() },\n resetCredits: creditsValue === undefined\n ? { state: creditsSection.state, value: previousCreditsUsable ? previous?.resetCredits.value : undefined, at: previousCreditsUsable ? previous?.resetCredits.at : undefined, error: creditsSection.error }\n : { state: 'fresh', value: creditsValue, at: this.now() },\n });\n }\n return result;\n }\n\n async get(accountRef: string, signal: AbortSignal, options: { forceFresh?: boolean; retry?: number } = {}): Promise<UsageResult> {\n const lease = await waitFor(this.deps.credential(accountRef, signal), signal, this.deps.hostSignal);\n const cached = this.cache.get(accountRef);\n if (!options.forceFresh && cached?.generation === lease.version) {\n const usageValid = cached.usage.state === 'fresh' && cached.usage.at !== undefined && this.now() - cached.usage.at <= CACHE_TTL_MS;\n const creditsValid = cached.resetCredits.state === 'fresh' && cached.resetCredits.at !== undefined && this.now() - cached.resetCredits.at <= CACHE_TTL_MS;\n if (usageValid && creditsValid) {\n return {\n usage: cached.usage.value === undefined ? { state: cached.usage.state, error: cached.usage.error } : { state: cached.usage.state, ...cached.usage.value, ...(cached.usage.error ? { error: cached.usage.error } : {}) },\n resetCredits: cached.resetCredits.value === undefined ? { state: cached.resetCredits.state, error: cached.resetCredits.error } : { state: cached.resetCredits.state, ...cached.resetCredits.value, ...(cached.resetCredits.error ? { error: cached.resetCredits.error } : {}) },\n };\n }\n }\n const operationKey = this.operationKey(accountRef, lease.version);\n let operation = this.gets.get(operationKey);\n if (operation === undefined) {\n const controller = new AbortController();\n this.getControllers.set(operationKey, controller);\n const epoch = this.epoch(accountRef);\n const promise = this.runGet(accountRef, lease, controller.signal, epoch).finally(() => {\n if (this.gets.get(operationKey)?.promise === promise) this.gets.delete(operationKey);\n if (this.getControllers.get(operationKey) === controller) this.getControllers.delete(operationKey);\n });\n operation = { generation: lease.version, controller, promise };\n this.gets.set(operationKey, operation);\n }\n const result = await waitFor(operation.promise, signal, this.deps.hostSignal);\n const latest = await waitFor(this.deps.credential(accountRef, signal), signal, this.deps.hostSignal);\n if (latest.version !== lease.version) {\n this.invalidate(accountRef);\n if ((options.retry ?? 0) >= 2) throw new UsageError('stale_generation');\n return this.get(accountRef, signal, { forceFresh: true, retry: (options.retry ?? 0) + 1 });\n }\n return result;\n }\n\n private resetKey(redeemRequestId: string, creditId: string): string { return `${redeemRequestId}\\u0000${creditId}`; }\n\n restorePendingReset(accountRef: string, redeemRequestId: string, creditId: string): void {\n this.unknownReset.set(accountRef, this.resetKey(redeemRequestId, creditId));\n }\n\n private async runReset(accountRef: string, lease: CredentialLease, key: string, body: Record<string, string>): Promise<ResetResult> {\n let outcome: ResetOutcome;\n let windowsReset = 0;\n try {\n const response = await this.requestJson(`${USAGE_ORIGIN}${CONSUME_RESET_CREDITS_PATH}`, lease, this.deps.hostSignal, 'POST', body);\n const input = object(response.value);\n const code = input.code;\n if (input.windows_reset !== undefined && input.windows_reset !== null) windowsReset = nonNegativeInteger(input.windows_reset, Number.MAX_SAFE_INTEGER);\n outcome = code === 'reset' ? 'reset'\n : code === 'already_redeemed' ? 'already_redeemed'\n : code === 'nothing_to_reset' ? 'nothing_to_reset'\n : code === 'no_credit' ? 'no_credit'\n : 'reset_outcome_unknown';\n } catch (error) {\n if (error instanceof UpstreamError && error.code === 'cancelled') await this.rejectOnce(accountRef, lease.version);\n outcome = 'reset_outcome_unknown';\n }\n this.invalidate(accountRef);\n if (outcome === 'reset_outcome_unknown') this.unknownReset.set(accountRef, key);\n else this.unknownReset.delete(accountRef);\n let usage: UsageResult | undefined;\n try { usage = await this.get(accountRef, this.deps.hostSignal, { forceFresh: true }); }\n catch { /* consume outcome is authoritative; the refresh is best effort and host-owned */ }\n return { outcome, windowsReset, ...(usage === undefined ? {} : { usage }) };\n }\n\n async consume(\n accountRef: string,\n redeemRequestId: string,\n creditId: string,\n signal: AbortSignal,\n options: { canConsume?: (credit: ResetCredit) => Promise<boolean>; beforeConsume?: (credit: ResetCredit) => Promise<void> } = {},\n ): Promise<ResetResult> {\n const key = this.resetKey(redeemRequestId, creditId);\n const active = this.resets.get(accountRef);\n if (active !== undefined) {\n if (active.key !== key) throw new UsageError('reset_in_progress');\n return waitFor(active.promise, signal, this.deps.hostSignal);\n }\n const blocked = this.unknownReset.get(accountRef);\n if (blocked !== undefined && blocked !== key) throw new UsageError('reset_in_progress');\n const retryingUnknown = blocked === key;\n let resolveOperation!: (result: ResetResult) => void;\n let rejectOperation!: (error: unknown) => void;\n const promise = new Promise<ResetResult>((resolve, reject) => { resolveOperation = resolve; rejectOperation = reject; });\n this.resets.set(accountRef, { key, promise });\n void (async () => {\n try {\n let lease: CredentialLease;\n if (retryingUnknown) {\n lease = await this.deps.credential(accountRef, this.deps.hostSignal);\n } else {\n const current = await this.get(accountRef, this.deps.hostSignal, { forceFresh: true });\n if (current.resetCredits.state !== 'fresh' || current.resetCredits.availableCount === undefined) throw new UsageError('credits_unavailable');\n const selected = current.resetCredits.credits?.find((item) => item.id === creditId);\n if (current.resetCredits.availableCount <= 0 || selected?.status !== 'available') throw new UsageError('credit_unavailable');\n lease = await this.deps.credential(accountRef, this.deps.hostSignal);\n if (options.canConsume && !(await options.canConsume(selected))) throw new UsageError('credit_unavailable');\n await options.beforeConsume?.(selected);\n }\n this.invalidate(accountRef);\n resolveOperation(await this.runReset(accountRef, lease, key, { redeem_request_id: redeemRequestId, credit_id: creditId }));\n } catch (error) {\n rejectOperation(error);\n } finally {\n if (this.resets.get(accountRef)?.promise === promise) this.resets.delete(accountRef);\n }\n })();\n return waitFor(promise, signal, this.deps.hostSignal);\n }\n\n dispose(): void {\n this.deps.hostSignal.removeEventListener('abort', this.hostAbortListener);\n for (const controller of this.getControllers.values()) controller.abort('disposed');\n this.getControllers.clear();\n this.gets.clear();\n this.cache.clear();\n this.resets.clear();\n this.unknownReset.clear();\n }\n}\n",
|
|
18
19
|
"import { accountListItem, type AccountStore } from './accounts';\nimport { UsageError, type UsageService, type ResetCredit } from './usage';\n\nexport const AUTO_RESET_LEAD_MS = 30 * 60 * 1000;\nexport const AUTO_RESET_INTERVAL_MS = 5 * 60 * 1000;\nconst MAX_TIMER_DELAY_MS = 2_147_483_647;\n\ninterface AccountPlan {\n credits: ResetCredit[];\n handle?: unknown;\n}\n\n/** Injectable timer keeps simulations independent of wall-clock time and real services. */\nexport interface AutoResetTimer {\n schedule(callback: () => Promise<void>, delayMs: number): unknown;\n cancel(handle: unknown): void;\n}\n\nconst defaultTimer: AutoResetTimer = {\n schedule: (callback, delay) => {\n const timer = setTimeout(() => { void callback(); }, delay);\n timer.unref?.();\n return timer;\n },\n cancel: handle => clearTimeout(handle as ReturnType<typeof setTimeout>),\n};\n\nexport function isAutoResetDue(credit: ResetCredit, now: number): boolean {\n return credit.status === 'available' && typeof credit.expiresAt === 'number' && Number.isFinite(credit.expiresAt)\n && credit.expiresAt > now && credit.expiresAt - now <= AUTO_RESET_LEAD_MS;\n}\n\n/** One host-owned loop, independent of browser tabs, requests and worker instances. */\nexport class AutoResetScheduler {\n private handle: unknown;\n private started = false;\n private disposed = false;\n private running?: Promise<void>;\n private readonly plans = new Map<string, AccountPlan>();\n private readonly accountRuns = new Map<string, Promise<void>>();\n\n constructor(\n private readonly accounts: AccountStore,\n private readonly usage: UsageService,\n private readonly signal: AbortSignal,\n private readonly now: () => number = Date.now,\n private readonly timer: AutoResetTimer = defaultTimer,\n ) {}\n\n start(): void {\n if (this.started || this.disposed || this.signal.aborted) return;\n this.started = true;\n this.schedule(0);\n }\n\n private schedule(delay: number): void {\n if (!this.started || this.disposed || this.signal.aborted) return;\n this.handle = this.timer.schedule(async () => {\n try { await this.runOnce(); }\n catch { /* Store failures stop this scan; retry discovery on the next scan, never a pending POST. */ }\n finally { this.schedule(AUTO_RESET_INTERVAL_MS); }\n }, delay);\n }\n\n runOnce(): Promise<void> {\n if (this.disposed || this.signal.aborted) return Promise.resolve();\n if (!this.running) this.running = this.scan().finally(() => { this.running = undefined; });\n return this.running;\n }\n\n private async scan(): Promise<void> {\n const accounts = await this.accounts.list();\n const eligible = new Set(accounts.filter(account => account.available && account.autoResetCredits\n && (!account.pendingAutoReset || this.accountRuns.has(account.id))).map(account => account.id));\n for (const id of this.plans.keys()) if (!eligible.has(id)) this.cancelPlan(id);\n for (const account of accounts) {\n if (this.disposed || this.signal.aborted) return;\n if (!eligible.has(account.id)) continue;\n // An owned redemption will arm its remaining credits when it finishes. Discovery must not cancel that plan.\n if (this.accountRuns.has(account.id)) continue;\n try {\n const snapshot = await this.usage.get(account.id, this.signal, { forceFresh: true });\n if (this.disposed || this.signal.aborted) return;\n // Keep a known deadline on a failed discovery; consumption still requires its own fresh validation.\n if (snapshot.resetCredits.state !== 'fresh') continue;\n this.cancelPlan(account.id);\n if ((snapshot.resetCredits.availableCount ?? 0) <= 0) continue;\n const credits = [...(snapshot.resetCredits.credits ?? [])].filter(credit => credit.status === 'available'\n && typeof credit.expiresAt === 'number' && Number.isFinite(credit.expiresAt) && credit.expiresAt > this.now())\n .sort((a, b) => a.expiresAt! - b.expiresAt!);\n const plan: AccountPlan = { credits };\n this.plans.set(account.id, plan);\n await this.executePlan(account.id, plan);\n } catch { /* Keep known deadlines; one unavailable account must not stop other accounts. */ }\n }\n }\n\n private cancelPlan(accountRef: string, expected?: AccountPlan): void {\n const plan = this.plans.get(accountRef);\n if (expected && plan !== expected) return;\n if (plan?.handle !== undefined) this.timer.cancel(plan.handle);\n this.plans.delete(accountRef);\n }\n\n private armPlan(accountRef: string, plan: AccountPlan): void {\n if (this.disposed || this.signal.aborted || this.plans.get(accountRef) !== plan) return;\n if (plan.credits.length === 0) { this.cancelPlan(accountRef); return; }\n const dueAt = plan.credits[0].expiresAt! - AUTO_RESET_LEAD_MS;\n // Cap long delays: native timers overflow beyond roughly 24 days.\n plan.handle = this.timer.schedule(() => this.executePlan(accountRef, plan), Math.min(MAX_TIMER_DELAY_MS, Math.max(0, dueAt - this.now())));\n }\n\n private executePlan(accountRef: string, plan: AccountPlan): Promise<void> {\n // Discovery and a deadline may overlap; serialize only this account, preserving the durable CAS fence.\n const previous = this.accountRuns.get(accountRef) ?? Promise.resolve();\n const operation = previous.catch(() => undefined).then(async () => {\n if (this.disposed || this.signal.aborted || this.plans.get(accountRef) !== plan) return;\n try {\n const account = accountListItem(await this.accounts.get(accountRef));\n if (!account.available || !account.autoResetCredits || account.pendingAutoReset) { this.cancelPlan(accountRef, plan); return; }\n while (this.plans.get(accountRef) === plan && plan.credits.length > 0) {\n if (this.disposed || this.signal.aborted) return;\n const credit = plan.credits[0];\n if (credit.expiresAt! - AUTO_RESET_LEAD_MS > this.now()) break;\n plan.credits.shift();\n if (!isAutoResetDue(credit, this.now())) continue;\n const attempt = await this.accounts.claimAutoReset(accountRef, credit, this.now());\n if (!attempt) continue;\n let deferred: ResetCredit | undefined;\n try {\n const result = await this.usage.consume(accountRef, attempt.redeemRequestId, credit.id, this.signal, {\n canConsume: async selected => {\n const latest = await this.accounts.get(accountRef);\n if (this.disposed || this.signal.aborted || latest.autoResetCredits !== true || latest.status !== 'active') return false;\n if (selected.status === 'available' && typeof selected.expiresAt === 'number' && Number.isFinite(selected.expiresAt)\n && selected.expiresAt - AUTO_RESET_LEAD_MS > this.now()) deferred = selected;\n return isAutoResetDue(selected, this.now());\n },\n });\n if (result.outcome === 'reset_outcome_unknown') { this.cancelPlan(accountRef, plan); return; }\n await this.accounts.finishAutoReset(accountRef, attempt.redeemRequestId);\n } catch (error) {\n // These errors occur before this request's POST. All other failures remain pending across restarts.\n if (error instanceof UsageError && ['credits_unavailable', 'credit_unavailable', 'reset_in_progress'].includes(error.code)) {\n await this.accounts.finishAutoReset(accountRef, attempt.redeemRequestId, true);\n if (error.code === 'credit_unavailable') {\n if (deferred) {\n plan.credits.push(deferred);\n plan.credits.sort((a, b) => a.expiresAt! - b.expiresAt!);\n }\n continue;\n }\n }\n this.cancelPlan(accountRef, plan);\n return;\n }\n }\n this.armPlan(accountRef, plan);\n } catch { this.cancelPlan(accountRef, plan); }\n }).finally(() => {\n if (this.accountRuns.get(accountRef) === operation) this.accountRuns.delete(accountRef);\n });\n this.accountRuns.set(accountRef, operation);\n return operation;\n }\n\n dispose(): void {\n this.started = false;\n this.disposed = true;\n this.timer.cancel(this.handle);\n for (const id of this.plans.keys()) this.cancelPlan(id);\n }\n}\n"
|
|
19
20
|
],
|
|
20
|
-
"mappings": ";;AAsBA;;;ACPA;AAwGO,IAAM,qBAAqB,KAAK;AAEhC,IAAM,yBAAyB,MAAM;AAE5C,IAAM,iBAAiB;AACvB,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AAC3B,IAAM,kBAAkB;AACxB,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AACxB,IAAM,oBAAoB,IAAI,IAAoB,CAAC,aAAa,cAAc,cAAc,WAAW,SAAS,CAAC;AACjH,IAAM,4BAA4B,IAAI,IAA6B,CAAC,qBAAqB,qBAAqB,MAAM,CAAC;AACrH,IAAM,0BAA0B,IAAI,IAAI,CAAC,iBAAiB,qBAAqB,cAAc,gBAAgB,CAAC;AAC9G,IAAM,gBAAgB,CAAC,MAAM,WAAW,SAAS;AACjD,IAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAAA;AAKO,MAAM,yBAAyB,MAAM;AAAA,EAI/B;AAAA,EAHF,OAAO;AAAA,EAEhB,WAAW,CACA,MACT,SACA;AAAA,IACA,MAAM,OAAO;AAAA,IAHJ;AAAA;AAKb;AAGA,SAAS,QAAQ,CAAC,UAAyB;AAAA,EACzC,MAAM,IAAI,iBAAiB,gBAAgB,mBAAmB,UAAU;AAAA;AAG1E,SAAS,QAAQ,GAAU;AAAA,EACzB,MAAM,IAAI,iBAAiB,cAAc,+CAA+C;AAAA;AAG1F,SAAS,YAAY,CAAC,QAAuB;AAAA,EAC3C,MAAM,IAAI,iBAAiB,oBAAoB,qBAAqB,QAAQ;AAAA;AAG9E,SAAS,aAAa,CAAC,OAAkD;AAAA,EACvE,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK;AAAA,IAAG,OAAO;AAAA,EAChF,IAAI,QAAQ,KAAK;AAAA,IAAG,OAAO;AAAA,EAC3B,MAAM,YAAY,OAAO,eAAe,KAAK;AAAA,EAC7C,OAAO,cAAc,OAAO,aAAa,cAAc;AAAA;AAGzD,SAAS,qBAAqB,CAAC,OAAiC;AAAA,EAC9D,OAAO,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,QAAQ;AAAA;AAG7E,SAAS,wBAAwB,CAAC,OAAiC;AAAA,EACjE,OAAO,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,SAAS;AAAA;AAG9E,SAAS,gBAAgB,CAAC,OAAwB;AAAA,EAChD,SAAS,QAAQ,EAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;AAAA,IACpD,MAAM,OAAO,MAAM,WAAW,KAAK;AAAA,IACnC,IAAI,QAAQ,SAAU,QAAQ,OAAQ;AAAA,MACpC,IAAI,QAAQ,KAAK,MAAM;AAAA,QAAQ,OAAO;AAAA,MACtC,MAAM,OAAO,MAAM,WAAW,QAAQ,CAAC;AAAA,MACvC,IAAI,OAAO,SAAU,OAAO;AAAA,QAAQ,OAAO;AAAA,MAC3C,SAAS;AAAA,IACX,EAAO,SAAI,QAAQ,SAAU,QAAQ,OAAQ;AAAA,MAC3C,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,YAAY,CAAC,KAAa,QAAyB;AAAA,EAC1D,IAAI,CAAC,mBAAmB,KAAK,GAAG;AAAA,IAAG,OAAO;AAAA,EAC1C,MAAM,QAAQ,OAAO,GAAG;AAAA,EACxB,OAAO,OAAO,cAAc,KAAK,KAAK,SAAS,KAAK,QAAQ;AAAA;AAG9D,SAAS,eAAe,CAAC,OAAgC,SAA4B,UAAwB;AAAA,EAC3G,WAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AAAA,IACpC,IAAI,CAAC,QAAQ,SAAS,GAAG;AAAA,MAAG,aAAa,WAAW,gBAAgB;AAAA,EACtE;AAAA;AAaF,SAAS,KAAK,CAAC,QAAwB,OAAqB;AAAA,EAC1D,OAAO,QAAQ;AAAA,EACf,IAAI,OAAO,OAAO;AAAA,IAAG,SAAS;AAAA;AAUhC,SAAS,QAAQ,CAAC,OAAgB,OAAe,WAAwB,QAAiC;AAAA,EACxG,IAAI,UAAU,MAAM;AAAA,IAClB,MAAM,QAAQ,CAAC;AAAA,IACf,OAAO;AAAA,EACT;AAAA,EACA,IAAI,OAAO,UAAU,WAAW;AAAA,IAC9B,MAAM,QAAQ,QAAQ,IAAI,CAAC;AAAA,IAC3B,OAAO;AAAA,EACT;AAAA,EACA,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,IAAI,iBAAiB,KAAK;AAAA,MAAG,SAAS,QAAQ;AAAA,IAC9C,MAAM,QAAQ,OAAO,WAAW,OAAO,MAAM,IAAI,CAAC;AAAA,IAClD,OAAO;AAAA,EACT;AAAA,EACA,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,IAAI,CAAC,OAAO,SAAS,KAAK;AAAA,MAAG,SAAS,QAAQ;AAAA,IAC9C,MAAM,QAAQ,CAAC;AAAA,IACf,OAAO;AAAA,EACT;AAAA,EACA,IAAI,OAAO,UAAU;AAAA,IAAU,SAAS,MAAM;AAAA,EAC9C,MAAM,SAAS;AAAA,EACf,IAAI,QAAQ,MAAM;AAAA,IAAG,SAAS,MAAM;AAAA,EACpC,IAAI,UAAU,IAAI,MAAM;AAAA,IAAG,SAAS,MAAM;AAAA,EAC1C,MAAM,YAAY,QAAQ;AAAA,EAC1B,IAAI,YAAY;AAAA,IAAgB,SAAS,MAAM;AAAA,EAC/C,IAAI,MAAM,QAAQ,MAAM,GAAG;AAAA,IACzB,IAAI,OAAO,eAAe,MAAM,MAAM,MAAM;AAAA,MAAW,SAAS,OAAO;AAAA,IACvE,MAAM,mBAAmB,OAAO,yBAAyB,QAAQ,QAAQ;AAAA,IACzE,IAAI,CAAC,oBAAoB,EAAE,WAAW,qBAAqB,OAAO,iBAAiB,UAAU,UAAU;AAAA,MACrG,SAAS,OAAO;AAAA,IAClB;AAAA,IACA,MAAM,SAAS,iBAAiB;AAAA,IAChC,IAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS;AAAA,MAAG,SAAS,OAAO;AAAA,IACjE,IAAI,SAAS,OAAO;AAAA,MAAM,SAAS;AAAA,IACnC,MAAM,QAAQ,CAAC;AAAA,IACf,IAAI,SAAS;AAAA,MAAG,MAAM,QAAQ,SAAS,CAAC;AAAA,IACxC,UAAU,IAAI,MAAM;AAAA,IACpB,MAAM,QAAmB,IAAI,MAAM,MAAM;AAAA,IACzC,IAAI,QAAQ;AAAA,IACZ,WAAW,OAAO,QAAQ,QAAQ,MAAM,GAAG;AAAA,MACzC,IAAI,QAAQ;AAAA,QAAU;AAAA,MACtB,IAAI,OAAO,QAAQ,YAAY,CAAC,aAAa,KAAK,MAAM;AAAA,QAAG,SAAS,OAAO;AAAA,MAC3E,MAAM,aAAa,OAAO,yBAAyB,QAAQ,GAAG;AAAA,MAC9D,IAAI,CAAC,cAAc,CAAC,WAAW,cAAc,EAAE,WAAW;AAAA,QAAa,SAAS,OAAO;AAAA,MACvF,MAAM,OAAO,GAAG,KAAK,SAAS,WAAW,OAAO,WAAW,WAAW,MAAM;AAAA,MAC5E,SAAS;AAAA,IACX;AAAA,IACA,IAAI,UAAU;AAAA,MAAQ,SAAS,OAAO;AAAA,IACtC,UAAU,OAAO,MAAM;AAAA,IACvB,OAAO;AAAA,EACT;AAAA,EACA,MAAM,YAAY,OAAO,eAAe,MAAM;AAAA,EAC9C,IAAI,cAAc,OAAO,aAAa,cAAc;AAAA,IAAM,SAAS,QAAQ;AAAA,EAC3E,MAAM,OAAO,QAAQ,QAAQ,MAAM;AAAA,EACnC,IAAI,KAAK,SAAS,OAAO;AAAA,IAAM,SAAS;AAAA,EACxC,MAAM,QAAQ,CAAC;AAAA,EACf,IAAI,KAAK,SAAS;AAAA,IAAG,MAAM,QAAQ,KAAK,SAAS,CAAC;AAAA,EAClD,UAAU,IAAI,MAAM;AAAA,EACpB,MAAM,SAAkC,CAAC;AAAA,EACzC,WAAW,OAAO,MAAM;AAAA,IACtB,IAAI,OAAO,QAAQ;AAAA,MAAU,SAAS,QAAQ;AAAA,IAC9C,IAAI,iBAAiB,GAAG;AAAA,MAAG,SAAS,QAAQ;AAAA,IAC5C,MAAM,aAAa,OAAO,yBAAyB,QAAQ,GAAG;AAAA,IAC9D,IAAI,CAAC,cAAc,CAAC,WAAW,cAAc,EAAE,WAAW;AAAA,MAAa,SAAS,QAAQ;AAAA,IACxF,MAAM,QAAQ,OAAO,WAAW,KAAK,MAAM,IAAI,CAAC;AAAA,IAEhD,OAAO,eAAe,QAAQ,KAAK;AAAA,MACjC,OAAO,SAAS,WAAW,OAAO,WAAW,WAAW,MAAM;AAAA,MAC9D,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EACA,UAAU,OAAO,MAAM;AAAA,EACvB,OAAO;AAAA;AAIT,SAAS,iBAAiB,CAAC,OAAyB;AAAA,EAClD,IAAI;AAAA,IACF,MAAM,OAAO,SAAS,OAAO,GAAG,IAAI,KAAO,EAAE,MAAM,uBAAuB,CAAC;AAAA,IAC3E,IAAI,OAAO,WAAW,KAAK,UAAU,IAAI,GAAG,MAAM,IAAI;AAAA,MAAwB,aAAa,sCAAsC;AAAA,IACjI,OAAO;AAAA,IACP,OAAO,OAAO;AAAA,IACd,IAAI,iBAAiB,qBAAqB,MAAM,SAAS,kBAAkB,MAAM,SAAS,eAAe;AAAA,MACvG,aAAa,sCAAsC;AAAA,IACrD;AAAA,IACA,MAAM;AAAA;AAAA;AAiOV,SAAS,wBAAwB,CAAC,OAAgB,OAAmC;AAAA,EACnF,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,IAAI,CAAC,yBAAyB,KAAK;AAAA,IAAG,aAAa,GAAG,2CAA2C;AAAA,EACjG,OAAO;AAAA;AAGT,SAAS,mBAAmB,CAAC,OAAgB,OAAmC;AAAA,EAC9E,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK;AAAA,IAAG,aAAa,GAAG,+BAA+B;AAAA,EACzG,OAAO;AAAA;AAGT,SAAS,WAAW,CAAC,OAAgB,OAAe,MAAyB;AAAA,EAC3E,IAAI,QAAQ;AAAA,IAAkB,aAAa,kCAAkC;AAAA,EAC7E,IAAI,CAAC,cAAc,KAAK;AAAA,IAAG,aAAa,+BAA+B;AAAA,EACvE,IAAI,KAAK,IAAI,KAAK;AAAA,IAAG,aAAa,gCAAgC;AAAA,EAClE,KAAK,IAAI,KAAK;AAAA,EACd,MAAM,OAAO,MAAM;AAAA,EACnB,IAAI,SAAS,UAAU;AAAA,IACrB,gBAAgB,OAAO,CAAC,QAAQ,aAAa,WAAW,GAAG,QAAQ;AAAA,IACnE,MAAM,MAAM,yBAAyB,MAAM,WAAW,WAAW;AAAA,IACjE,MAAM,MAAM,yBAAyB,MAAM,WAAW,WAAW;AAAA,IACjE,IAAI,QAAQ,aAAa,QAAQ,aAAa,MAAM;AAAA,MAAK,aAAa,4CAA4C;AAAA,EACpH,EAAO,SAAI,SAAS,UAAU;AAAA,IAC5B,gBAAgB,OAAO,CAAC,QAAQ,WAAW,WAAW,SAAS,GAAG,QAAQ;AAAA,IAC1E,IAAI,MAAM,YAAY,aAAa,OAAO,MAAM,YAAY;AAAA,MAAW,aAAa,qCAAqC;AAAA,IACzH,MAAM,MAAM,oBAAoB,MAAM,SAAS,SAAS;AAAA,IACxD,MAAM,MAAM,oBAAoB,MAAM,SAAS,SAAS;AAAA,IACxD,IAAI,QAAQ,aAAa,QAAQ,aAAa,MAAM;AAAA,MAAK,aAAa,wCAAwC;AAAA,EAChH,EAAO,SAAI,SAAS,WAAW;AAAA,IAC7B,gBAAgB,OAAO,CAAC,MAAM,GAAG,QAAQ;AAAA,EAC3C,EAAO,SAAI,SAAS,QAAQ;AAAA,IAC1B,gBAAgB,OAAO,CAAC,MAAM,GAAG,QAAQ;AAAA,EAC3C,EAAO,SAAI,SAAS,WAAW;AAAA,IAC7B,gBAAgB,OAAO,CAAC,QAAQ,OAAO,GAAG,QAAQ;AAAA,IAClD,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,OAAO,OAAO;AAAA,MAAG,aAAa,iCAAiC;AAAA,IACzG,IAAI;AAAA,MACF,SAAS,MAAM,OAAO,GAAG,IAAI,KAAO,EAAE,MAAM,SAAS,CAAC;AAAA,MACtD,OAAO,OAAO;AAAA,MACd,IAAI,iBAAiB,oBAAoB,MAAM,SAAS,gBAAgB;AAAA,QACtE,aAAa,iCAAiC;AAAA,MAChD;AAAA,MACA,MAAM;AAAA;AAAA,EAEV,EAAO,SAAI,SAAS,SAAS;AAAA,IAC3B,gBAAgB,OAAO,CAAC,QAAQ,SAAS,UAAU,GAAG,QAAQ;AAAA,IAC9D,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,OAAO,OAAO;AAAA,MAAG,aAAa,6BAA6B;AAAA,IACrG,YAAY,MAAM,OAAO,QAAQ,GAAG,IAAI;AAAA,IACxC,yBAAyB,MAAM,UAAU,UAAU;AAAA,EACrD,EAAO,SAAI,SAAS,UAAU;AAAA,IAC5B,gBAAgB,OAAO,CAAC,QAAQ,cAAc,UAAU,GAAG,QAAQ;AAAA,IACnE,MAAM,aAAa,MAAM;AAAA,IACzB,IAAI,CAAC,cAAc,UAAU;AAAA,MAAG,aAAa,4CAA4C;AAAA,IACzF,WAAW,OAAO,OAAO,KAAK,UAAU;AAAA,MAAG,YAAY,WAAW,MAAM,QAAQ,GAAG,IAAI;AAAA,IACvF,MAAM,WAAW,MAAM;AAAA,IACvB,IAAI,aAAa,WAAW;AAAA,MAC1B,IAAI,CAAC,MAAM,QAAQ,QAAQ;AAAA,QAAG,aAAa,iDAAiD;AAAA,MAC5F,MAAM,QAAQ,IAAI;AAAA,MAClB,WAAW,QAAQ,UAAU;AAAA,QAC3B,IAAI,OAAO,SAAS;AAAA,UAAU,aAAa,yCAAyC;AAAA,QACpF,IAAI,MAAM,IAAI,IAAI;AAAA,UAAG,aAAa,wCAAwC;AAAA,QAC1E,MAAM,IAAI,IAAI;AAAA,QACd,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,YAAY,IAAI,GAAG;AAAA,UAC3D,aAAa,gDAAgD;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA,EACF,EAAO,SAAI,SAAS,UAAU;AAAA,IAC5B,gBAAgB,OAAO,CAAC,QAAQ,UAAU,YAAY,GAAG,QAAQ;AAAA,IACjE,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,OAAO,QAAQ;AAAA,MAAG,aAAa,+BAA+B;AAAA,IACxG,YAAY,MAAM,QAAQ,QAAQ,GAAG,IAAI;AAAA,IACzC,yBAAyB,MAAM,YAAY,YAAY;AAAA,EACzD,EAAO,SAAI,SAAS,SAAS;AAAA,IAC3B,gBAAgB,OAAO,CAAC,QAAQ,UAAU,GAAG,QAAQ;AAAA,IACrD,MAAM,WAAW,MAAM;AAAA,IACvB,IAAI,CAAC,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW,GAAG;AAAA,MACrD,aAAa,kDAAkD;AAAA,IACjE;AAAA,IACA,WAAW,WAAW;AAAA,MAAU,YAAY,SAAS,QAAQ,GAAG,IAAI;AAAA,EACtE,EAAO,SAAI,SAAS,QAAQ;AAAA,IAC1B,gBAAgB,OAAO,CAAC,QAAQ,UAAU,GAAG,QAAQ;AAAA,IACrD,IAAI,MAAM,aAAa,aAAa,CAAC,sBAAsB,MAAM,QAAQ,GAAG;AAAA,MAC1E,aAAa,sDAAsD;AAAA,IACrE;AAAA,EACF,EAAO;AAAA,IACL,aAAa,qBAAqB;AAAA;AAAA,EAEpC,KAAK,OAAO,KAAK;AAAA;AAiHnB,SAAS,cAAc,CAAC,OAAgB,OAAmC;AAAA,EACzE,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,IAAI,CAAC,sBAAsB,KAAK,KAAK,QAAQ,oBAAoB;AAAA,IAC/D,aAAa,GAAG,kEAAkE;AAAA,EACpF;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,kBAAkB,CAAC,QAAiC,gBAA8B;AAAA,EACzF,MAAM,OAAO,OAAO,KAAK,MAAM;AAAA,EAC/B,IAAI,KAAK,WAAW,wBAAwB,QAAQ,KAAK,KAAK,CAAC,QAAQ,CAAC,wBAAwB,IAAI,GAAG,CAAC,GAAG;AAAA,IACzG,aAAa,iCAAiC;AAAA,EAChD;AAAA,EACA,MAAM,gBAAgB,OAAO;AAAA,EAC7B,IAAI,OAAO,kBAAkB,YAAY,CAAC,0BAA0B,IAAI,aAAwC,GAAG;AAAA,IACjH,aAAa,+BAA+B;AAAA,EAC9C;AAAA,EACA,MAAM,YAAY,OAAO;AAAA,EACzB,IAAI,cAAc,QAAQ,CAAC,sBAAsB,SAAS,GAAG;AAAA,IAC3D,aAAa,sDAAsD;AAAA,EACrE;AAAA,EACA,MAAM,iBAAiB,OAAO;AAAA,EAC9B,IAAI,CAAC,sBAAsB,cAAc;AAAA,IAAG,aAAa,gDAAgD;AAAA,EACzG,IAAI,iBAAiB;AAAA,IAAgB,aAAa,+CAA+C;AAAA,EACjG,MAAM,aAAa,OAAO;AAAA,EAC1B,IAAI,CAAC,sBAAsB,UAAU;AAAA,IAAG,aAAa,4CAA4C;AAAA,EACjG,IAAI,aAAa;AAAA,IAAgB,aAAa,gDAAgD;AAAA;AAGhG,SAAS,WAAW,CAAC,YAA2C;AAAA,EAC9D,gBAAgB,YAAY,aAAa,QAAQ;AAAA,EACjD,MAAM,OAAO,WAAW;AAAA,EACxB,IAAI,SAAS,WAAW,SAAS;AAAA,IAAW,aAAa,sCAAsC;AAAA,EAC/F,YAAY,WAAW,OAAO,GAAG,IAAI,GAAK;AAAA,EAC1C,YAAY,WAAW,QAAQ,GAAG,IAAI,GAAK;AAAA,EAC3C,MAAM,WAAW,WAAW;AAAA,EAC5B,IAAI,CAAC,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW;AAAA,IAAG,aAAa,oCAAoC;AAAA,EACxG,MAAM,eAAe,IAAI;AAAA,EACzB,WAAW,WAAW,UAAU;AAAA,IAC9B,IAAI,OAAO,YAAY,YAAY,CAAC,kBAAkB,IAAI,OAAyB;AAAA,MAAG,aAAa,iBAAiB;AAAA,IACpH,IAAI,aAAa,IAAI,OAAO;AAAA,MAAG,aAAa,yBAAyB;AAAA,IACrE,aAAa,IAAI,OAAO;AAAA,EAC1B;AAAA,EACA,IAAI,WAAW,cAAc,WAAW;AAAA,IACtC,IAAI,CAAC,sBAAsB,WAAW,SAAS,KAAK,WAAW,YAAY,oBAAoB;AAAA,MAC7F,aAAa,uEAAuE;AAAA,IACtF;AAAA,EACF;AAAA,EACA,eAAe,WAAW,eAAe,eAAe;AAAA,EACxD,MAAM,iBAAiB,eAAe,WAAW,gBAAgB,gBAAgB;AAAA,EACjF,MAAM,UAAU,WAAW;AAAA,EAC3B,IAAI,SAAS,WAAW;AAAA,IACtB,IAAI,CAAC,cAAc,OAAO;AAAA,MAAG,aAAa,oDAAoD;AAAA,IAC9F,mBAAmB,SAAS,kBAAkB,kBAAkB;AAAA,EAClE,EAAO,SAAI,YAAY,WAAW;AAAA,IAChC,aAAa,iDAAiD;AAAA,EAChE;AAAA;AAGF,SAAS,aAAa,CAAC,UAAyB;AAAA,EAC9C,IAAI,CAAC,cAAc,QAAQ;AAAA,IAAG,aAAa,iCAAiC;AAAA,EAC5E,gBAAgB,UAAU,eAAe,UAAU;AAAA,EACnD,IAAI,OAAO,SAAS,OAAO,YAAY,CAAC,eAAe,KAAK,SAAS,EAAE;AAAA,IAAG,aAAa,oBAAoB;AAAA,EAC3G,IAAI,CAAC,sBAAsB,SAAS,OAAO;AAAA,IAAG,aAAa,iDAAiD;AAAA,EAC5G,MAAM,UAAU,SAAS;AAAA,EACzB,IAAI,CAAC,cAAc,OAAO;AAAA,IAAG,aAAa,gCAAgC;AAAA,EAC1E,MAAM,QAAQ,OAAO,KAAK,OAAO;AAAA,EACjC,IAAI,MAAM,WAAW;AAAA,IAAG,aAAa,0CAA0C;AAAA,EAC/E,IAAI,MAAM,SAAS;AAAA,IAAiB,aAAa,mCAAmC;AAAA,EACpF,WAAW,QAAQ,OAAO;AAAA,IACxB,IAAI,CAAC,gBAAgB,KAAK,IAAI;AAAA,MAAG,aAAa,qBAAqB;AAAA,IACnE,MAAM,aAAa,QAAQ;AAAA,IAC3B,IAAI,CAAC,cAAc,UAAU;AAAA,MAAG,aAAa,0CAA0C;AAAA,IACvF,YAAY,UAAU;AAAA,EACxB;AAAA;AAGF,SAAS,UAAU,CAAC,OAAyB;AAAA,EAC3C,IAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,IACxB,WAAW,QAAQ;AAAA,MAAO,WAAW,IAAI;AAAA,IACzC,OAAO,OAAO,OAAO,KAAK;AAAA,EAC5B;AAAA,EACA,IAAI,cAAc,KAAK,GAAG;AAAA,IACxB,WAAW,OAAO,OAAO,KAAK,KAAK;AAAA,MAAG,WAAW,MAAM,IAAI;AAAA,IAC3D,OAAO,OAAO,OAAO,KAAK;AAAA,EAC5B;AAAA,EACA,OAAO;AAAA;AAQF,SAAS,gBAAqE,CAAC,UAI5D;AAAA,EACxB,MAAM,OAAO,kBAAkB,QAAQ;AAAA,EACvC,cAAc,IAAI;AAAA,EAClB,OAAO,WAAW,IAAI;AAAA;;;ACryBxB,IAAM,YAAY,IAAI,IAAY,CAAC,WAAW,UAAU,SAAS,CAAC;AAClE,IAAM,SAAS,IAAI,IAAY,CAAC,UAAU,SAAS,CAAC;AACpD,IAAM,WAAW,IAAI,IAAY,CAAC,aAAa,cAAc,cAAc,WAAW,SAAS,CAAC;AAqQhG,IAAM,YAAY,IAAI;AAEtB,IAAM,UAAU,IAAI;;;AFtOpB,IAAM,yBAA8D;AAAA,EAClE,cAAc;AAAA,EACd,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,EACT,wBAAwB;AAAA,EACxB,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,qBAAqB;AAAA,EACrB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,qBAAqB;AAAA,EACrB,sBAAsB;AACxB;AAEA,IAAM,sBAAsB,IAAI,IAAyB,OAAO,KAAK,sBAAsB,CAA0B;AA2RrH,IAAM,gBAAgC,OAAO,OAAO,CAAC,CAAC;AAWtD,IAAM,cAAc,IAAI;AA8CxB,IAAM,cAAc,IAAI;;AGnajB,IAAM,4BAA4B,IAAI;AAEtC,IAAM,2BAA2B,KAAK;AAEtC,IAAM,0BAA0B,KAAK;AAiDrC,IAAM,uBAAqD,OAAO,OAAO,CAAC,SAAS,YAAY,QAAQ,CAAC;AA4F/G,IAAM,cAAc,IAAI,IAA4B;AAAA,EAClD;AAAA,EAAe;AAAA,EAAa;AAAA,EAAgB;AAAA,EAAW;AAAA,EAAc;AAAA,EACrE;AAAA,EAAY;AAAA,EAAO;AAAA,EAAa;AAAA,EAAY;AAAA,EAAa;AAAA,EAAU;AAAA,EAAW;AAChF,CAAC;AAuCD,IAAM,qBAAoB,IAAI,IAAoB,CAAC,aAAa,cAAc,cAAc,WAAW,SAAS,CAAC;;;ACvI1G,IAAM,oCAAoC,IAAI;AAE9C,IAAM,iCAAiC,KAAK;AAE5C,IAAM,iCAAiC,KAAK,OAAO;AAEnD,IAAM,kCAAkC,IAAI;AAG5C,IAAM,sCAAsC,IAAI;AAchD,IAAM,6BAA6B,KAAK,OAAO;AAQ/C,IAAM,kCAAkC,KAAK;AAGpD,IAAM,QAAQ,IAAI,WAAW,CAAC;AA6gB9B,IAAM,uBAAuB,IAAI;;;ACjmBjC,IAAM,sBAAsB,KAAK;AAQjC,IAAM,uBAAuB,IAAI;;;AClBjC,IAAM,gBAAgB,IAAI,IAAI,CAAC,UAAU,YAAY,QAAQ,CAAC;;;ACpB9D,IAAM,UAAU,EAAE,eAAe,QAAQ,mBAAmB,MAAM,YAAY,OAAO,gBAAgB,MAAM;AACpG,IAAM,cAAc,iBAAiB,EAAC,IAAI,gCAAgC,SAAS,GAAG,SAAS;AAAA,EACpG,eAAe,EAAC,MAAM,WAAW,OAAO,EAAC,MAAM,UAAU,YAAY,CAAC,EAAC,GAAG,QAAQ,EAAC,MAAM,UAAU,YAAY,EAAC,SAAS,EAAC,MAAM,UAAU,SAAS,MAAM,SAAS,EAAC,GAAG,WAAW,EAAC,MAAM,SAAQ,GAAG,SAAS,EAAC,MAAM,UAAU,QAAQ,EAAC,MAAM,SAAQ,GAAG,YAAY,GAAE,EAAC,EAAC,GAAG,UAAU,CAAC,SAAS,GAAG,SAAS,WAAW,MAAK;AAAA,EAC1T,cAAc,EAAC,MAAM,WAAW,OAAO,EAAC,MAAM,UAAU,YAAY,EAAC,SAAS,EAAC,MAAM,UAAU,SAAS,MAAM,SAAS,EAAC,EAAC,EAAC,GAAG,QAAQ,EAAC,MAAM,UAAU,YAAY,EAAC,UAAU,EAAC,MAAM,UAAS,EAAC,EAAC,GAAG,UAAU,CAAC,SAAS,GAAG,SAAS,WAAW,MAAK;AACpP,EAAC,CAAC;;;ACLF,uBAAS;;;ACDT;AAEO,IAAM,kBAAkB;AACxB,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AACxB,IAAM,6BAA6B;AACnC,IAAM,yBAAyB;AAC/B,IAAM,qCAAqC;AAC3C,IAAM,qBAAqB;AAC3B,IAAM,mBAAmB;AACzB,IAAM,0BAA0B,KAAK,KAAK;AAC1C,IAAM,wBAAwB,IAAI,KAAK;AAAA;AAcvC,MAAM,wBAAwB,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,WAAW,CAAC,MAAsB,SAAiB,UAA2E,CAAC,GAAG;AAAA,IAChI,MAAM,OAAO;AAAA,IACb,KAAK,OAAO;AAAA,IACZ,KAAK,OAAO;AAAA,IACZ,KAAK,SAAS,QAAQ;AAAA,IACtB,KAAK,eAAe,QAAQ;AAAA,IAC5B,KAAK,YAAY,QAAQ,cAAc,SAAS,aAAa,SAAS;AAAA;AAE1E;AAqBA,IAAM,qBAAqB;AAC3B,IAAM,yBAAyB,MAAM;AAErC,SAAS,OAAO,CAAC,WAAkC;AAAA,EACjD,OAAO,aAAa;AAAA;AAGtB,SAAS,WAAW,CAAC,MAAsB,QAAyB;AAAA,EAClE,IAAI,SAAS;AAAA,IAAa,OAAO;AAAA,EACjC,IAAI,SAAS;AAAA,IAAW,OAAO;AAAA,EAC/B,IAAI,SAAS;AAAA,IAAW,OAAO;AAAA,EAC/B,IAAI,SAAS;AAAA,IAAc,OAAO;AAAA,EAClC,IAAI,SAAS;AAAA,IAAwB,OAAO;AAAA,EAC5C,IAAI,SAAS;AAAA,IAAoB,OAAO;AAAA,EACxC,IAAI,SAAS;AAAA,IAAoB,OAAO;AAAA,EACxC,OAAO,6BAA6B,WAAW,YAAY,KAAK,UAAU;AAAA;AAG5E,SAAS,UAAU,CAAC,QAAuC;AAAA,EACzD,OAAO,IAAI,gBAAgB,QAAQ,WAAW,YAAY,YAAY,aAAa,YAAY,QAAQ,WAAW,YAAY,YAAY,WAAW,CAAC;AAAA;AAGxJ,SAAS,gBAAgB,CAAC,OAAgB,QAAuC;AAAA,EAC/E,IAAI,iBAAiB;AAAA,IAAiB,OAAO;AAAA,EAC7C,IAAI,QAAQ;AAAA,IAAS,OAAO,WAAW,MAAM;AAAA,EAC7C,OAAO,IAAI,gBAAgB,WAAW,YAAY,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA;AAKnF,SAAS,SAAS,CAAC,QAAiD,QAAgD;AAAA,EAClH,IAAI,CAAC;AAAA,IAAQ,OAAO,OAAO,KAAK;AAAA,EAChC,IAAI,OAAO;AAAA,IAAS,OAAO,QAAQ,OAAO,WAAW,MAAM,CAAC;AAAA,EAC5D,OAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AAAA,IACtC,IAAI,UAAU;AAAA,IACd,MAAM,UAAU,MAAM,OAAO,oBAAoB,SAAS,OAAO;AAAA,IACjE,MAAM,UAAU,MAAM;AAAA,MACpB,IAAI;AAAA,QAAS;AAAA,MACb,UAAU;AAAA,MACV,QAAQ;AAAA,MACH,OAAO,OAAO,EAAE,MAAM,MAAG;AAAA,QAAG;AAAA,OAAS;AAAA,MAC1C,OAAO,WAAW,MAAM,CAAC;AAAA;AAAA,IAE3B,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,IACxD,OAAO,KAAK,EAAE,KACZ,CAAC,UAAU;AAAA,MACT,IAAI;AAAA,QAAS;AAAA,MACb,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ,KAAK;AAAA,OAEf,CAAC,UAAU;AAAA,MACT,IAAI;AAAA,QAAS;AAAA,MACb,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO,KAAK;AAAA,KAEhB;AAAA,GACD;AAAA;AAGH,SAAS,eAAkB,CAAC,SAAqB,QAAkC;AAAA,EACjF,IAAI,CAAC;AAAA,IAAQ,OAAO;AAAA,EACpB,IAAI,OAAO;AAAA,IAAS,OAAO,QAAQ,OAAO,WAAW,MAAM,CAAC;AAAA,EAC5D,OAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AAAA,IACtC,IAAI,UAAU;AAAA,IACd,MAAM,UAAU,MAAM,OAAO,oBAAoB,SAAS,OAAO;AAAA,IACjE,MAAM,UAAU,MAAM;AAAA,MACpB,IAAI;AAAA,QAAS;AAAA,MACb,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO,WAAW,MAAM,CAAC;AAAA;AAAA,IAE3B,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,IACxD,QAAQ,KACN,CAAC,UAAU;AAAA,MACT,IAAI;AAAA,QAAS;AAAA,MACb,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ,KAAK;AAAA,OAEf,CAAC,UAAU;AAAA,MACT,IAAI;AAAA,QAAS;AAAA,MACb,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO,KAAK;AAAA,KAEhB;AAAA,GACD;AAAA;AAGH,SAAS,cAAc,CAAC,QAAiC,WAAiE;AAAA,EACxH,MAAM,aAAa,IAAI;AAAA,EACvB,MAAM,UAAU,MAAM,WAAW,MAAM,QAAQ,UAAU,IAAI,aAAa,WAAW,YAAY,CAAC;AAAA,EAClG,IAAI,QAAQ;AAAA,IAAS,QAAQ;AAAA,EACxB;AAAA,YAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,EAC9D,MAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,SAAS,GAAG,SAAS;AAAA,EACrE,OAAO;AAAA,IACL,QAAQ,WAAW;AAAA,IACnB,SAAS,MAAM;AAAA,MACb,aAAa,KAAK;AAAA,MAClB,QAAQ,oBAAoB,SAAS,OAAO;AAAA;AAAA,EAEhD;AAAA;AAGF,eAAe,WAAW,CAAC,UAAoB,cAAsB,QAAuC;AAAA,EAC1G,IAAI;AAAA,IACF,IAAI,CAAC,SAAS,MAAM;AAAA,MAClB,MAAM,OAAO,MAAM,gBAAgB,SAAS,KAAK,GAAG,MAAM;AAAA,MAC1D,IAAI,IAAI,YAAY,EAAE,OAAO,IAAI,EAAE,aAAa,cAAc;AAAA,QAC5D,MAAM,IAAI,gBAAgB,cAAc,YAAY,YAAY,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,MACzF;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA,MAAM,SAAS,SAAS,KAAK,UAAU;AAAA,IACvC,IAAI;AAAA,MACF,MAAM,SAAuB,CAAC;AAAA,MAC9B,IAAI,QAAQ;AAAA,MACZ,UAAS;AAAA,QACP,MAAM,OAAO,MAAM,UAAU,QAAQ,MAAM;AAAA,QAC3C,IAAI,KAAK;AAAA,UAAM;AAAA,QACf,SAAS,KAAK,MAAM;AAAA,QACpB,IAAI,QAAQ,cAAc;AAAA,UACnB,OAAO,OAAO,EAAE,MAAM,MAAG;AAAA,YAAG;AAAA,WAAS;AAAA,UAC1C,MAAM,IAAI,gBAAgB,cAAc,YAAY,YAAY,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,QACzF;AAAA,QACA,OAAO,KAAK,KAAK,KAAK;AAAA,MACxB;AAAA,MACA,MAAM,QAAQ,IAAI,WAAW,KAAK;AAAA,MAClC,IAAI,SAAS;AAAA,MACb,WAAW,SAAS,QAAQ;AAAA,QAC1B,MAAM,IAAI,OAAO,MAAM;AAAA,QACvB,UAAU,MAAM;AAAA,MAClB;AAAA,MACA,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,cACrC;AAAA,MACA,OAAO,YAAY;AAAA;AAAA,IAErB,OAAO,OAAO;AAAA,IACd,MAAM,iBAAiB,OAAO,MAAM;AAAA;AAAA;AAIxC,SAAS,UAAU,CAAC,MAAuC;AAAA,EACzD,IAAI;AAAA,IACF,MAAM,QAAiB,KAAK,MAAM,IAAI;AAAA,IACtC,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA,MAAG,OAAO;AAAA,IACjF,MAAM;AAAA,EAGR,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA;AAGrG,SAAS,gBAAgB,CAAC,MAAkC;AAAA,EAC1D,MAAM,YAAY,IAAI,IAAI,CAAC,wBAAwB,iBAAiB,yBAAyB,aAAa,iBAAiB,iBAAiB,iBAAiB,CAAC;AAAA,EAC9J,MAAM,OAAO,CAAC,OAAgB,UAAsC;AAAA,IAClE,IAAI,QAAQ,KAAK,UAAU,QAAQ,OAAO,UAAU;AAAA,MAAU;AAAA,IAC9D,IAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,MACxB,WAAW,QAAQ,OAAO;AAAA,QACxB,MAAM,QAAQ,KAAK,MAAM,QAAQ,CAAC;AAAA,QAClC,IAAI;AAAA,UAAO,OAAO;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AAAA,IACA,YAAY,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG;AAAA,MAC/C,IAAI,CAAC,SAAS,cAAc,MAAM,EAAE,SAAS,GAAG,KAAK,OAAO,SAAS,YAAY,UAAU,IAAI,KAAK,YAAY,CAAC;AAAA,QAAG,OAAO,KAAK,YAAY;AAAA,MAC5I,MAAM,QAAQ,KAAK,MAAM,QAAQ,CAAC;AAAA,MAClC,IAAI;AAAA,QAAO,OAAO;AAAA,IACpB;AAAA,IACA;AAAA;AAAA,EAEF,IAAI;AAAA,IACF,MAAM,QAAiB,KAAK,MAAM,IAAI;AAAA,IACtC,OAAO,KAAK,OAAO,CAAC;AAAA,IACpB,MAAM;AAAA,EAGR;AAAA;AAGF,SAAS,aAAa,CAAC,QAAgB,MAAc,UAAU,OAAwB;AAAA,EACrF,MAAM,OAAO,iBAAiB,IAAI;AAAA,EAClC,IAAI,WAAW,MAAM,YAAY,MAAM,wBAAwB;AAAA,IAC7D,OAAO,IAAI,gBAAgB,wBAAwB,YAAY,sBAAsB,GAAG;AAAA,MACtF;AAAA,MACA,cAAc;AAAA,MACd,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAAA,EACA,OAAO,IAAI,gBAAgB,QAAQ,YAAY,QAAQ,MAAM,GAAG;AAAA,IAC9D;AAAA,IACA,cAAc;AAAA,IACd,WAAW,UAAU,OAAO,WAAW,OAAO,WAAW;AAAA,EAC3D,CAAC;AAAA;AAGH,eAAe,WAAW,CAAC,KAAa,MAAmB,SAA8B,UAAU,OAAyC;AAAA,EAC1I,MAAM,YAAY,QAAQ,aAAa;AAAA,EACvC,MAAM,WAAW,eAAe,QAAQ,QAAQ,SAAS;AAAA,EACzD,IAAI;AAAA,IACF,IAAI,SAAS,OAAO;AAAA,MAAS,MAAM,WAAW,SAAS,MAAM;AAAA,IAC7D,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,WAAW,MAAM,QAAQ,QAAQ,SAAS,EAAE,KAAK,KAAK,MAAM,UAAU,SAAS,QAAQ,SAAS,OAAO,CAAC;AAAA,MACxG,OAAO,OAAO;AAAA,MACd,MAAM,iBAAiB,OAAO,SAAS,MAAM;AAAA;AAAA,IAE/C,MAAM,OAAO,MAAM,YAAY,UAAU,QAAQ,gBAAgB,wBAAwB,SAAS,MAAM;AAAA,IACxG,IAAI,CAAC,SAAS;AAAA,MAAI,MAAM,cAAc,SAAS,QAAQ,MAAM,OAAO;AAAA,IACpE,OAAO,WAAW,IAAI;AAAA,IACtB,OAAO,OAAO;AAAA,IACd,MAAM,iBAAiB,OAAO,SAAS,MAAM;AAAA,YAC7C;AAAA,IACA,SAAS,QAAQ;AAAA;AAAA;AAIrB,SAAS,WAAW,CAAC,WAAoC,OAAqC;AAAA,EAC5F,WAAW,QAAQ,OAAO;AAAA,IACxB,IAAI,OAAO,OAAO,UAAU,YAAY,OAAO,MAAM,KAAK;AAAA,MAAG,OAAO,OAAO,MAAM,KAAK;AAAA,EACxF;AAAA,EACA;AAAA;AAGF,SAAS,cAAc,CAAC,OAAoC;AAAA,EAC1D,IAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,QAAQ;AAAA,IAAG,OAAO;AAAA,EAC7E,IAAI,OAAO,UAAU,YAAY,kBAAkB,KAAK,MAAM,KAAK,CAAC,GAAG;AAAA,IACrE,MAAM,SAAS,OAAO,KAAK;AAAA,IAC3B,OAAO,OAAO,SAAS,MAAM,KAAK,SAAS,IAAI,SAAS;AAAA,EAC1D;AAAA,EACA;AAAA;AAGF,eAAsB,iBAAiB,CAAC,UAA+B,CAAC,GAAwB;AAAA,EAC9F,MAAM,OAAO,MAAM,YAAY,4BAA4B;AAAA,IACzD,QAAQ;AAAA,IACR,SAAS,EAAE,QAAQ,oBAAoB,gBAAgB,mBAAmB;AAAA,IAC1E,MAAM,KAAK,UAAU,EAAE,WAAW,gBAAgB,CAAC;AAAA,EACrD,GAAG,OAAO;AAAA,EACV,MAAM,eAAe,YAAY,MAAM,gBAAgB;AAAA,EACvD,MAAM,WAAW,YAAY,MAAM,aAAa,UAAU;AAAA,EAC1D,IAAI,CAAC,gBAAgB,CAAC;AAAA,IAAU,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EACnI,MAAM,UAAU,eAAe,KAAK,QAAQ,KAAK;AAAA,EACjD,OAAO,EAAE,cAAc,UAAU,YAAY,KAAK,IAAI,KAAK,KAAK,MAAM,UAAU,IAAI,CAAC,EAAE;AAAA;AAGzF,SAAS,KAAK,CAAC,IAAY,QAAqC;AAAA,EAC9D,OAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AAAA,IACtC,IAAI,QAAQ;AAAA,MAAS,OAAO,OAAO,WAAW,MAAM,CAAC;AAAA,IACrD,IAAI,UAAU;AAAA,IACd,MAAM,UAAU,MAAM,QAAQ,oBAAoB,SAAS,OAAO;AAAA,IAClE,MAAM,QAAQ,WAAW,MAAM;AAAA,MAC7B,IAAI;AAAA,QAAS;AAAA,MACb,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ;AAAA,OACP,EAAE;AAAA,IACL,MAAM,UAAU,MAAM;AAAA,MACpB,IAAI;AAAA,QAAS;AAAA,MACb,UAAU;AAAA,MACV,aAAa,KAAK;AAAA,MAClB,QAAQ;AAAA,MACR,OAAO,WAAW,MAAM,CAAC;AAAA;AAAA,IAE3B,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,GAC1D;AAAA;AAGH,eAAsB,eAAe,CACnC,QACA,UAA4D,CAAC,GAC/B;AAAA,EAC9B,IAAI,CAAC,OAAO,aAAa,KAAK,KAAK,CAAC,OAAO,SAAS,KAAK;AAAA,IAAG,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EAC/J,MAAM,gBAAgB,KAAK,IAAI,QAAQ,iBAAiB,yBAAyB,uBAAuB;AAAA,EACxG,MAAM,WAAW,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,aAAa;AAAA,EACvD,MAAM,aAAa,KAAK,IAAI,KAAK,OAAO,cAAc,IAAI;AAAA,EAC1D,UAAS;AAAA,IACP,IAAI,KAAK,IAAI,KAAK;AAAA,MAAU,MAAM,IAAI,gBAAgB,WAAW,0DAA0D,EAAE,WAAW,MAAM,CAAC;AAAA,IAC/I,MAAM,YAAY,WAAW,KAAK,IAAI;AAAA,IACtC,MAAM,OAAO,KAAK,UAAU,EAAE,gBAAgB,OAAO,cAAc,WAAW,OAAO,SAAS,CAAC;AAAA,IAC/F,IAAI;AAAA,IACJ,MAAM,WAAW,eAAe,QAAQ,QAAQ,KAAK,IAAI,QAAQ,aAAa,oBAAoB,SAAS,CAAC;AAAA,IAC5G,IAAI;AAAA,MACF,IAAI;AAAA,QACF,WAAW,MAAM,QAAQ,QAAQ,SAAS,EAAE,wBAAwB;AAAA,UAClE,QAAQ;AAAA,UACR,SAAS,EAAE,QAAQ,oBAAoB,gBAAgB,mBAAmB;AAAA,UAC1E;AAAA,UACA,UAAU;AAAA,UACV,QAAQ,SAAS;AAAA,QACnB,CAAC;AAAA,QACD,OAAO,OAAO;AAAA,QACd,MAAM,iBAAiB,OAAO,SAAS,MAAM;AAAA;AAAA,MAE/C,MAAM,OAAO,MAAM,YAAY,UAAU,QAAQ,gBAAgB,wBAAwB,SAAS,MAAM;AAAA,MACxG,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;AAAA,QAGtD,IAAI,KAAK,IAAI,KAAK;AAAA,UAAU,MAAM,IAAI,gBAAgB,WAAW,0DAA0D,EAAE,WAAW,MAAM,CAAC;AAAA,QAC/I,MAAM,MAAM,KAAK,IAAI,YAAY,WAAW,KAAK,IAAI,CAAC,GAAG,QAAQ,MAAM;AAAA,QACvE;AAAA,MACF;AAAA,MACA,IAAI,CAAC,SAAS;AAAA,QAAI,MAAM,cAAc,SAAS,QAAQ,IAAI;AAAA,MAC3D,MAAM,SAAS,WAAW,IAAI;AAAA,MAC9B,MAAM,oBAAoB,YAAY,QAAQ,oBAAoB;AAAA,MAClE,MAAM,eAAe,YAAY,QAAQ,eAAe;AAAA,MACxD,IAAI,CAAC,qBAAqB,CAAC;AAAA,QAAc,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,MAC5I,OAAO,EAAE,mBAAmB,cAAc,eAAe,YAAY,QAAQ,gBAAgB,EAAE;AAAA,MAC/F,OAAO,OAAO;AAAA,MACd,MAAM,iBAAiB,OAAO,SAAS,MAAM;AAAA,cAC7C;AAAA,MACA,SAAS,QAAQ;AAAA;AAAA,EAErB;AAAA;AASK,SAAS,SAAS,CAAC,OAA2B;AAAA,EACnD,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,WAAW;AAAA;AAGzC,SAAS,UAAU,CAAC,QAA6C;AAAA,EACtE,MAAM,QAAQ,WAAW,CAAC,SAAS,YAAY,IAAI;AAAA,EACnD,MAAM,eAAe,UAAU,MAAM,EAAE,CAAC;AAAA,EACxC,MAAM,QAAQ,UAAU,MAAM,EAAE,CAAC;AAAA,EACjC,MAAM,gBAAgB,UAAU,IAAI,WAAW,WAAW,QAAQ,EAAE,OAAO,YAAY,EAAE,OAAO,CAAC,CAAC;AAAA,EAClG,OAAO,EAAE,OAAO,cAAc,cAAc;AAAA;AAGvC,SAAS,0BAA0B,CAAC,MAAqD;AAAA,EAC9F,MAAM,MAAM,IAAI,IAAI,cAAc;AAAA,EAClC,IAAI,SAAS,IAAI,gBAAgB;AAAA,IAC/B,WAAW;AAAA,IACX,eAAe;AAAA,IACf,cAAc;AAAA,IACd,OAAO;AAAA,IACP,OAAO,KAAK;AAAA,IACZ,gBAAgB,KAAK;AAAA,IACrB,uBAAuB;AAAA,IACvB,QAAQ;AAAA,IACR,4BAA4B;AAAA,IAC5B,2BAA2B;AAAA,EAC7B,CAAC,EAAE,SAAS;AAAA,EACZ,OAAO,IAAI,SAAS;AAAA;AAmBtB,IAAM,uBAAuB,IAAI,IAAI;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,qBAAqB,CAAC,KAAa,SAA8C;AAAA,EAC/F,IAAI;AAAA,EACJ,IAAI;AAAA,IACF,MAAM,IAAI,IAAI,GAAG;AAAA,IACjB,MAAM;AAAA,IACN,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA;AAAA,EAErG,MAAM,cAAc,IAAI,IAAI,kBAAkB;AAAA,EAC9C,IACG,QAAQ,mBAAmB,aAAa,QAAQ,mBAAmB,YAAY,UAC/E,QAAQ,iBAAiB,aAAa,QAAQ,iBAAiB,YAAY,YAC5E,IAAI,WAAW,YAAY,UAC3B,IAAI,aAAa,YAAY,YAC7B,IAAI,YACJ,IAAI,YACJ,IAAI,MACJ;AAAA,IACA,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EACrG;AAAA,EACA,MAAM,YAAY,CAAC,SAAS,QAAQ,SAAS,mBAAmB,EAAE,KAAK,CAAC,SAAS,IAAI,aAAa,OAAO,IAAI,EAAE,SAAS,CAAC;AAAA,EACzH,IAAI,aAAa,IAAI,aAAa,IAAI,UAAU,GAAG;AAAA,IACjD,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EACrG;AAAA,EACA,MAAM,QAAQ,IAAI,aAAa,IAAI,OAAO,KAAK;AAAA,EAC/C,IAAI,CAAC,SAAS,UAAU,QAAQ;AAAA,IAAe,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EAClJ,MAAM,MAAM,QAAQ,OAAO,KAAK,IAAI;AAAA,EACpC,MAAM,MAAM,QAAQ,SAAS;AAAA,EAC7B,IAAI,CAAC,OAAO,SAAS,GAAG,KAAK,CAAC,OAAO,SAAS,GAAG,KAAK,OAAO,KAAM,QAAQ,aAAa,cAAc,CAAC,OAAO,SAAS,QAAQ,QAAQ,KAAK,QAAQ,WAAW,KAAK,MAAM,QAAQ,YAAY,MAAM,QAAQ,WAAW,MAAO;AAAA,IAC5N,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EACrG;AAAA,EACA,MAAM,UAAU,IAAI,aAAa,IAAI,MAAM;AAAA,EAC3C,MAAM,WAAW,IAAI,aAAa,IAAI,OAAO;AAAA,EAC7C,IAAI,WAAW;AAAA,IAAU,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EAC5H,MAAM,OAAO,IAAI,aAAa,IAAI,MAAM,GAAG,KAAK,KAAK;AAAA,EACrD,MAAM,WAAW,IAAI,aAAa,IAAI,OAAO,GAAG,KAAK,KAAK;AAAA,EAC1D,IAAK,WAAW,CAAC,QAAU,YAAY,CAAC,UAAW;AAAA,IACjD,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EACrG;AAAA,EACA,MAAM,QAAQ,WAAY,qBAAqB,IAAI,QAAQ,IAAI,WAAW,kBAAmB;AAAA,EAC7F,MAAM,sBAAsB,aAAa,aAAa,IAAI,aAAa,IAAI,mBAAmB;AAAA,EAC9F,IAAI,aAAa,aAAa,IAAI,aAAa,IAAI,mBAAmB,GAAG;AAAA,IACvE,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EACrG;AAAA,EACA,MAAM,SAAwB;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB,sBAAsB,EAAE,SAAS,KAAK,IAAI;AAAA,EAC9D;AAAA,EACA,IAAI,CAAC,OAAO,QAAQ,CAAC,OAAO;AAAA,IAAO,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EACtI,OAAO;AAAA;AAcT,SAAS,QAAQ,CAAC,QAAiC,sBAA8C;AAAA,EAC/F,MAAM,cAAc,YAAY,QAAQ,cAAc;AAAA,EACtD,MAAM,eAAe,YAAY,QAAQ,eAAe,KAAK;AAAA,EAC7D,IAAI,CAAC,eAAe,CAAC;AAAA,IAAc,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EACtI,MAAM,YAAY,eAAe,OAAO,UAAU;AAAA,EAClD,MAAM,UAAU,YAAY,QAAQ,UAAU;AAAA,EAC9C,IAAI;AAAA,EACJ,IAAI,iBAAkD;AAAA,EACtD,IAAI,SAAS;AAAA,IACX,IAAI;AAAA,MACF,WAAW,qBAAqB,OAAO;AAAA,MACvC,iBAAiB;AAAA,MACjB,MAAM;AAAA,MAEN,iBAAiB;AAAA;AAAA,EAErB;AAAA,EACA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,YAAY,QAAQ,YAAY;AAAA,IAC3C;AAAA,IACA,WAAW,cAAc,YAAY,YAAY,KAAK,IAAI,IAAI,YAAY;AAAA,IAC1E;AAAA,IACA;AAAA,EACF;AAAA;AAGF,eAAsB,iBAAiB,CACrC,MACA,cACA,UAA0D,CAAC,GACnC;AAAA,EACxB,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,aAAa,KAAK;AAAA,IAAG,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EAC7I,MAAM,cAAc,QAAQ,eAAe;AAAA,EAC3C,MAAM,OAAO,IAAI,gBAAgB,EAAE,YAAY,sBAAsB,WAAW,iBAAiB,MAAM,cAAc,aAAa,eAAe,aAAa,CAAC;AAAA,EAC/J,MAAM,WAAW,MAAM,YAAY,iBAAiB;AAAA,IAClD,QAAQ;AAAA,IACR,SAAS,EAAE,QAAQ,oBAAoB,gBAAgB,oCAAoC;AAAA,IAC3F,MAAM,KAAK,SAAS;AAAA,EACtB,GAAG,OAAO;AAAA,EACV,OAAO,SAAS,QAAQ;AAAA;AAG1B,eAAsB,gCAAgC,CACpD,aACA,UAA+B,CAAC,GACR;AAAA,EACxB,OAAO,kBAAkB,YAAY,mBAAmB,YAAY,cAAc;AAAA,OAC7E;AAAA,IACH,aAAa;AAAA,EACf,CAAC;AAAA;AAGH,eAAsB,iBAAiB,CACrC,cACA,UAA+B,CAAC,GACR;AAAA,EACxB,IAAI,CAAC,aAAa,KAAK;AAAA,IAAG,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EAC7H,MAAM,OAAO,IAAI,gBAAgB,EAAE,WAAW,iBAAiB,YAAY,iBAAiB,eAAe,cAAc,OAAO,uBAAuB,CAAC;AAAA,EACxJ,MAAM,WAAW,MAAM,YAAY,iBAAiB;AAAA,IAClD,QAAQ;AAAA,IACR,SAAS,EAAE,QAAQ,oBAAoB,gBAAgB,oCAAoC;AAAA,IAC3F,MAAM,KAAK,SAAS;AAAA,EACtB,GAAG,KAAK,QAAQ,GAAG,IAAI;AAAA,EACvB,OAAO,SAAS,UAAU,YAAY;AAAA;AAiBjC,SAAS,eAAe,CAAC,SAAkC;AAAA,EAChE,MAAM,QAAQ,QAAQ,MAAM,GAAG;AAAA,EAC/B,IAAI,MAAM,WAAW,KAAK,CAAC,MAAM;AAAA,IAAI,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA,EACxI,IAAI;AAAA,IACF,MAAM,UAAmB,KAAK,MAAM,OAAO,KAAK,MAAM,IAAI,WAAW,EAAE,SAAS,MAAM,CAAC;AAAA,IACvF,IAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,MAAM,QAAQ,OAAO;AAAA,MAAG,MAAM,IAAI,MAAM,eAAe;AAAA,IAC9G,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM,IAAI,gBAAgB,oBAAoB,YAAY,kBAAkB,GAAG,EAAE,WAAW,MAAM,CAAC;AAAA;AAAA;AAIhG,SAAS,oBAAoB,CAAC,SAAgC;AAAA,EACnE,MAAM,UAAU,gBAAgB,OAAO;AAAA,EACvC,MAAM,OAAO,QAAQ;AAAA,EACrB,MAAM,aAAa,OAAO,SAAS,YAAY,SAAS,QAAQ,CAAC,MAAM,QAAQ,IAAI,IAAI,OAAkC,CAAC;AAAA,EAC1H,OAAO;AAAA,IACL,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ;AAAA,IAC3D,WAAW,OAAO,WAAW,uBAAuB,WAAW,WAAW,qBAAqB;AAAA,IAC/F,UAAU,OAAO,WAAW,sBAAsB,WAAW,WAAW,oBAAoB;AAAA,IAC5F,QAAQ,OAAO,WAAW,YAAY,WAAW,WAAW,UAAU;AAAA,EACxE;AAAA;;;AC9lBF;AAYO,IAAM,oBAAoB;AAC1B,IAAM,yBAAyB;AAAA;AAwC/B,MAAM,4BAA4B,MAAM;AAAA,EAExB;AAAA,EADZ,OAAO;AAAA,EAChB,WAAW,CAAU,MAAwB;AAAA,IAC3C,MAAM,IAAI;AAAA,IADS;AAAA;AAGvB;AAcA,IAAM,eAAe;AACrB,IAAM,WAAW;AACjB,IAAM,YAAY;AAClB,IAAM,0BAA0B;AAEhC,SAAS,IAAI,CAAC,OAAgB,MAAM,UAAkB;AAAA,EACpD,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,MAAM,SAAS,OAAO,MAAM,KAAK,MAAM,OAAO;AAAA,IACnG,MAAM,IAAI,oBAAoB,eAAe;AAAA,EAC/C;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,YAAY,CAAC,OAAgB,MAAM,UAA8B;AAAA,EACxE,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,OAAO,KAAK,OAAO,GAAG;AAAA;AAiBxB,SAAS,YAAY,CAAC,OAA6D;AAAA,EACjF,OAAO,UAAU,YAAY,YAAY,KAAK,MAAM;AAAA;AAGtD,SAAS,WAAW,CAAC,OAAqC;AAAA,EACxD,OAAO;AAAA,OAAK;AAAA,IAAO,UAAU,aAAa,MAAM,QAAQ;AAAA,IAAG,aAAa,MAAM,eAAe,KAAK,MAAM,YAAY;AAAA,IAClH,mBAAmB,MAAM,mBAAmB,IAAI,WAAS,KAAK,KAAK,EAAE;AAAA,EAAE;AAAA;AAG3E,SAAS,sBAAsB,CAAC,OAAyB;AAAA,EACvD,OAAO,UAAU,aAAc,MAAM,QAAQ,KAAK,KAAK,MAAM,UAAU,2BAA2B,MAAM,MAAM,UAC5G,QAAQ,OAAO,KAAK,aAAa,YAAY,KAAK,SAAS,SAAS,KAAK,KAAK,SAAS,UAAU,YACjG,CAAC,wBAAwB,KAAK,KAAK,QAAQ,KAC3C,OAAO,KAAK,oBAAoB,YAAY,wEAAwE,KAAK,KAAK,eAAe,MAC5I,KAAK,cAAc,aAAc,OAAO,SAAS,KAAK,SAAS,KAAK,KAAK,aAAa,MAAO,OAAO,KAAK,cAAc,SAAS;AAAA;AAGrI,SAAS,kBAAkB,CAAC,OAAwC;AAAA,EAClE,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK;AAAA,IAAG,OAAO;AAAA,EAChF,MAAM,UAAU;AAAA,EAChB,OAAO,OAAO,QAAQ,OAAO,YAAY,QAAQ,GAAG,SAAS,KAAK,QAAQ,GAAG,UAAU,OACrF,OAAO,QAAQ,UAAU,YAAY,QAAQ,MAAM,SAAS,KAAK,QAAQ,MAAM,UAAU,YACzF,CAAC,UAAU,YAAY,mBAAmB,SAAS,EAAE,SAAS,QAAQ,MAAgB,KACtF,OAAO,cAAc,QAAQ,UAAU,KAAM,QAAQ,aAAwB,MAC5E,QAAQ,eAAe,aAAc,OAAO,cAAc,QAAQ,UAAU,KAAM,QAAQ,aAAwB,OAClH,QAAQ,oBAAoB,aAAa,OAAO,QAAQ,oBAAoB,eAC5E,QAAQ,qBAAqB,aAAa,OAAO,QAAQ,qBAAqB,cAC/E,uBAAuB,QAAQ,iBAAiB,KAChD,OAAO,SAAS,QAAQ,SAAS,KAAK,OAAO,SAAS,QAAQ,SAAS;AAAA;AAG3E,SAAS,MAAM,CAAC,OAA6C;AAAA,EAC3D,IAAI,UAAU;AAAA,IAAW,OAAO,EAAE,QAAQ,wBAAwB,UAAU,CAAC,EAAE;AAAA,EAC/E,IAAI;AAAA,IACF,MAAM,SAAkB,KAAK,MAAM,KAAK;AAAA,IACxC,IAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM;AAAA,MAAG,MAAM,IAAI;AAAA,IACtF,MAAM,YAAY;AAAA,IAClB,IAAI,UAAU,WAAW,0BAA0B,CAAC,MAAM,QAAQ,UAAU,QAAQ,KAAK,UAAU,SAAS,SAAS,gBACjH,CAAC,UAAU,SAAS,MAAM,kBAAkB;AAAA,MAAG,MAAM,IAAI;AAAA,IAC7D,OAAO,EAAE,QAAQ,wBAAwB,UAAU,UAAU,SAAS,IAAI,CAAC,UAAU;AAAA,SAChF,YAAY,IAAI;AAAA,MAAG,YAAY,KAAK,cAAc;AAAA,MACrD,iBAAiB,KAAK,mBAAmB,KAAK,WAAW;AAAA,IAC3D,EAAE,EAAE;AAAA,IACJ,MAAM;AAAA,IACN,MAAM,IAAI,oBAAoB,eAAe;AAAA;AAAA;AAIjD,SAAS,MAAM,CAAC,OAAiC;AAAA,EAC/C,OAAO,KAAK,UAAU,KAAK;AAAA;AAG7B,SAAS,YAAY,CAAC,SAA4C;AAAA,EAChE,IAAI,QAAQ,WAAW;AAAA,IAAY,OAAO;AAAA,EAC1C,IAAI,QAAQ,WAAW;AAAA,IAAmB,OAAO;AAAA,EACjD,IAAI,QAAQ,WAAW;AAAA,IAAW,OAAO;AAAA,EACzC;AAAA;AAGK,SAAS,eAAe,CAAC,SAAyC;AAAA,EACvE,MAAM,UAAU,QAAQ,mBAAmB,KAAK,UAAQ,CAAC,KAAK,SAAS;AAAA,EACvE,OAAO;AAAA,IACL,IAAI,QAAQ;AAAA,IACZ,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,IAChB,WAAW,QAAQ,WAAW,YAAY,QAAQ,mBAAmB,QAAQ,QAAQ,eAAe,QAAQ,gBAAgB,OAAO,SAAS,QAAQ,SAAS,CAAC;AAAA,IAC9J,QAAQ,aAAa,OAAO;AAAA,IAC5B,WAAW,QAAQ;AAAA,IACnB,UAAU,aAAa,QAAQ,QAAQ;AAAA,IACvC,kBAAkB,QAAQ,qBAAqB;AAAA,IAC/C,kBAAkB,WAAW,KAAK,QAAQ;AAAA,EAC5C;AAAA;AAAA;AAGK,MAAM,aAAa;AAAA,EACK;AAAA,EAA2C;AAAA,EAAxE,WAAW,CAAkB,aAA2C,WAA0B,MAAM,MAAM;AAAA,IAAjF;AAAA,IAA2C;AAAA;AAAA,OAElE,KAAI,GAAqE;AAAA,IAC7E,MAAM,QAAQ,MAAM,KAAK,YAAY,IAAI,iBAAiB;AAAA,IAC1D,OAAO,EAAE,WAAW,OAAO,OAAO,KAAK,GAAG,SAAS,OAAO,WAAW,KAAK;AAAA;AAAA,OAG9D,OAAS,CAAC,SAA6C,YAA2B,MAAM,MAAkB;AAAA,IACtH,SAAS,UAAU,EAAG,UAAU,IAAI,WAAW;AAAA,MAC7C,IAAI,CAAC,KAAK,SAAS,KAAK,CAAC,UAAU;AAAA,QAAG,MAAM,IAAI,oBAAoB,UAAU;AAAA,MAC9E,MAAM,UAAU,MAAM,KAAK,KAAK;AAAA,MAChC,MAAM,OAAyB,EAAE,QAAQ,wBAAwB,UAAU,QAAQ,UAAU,SAAS,IAAI,WAAW,EAAE;AAAA,MACvH,MAAM,SAAS,QAAQ,IAAI;AAAA,MAC3B,IAAI,CAAC,KAAK,SAAS,KAAK,CAAC,UAAU;AAAA,QAAG,MAAM,IAAI,oBAAoB,UAAU;AAAA,MAC9E,IAAI;AAAA,QACF,MAAM,KAAK,YAAY,cAAc,mBAAmB,QAAQ,SAAS,OAAO,IAAI,CAAC;AAAA,QACrF,OAAO;AAAA,QACP,OAAO,OAAO;AAAA,QACd,IAAK,MAA4B,SAAS;AAAA,UAAoB,MAAM;AAAA;AAAA,IAExE;AAAA,IACA,MAAM,IAAI,oBAAoB,kBAAkB;AAAA;AAAA,OAG5C,KAAI,GAA+B;AAAA,IACvC,QAAQ,MAAM,KAAK,KAAK,GAAG,UAAU,SAAS,IAAI,eAAe;AAAA;AAAA,OAG7D,IAAG,CAAC,IAAoC;AAAA,IAC5C,MAAM,WAAW,MAAM,KAAK,KAAK,GAAG,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,IACpF,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,IACvD,OAAO,YAAY,OAAO;AAAA;AAAA,OAGtB,OAAM,CAAC,OAAe,OAAsB,YAA2B,MAAM,MAA8B;AAAA,IAC/G,KAAK,KAAK;AAAA,IACV,IAAI,MAAM,mBAAmB,YAAY,CAAC,MAAM,UAAU;AAAA,MAAW,MAAM,IAAI,oBAAoB,kBAAkB;AAAA,IACrH,OAAO,KAAK,OAAO,CAAC,cAAc;AAAA,MAChC,IAAI,UAAU,SAAS,UAAU;AAAA,QAAc,MAAM,IAAI,oBAAoB,eAAe;AAAA,MAC5F,MAAM,MAAM,KAAK,IAAI;AAAA,MACrB,MAAM,UAAyB;AAAA,QAC7B,IAAI,WAAW;AAAA,QAAG;AAAA,QAAO,QAAQ,MAAM,cAAc,YAAY,oBAAoB;AAAA,QAAU,YAAY;AAAA,QAAG,YAAY;AAAA,QAC1H,iBAAiB,MAAM,cAAc;AAAA,QAAW,WAAW;AAAA,QAAK,WAAW;AAAA,QAC3E,aAAa,KAAK,MAAM,aAAa,SAAS;AAAA,QAAG,cAAc,KAAK,MAAM,cAAc,SAAS;AAAA,QACjG,SAAS,aAAa,MAAM,SAAS,SAAS;AAAA,QAAG,WAAW,MAAM;AAAA,QAClE,UAAU,aAAa,MAAM,QAAQ;AAAA,MACvC;AAAA,MACA,UAAU,SAAS,KAAK,OAAO;AAAA,MAC/B,OAAO,YAAY,OAAO;AAAA,OACzB,SAAS;AAAA;AAAA,OAGR,mBAAkB,CACtB,IACA,OACA,UAAmD,CAAC,GAC5B;AAAA,IACxB,IAAI,QAAQ,UAAU,aAAa,QAAQ,eAAe;AAAA,MAAW,MAAM,IAAI,oBAAoB,eAAe;AAAA,IAClH,OAAO,KAAK,OAAO,CAAC,cAAc;AAAA,MAChC,MAAM,UAAU,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,MAChE,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,IAAI,QAAQ,eAAe,QAAQ;AAAA,QAAY,MAAM,IAAI,oBAAoB,eAAe;AAAA,MAC5F,IAAI,QAAQ,aAAa,UAAU,QAAQ;AAAA,QAAO,MAAM,IAAI,oBAAoB,eAAe;AAAA,MAC/F,IAAI,QAAQ,WAAW;AAAA,QAAW,MAAM,IAAI,oBAAoB,SAAS;AAAA,MACzE,IAAI,QAAQ,WAAW;AAAA,QAAY,MAAM,IAAI,oBAAoB,UAAU;AAAA,MAC3E,IAAI,MAAM,UAAU,aAAa,QAAQ,UAAU,aAAa,MAAM,SAAS,cAAc,QAAQ,SAAS,WAAW;AAAA,QACvH,MAAM,IAAI,oBAAoB,mBAAmB;AAAA,MACnD;AAAA,MACA,MAAM,MAAM,KAAK,IAAI;AAAA,MACrB,QAAQ,cAAc,KAAK,MAAM,aAAa,SAAS;AAAA,MACvD,QAAQ,eAAe,KAAK,MAAM,cAAc,SAAS;AAAA,MACzD,IAAI,MAAM,YAAY,aAAa,MAAM,mBAAmB;AAAA,QAAW,QAAQ,UAAU,KAAK,MAAM,SAAS,SAAS;AAAA,MACtH,IAAI,MAAM,cAAc;AAAA,QAAW,QAAQ,YAAY,MAAM;AAAA,MACxD;AAAA,eAAO,QAAQ;AAAA,MAGpB,IAAI,MAAM,mBAAmB,aAAa,MAAM,aAAa,cACxD,QAAQ,UAAU,cAAc,aAAa,MAAM,SAAS,cAAc,YAAY;AAAA,QACzF,QAAQ,WAAW,aAAa,MAAM,QAAQ;AAAA,MAChD;AAAA,MACA,QAAQ,kBAAkB,MAAM,cAAc;AAAA,MAC9C,QAAQ,SAAS,MAAM,cAAc,YAAY,oBAAoB;AAAA,MACrE,QAAQ,cAAc;AAAA,MACtB,QAAQ,YAAY;AAAA,MACpB,OAAO,QAAQ;AAAA,MACf,OAAO,YAAY,OAAO;AAAA,KAC3B;AAAA;AAAA,OAGG,eAAc,CAAC,IAAiE;AAAA,IACpF,OAAO,KAAK,OAAO,CAAC,cAAc;AAAA,MAChC,MAAM,UAAU,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,MAChE,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,IAAI,QAAQ,WAAW;AAAA,QAAW,MAAM,IAAI,oBAAoB,SAAS;AAAA,MACzE,QAAQ,cAAc;AAAA,MACtB,QAAQ,YAAY,KAAK,IAAI;AAAA,MAC7B,OAAO,EAAE,YAAY,QAAQ,YAAY,YAAY,QAAQ,WAAW;AAAA,KACzE;AAAA;AAAA,OAGG,QAAO,CACX,IACA,OACA,UACA,YAA2B,MAAM,MACT;AAAA,IACxB,OAAO,KAAK,OAAO,CAAC,cAAc;AAAA,MAChC,MAAM,UAAU,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,MAChE,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,IAAI,QAAQ,WAAW;AAAA,QAAW,MAAM,IAAI,oBAAoB,SAAS;AAAA,MACzE,IAAI,QAAQ,eAAe,SAAS,cAAc,QAAQ,eAAe,SAAS,YAAY;AAAA,QAC5F,MAAM,IAAI,oBAAoB,eAAe;AAAA,MAC/C;AAAA,MACA,IAAI,MAAM,mBAAmB,YAAY,CAAC,MAAM,UAAU;AAAA,QAAW,MAAM,IAAI,oBAAoB,kBAAkB;AAAA,MACrH,IAAI,QAAQ,UAAU,aAAa,MAAM,SAAS,cAAc,QAAQ,SAAS,WAAW;AAAA,QAC1F,MAAM,IAAI,oBAAoB,mBAAmB;AAAA,MACnD;AAAA,MACA,QAAQ,cAAc,KAAK,MAAM,aAAa,SAAS;AAAA,MACvD,QAAQ,eAAe,KAAK,MAAM,cAAc,SAAS;AAAA,MACzD,IAAI,MAAM,YAAY;AAAA,QAAW,QAAQ,UAAU,KAAK,MAAM,SAAS,SAAS;AAAA,MAChF,IAAI,MAAM,cAAc,WAAW;AAAA,QACjC,OAAO,QAAQ;AAAA,QACf,QAAQ,kBAAkB;AAAA,QAC1B,QAAQ,SAAS;AAAA,MACnB,EAAO;AAAA,QACL,QAAQ,YAAY,MAAM;AAAA,QAC1B,QAAQ,kBAAkB;AAAA,QAC1B,QAAQ,SAAS;AAAA;AAAA,MAEnB,QAAQ,WAAW,aAAa,MAAM,QAAQ;AAAA,MAC9C,QAAQ,cAAc;AAAA,MACtB,QAAQ,YAAY,KAAK,IAAI;AAAA,MAC7B,OAAO,QAAQ;AAAA,MACf,OAAO,YAAY,OAAO;AAAA,OACzB,SAAS;AAAA;AAAA,OAGR,UAAS,CAAC,IAAY,QAAkE;AAAA,IAC5F,OAAO,KAAK,OAAO,CAAC,cAAc;AAAA,MAChC,MAAM,UAAU,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,MAChE,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,IAAI,QAAQ,WAAW,WAAW;AAAA,QAChC,IAAI,WAAW;AAAA,UAAW,OAAO,YAAY,OAAO;AAAA,QACpD,MAAM,IAAI,oBAAoB,SAAS;AAAA,MACzC;AAAA,MACA,QAAQ,SAAS;AAAA,MACjB,QAAQ,cAAc;AAAA,MACtB,QAAQ,YAAY,KAAK,IAAI;AAAA,MAC7B,OAAO,QAAQ;AAAA,MACf,IAAI,WAAW,WAAW;AAAA,QACxB,OAAO,QAAQ;AAAA,QACf,OAAO,QAAQ;AAAA,QACf,OAAO,QAAQ;AAAA,QACf,OAAO,QAAQ;AAAA,QACf,QAAQ,kBAAkB;AAAA,MAC5B;AAAA,MACA,OAAO,YAAY,OAAO;AAAA,KAC3B;AAAA;AAAA,OAGG,OAAM,CAAC,IAAY,OAAuC;AAAA,IAC9D,KAAK,KAAK;AAAA,IACV,OAAO,KAAK,OAAO,CAAC,cAAc;AAAA,MAChC,MAAM,UAAU,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,MAChE,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,IAAI,QAAQ,WAAW;AAAA,QAAW,MAAM,IAAI,oBAAoB,SAAS;AAAA,MACzE,QAAQ,QAAQ;AAAA,MAChB,QAAQ,YAAY,KAAK,IAAI;AAAA,MAC7B,OAAO,YAAY,OAAO;AAAA,KAC3B;AAAA;AAAA,OAGG,oBAAmB,CAAC,IAAY,SAA0C;AAAA,IAC9E,IAAI,OAAO,YAAY;AAAA,MAAW,MAAM,IAAI,oBAAoB,eAAe;AAAA,IAC/E,OAAO,KAAK,OAAO,eAAa;AAAA,MAC9B,MAAM,UAAU,UAAU,SAAS,KAAK,UAAQ,KAAK,OAAO,EAAE;AAAA,MAC9D,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,IAAI,QAAQ,WAAW;AAAA,QAAW,MAAM,IAAI,oBAAoB,SAAS;AAAA,MACzE,QAAQ,mBAAmB;AAAA,MAC3B,QAAQ,YAAY,KAAK,IAAI;AAAA,MAC7B,OAAO,YAAY,OAAO;AAAA,KAC3B;AAAA;AAAA,OAIG,eAAc,CAAC,IAAY,QAAqB,KAAoD;AAAA,IACxG,OAAO,KAAK,OAAO,eAAa;AAAA,MAC9B,MAAM,UAAU,UAAU,SAAS,KAAK,UAAQ,KAAK,OAAO,EAAE;AAAA,MAC9D,IAAI,CAAC,WAAW,CAAC,gBAAgB,OAAO,EAAE,aAAa,QAAQ,qBAAqB;AAAA,QAAM;AAAA,MAC1F,MAAM,WAAW,QAAQ,qBAAqB,CAAC;AAAA,MAC/C,IAAI,SAAS,KAAK,UAAQ,CAAC,KAAK,aAAa,KAAK,aAAa,OAAO,EAAE;AAAA,QAAG;AAAA,MAC3E,QAAQ,oBAAoB,SAAS,OAAO,UAAQ,CAAC,KAAK,aAAa,KAAK,cAAc,aAAa,KAAK,YAAY,GAAG;AAAA,MAC3H,IAAI,QAAQ,kBAAkB,UAAU,2BAA2B,OAAO,cAAc,aAAa,OAAO,aAAa;AAAA,QAAK;AAAA,MAC9H,MAAM,UAA4B,EAAE,UAAU,OAAO,IAAI,iBAAiB,WAAW,GAAG,WAAW,OAAO,WAAW,WAAW,MAAM;AAAA,MACtI,QAAQ,kBAAkB,KAAK,OAAO;AAAA,MACtC,QAAQ,YAAY,KAAK,IAAI;AAAA,MAC7B,OAAO,KAAK,QAAQ;AAAA,KACrB;AAAA;AAAA,OAIG,mBAAkB,CAAC,IAAY,iBAAyB,QAAqB,KAA4B;AAAA,IAC7G,MAAM,KAAK,OAAO,eAAa;AAAA,MAC7B,MAAM,UAAU,UAAU,SAAS,KAAK,UAAQ,KAAK,OAAO,EAAE;AAAA,MAC9D,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,MAAM,WAAW,QAAQ,qBAAqB,CAAC;AAAA,MAC/C,MAAM,UAAU,SAAS,KAAK,UAAQ,CAAC,KAAK,SAAS;AAAA,MACrD,IAAI,SAAS;AAAA,QACX,IAAI,QAAQ,oBAAoB,mBAAmB,QAAQ,aAAa,OAAO;AAAA,UAAI,MAAM,IAAI,oBAAoB,kBAAkB;AAAA,QACnI;AAAA,MACF;AAAA,MACA,QAAQ,oBAAoB,SAAS,OAAO,UAAQ,KAAK,aAAa,OAAO,OAAO,KAAK,cAAc,aAAa,KAAK,YAAY,IAAI;AAAA,MACzI,IAAI,QAAQ,kBAAkB,UAAU;AAAA,QAAyB,MAAM,IAAI,oBAAoB,eAAe;AAAA,MAC9G,QAAQ,kBAAkB,KAAK,EAAE,UAAU,OAAO,IAAI,iBAAiB,WAAW,OAAO,WAAW,WAAW,MAAM,CAAC;AAAA,MACtH,QAAQ,YAAY,KAAK,IAAI;AAAA,KAC9B;AAAA;AAAA,OAGG,gBAAe,CAAC,IAAY,iBAAyB,SAAS,OAAsB;AAAA,IACxF,MAAM,KAAK,OAAO,eAAa;AAAA,MAC7B,MAAM,UAAU,UAAU,SAAS,KAAK,UAAQ,KAAK,OAAO,EAAE;AAAA,MAC9D,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,IAAI;AAAA,QAAQ,QAAQ,oBAAoB,QAAQ,mBAAmB,OAAO,UAAQ,KAAK,oBAAoB,eAAe;AAAA,MACrH;AAAA,QACH,MAAM,UAAU,QAAQ,mBAAmB,KAAK,UAAQ,KAAK,oBAAoB,eAAe;AAAA,QAChG,IAAI;AAAA,UAAS,QAAQ,YAAY;AAAA;AAAA,MAEnC,QAAQ,YAAY,KAAK,IAAI;AAAA,KAC9B;AAAA;AAAA,OAGG,OAAM,CAAC,IAAoC;AAAA,IAC/C,OAAO,KAAK,OAAO,CAAC,cAAc;AAAA,MAChC,MAAM,UAAU,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,MAChE,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,IAAI,QAAQ,WAAW;AAAA,QAAW,MAAM,IAAI,oBAAoB,SAAS;AAAA,MACzE,IAAI,QAAQ,WAAW;AAAA,QAAY,MAAM,IAAI,oBAAoB,iBAAiB;AAAA,MAClF,IAAI,CAAC,QAAQ,eAAe,CAAC,QAAQ;AAAA,QAAiB,MAAM,IAAI,oBAAoB,iBAAiB;AAAA,MACrG,QAAQ,SAAS;AAAA,MACjB,QAAQ,cAAc;AAAA,MACtB,QAAQ,YAAY,KAAK,IAAI;AAAA,MAC7B,OAAO,YAAY,OAAO;AAAA,KAC3B;AAAA;AAAA,OAGG,aAAY,CAAC,IAAY,YAAsC;AAAA,IACnE,OAAO,KAAK,OAAO,CAAC,cAAc;AAAA,MAChC,MAAM,UAAU,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,MAChE,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,IAAI,QAAQ,eAAe,cAAc,QAAQ,WAAW;AAAA,QAAU,OAAO;AAAA,MAC7E,QAAQ,SAAS;AAAA,MACjB,QAAQ,kBAAkB;AAAA,MAC1B,QAAQ,cAAc;AAAA,MACtB,QAAQ,YAAY,KAAK,IAAI;AAAA,MAC7B,OAAO,QAAQ;AAAA,MACf,OAAO;AAAA,KACR;AAAA;AAAA,OAGG,eAAc,CAAC,IAAY,OAAe,OAAuE;AAAA,IACrH,OAAO,KAAK,OAAO,CAAC,cAAc;AAAA,MAChC,MAAM,UAAU,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,MAChE,IAAI,CAAC;AAAA,QAAS,MAAM,IAAI,oBAAoB,WAAW;AAAA,MACvD,IAAI,QAAQ,WAAW;AAAA,QAAU,MAAM,IAAI,oBAAoB,QAAQ,MAAM;AAAA,MAC7E,IAAI,QAAQ,eAAe,QAAQ,YAAY,UAAU,SAAS,QAAQ,YAAY,QAAQ,KAAK,IAAI,GAAG;AAAA,QACxG,OAAO,EAAE,UAAU,OAAO,SAAS,YAAY,OAAO,EAAE;AAAA,MAC1D;AAAA,MACA,QAAQ,cAAc,EAAE,OAAO,MAAM;AAAA,MACrC,QAAQ,YAAY,KAAK,IAAI;AAAA,MAC7B,OAAO,EAAE,UAAU,MAAM,SAAS,YAAY,OAAO,EAAE;AAAA,KACxD;AAAA;AAAA,OAGG,eAAc,CAAC,IAAY,OAAe,YAAsC;AAAA,IACpF,IAAI;AAAA,MACF,OAAO,MAAM,KAAK,OAAO,CAAC,cAAc;AAAA,QACtC,MAAM,UAAU,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,QAChE,IAAI,SAAS,eAAe,cAAc,QAAQ,aAAa,UAAU,SAAS,QAAQ,WAAW,UAAU;AAAA,UAC7G,OAAO,QAAQ;AAAA,UACf,QAAQ,YAAY,KAAK,IAAI;AAAA,UAC7B,OAAO;AAAA,QACT;AAAA,QACA,OAAO;AAAA,OACR;AAAA,MACD,OAAO,OAAO;AAAA,MACd,IAAK,MAA4B,SAAS,eAAgB,MAA4B,SAAS;AAAA,QAAY,MAAM;AAAA,MACjH,OAAO;AAAA;AAAA;AAAA,OAIL,kBAAiB,CAAC,IAAY,OAAe,YAAsC;AAAA,IACvF,OAAO,KAAK,OAAO,CAAC,cAAc;AAAA,MAChC,MAAM,UAAU,UAAU,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAAA,MAChE,IAAI,CAAC,WAAW,QAAQ,WAAW,YAAY,QAAQ,eAAe,cAAc,QAAQ,aAAa,UAAU;AAAA,QAAO,OAAO;AAAA,MACjI,QAAQ,SAAS;AAAA,MACjB,QAAQ,cAAc;AAAA,MACtB,QAAQ,YAAY,KAAK,IAAI;AAAA,MAC7B,OAAO,QAAQ;AAAA,MACf,OAAO;AAAA,KACR;AAAA;AAEL;;;AC/dA,uBAAS;AAiDF,MAAM,0BAA0B,MAAM;AAAA,EAEtB;AAAA,EADZ,OAAO;AAAA,EAChB,WAAW,CAAU,MAA6B;AAAA,IAChD,MAAM,IAAI;AAAA,IADS;AAAA;AAGvB;AAiDA,SAAS,WAAW,CAAC,MAAgC,QAA0C;AAAA,EAC7F,OAAO,EAAE,WAAW,KAAK,WAAW,OAAO;AAAA;AAAA;AAGtC,MAAM,oBAAoB;AAAA,EAOF;AAAA,EAA0C;AAAA,EANtD,WAAW,IAAI;AAAA,EACf;AAAA,EACA;AAAA,EACT,WAAW;AAAA,EACF;AAAA,EAEjB,WAAW,CAAkB,YAA0C,OAAiC,CAAC,GAAG;AAAA,IAA/E;AAAA,IAA0C;AAAA,IACrE,KAAK,MAAM,KAAK,OAAO,KAAK;AAAA,IAC5B,KAAK,cAAc,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,eAAe,EAAE,CAAC;AAAA,IACpE,KAAK,cAAc,MAAM,KAAK,QAAQ;AAAA,IACtC,IAAI,WAAW;AAAA,MAAS,KAAK,QAAQ;AAAA,IAChC;AAAA,iBAAW,iBAAiB,SAAS,KAAK,aAAa,EAAE,MAAM,KAAK,CAAC;AAAA;AAAA,EAGpE,UAAU,CAAC,MAAiB,YAAgC,OAA+B,KAA2B;AAAA,IAC5H,IAAI,KAAK,YAAY,KAAK,WAAW;AAAA,MAAS,MAAM,IAAI,kBAAkB,UAAU;AAAA,IACpF,KAAK,QAAQ;AAAA,IACb,IAAI,KAAK,SAAS,QAAQ,KAAK;AAAA,MAAa,MAAM,IAAI,kBAAkB,MAAM;AAAA,IAC9E,MAAM,aAAa,IAAI;AAAA,IACvB,MAAM,cAAc,MAAM,WAAW,MAAM,KAAK,WAAW,MAAM;AAAA,IACjE,KAAK,WAAW,iBAAiB,SAAS,aAAa,EAAE,MAAM,KAAK,CAAC;AAAA,IACrE,MAAM,WAAW,KAAK,IAAI;AAAA,IAC1B,MAAM,UAAwB;AAAA,MAC5B,IAAI,YAAW;AAAA,MAAG;AAAA,MAAM,OAAO;AAAA,MAAW;AAAA,MAAU,WAAW,WAAW;AAAA,MAC1E;AAAA,MAAY;AAAA,MAAO;AAAA,MAAY,YAAY,MAAM,KAAK,WAAW,oBAAoB,SAAS,WAAW;AAAA,MACzG,aAAa,WAAW,MAAM,KAAK,OAAO,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,GAAG,CAAC;AAAA,IACzE;AAAA,IACA,KAAK,SAAS,IAAI,QAAQ,IAAI,OAAO;AAAA,IACrC,OAAO;AAAA;AAAA,EAGD,MAAM,CAAC,IAAkB;AAAA,IAC/B,MAAM,UAAU,KAAK,SAAS,IAAI,EAAE;AAAA,IACpC,IAAI,CAAC;AAAA,MAAS;AAAA,IACd,IAAI,QAAQ,UAAU,aAAa,QAAQ,UAAU,UAAU;AAAA,MAAE,KAAK,OAAO,EAAE;AAAA,MAAG;AAAA,IAAQ;AAAA,IAC1F,IAAI,QAAQ,UAAU;AAAA,MAAa;AAAA,IACnC,IAAI,QAAQ,UAAU,cAAc;AAAA,MAAE,QAAQ,sBAAsB;AAAA,MAAM;AAAA,IAAQ;AAAA,IAClF,QAAQ,QAAQ;AAAA,IAChB,QAAQ,WAAW,MAAM,SAAS;AAAA;AAAA,EAG5B,OAAO,GAAS;AAAA,IACtB,MAAM,MAAM,KAAK,IAAI;AAAA,IACrB,YAAY,IAAI,YAAY,KAAK,UAAU;AAAA,MACzC,KAAK,QAAQ,UAAU,eAAe,QAAQ,UAAU,aAAa,QAAQ,UAAU,aAAa,QAAQ,aAAa;AAAA,QAAK,KAAK,OAAO,EAAE;AAAA,IAC9I;AAAA;AAAA,EAGM,MAAM,CAAC,IAAkB;AAAA,IAC/B,MAAM,UAAU,KAAK,SAAS,IAAI,EAAE;AAAA,IACpC,IAAI,CAAC;AAAA,MAAS;AAAA,IACd,aAAa,QAAQ,WAAW;AAAA,IAChC,QAAQ,WAAW;AAAA,IACnB,KAAK,SAAS,OAAO,EAAE;AAAA;AAAA,EAGjB,GAAG,CAAC,IAA0B;AAAA,IACpC,IAAI,OAAO,OAAO,YAAY,GAAG,SAAS,KAAK,GAAG,SAAS;AAAA,MAAK,MAAM,IAAI,kBAAkB,eAAe;AAAA,IAC3G,MAAM,UAAU,KAAK,SAAS,IAAI,EAAE;AAAA,IACpC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,kBAAkB,WAAW;AAAA,IACrD,IAAI,QAAQ,aAAa,KAAK,IAAI,KAAK,QAAQ,UAAU,cAAc;AAAA,MACrE,KAAK,OAAO,EAAE;AAAA,MACd,MAAM,IAAI,kBAAkB,SAAS;AAAA,IACvC;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,YAAW,CAAC,YAAqB,iBAAmG;AAAA,IACxI,IAAI,eAAe,cAAc,OAAO,eAAe,YAAY,WAAW,SAAS,KAAK,WAAW,SAAS,MAAM;AAAA,MACpH,MAAM,IAAI,kBAAkB,eAAe;AAAA,IAC7C;AAAA,IACA,MAAM,UAAU,KAAK,WAAW,UAAU,YAAY,OAAO,oBAAoB,aAAa,YAAY,iBAAiB,uBAAuB;AAAA,IAClJ,IAAI;AAAA,MACF,IAAI,OAAO,oBAAoB;AAAA,QAAY,QAAQ,QAAQ,MAAM,gBAAgB;AAAA,MACjF,MAAM,SAAS,MAAM,kBAAkB,YAAY,KAAK,MAAM,QAAQ,WAAW,MAAM,CAAC;AAAA,MACxF,IAAI,CAAC,KAAK,UAAU,OAAO;AAAA,QAAG,MAAM,IAAI,kBAAkB,WAAW;AAAA,MACrE,QAAQ,SAAS;AAAA,MACjB,OAAO,EAAE,WAAW,QAAQ,IAAI,UAAU,OAAO,UAAU,iBAAiB,kBAAkB,WAAW,QAAQ,UAAU;AAAA,MAC3H,OAAO,OAAO;AAAA,MACd,QAAQ,QAAQ;AAAA,MAChB,QAAQ,WAAW,MAAM;AAAA,MACzB,KAAK,OAAO,QAAQ,EAAE;AAAA,MACtB,MAAM;AAAA;AAAA;AAAA,EAIV,SAAS,CAAC,YAAqB,OAAoC;AAAA,IACjE,IAAI,eAAe,cAAc,OAAO,eAAe,YAAY,WAAW,SAAS,KAAK,WAAW,SAAS,MAAM;AAAA,MACpH,MAAM,IAAI,kBAAkB,eAAe;AAAA,IAC7C;AAAA,IACA,MAAM,OAAO,WAAW,KAAK,KAAK,MAAM;AAAA,IACxC,MAAM,UAAU,KAAK,WAAW,QAAQ,YAAY,OAAO,qBAAqB;AAAA,IAChF,QAAQ,aAAa,KAAK;AAAA,IAC1B,QAAQ,eAAe,KAAK;AAAA,IAC5B,OAAO,EAAE,WAAW,QAAQ,IAAI,kBAAkB,2BAA2B,IAAI,GAAG,WAAW,QAAQ,UAAU;AAAA;AAAA,EAGnH,QAAQ,CAAC,IAAY,OAAyB;AAAA,IAC5C,MAAM,UAAU,KAAK,IAAI,EAAE;AAAA,IAC3B,IAAI,QAAQ,UAAU;AAAA,MAAW,MAAM,IAAI,kBAAkB,MAAM;AAAA,IACnE,QAAQ,QAAQ;AAAA;AAAA,EAGlB,MAAM,CAAC,IAAyB;AAAA,IAC9B,MAAM,UAAU,KAAK,SAAS,IAAI,EAAE;AAAA,IACpC,IAAI,CAAC;AAAA,MAAS,MAAM,IAAI,kBAAkB,WAAW;AAAA,IACrD,OAAO;AAAA,MACL,WAAW,QAAQ;AAAA,MAAI,MAAM,QAAQ;AAAA,MACrC,OAAO,QAAQ,UAAU,eAAe,eAAe,QAAQ,aAAa,KAAK,IAAI,IAAI,YAAY,QAAQ;AAAA,MAC7G,UAAU,QAAQ;AAAA,MAAU,WAAW,QAAQ;AAAA,MAAW,YAAY,QAAQ;AAAA,MAC9E,WAAW,QAAQ,UAAU,eAAe,YAAY,QAAQ,aAAa,KAAK,IAAI,IAAI,YAAY,QAAQ;AAAA,MAC9G,SAAS,QAAQ;AAAA,IACnB;AAAA;AAAA,EAGM,SAAS,CAAC,SAAgC;AAAA,IAChD,OAAO,CAAC,KAAK,YAAY,CAAC,KAAK,WAAW,WAAW,CAAC,QAAQ,WAAW,OAAO,WAC9E,QAAQ,UAAU,eAAe,QAAQ,UAAU,YAAY,QAAQ,UAAU,gBAAgB,QAAQ,YAAY,KAAK,IAAI;AAAA;AAAA,EAG1H,KAAK,CAAC,IAAY,MAA+B;AAAA,IACvD,MAAM,UAAU,KAAK,IAAI,EAAE;AAAA,IAC3B,IAAI,QAAQ,SAAS;AAAA,MAAM,MAAM,IAAI,kBAAkB,eAAe;AAAA,IACtE,IAAI,QAAQ,UAAU;AAAA,MAAa,MAAM,IAAI,kBAAkB,QAAQ,aAAa,KAAK,IAAI,IAAI,YAAY,WAAW;AAAA,IACxH,IAAI,QAAQ,UAAU;AAAA,MAAW,MAAM,IAAI,kBAAkB,kBAAkB;AAAA,IAC/E,IAAI,QAAQ,UAAU;AAAA,MAAU,MAAM,IAAI,kBAAkB,QAAQ;AAAA,IACpE,IAAI,QAAQ,UAAU,aAAa,QAAQ,UAAU,gBAAgB,QAAQ,UAAU;AAAA,MAAc,MAAM,IAAI,kBAAkB,MAAM;AAAA,IACvI,QAAQ,QAAQ,SAAS,WAAW,YAAY;AAAA,IAChD,OAAO;AAAA;AAAA,OAGK,OAAe,CAAC,SAAuB,OAAsB,QAAyG;AAAA,IAClL,IAAI,CAAC,KAAK,UAAU,OAAO;AAAA,MAAG,MAAM,IAAI,kBAAkB,WAAW;AAAA,IAGrE,QAAQ,QAAQ;AAAA,IAChB,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,SAAS,WAAW,YAAY,YAAY,MAAM,OAAO,OAAO,EAAE,YAAY,QAAQ,YAAY,OAAO,QAAQ,MAAM,GAAG,MAAM,QAAQ,UAAU,YAAY;AAAA,MAC9J,OAAO,OAAO;AAAA,MACd,QAAQ,QAAQ;AAAA,MAChB,QAAQ,YAAY;AAAA,MACpB,MAAM;AAAA;AAAA,IAER,QAAQ,UAAU,KAAK,eAAe,MAAM;AAAA,IAC5C,QAAQ,QAAQ;AAAA,IAChB,IAAI,QAAQ,uBAAuB,QAAQ,aAAa,KAAK,IAAI;AAAA,MAAG,KAAK,OAAO,QAAQ,EAAE;AAAA,IAC1F,OAAO,EAAE,OAAO,YAAY,QAAQ,YAAY,OAAO;AAAA;AAAA,EAGjD,cAAc,CAAC,OAAwC;AAAA,IAC7D,IAAI,OAAO,UAAU,YAAY,UAAU;AAAA,MAAM;AAAA,IACjD,MAAM,OAAO;AAAA,IACb,IAAI,OAAO,KAAK,OAAO,YAAY,OAAO,KAAK,UAAU,YAAY,OAAO,KAAK,WAAW,YAAY,OAAO,KAAK,cAAc;AAAA,MAAW;AAAA,IAC7I,MAAM,WAAW,OAAO,KAAK,aAAa,YAAY,KAAK,aAAa,OAAO,KAAK,WAAsC;AAAA,IAC1H,OAAO,EAAE,IAAI,KAAK,IAAI,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,WAAW,KAAK,WAAW,WAAW,OAAO,UAAU,cAAc,WAAW,SAAS,YAAY,UAAU;AAAA;AAAA,OAGzK,eAAiC,CAAC,IAAY,QAAyG;AAAA,IAC3J,MAAM,UAAU,KAAK,MAAM,IAAI,QAAQ;AAAA,IACvC,IAAI;AAAA,MACF,MAAM,SAAS,QAAQ;AAAA,MACvB,IAAI,CAAC;AAAA,QAAQ,MAAM,IAAI,kBAAkB,MAAM;AAAA,MAC/C,MAAM,QAAQ,MAAM,gBAAgB,QAAQ,KAAK,YAAY,KAAK,MAAM,QAAQ,WAAW,MAAM,GAAG,eAAe,KAAK,IAAI,GAAG,QAAQ,YAAY,KAAK,IAAI,CAAC,EAAE,CAAC;AAAA,MAChK,IAAI,CAAC,KAAK,UAAU,OAAO;AAAA,QAAG,MAAM,IAAI,kBAAkB,WAAW;AAAA,MACrE,QAAQ,QAAQ;AAAA,MAChB,MAAM,YAAY,MAAM,iCAAiC,OAAO,YAAY,KAAK,MAAM,QAAQ,WAAW,MAAM,CAAC;AAAA,MACjH,OAAO,MAAM,KAAK,OAAO,SAAS,WAAW,MAAM;AAAA,MACnD,OAAO,OAAO;AAAA,MACd,IAAI,QAAQ,WAAW,OAAO,WAAW,QAAQ,UAAU;AAAA,QAAa,MAAM,IAAI,kBAAkB,WAAW;AAAA,MAC/G,IAAI,QAAQ,UAAU,aAAa,QAAQ,UAAU,cAAc;AAAA,QACjE,QAAQ,QAAQ,QAAQ,WAAW,OAAO,UAAU,cAAc;AAAA,QAClE,QAAQ,YAAY,QAAQ,WAAW,OAAO,UAAU,cAAc;AAAA,QACtE,IAAI,QAAQ,UAAU;AAAA,UAAU,MAAM,IAAI,kBAAkB,QAAQ;AAAA,MACtE;AAAA,MACA,MAAM;AAAA;AAAA;AAAA,OAIJ,aAA+B,CAAC,IAAY,aAAqB,QAAyG;AAAA,IAC9K,MAAM,UAAU,KAAK,MAAM,IAAI,MAAM;AAAA,IACrC,IAAI;AAAA,MACF,IAAI,OAAO,gBAAgB,YAAY,YAAY,SAAS;AAAA,QAAM,MAAM,IAAI,kBAAkB,eAAe;AAAA,MAC7G,MAAM,WAAW,sBAAsB,aAAa,EAAE,eAAe,QAAQ,YAAsB,UAAU,QAAQ,UAAU,KAAK,KAAK,IAAI,GAAG,OAAO,sBAAsB,CAAC;AAAA,MAC9K,IAAI,CAAC,SAAS;AAAA,QAAM,MAAM,IAAI,kBAAkB,WAAW;AAAA,MAC3D,MAAM,QAAQ,MAAM,kBAAkB,SAAS,MAAM,QAAQ,cAAwB,YAAY,KAAK,MAAM,QAAQ,WAAW,MAAM,CAAC;AAAA,MACtI,OAAO,MAAM,KAAK,OAAO,SAAS,OAAO,MAAM;AAAA,MAC/C,OAAO,OAAO;AAAA,MACd,IAAI,QAAQ,WAAW,OAAO,WAAW,QAAQ,UAAU;AAAA,QAAa,MAAM,IAAI,kBAAkB,WAAW;AAAA,MAC/G,IAAI,QAAQ,UAAU,cAAc;AAAA,QAClC,QAAQ,QAAQ,QAAQ,WAAW,OAAO,UAAU,cAAc;AAAA,QAClE,QAAQ,YAAY,QAAQ,WAAW,OAAO,UAAU,cAAc;AAAA,QACtE,IAAI,QAAQ,UAAU;AAAA,UAAU,MAAM,IAAI,kBAAkB,QAAQ;AAAA,MACtE;AAAA,MACA,MAAM;AAAA;AAAA;AAAA,EAIV,MAAM,CAAC,IAAqB;AAAA,IAC1B,MAAM,UAAU,KAAK,IAAI,EAAE;AAAA,IAC3B,IAAI,QAAQ,UAAU,aAAa,QAAQ,UAAU,eAAe,QAAQ,UAAU,YAAY,QAAQ,UAAU;AAAA,MAAc,OAAO;AAAA,IACzI,QAAQ,QAAQ;AAAA,IAChB,QAAQ,WAAW,MAAM,WAAW;AAAA,IACpC,OAAO;AAAA;AAAA,EAGT,OAAO,GAAS;AAAA,IACd,IAAI,KAAK;AAAA,MAAU;AAAA,IACnB,KAAK,WAAW;AAAA,IAChB,KAAK,WAAW,oBAAoB,SAAS,KAAK,WAAW;AAAA,IAC7D,WAAW,WAAW,KAAK,SAAS,OAAO,GAAG;AAAA,MAC5C,IAAI,QAAQ,UAAU;AAAA,QAAc,QAAQ,QAAQ;AAAA,MACpD,IAAI,QAAQ,UAAU;AAAA,QAAc,QAAQ,WAAW,MAAM,UAAU;AAAA,MACvE,QAAQ,WAAW;AAAA,MACnB,aAAa,QAAQ,WAAW;AAAA,IAClC;AAAA,IACA,YAAY,IAAI,YAAY,KAAK;AAAA,MAAU,IAAI,QAAQ,UAAU;AAAA,QAAc,KAAK,OAAO,EAAE;AAAA;AAEjG;;;ACnUO,IAAM,aAAa;AACnB,IAAM,qBAAqB;AAC3B,IAAM,6BAA6B;AACnC,IAAM,eAAe;AACrB,IAAM,eAAe;AAE5B,IAAM,uBAAuB,MAAM;AACnC,IAAM,yBAAyB,KAAK;AACpC,IAAM,iBAAiB;AACvB,IAAM,cAAc;AACpB,IAAM,eAAe;AACrB,IAAM,sBAAqB;AAAA;AA8DpB,MAAM,mBAAmB,MAAM;AAAA,EAEf;AAAA,EADZ,OAAO;AAAA,EAChB,WAAW,CAAU,MAAmK;AAAA,IACtL,MAAM,IAAI;AAAA,IADS;AAAA;AAGvB;AAAA;AAgBA,MAAM,sBAAsB,MAAM;AAAA,EACX;AAAA,EAAmC;AAAA,EAAxD,WAAW,CAAU,MAAmC,mBAA4B;AAAA,IAAE,MAAM,IAAI;AAAA,IAA3E;AAAA,IAAmC;AAAA;AAC1D;AA0BA,SAAS,MAAM,CAAC,OAAyC;AAAA,EACvD,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK;AAAA,IAAG,MAAM,IAAI,cAAc,kBAAkB;AAAA,EACnH,OAAO;AAAA;AAGT,SAAS,aAAa,CAAC,OAAwB;AAAA,EAC7C,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,MAAM,SAAS,kBAAkB,wBAAwB,KAAK,KAAK,GAAG;AAAA,IAC3H,MAAM,IAAI,cAAc,kBAAkB;AAAA,EAC5C;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,YAAY,CAAC,OAAwB;AAAA,EAC5C,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK;AAAA,IAAG,MAAM,IAAI,cAAc,kBAAkB;AAAA,EACpG,OAAO;AAAA;AAGT,SAAS,kBAAkB,CAAC,OAAgB,MAAM,aAAqB;AAAA,EACrE,MAAM,SAAS,aAAa,KAAK;AAAA,EACjC,IAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS,KAAK,SAAS;AAAA,IAAK,MAAM,IAAI,cAAc,kBAAkB;AAAA,EAC3G,OAAO;AAAA;AAGT,SAAS,IAAI,CAAC,OAAyB;AAAA,EACrC,IAAI,OAAO,UAAU;AAAA,IAAW,MAAM,IAAI,cAAc,kBAAkB;AAAA,EAC1E,OAAO;AAAA;AAGT,SAAS,OAAO,CAAC,OAAwB;AAAA,EACvC,MAAM,SAAS,OAAO,UAAU,WAC5B,QAAQ,gBAAoB,QAAQ,OAAO,QAC3C,OAAO,UAAU,WAAW,KAAK,MAAM,KAAK,IAAI;AAAA,EACpD,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,KAAK,SAAS;AAAA,IAAuB,MAAM,IAAI,cAAc,kBAAkB;AAAA,EACxH,OAAO;AAAA;AAGT,SAAS,aAAY,CAAC,OAAoC;AAAA,EACxD,IAAI,UAAU,aAAa,UAAU,QAAQ,UAAU;AAAA,IAAI;AAAA,EAC3D,OAAO,cAAc,KAAK;AAAA;AAG5B,SAAS,eAAe,CAAC,OAAoC;AAAA,EAC3D,OAAO,UAAU,aAAa,UAAU,OAAO,YAAY,QAAQ,KAAK;AAAA;AAG1E,SAAS,cAAc,CAAC,OAAsB,KAAiC;AAAA,EAC7E,IAAI,UAAU,QAAQ,MAAM,KAAK,MAAM,SAAS,MAAM,WAAW;AAAA,IAAG;AAAA,EACpE,MAAM,UAAU,kBAAkB,KAAK,KAAK,IAAI,OAAO,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,OAAO;AAAA,EAC5F,OAAO,OAAO,SAAS,OAAO,KAAK,WAAW,KAAK,WAAW,OAAO,mBAAmB,UAAU;AAAA;AAGpG,SAAS,YAAY,CAAC,OAAsC;AAAA,EAC1D,OAAO,MAAM,sBAAsB,YAC/B,EAAE,MAAM,MAAM,KAAK,IACnB,EAAE,MAAM,MAAM,MAAM,mBAAmB,MAAM,kBAAkB;AAAA;AAGrE,SAAS,UAAU,CAAC,UAA0B;AAAA,EAC5C,IAAI;AAAA,IAAO,SAAS,MAAM,OAAO,EAAE,MAAM,MAAG;AAAA,MAAG;AAAA,KAAS;AAAA,IAAK,MAAM;AAAA;AAGrE,SAAS,WAAW,CAAC,OAAgB,KAA0B;AAAA,EAC7D,MAAM,QAAQ,OAAO,KAAK;AAAA,EAC1B,MAAM,cAAc,aAAa,MAAM,YAAY;AAAA,EACnD,MAAM,gBAAgB,aAAa,MAAM,wBAAwB,MAAM,cAAc;AAAA,EACrF,IAAI,cAAc,KAAK,cAAc,OAAO,iBAAiB;AAAA,IAAG,MAAM,IAAI,cAAc,kBAAkB;AAAA,EAC1G,MAAM,WAAW,MAAM,wBAAwB;AAAA,EAC/C,MAAM,QAAQ,MAAM,aAAa;AAAA,EACjC,IAAI,CAAC,YAAY,CAAC;AAAA,IAAO,MAAM,IAAI,cAAc,kBAAkB;AAAA,EACnE,MAAM,oBAAoB,WAAW,aAAa,MAAM,mBAAmB,IAAI,KAAK,IAAI,IAAI,QAAQ,MAAM,QAAQ,IAAI,OAAO,IAAI;AAAA,EACjI,MAAM,UAAU,QAAQ,QAAQ,MAAM,QAAQ,IAAI,MAAM,oBAAoB;AAAA,EAC5E,IAAI,oBAAoB,KAAK,CAAC,OAAO,SAAS,iBAAiB,KAAK,CAAC,OAAO,SAAS,OAAO;AAAA,IAAG,MAAM,IAAI,cAAc,kBAAkB;AAAA,EACzI,OAAO,EAAE,aAAa,eAAe,mBAAmB,QAAQ;AAAA;AAGlE,SAAS,UAAU,CAAC,OAAgB,KAAoD;AAAA,EACtF,MAAM,QAAQ,OAAO,KAAK;AAAA,EAC1B,MAAM,OAAO,MAAM,eAAe,YAAY,QAAQ,OAAO,MAAM,UAAU;AAAA,EAC7E,MAAM,SAAoJ,CAAC;AAAA,EAC3J,IAAI,MAAM,cAAc;AAAA,IAAW,OAAO,WAAW,cAAc,MAAM,SAAS;AAAA,EAClF,IAAI,MAAM,YAAY;AAAA,IAAW,OAAO,UAAU,KAAK,MAAM,OAAO;AAAA,EAC/D,SAAI,KAAK,YAAY;AAAA,IAAW,OAAO,UAAU,KAAK,KAAK,OAAO;AAAA,EACvE,IAAI,MAAM,kBAAkB;AAAA,IAAW,OAAO,eAAe,KAAK,MAAM,aAAa;AAAA,EAChF,SAAI,KAAK,kBAAkB;AAAA,IAAW,OAAO,eAAe,KAAK,KAAK,aAAa;AAAA,EACxF,IAAI,MAAM,6BAA6B,aAAa,MAAM,6BAA6B,MAAM;AAAA,IAC3F,MAAM,eAAe,OAAO,MAAM,wBAAwB;AAAA,IAC1D,OAAO,iBAAiB,mBAAmB,aAAa,eAAe;AAAA,EACzE;AAAA,EACA,IAAI,KAAK,mBAAmB,aAAa,KAAK,mBAAmB;AAAA,IAAM,OAAO,UAAU,YAAY,KAAK,gBAAgB,GAAG;AAAA,EAC5H,IAAI,KAAK,qBAAqB,aAAa,KAAK,qBAAqB;AAAA,IAAM,OAAO,YAAY,YAAY,KAAK,kBAAkB,GAAG;AAAA,EACpI,IAAI,OAAO,aAAa,aAAa,OAAO,YAAY,aAAa,OAAO,iBAAiB,aAAa,OAAO,mBAAmB,aAC/H,OAAO,YAAY,aAAa,OAAO,cAAc;AAAA,IAAW,MAAM,IAAI,cAAc,kBAAkB;AAAA,EAC/G,OAAO;AAAA;AAGT,SAAS,WAAW,CAAC,OAA6B;AAAA,EAChD,MAAM,QAAQ,OAAO,KAAK;AAAA,EAC1B,MAAM,KAAK,cAAc,MAAM,EAAE;AAAA,EACjC,MAAM,YAAY,cAAc,MAAM,UAAU;AAAA,EAChD,MAAM,YAAY,QAAQ,MAAM,UAAU;AAAA,EAC1C,MAAM,YAAY,MAAM;AAAA,EACxB,IAAI,cAAc,aAAa,OAAO,cAAc;AAAA,IAAU,MAAM,IAAI,cAAc,kBAAkB;AAAA,EACxG,IAAI,cAAc;AAAA,IAAW,MAAM,IAAI,cAAc,kBAAkB;AAAA,EACvE,MAAM,SAAS,cAAc,eAAe,cAAc,eAAe,cAAc,aAAa,YAAY;AAAA,EAChH,MAAM,SAAsB,EAAE,IAAI,WAAW,QAAQ,UAAU;AAAA,EAC/D,YAAY,QAAQ,WAAW,CAAC,CAAC,SAAS,OAAO,GAAG,CAAC,eAAe,aAAa,CAAC,GAAY;AAAA,IAC5F,MAAM,OAAO,cAAa,MAAM,OAAO;AAAA,IACvC,IAAI,SAAS;AAAA,MAAY,OAA8C,UAAU;AAAA,EACnF;AAAA,EACA,MAAM,YAAY,gBAAgB,MAAM,UAAU;AAAA,EAClD,IAAI,cAAc;AAAA,IAAY,OAA8C,YAAY;AAAA,EACxF,OAAO;AAAA;AAGT,SAAS,iBAAiB,CAAC,OAA8D;AAAA,EACvF,MAAM,QAAQ,OAAO,KAAK;AAAA,EAC1B,MAAM,iBAAiB,mBAAmB,MAAM,eAAe;AAAA,EAC/D,IAAI,CAAC,MAAM,QAAQ,MAAM,OAAO,KAAK,MAAM,QAAQ,SAAS;AAAA,IAAa,MAAM,IAAI,cAAc,kBAAkB;AAAA,EACnH,MAAM,UAAU,MAAM,QAAQ,IAAI,WAAW,EAAE,KAAK,CAAC,GAAG,OAAO,EAAE,aAAa,OAAO,qBAAqB,EAAE,aAAa,OAAO,iBAAiB;AAAA,EACjJ,OAAO,EAAE,gBAAgB,QAAQ;AAAA;AAGnC,eAAe,QAAQ,CAAC,UAAoB,QAAqB,UAAoC;AAAA,EACnG,IAAI,CAAC,SAAS;AAAA,IAAM;AAAA,EACpB,IAAI,OAAO;AAAA,IAAS,MAAM,IAAI,WAAW,OAAO,WAAW,YAAY,YAAY,WAAW;AAAA,EAC9F,MAAM,SAAS,SAAS,KAAK,UAAU;AAAA,EACvC,MAAM,UAAU,IAAI;AAAA,EACpB,IAAI,OAAO;AAAA,EACX,IAAI,QAAQ;AAAA,EACZ,IAAI;AAAA,EACJ,MAAM,QAAQ,IAAI,QAAe,CAAC,GAAG,WAAW;AAAA,IAC9C,UAAU,MAAM,OAAO,IAAI,WAAW,OAAO,WAAW,YAAY,YAAY,WAAW,CAAC;AAAA,IAC5F,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,GACzD;AAAA,EACD,IAAI;AAAA,IACF,UAAS;AAAA,MACP,MAAM,OAAO,MAAM,QAAQ,KAAK,CAAC,OAAO,KAAK,GAAG,KAAK,CAAC;AAAA,MACtD,IAAI,KAAK;AAAA,QAAM;AAAA,MACf,SAAS,KAAK,MAAM;AAAA,MACpB,IAAI,QAAQ;AAAA,QAAU,MAAM,IAAI,cAAc,kBAAkB;AAAA,MAChE,QAAQ,QAAQ,OAAO,KAAK,OAAO,EAAE,QAAQ,KAAK,CAAC;AAAA,IACrD;AAAA,IACA,QAAQ,QAAQ,OAAO;AAAA,IACvB,OAAO,OAAO;AAAA,IACT,OAAO,OAAO,EAAE,MAAM,MAAG;AAAA,MAAG;AAAA,KAAS;AAAA,IAC1C,MAAM;AAAA,YACN;AAAA,IACA,OAAO,oBAAoB,SAAS,OAAO;AAAA,IAC3C,OAAO,YAAY;AAAA;AAAA,EAErB,IAAI;AAAA,IAAE,OAAO,KAAK,MAAM,IAAI;AAAA,IAC5B,MAAM;AAAA,IAAE,MAAM,IAAI,cAAc,kBAAkB;AAAA;AAAA;AAGpD,SAAS,OAAU,CAAC,SAAqB,QAAqB,YAAqC;AAAA,EACjG,IAAI,WAAW;AAAA,IAAS,OAAO,QAAQ,OAAO,IAAI,WAAW,UAAU,CAAC;AAAA,EACxE,IAAI,OAAO;AAAA,IAAS,OAAO,QAAQ,OAAO,IAAI,WAAW,WAAW,CAAC;AAAA,EACrE,OAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AAAA,IACzC,IAAI,UAAU;AAAA,IACd,MAAM,UAAU,MAAM;AAAA,MAAE,OAAO,oBAAoB,SAAS,QAAQ;AAAA,MAAG,WAAW,oBAAoB,SAAS,SAAS;AAAA;AAAA,IACxH,MAAM,WAAW,MAAM;AAAA,MAAE,IAAI,CAAC,SAAS;AAAA,QAAE,UAAU;AAAA,QAAM,QAAQ;AAAA,QAAG,OAAO,IAAI,WAAW,WAAW,CAAC;AAAA,MAAG;AAAA;AAAA,IACzG,MAAM,YAAY,MAAM;AAAA,MAAE,IAAI,CAAC,SAAS;AAAA,QAAE,UAAU;AAAA,QAAM,QAAQ;AAAA,QAAG,OAAO,IAAI,WAAW,UAAU,CAAC;AAAA,MAAG;AAAA;AAAA,IACzG,OAAO,iBAAiB,SAAS,UAAU,EAAE,MAAM,KAAK,CAAC;AAAA,IACzD,WAAW,iBAAiB,SAAS,WAAW,EAAE,MAAM,KAAK,CAAC;AAAA,IAC9D,QAAQ,KAAK,CAAC,UAAU;AAAA,MAAE,IAAI,CAAC,SAAS;AAAA,QAAE,UAAU;AAAA,QAAM,QAAQ;AAAA,QAAG,QAAQ,KAAK;AAAA,MAAG;AAAA,OAAK,CAAC,UAAU;AAAA,MAAE,IAAI,CAAC,SAAS;AAAA,QAAE,UAAU;AAAA,QAAM,QAAQ;AAAA,QAAG,OAAO,KAAK;AAAA,MAAG;AAAA,KAAG;AAAA,GACrK;AAAA;AAAA;AAGI,MAAM,aAAa;AAAA,EAYK;AAAA,EAXZ;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ,IAAI;AAAA,EACZ,OAAO,IAAI;AAAA,EACX,SAAS,IAAI;AAAA,EACb,eAAe,IAAI;AAAA,EACnB,SAAS,IAAI;AAAA,EACb,iBAAiB,IAAI;AAAA,EACrB,oBAAoB,MAAM,KAAK,QAAQ;AAAA,EAExD,WAAW,CAAkB,MAAyB;AAAA,IAAzB;AAAA,IAC3B,KAAK,YAAY,KAAK,aAAa;AAAA,IACnC,KAAK,MAAM,KAAK,OAAO,KAAK;AAAA,IAC5B,KAAK,YAAY,KAAK,IAAI,GAAG,KAAK,aAAa,mBAAkB;AAAA,IACjE,IAAI,KAAK,WAAW;AAAA,MAAS,KAAK,QAAQ;AAAA,IACrC;AAAA,WAAK,WAAW,iBAAiB,SAAS,KAAK,mBAAmB,EAAE,MAAM,KAAK,CAAC;AAAA;AAAA,EAG/E,KAAK,CAAC,YAA4B;AAAA,IAAE,OAAO,KAAK,OAAO,IAAI,UAAU,KAAK;AAAA;AAAA,EAE1E,YAAY,CAAC,YAAoB,YAA4B;AAAA,IAAE,OAAO,GAAG,iBAAmB;AAAA;AAAA,EAE5F,UAAU,CAAC,YAAoB,WAAW,MAAY;AAAA,IAC5D,KAAK,OAAO,IAAI,YAAY,KAAK,MAAM,UAAU,IAAI,CAAC;AAAA,IACtD,KAAK,MAAM,OAAO,UAAU;AAAA,IAC5B,WAAW,OAAO,KAAK,KAAK,KAAK,GAAG;AAAA,MAClC,IAAI,CAAC,IAAI,WAAW,GAAG,gBAAkB;AAAA,QAAG;AAAA,MAC5C,IAAI;AAAA,QAAU,KAAK,eAAe,IAAI,GAAG,GAAG,MAAM,aAAa;AAAA,MAC/D,KAAK,eAAe,OAAO,GAAG;AAAA,MAC9B,KAAK,KAAK,OAAO,GAAG;AAAA,IACtB;AAAA;AAAA,EAGF,iBAAiB,CAAC,YAA0B;AAAA,IAAE,KAAK,WAAW,UAAU;AAAA;AAAA,OAE1D,YAAW,CACvB,KACA,OACA,iBACA,QACA,MACkC;AAAA,IAClC,IAAI,gBAAgB;AAAA,MAAS,MAAM,IAAI,WAAW,KAAK,KAAK,WAAW,UAAU,aAAa,WAAW;AAAA,IACzG,MAAM,aAAa,IAAI;AAAA,IACvB,IAAI,WAAW;AAAA,IACf,IAAI;AAAA,IACJ,MAAM,UAAU,IAAI,QAAe,CAAC,GAAG,WAAW;AAAA,MAAE,cAAc;AAAA,KAAS;AAAA,IAC3E,MAAM,UAAU,MAAM;AAAA,MACpB,WAAW,MAAM,gBAAgB,MAAM;AAAA,MACvC,YAAY,IAAI,WAAW,KAAK,KAAK,WAAW,UAAU,aAAa,WAAW,CAAC;AAAA;AAAA,IAErF,gBAAgB,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,IACjE,IAAI;AAAA,IACJ,MAAM,UAAU,IAAI,QAAe,CAAC,GAAG,WAAW;AAAA,MAAE,gBAAgB;AAAA,KAAS;AAAA,IAC7E,MAAM,QAAQ,WAAW,MAAM;AAAA,MAC7B,WAAW;AAAA,MACX,WAAW,MAAM,SAAS;AAAA,MAC1B,cAAc,IAAI,cAAc,SAAS,CAAC;AAAA,OACzC,KAAK,SAAS;AAAA,IACjB,IAAI;AAAA,MACF,MAAM,UAAkC;AAAA,QACtC,eAAe,MAAM,QAAQ;AAAA,QAC7B,sBAAsB,MAAM,QAAQ;AAAA,QACpC,eAAe;AAAA,QACf,gBAAgB;AAAA,QAChB,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,QAClB,UAAU;AAAA,MACZ;AAAA,MACA,IAAI,WAAW;AAAA,QAAQ,QAAQ,kBAAkB;AAAA,MACjD,IAAI;AAAA,MACJ,IAAI;AAAA,QACF,WAAW,MAAM,QAAQ,KAAK,CAAC,KAAK,UAAU,KAAK;AAAA,UACjD;AAAA,UACA;AAAA,aACI,SAAS,YAAY,CAAC,IAAI,EAAE,MAAM,KAAK,UAAU,IAAI,EAAE;AAAA,UAC3D,UAAU;AAAA,UACV,QAAQ,WAAW;AAAA,QACrB,CAAC,GAAG,SAAS,OAAO,CAAC;AAAA,QACrB,MAAM;AAAA,QACN,IAAI;AAAA,UAAU,MAAM,IAAI,cAAc,SAAS;AAAA,QAC/C,IAAI,gBAAgB;AAAA,UAAS,MAAM,IAAI,WAAW,KAAK,KAAK,WAAW,UAAU,aAAa,WAAW;AAAA,QACzG,MAAM,IAAI,cAAc,sBAAsB;AAAA;AAAA,MAEhD,MAAM,oBAAoB,SAAS,WAAW,MAAM,eAAe,SAAS,QAAQ,IAAI,aAAa,GAAG,KAAK,IAAI,CAAC,IAAI;AAAA,MACtH,IAAI,SAAS,SAAS,OAAO,SAAS,UAAU,OAAO,SAAS,YAAY;AAAA,QAC1E,WAAW,QAAQ;AAAA,QACnB,IAAI,SAAS,WAAW;AAAA,UAAK,MAAM,IAAI,cAAc,WAAW;AAAA,QAChE,IAAI,SAAS,WAAW;AAAA,UAAK,MAAM,IAAI,cAAc,sBAAsB,iBAAiB;AAAA,QAC5F,IAAI,SAAS,WAAW;AAAA,UAAK,MAAM,IAAI,cAAc,gBAAgB,iBAAiB;AAAA,QACtF,MAAM,IAAI,cAAc,sBAAsB;AAAA,MAChD;AAAA,MACA,MAAM,SAAS,MAAM,SAAS,UAAU,WAAW,QAAQ,WAAW,SAAS,yBAAyB,oBAAoB;AAAA,MAC5H,OAAO,EAAE,OAAO,QAAQ,kBAAkB;AAAA,MAC1C,OAAO,OAAO;AAAA,MACd,IAAI,YAAY,EAAE,iBAAiB;AAAA,QAAa,MAAM,IAAI,cAAc,SAAS;AAAA,MACjF,MAAM;AAAA,cACN;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,gBAAgB,oBAAoB,SAAS,OAAO;AAAA;AAAA;AAAA,OAI1C,WAAU,CAAC,YAAoB,SAAiC;AAAA,IAC5E,KAAK,WAAW,YAAY,KAAK;AAAA,IACjC,IAAI;AAAA,IACJ,IAAI;AAAA,MAAE,WAAW,MAAM,KAAK,KAAK,aAAa,YAAY,OAAO;AAAA,MACjE,MAAM;AAAA,MAAE,MAAM,IAAI,WAAW,sBAAsB;AAAA;AAAA,IACnD,MAAM,IAAI,WAAW,WAAW,oBAAoB,kBAAkB;AAAA;AAAA,OAG1D,OAAM,CAAC,YAAoB,OAAwB,QAAqB,gBAA8C;AAAA,IAClI,MAAM,WAAW,KAAK,MAAM,IAAI,UAAU;AAAA,IAC1C,MAAM,iBAAiB,UAAU,eAAe,MAAM,WAAW,SAAS,MAAM,UAAU;AAAA,IAC1F,MAAM,wBAAwB,UAAU,eAAe,MAAM,WAAW,SAAS,aAAa,UAAU;AAAA,IACxG,OAAO,OAAO,WAAW,MAAM,QAAQ,WAAW;AAAA,MAChD,KAAK,YAAY,GAAG,eAAe,cAAc,OAAO,QAAQ,KAAK;AAAA,MACrE,KAAK,YAAY,GAAG,eAAe,sBAAsB,OAAO,QAAQ,KAAK;AAAA,IAC/E,CAAC;AAAA,IACD,IAAI,KAAK,KAAK,WAAW;AAAA,MAAS,MAAM,IAAI,WAAW,UAAU;AAAA,IACjE,MAAM,eAAe,CAAC,OAAO,OAAO,EAAE,KAAK,CAAC,SAAS,KAAK,WAAW,cAAc,KAAK,kBAAkB,iBAAiB,KAAK,OAAO,SAAS,WAAW;AAAA,IAC3J,IAAI;AAAA,MAAc,OAAO,KAAK,WAAW,YAAY,MAAM,OAAO;AAAA,IAClE,IAAI,aAAa,MAAM,WAAW,aAAa,MAAM,SAAS;AAAA,IAC9D,IAAI,eAAe,QAAQ,WAAW,aAAa,QAAQ,SAAS;AAAA,IACpE,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI,MAAM,WAAW,aAAa;AAAA,MAChC,IAAI;AAAA,QAAE,aAAa,WAAW,MAAM,MAAM,OAAO,KAAK,IAAI,CAAC;AAAA,QAC3D,OAAO,OAAO;AAAA,QAAE,kBAAkB,iBAAiB,gBAAgB,QAAQ,IAAI,cAAc,kBAAkB;AAAA;AAAA,IACjH;AAAA,IACA,IAAI,QAAQ,WAAW,aAAa;AAAA,MAClC,IAAI;AAAA,QAAE,eAAe,kBAAkB,QAAQ,MAAM,KAAK;AAAA,QAC1D,OAAO,OAAO;AAAA,QAAE,oBAAoB,iBAAiB,gBAAgB,QAAQ,IAAI,cAAc,kBAAkB;AAAA;AAAA,IACnH;AAAA,IACA,IAAI,oBAAoB;AAAA,MAAW,aAAa;AAAA,IAChD,IAAI,sBAAsB;AAAA,MAAW,eAAe;AAAA,IACpD,MAAM,eAAe,sBAAsB,gBAAgB,aAAa,UAAU,IAAI,sBAAsB,aAAa,EAAE,MAAM,WAAW,SAAS,YAAY,YAAY,YAAY,IAAsB,EAAE,MAAM,mBAA4B;AAAA,IACnP,MAAM,iBAAiB,wBAAwB,gBAAgB,aAAa,YAAY,IAAI,wBAAwB,aAAa,EAAE,MAAM,aAAa,SAAS,YAAY,YAAY,YAAY,IAAsB,EAAE,MAAM,mBAA4B;AAAA,IAC7P,MAAM,eAA6B,eAAe,YAC9C,EAAE,OAAO,YAAY,WAAW,IAChC,kBAAkB,UAAU,MAAM,UAAU,YAC5C,EAAE,OAAO,YAAY,SAAS,MAAM,OAAO,OAAO,aAAa,IAC/D,EAAE,OAAO,eAAe,OAAO,aAAa;AAAA,IAChD,MAAM,iBAAsC,iBAAiB,YACzD,EAAE,OAAO,YAAY,aAAa,IAClC,yBAAyB,UAAU,aAAa,UAAU,YAC1D,EAAE,OAAO,YAAY,SAAS,aAAa,OAAO,OAAO,eAAe,IACxE,EAAE,OAAO,eAAe,OAAO,eAAe;AAAA,IAClD,MAAM,SAAS,EAAE,OAAO,cAAc,cAAc,eAAe;AAAA,IACnE,IAAI,KAAK,MAAM,UAAU,MAAM,kBAAkB,CAAC,KAAK,KAAK,WAAW,SAAS;AAAA,MAC9E,KAAK,MAAM,IAAI,YAAY;AAAA,QACzB,YAAY,MAAM;AAAA,QAClB,OAAO,eAAe,YAClB,EAAE,OAAO,aAAa,OAAO,OAAO,iBAAiB,UAAU,MAAM,QAAQ,WAAW,IAAI,iBAAiB,UAAU,MAAM,KAAK,WAAW,OAAO,aAAa,MAAM,IACvK,EAAE,OAAO,SAAS,OAAO,YAAY,IAAI,KAAK,IAAI,EAAE;AAAA,QACxD,cAAc,iBAAiB,YAC3B,EAAE,OAAO,eAAe,OAAO,OAAO,wBAAwB,UAAU,aAAa,QAAQ,WAAW,IAAI,wBAAwB,UAAU,aAAa,KAAK,WAAW,OAAO,eAAe,MAAM,IACvM,EAAE,OAAO,SAAS,OAAO,cAAc,IAAI,KAAK,IAAI,EAAE;AAAA,MAC5D,CAAC;AAAA,IACH;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,IAAG,CAAC,YAAoB,QAAqB,UAAoD,CAAC,GAAyB;AAAA,IAC/H,MAAM,QAAQ,MAAM,QAAQ,KAAK,KAAK,WAAW,YAAY,MAAM,GAAG,QAAQ,KAAK,KAAK,UAAU;AAAA,IAClG,MAAM,SAAS,KAAK,MAAM,IAAI,UAAU;AAAA,IACxC,IAAI,CAAC,QAAQ,cAAc,QAAQ,eAAe,MAAM,SAAS;AAAA,MAC/D,MAAM,aAAa,OAAO,MAAM,UAAU,WAAW,OAAO,MAAM,OAAO,aAAa,KAAK,IAAI,IAAI,OAAO,MAAM,MAAM;AAAA,MACtH,MAAM,eAAe,OAAO,aAAa,UAAU,WAAW,OAAO,aAAa,OAAO,aAAa,KAAK,IAAI,IAAI,OAAO,aAAa,MAAM;AAAA,MAC7I,IAAI,cAAc,cAAc;AAAA,QAC9B,OAAO;AAAA,UACL,OAAO,OAAO,MAAM,UAAU,YAAY,EAAE,OAAO,OAAO,MAAM,OAAO,OAAO,OAAO,MAAM,MAAM,IAAI,EAAE,OAAO,OAAO,MAAM,UAAU,OAAO,MAAM,UAAW,OAAO,MAAM,QAAQ,EAAE,OAAO,OAAO,MAAM,MAAM,IAAI,CAAC,EAAG;AAAA,UACtN,cAAc,OAAO,aAAa,UAAU,YAAY,EAAE,OAAO,OAAO,aAAa,OAAO,OAAO,OAAO,aAAa,MAAM,IAAI,EAAE,OAAO,OAAO,aAAa,UAAU,OAAO,aAAa,UAAW,OAAO,aAAa,QAAQ,EAAE,OAAO,OAAO,aAAa,MAAM,IAAI,CAAC,EAAG;AAAA,QAChR;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM,eAAe,KAAK,aAAa,YAAY,MAAM,OAAO;AAAA,IAChE,IAAI,YAAY,KAAK,KAAK,IAAI,YAAY;AAAA,IAC1C,IAAI,cAAc,WAAW;AAAA,MAC3B,MAAM,aAAa,IAAI;AAAA,MACvB,KAAK,eAAe,IAAI,cAAc,UAAU;AAAA,MAChD,MAAM,QAAQ,KAAK,MAAM,UAAU;AAAA,MACnC,MAAM,UAAU,KAAK,OAAO,YAAY,OAAO,WAAW,QAAQ,KAAK,EAAE,QAAQ,MAAM;AAAA,QACrF,IAAI,KAAK,KAAK,IAAI,YAAY,GAAG,YAAY;AAAA,UAAS,KAAK,KAAK,OAAO,YAAY;AAAA,QACnF,IAAI,KAAK,eAAe,IAAI,YAAY,MAAM;AAAA,UAAY,KAAK,eAAe,OAAO,YAAY;AAAA,OAClG;AAAA,MACD,YAAY,EAAE,YAAY,MAAM,SAAS,YAAY,QAAQ;AAAA,MAC7D,KAAK,KAAK,IAAI,cAAc,SAAS;AAAA,IACvC;AAAA,IACA,MAAM,SAAS,MAAM,QAAQ,UAAU,SAAS,QAAQ,KAAK,KAAK,UAAU;AAAA,IAC5E,MAAM,SAAS,MAAM,QAAQ,KAAK,KAAK,WAAW,YAAY,MAAM,GAAG,QAAQ,KAAK,KAAK,UAAU;AAAA,IACnG,IAAI,OAAO,YAAY,MAAM,SAAS;AAAA,MACpC,KAAK,WAAW,UAAU;AAAA,MAC1B,KAAK,QAAQ,SAAS,MAAM;AAAA,QAAG,MAAM,IAAI,WAAW,kBAAkB;AAAA,MACtE,OAAO,KAAK,IAAI,YAAY,QAAQ,EAAE,YAAY,MAAM,QAAQ,QAAQ,SAAS,KAAK,EAAE,CAAC;AAAA,IAC3F;AAAA,IACA,OAAO;AAAA;AAAA,EAGD,QAAQ,CAAC,iBAAyB,UAA0B;AAAA,IAAE,OAAO,GAAG,sBAAwB;AAAA;AAAA,EAExG,mBAAmB,CAAC,YAAoB,iBAAyB,UAAwB;AAAA,IACvF,KAAK,aAAa,IAAI,YAAY,KAAK,SAAS,iBAAiB,QAAQ,CAAC;AAAA;AAAA,OAG9D,SAAQ,CAAC,YAAoB,OAAwB,KAAa,MAAoD;AAAA,IAClI,IAAI;AAAA,IACJ,IAAI,eAAe;AAAA,IACnB,IAAI;AAAA,MACF,MAAM,WAAW,MAAM,KAAK,YAAY,GAAG,eAAe,8BAA8B,OAAO,KAAK,KAAK,YAAY,QAAQ,IAAI;AAAA,MACjI,MAAM,QAAQ,OAAO,SAAS,KAAK;AAAA,MACnC,MAAM,OAAO,MAAM;AAAA,MACnB,IAAI,MAAM,kBAAkB,aAAa,MAAM,kBAAkB;AAAA,QAAM,eAAe,mBAAmB,MAAM,eAAe,OAAO,gBAAgB;AAAA,MACrJ,UAAU,SAAS,UAAU,UACzB,SAAS,qBAAqB,qBAC9B,SAAS,qBAAqB,qBAC9B,SAAS,cAAc,cACvB;AAAA,MACJ,OAAO,OAAO;AAAA,MACd,IAAI,iBAAiB,iBAAiB,MAAM,SAAS;AAAA,QAAa,MAAM,KAAK,WAAW,YAAY,MAAM,OAAO;AAAA,MACjH,UAAU;AAAA;AAAA,IAEZ,KAAK,WAAW,UAAU;AAAA,IAC1B,IAAI,YAAY;AAAA,MAAyB,KAAK,aAAa,IAAI,YAAY,GAAG;AAAA,IACzE;AAAA,WAAK,aAAa,OAAO,UAAU;AAAA,IACxC,IAAI;AAAA,IACJ,IAAI;AAAA,MAAE,QAAQ,MAAM,KAAK,IAAI,YAAY,KAAK,KAAK,YAAY,EAAE,YAAY,KAAK,CAAC;AAAA,MACnF,MAAM;AAAA,IACN,OAAO,EAAE,SAAS,iBAAkB,UAAU,YAAY,CAAC,IAAI,EAAE,MAAM,EAAG;AAAA;AAAA,OAGtE,QAAO,CACX,YACA,iBACA,UACA,QACA,UAA8H,CAAC,GACzG;AAAA,IACtB,MAAM,MAAM,KAAK,SAAS,iBAAiB,QAAQ;AAAA,IACnD,MAAM,SAAS,KAAK,OAAO,IAAI,UAAU;AAAA,IACzC,IAAI,WAAW,WAAW;AAAA,MACxB,IAAI,OAAO,QAAQ;AAAA,QAAK,MAAM,IAAI,WAAW,mBAAmB;AAAA,MAChE,OAAO,QAAQ,OAAO,SAAS,QAAQ,KAAK,KAAK,UAAU;AAAA,IAC7D;AAAA,IACA,MAAM,UAAU,KAAK,aAAa,IAAI,UAAU;AAAA,IAChD,IAAI,YAAY,aAAa,YAAY;AAAA,MAAK,MAAM,IAAI,WAAW,mBAAmB;AAAA,IACtF,MAAM,kBAAkB,YAAY;AAAA,IACpC,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,MAAM,UAAU,IAAI,QAAqB,CAAC,SAAS,WAAW;AAAA,MAAE,mBAAmB;AAAA,MAAS,kBAAkB;AAAA,KAAS;AAAA,IACvH,KAAK,OAAO,IAAI,YAAY,EAAE,KAAK,QAAQ,CAAC;AAAA,KACtC,YAAY;AAAA,MAChB,IAAI;AAAA,QACF,IAAI;AAAA,QACJ,IAAI,iBAAiB;AAAA,UACnB,QAAQ,MAAM,KAAK,KAAK,WAAW,YAAY,KAAK,KAAK,UAAU;AAAA,QACrE,EAAO;AAAA,UACL,MAAM,UAAU,MAAM,KAAK,IAAI,YAAY,KAAK,KAAK,YAAY,EAAE,YAAY,KAAK,CAAC;AAAA,UACrF,IAAI,QAAQ,aAAa,UAAU,WAAW,QAAQ,aAAa,mBAAmB;AAAA,YAAW,MAAM,IAAI,WAAW,qBAAqB;AAAA,UAC3I,MAAM,WAAW,QAAQ,aAAa,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,QAAQ;AAAA,UAClF,IAAI,QAAQ,aAAa,kBAAkB,KAAK,UAAU,WAAW;AAAA,YAAa,MAAM,IAAI,WAAW,oBAAoB;AAAA,UAC3H,QAAQ,MAAM,KAAK,KAAK,WAAW,YAAY,KAAK,KAAK,UAAU;AAAA,UACnE,IAAI,QAAQ,cAAc,CAAE,MAAM,QAAQ,WAAW,QAAQ;AAAA,YAAI,MAAM,IAAI,WAAW,oBAAoB;AAAA,UAC1G,MAAM,QAAQ,gBAAgB,QAAQ;AAAA;AAAA,QAExC,KAAK,WAAW,UAAU;AAAA,QAC1B,iBAAiB,MAAM,KAAK,SAAS,YAAY,OAAO,KAAK,EAAE,mBAAmB,iBAAiB,WAAW,SAAS,CAAC,CAAC;AAAA,QACzH,OAAO,OAAO;AAAA,QACd,gBAAgB,KAAK;AAAA,gBACrB;AAAA,QACA,IAAI,KAAK,OAAO,IAAI,UAAU,GAAG,YAAY;AAAA,UAAS,KAAK,OAAO,OAAO,UAAU;AAAA;AAAA,OAEpF;AAAA,IACH,OAAO,QAAQ,SAAS,QAAQ,KAAK,KAAK,UAAU;AAAA;AAAA,EAGtD,OAAO,GAAS;AAAA,IACd,KAAK,KAAK,WAAW,oBAAoB,SAAS,KAAK,iBAAiB;AAAA,IACxE,WAAW,cAAc,KAAK,eAAe,OAAO;AAAA,MAAG,WAAW,MAAM,UAAU;AAAA,IAClF,KAAK,eAAe,MAAM;AAAA,IAC1B,KAAK,KAAK,MAAM;AAAA,IAChB,KAAK,MAAM,MAAM;AAAA,IACjB,KAAK,OAAO,MAAM;AAAA,IAClB,KAAK,aAAa,MAAM;AAAA;AAE5B;;;ACtkBO,IAAM,qBAAqB,KAAK,KAAK;AACrC,IAAM,yBAAyB,IAAI,KAAK;AAC/C,IAAM,qBAAqB;AAa3B,IAAM,eAA+B;AAAA,EACnC,UAAU,CAAC,UAAU,UAAU;AAAA,IAC7B,MAAM,QAAQ,WAAW,MAAM;AAAA,MAAO,SAAS;AAAA,OAAM,KAAK;AAAA,IAC1D,MAAM,QAAQ;AAAA,IACd,OAAO;AAAA;AAAA,EAET,QAAQ,YAAU,aAAa,MAAuC;AACxE;AAEO,SAAS,cAAc,CAAC,QAAqB,KAAsB;AAAA,EACxE,OAAO,OAAO,WAAW,eAAe,OAAO,OAAO,cAAc,YAAY,OAAO,SAAS,OAAO,SAAS,KAC3G,OAAO,YAAY,OAAO,OAAO,YAAY,OAAO;AAAA;AAAA;AAIpD,MAAM,mBAAmB;AAAA,EASX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAZX;AAAA,EACA,UAAU;AAAA,EACV,WAAW;AAAA,EACX;AAAA,EACS,QAAQ,IAAI;AAAA,EACZ,cAAc,IAAI;AAAA,EAEnC,WAAW,CACQ,UACA,OACA,QACA,MAAoB,KAAK,KACzB,QAAwB,cACzC;AAAA,IALiB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,EAGnB,KAAK,GAAS;AAAA,IACZ,IAAI,KAAK,WAAW,KAAK,YAAY,KAAK,OAAO;AAAA,MAAS;AAAA,IAC1D,KAAK,UAAU;AAAA,IACf,KAAK,SAAS,CAAC;AAAA;AAAA,EAGT,QAAQ,CAAC,OAAqB;AAAA,IACpC,IAAI,CAAC,KAAK,WAAW,KAAK,YAAY,KAAK,OAAO;AAAA,MAAS;AAAA,IAC3D,KAAK,SAAS,KAAK,MAAM,SAAS,YAAY;AAAA,MAC5C,IAAI;AAAA,QAAE,MAAM,KAAK,QAAQ;AAAA,QACzB,MAAM,WACN;AAAA,QAAU,KAAK,SAAS,sBAAsB;AAAA;AAAA,OAC7C,KAAK;AAAA;AAAA,EAGV,OAAO,GAAkB;AAAA,IACvB,IAAI,KAAK,YAAY,KAAK,OAAO;AAAA,MAAS,OAAO,QAAQ,QAAQ;AAAA,IACjE,IAAI,CAAC,KAAK;AAAA,MAAS,KAAK,UAAU,KAAK,KAAK,EAAE,QAAQ,MAAM;AAAA,QAAE,KAAK,UAAU;AAAA,OAAY;AAAA,IACzF,OAAO,KAAK;AAAA;AAAA,OAGA,KAAI,GAAkB;AAAA,IAClC,MAAM,WAAW,MAAM,KAAK,SAAS,KAAK;AAAA,IAC1C,MAAM,WAAW,IAAI,IAAI,SAAS,OAAO,aAAW,QAAQ,aAAa,QAAQ,qBAC3E,CAAC,QAAQ,oBAAoB,KAAK,YAAY,IAAI,QAAQ,EAAE,EAAE,EAAE,IAAI,aAAW,QAAQ,EAAE,CAAC;AAAA,IAChG,WAAW,MAAM,KAAK,MAAM,KAAK;AAAA,MAAG,IAAI,CAAC,SAAS,IAAI,EAAE;AAAA,QAAG,KAAK,WAAW,EAAE;AAAA,IAC7E,WAAW,WAAW,UAAU;AAAA,MAC9B,IAAI,KAAK,YAAY,KAAK,OAAO;AAAA,QAAS;AAAA,MAC1C,IAAI,CAAC,SAAS,IAAI,QAAQ,EAAE;AAAA,QAAG;AAAA,MAE/B,IAAI,KAAK,YAAY,IAAI,QAAQ,EAAE;AAAA,QAAG;AAAA,MACtC,IAAI;AAAA,QACF,MAAM,WAAW,MAAM,KAAK,MAAM,IAAI,QAAQ,IAAI,KAAK,QAAQ,EAAE,YAAY,KAAK,CAAC;AAAA,QACnF,IAAI,KAAK,YAAY,KAAK,OAAO;AAAA,UAAS;AAAA,QAE1C,IAAI,SAAS,aAAa,UAAU;AAAA,UAAS;AAAA,QAC7C,KAAK,WAAW,QAAQ,EAAE;AAAA,QAC1B,KAAK,SAAS,aAAa,kBAAkB,MAAM;AAAA,UAAG;AAAA,QACtD,MAAM,UAAU,CAAC,GAAI,SAAS,aAAa,WAAW,CAAC,CAAE,EAAE,OAAO,YAAU,OAAO,WAAW,eACzF,OAAO,OAAO,cAAc,YAAY,OAAO,SAAS,OAAO,SAAS,KAAK,OAAO,YAAY,KAAK,IAAI,CAAC,EAC5G,KAAK,CAAC,GAAG,MAAM,EAAE,YAAa,EAAE,SAAU;AAAA,QAC7C,MAAM,OAAoB,EAAE,QAAQ;AAAA,QACpC,KAAK,MAAM,IAAI,QAAQ,IAAI,IAAI;AAAA,QAC/B,MAAM,KAAK,YAAY,QAAQ,IAAI,IAAI;AAAA,QACvC,MAAM;AAAA,IACV;AAAA;AAAA,EAGM,UAAU,CAAC,YAAoB,UAA8B;AAAA,IACnE,MAAM,OAAO,KAAK,MAAM,IAAI,UAAU;AAAA,IACtC,IAAI,YAAY,SAAS;AAAA,MAAU;AAAA,IACnC,IAAI,MAAM,WAAW;AAAA,MAAW,KAAK,MAAM,OAAO,KAAK,MAAM;AAAA,IAC7D,KAAK,MAAM,OAAO,UAAU;AAAA;AAAA,EAGtB,OAAO,CAAC,YAAoB,MAAyB;AAAA,IAC3D,IAAI,KAAK,YAAY,KAAK,OAAO,WAAW,KAAK,MAAM,IAAI,UAAU,MAAM;AAAA,MAAM;AAAA,IACjF,IAAI,KAAK,QAAQ,WAAW,GAAG;AAAA,MAAE,KAAK,WAAW,UAAU;AAAA,MAAG;AAAA,IAAQ;AAAA,IACtE,MAAM,QAAQ,KAAK,QAAQ,GAAG,YAAa;AAAA,IAE3C,KAAK,SAAS,KAAK,MAAM,SAAS,MAAM,KAAK,YAAY,YAAY,IAAI,GAAG,KAAK,IAAI,oBAAoB,KAAK,IAAI,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC;AAAA;AAAA,EAGnI,WAAW,CAAC,YAAoB,MAAkC;AAAA,IAExE,MAAM,WAAW,KAAK,YAAY,IAAI,UAAU,KAAK,QAAQ,QAAQ;AAAA,IACrE,MAAM,YAAY,SAAS,MAAM,MAAG;AAAA,MAAG;AAAA,KAAS,EAAE,KAAK,YAAY;AAAA,MACjE,IAAI,KAAK,YAAY,KAAK,OAAO,WAAW,KAAK,MAAM,IAAI,UAAU,MAAM;AAAA,QAAM;AAAA,MACjF,IAAI;AAAA,QACF,MAAM,UAAU,gBAAgB,MAAM,KAAK,SAAS,IAAI,UAAU,CAAC;AAAA,QACnE,IAAI,CAAC,QAAQ,aAAa,CAAC,QAAQ,oBAAoB,QAAQ,kBAAkB;AAAA,UAAE,KAAK,WAAW,YAAY,IAAI;AAAA,UAAG;AAAA,QAAQ;AAAA,QAC9H,OAAO,KAAK,MAAM,IAAI,UAAU,MAAM,QAAQ,KAAK,QAAQ,SAAS,GAAG;AAAA,UACrE,IAAI,KAAK,YAAY,KAAK,OAAO;AAAA,YAAS;AAAA,UAC1C,MAAM,SAAS,KAAK,QAAQ;AAAA,UAC5B,IAAI,OAAO,YAAa,qBAAqB,KAAK,IAAI;AAAA,YAAG;AAAA,UACzD,KAAK,QAAQ,MAAM;AAAA,UACnB,IAAI,CAAC,eAAe,QAAQ,KAAK,IAAI,CAAC;AAAA,YAAG;AAAA,UACzC,MAAM,UAAU,MAAM,KAAK,SAAS,eAAe,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,UACjF,IAAI,CAAC;AAAA,YAAS;AAAA,UACd,IAAI;AAAA,UACJ,IAAI;AAAA,YACF,MAAM,SAAS,MAAM,KAAK,MAAM,QAAQ,YAAY,QAAQ,iBAAiB,OAAO,IAAI,KAAK,QAAQ;AAAA,cACnG,YAAY,OAAM,aAAY;AAAA,gBAC5B,MAAM,SAAS,MAAM,KAAK,SAAS,IAAI,UAAU;AAAA,gBACjD,IAAI,KAAK,YAAY,KAAK,OAAO,WAAW,OAAO,qBAAqB,QAAQ,OAAO,WAAW;AAAA,kBAAU,OAAO;AAAA,gBACnH,IAAI,SAAS,WAAW,eAAe,OAAO,SAAS,cAAc,YAAY,OAAO,SAAS,SAAS,SAAS,KAC9G,SAAS,YAAY,qBAAqB,KAAK,IAAI;AAAA,kBAAG,WAAW;AAAA,gBACtE,OAAO,eAAe,UAAU,KAAK,IAAI,CAAC;AAAA;AAAA,YAE9C,CAAC;AAAA,YACD,IAAI,OAAO,YAAY,yBAAyB;AAAA,cAAE,KAAK,WAAW,YAAY,IAAI;AAAA,cAAG;AAAA,YAAQ;AAAA,YAC7F,MAAM,KAAK,SAAS,gBAAgB,YAAY,QAAQ,eAAe;AAAA,YACvE,OAAO,OAAO;AAAA,YAEd,IAAI,iBAAiB,cAAc,CAAC,uBAAuB,sBAAsB,mBAAmB,EAAE,SAAS,MAAM,IAAI,GAAG;AAAA,cAC1H,MAAM,KAAK,SAAS,gBAAgB,YAAY,QAAQ,iBAAiB,IAAI;AAAA,cAC7E,IAAI,MAAM,SAAS,sBAAsB;AAAA,gBACvC,IAAI,UAAU;AAAA,kBACZ,KAAK,QAAQ,KAAK,QAAQ;AAAA,kBAC1B,KAAK,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,YAAa,EAAE,SAAU;AAAA,gBACzD;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,YACA,KAAK,WAAW,YAAY,IAAI;AAAA,YAChC;AAAA;AAAA,QAEJ;AAAA,QACA,KAAK,QAAQ,YAAY,IAAI;AAAA,QAC7B,MAAM;AAAA,QAAE,KAAK,WAAW,YAAY,IAAI;AAAA;AAAA,KAC3C,EAAE,QAAQ,MAAM;AAAA,MACf,IAAI,KAAK,YAAY,IAAI,UAAU,MAAM;AAAA,QAAW,KAAK,YAAY,OAAO,UAAU;AAAA,KACvF;AAAA,IACD,KAAK,YAAY,IAAI,YAAY,SAAS;AAAA,IAC1C,OAAO;AAAA;AAAA,EAGT,OAAO,GAAS;AAAA,IACd,KAAK,UAAU;AAAA,IACf,KAAK,WAAW;AAAA,IAChB,KAAK,MAAM,OAAO,KAAK,MAAM;AAAA,IAC7B,WAAW,MAAM,KAAK,MAAM,KAAK;AAAA,MAAG,KAAK,WAAW,EAAE;AAAA;AAE1D;;;ALzJO,IAAM,iBAAiB;AACvB,IAAM,4BAA4B;AAAA;AAIlC,MAAM,qBAAqB,MAAM;AAAA,EAEjB;AAAA,EADZ,OAAO;AAAA,EAChB,WAAW,CAAU,MAAwB;AAAA,IAAE,MAAM,IAAI;AAAA,IAApC;AAAA;AACvB;AASA,IAAM,2BAA2B;AACjC,IAAM,kBAAkB;AACxB,IAAM,iBAAiB,KAAK;AAE5B,SAAS,SAAS,CAAC,OAA8B;AAAA,EAC/C,IAAI,iBAAiB;AAAA,IAAc,OAAO;AAAA,EAC1C,IAAI,iBAAiB,qBAAqB;AAAA,IACxC,MAAM,MAAwC;AAAA,MAC5C,eAAe;AAAA,MACf,WAAW;AAAA,MAAa,UAAU;AAAA,MAAY,SAAS;AAAA,MAAW,iBAAiB;AAAA,MACnF,mBAAmB;AAAA,MAAqB,kBAAkB;AAAA,MAAoB,UAAU;AAAA,MACxF,eAAe;AAAA,IACjB;AAAA,IACA,OAAO,IAAI,aAAa,IAAI,MAAM,SAAS,gBAAgB;AAAA,EAC7D;AAAA,EACA,IAAI,iBAAiB,mBAAmB;AAAA,IACtC,MAAM,QAA0C,EAAE,eAAe,iBAAiB,WAAW,aAAa,SAAS,WAAW,WAAW,aAAa,kBAAkB,QAAQ,MAAM,QAAQ,QAAQ,gBAAgB,UAAU,WAAW;AAAA,IAC3O,OAAO,IAAI,aAAa,MAAM,MAAM,SAAS,eAAe;AAAA,EAC9D;AAAA,EACA,IAAI,iBAAiB,YAAY;AAAA,IAC/B,MAAM,QAA0C;AAAA,MAC9C,iBAAiB;AAAA,MAAmB,UAAU;AAAA,MAAY,WAAW;AAAA,MACrE,mBAAmB;AAAA,MAAqB,qBAAqB;AAAA,MAAuB,oBAAoB;AAAA,MACxG,kBAAkB;AAAA,MAAwB,sBAAsB;AAAA,IAClE;AAAA,IACA,OAAO,IAAI,aAAa,MAAM,MAAM,SAAS,gBAAgB;AAAA,EAC/D;AAAA,EACA,MAAM,OAAQ,MAA4B;AAAA,EAC1C,IAAI,SAAS;AAAA,IAAwB,OAAO,IAAI,aAAa,iBAAiB;AAAA,EAC9E,IAAI,OAAO,SAAS;AAAA,IAAU,OAAO,IAAI,aAAa,cAAc;AAAA,EACpE,OAAO,IAAI,aAAa,gBAAgB;AAAA;AAG1C,SAAS,YAAY,CAAC,OAAgB,SAAS,KAAe;AAAA,EAC5D,OAAO,IAAI,SAAS,KAAK,UAAU,KAAK,GAAG,EAAE,QAAQ,SAAS,EAAE,gBAAgB,kCAAkC,EAAE,CAAC;AAAA;AAGvH,SAAS,aAAa,CAAC,OAA0B;AAAA,EAC/C,MAAM,OAAO,UAAU,KAAK;AAAA,EAC5B,MAAM,SAAS,KAAK,SAAS,cAAc,MAAM,KAAK,SAAS,mBAAmB,KAAK,SAAS,sBAAsB,MAAM,KAAK,SAAS,eAAe,MAAM,KAAK,SAAS,gCAAgC,MAAM;AAAA,EACnN,OAAO,aAAa,EAAE,OAAO,KAAK,KAAK,GAAG,MAAM;AAAA;AAGlD,SAAS,MAAM,CAAC,OAAyC;AAAA,EACvD,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK;AAAA,IAAG,MAAM,IAAI,aAAa,eAAe;AAAA,EAC/G,OAAO;AAAA;AAGT,SAAS,SAAS,CAAC,OAAgC,MAA+B;AAAA,EAChF,MAAM,UAAU,IAAI,IAAI,IAAI;AAAA,EAC5B,IAAI,OAAO,KAAK,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,IAAI,GAAG,CAAC;AAAA,IAAG,MAAM,IAAI,aAAa,eAAe;AAAA;AAGjG,SAAS,YAAY,CAAC,OAAgB,MAAM,KAAa;AAAA,EACvD,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,MAAM,SAAS,OAAO,MAAM,KAAK,MAAM;AAAA,IAAO,MAAM,IAAI,aAAa,eAAe;AAAA,EAC3I,OAAO;AAAA;AAGT,SAAS,aAAY,CAAC,OAAgB,MAAM,KAAyB;AAAA,EAAE,OAAO,UAAU,YAAY,YAAY,aAAa,OAAO,GAAG;AAAA;AACvI,SAAS,eAAe,CAAC,OAAwB;AAAA,EAC/C,IAAI,CAAC,OAAO,cAAc,KAAK,KAAM,QAAmB;AAAA,IAAG,MAAM,IAAI,aAAa,eAAe;AAAA,EACjG,OAAO;AAAA;AAGT,SAAS,SAAY,CAAC,SAAqB,QAAqB,YAA0B,gBAA0C;AAAA,EAClI,IAAI,YAAY,WAAW,gBAAgB;AAAA,IAAS,OAAO,QAAQ,OAAO,IAAI,aAAa,UAAU,CAAC;AAAA,EACtG,IAAI,OAAO;AAAA,IAAS,OAAO,QAAQ,OAAO,IAAI,aAAa,mBAAmB,CAAC;AAAA,EAC/E,OAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AAAA,IACzC,IAAI,UAAU;AAAA,IACd,MAAM,UAAU,MAAM;AAAA,MAAE,OAAO,oBAAoB,SAAS,cAAc;AAAA,MAAG,YAAY,oBAAoB,SAAS,WAAW;AAAA,MAAG,gBAAgB,oBAAoB,SAAS,eAAe;AAAA;AAAA,IAChM,MAAM,iBAAiB,MAAM;AAAA,MAAE,IAAI,CAAC,SAAS;AAAA,QAAE,UAAU;AAAA,QAAM,QAAQ;AAAA,QAAG,OAAO,IAAI,aAAa,mBAAmB,CAAC;AAAA,MAAG;AAAA;AAAA,IACzH,MAAM,cAAc,MAAM;AAAA,MAAE,IAAI,CAAC,SAAS;AAAA,QAAE,UAAU;AAAA,QAAM,QAAQ;AAAA,QAAG,OAAO,IAAI,aAAa,UAAU,CAAC;AAAA,MAAG;AAAA;AAAA,IAC7G,MAAM,kBAAkB,MAAM;AAAA,MAAE,IAAI,CAAC,SAAS;AAAA,QAAE,UAAU;AAAA,QAAM,QAAQ;AAAA,QAAG,OAAO,IAAI,aAAa,UAAU,CAAC;AAAA,MAAG;AAAA;AAAA,IACjH,OAAO,iBAAiB,SAAS,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAAA,IAC/D,YAAY,iBAAiB,SAAS,aAAa,EAAE,MAAM,KAAK,CAAC;AAAA,IACjE,gBAAgB,iBAAiB,SAAS,iBAAiB,EAAE,MAAM,KAAK,CAAC;AAAA,IACzE,QAAQ,KAAK,CAAC,UAAU;AAAA,MAAE,IAAI,CAAC,SAAS;AAAA,QAAE,UAAU;AAAA,QAAM,QAAQ;AAAA,QAAG,QAAQ,KAAK;AAAA,MAAG;AAAA,OAAK,CAAC,UAAU;AAAA,MAAE,IAAI,CAAC,SAAS;AAAA,QAAE,UAAU;AAAA,QAAM,QAAQ;AAAA,QAAG,OAAO,KAAK;AAAA,MAAG;AAAA,KAAG;AAAA,GACrK;AAAA;AAGH,eAAe,eAAe,CAAC,SAAkB,eAA4B,YAAyB,iBAAiB,YAA8C;AAAA,EACnK,IAAI,WAAW,WAAW,eAAe;AAAA,IAAS,MAAM,IAAI,aAAa,UAAU;AAAA,EACnF,IAAI,cAAc;AAAA,IAAS,MAAM,IAAI,aAAa,mBAAmB;AAAA,EACrE,IAAI,CAAC,QAAQ;AAAA,IAAM,OAAO,CAAC;AAAA,EAC3B,MAAM,SAAS,QAAQ,KAAK,UAAU;AAAA,EACtC,MAAM,UAAU,IAAI;AAAA,EACpB,IAAI,OAAO;AAAA,EACX,IAAI,QAAQ;AAAA,EACZ,IAAI;AAAA,IACF,UAAS;AAAA,MACP,MAAM,OAAO,MAAM,UAAU,OAAO,KAAK,GAAG,eAAe,YAAY,cAAc;AAAA,MACrF,IAAI,KAAK;AAAA,QAAM;AAAA,MACf,SAAS,KAAK,MAAM;AAAA,MACpB,IAAI,QAAQ,gBAAgB;AAAA,QACrB,OAAO,OAAO,EAAE,MAAM,MAAG;AAAA,UAAG;AAAA,SAAS;AAAA,QAC1C,MAAM,IAAI,aAAa,YAAY;AAAA,MACrC;AAAA,MACA,QAAQ,QAAQ,OAAO,KAAK,OAAO,EAAE,QAAQ,KAAK,CAAC;AAAA,IACrD;AAAA,IACA,QAAQ,QAAQ,OAAO;AAAA,IACvB,OAAO,OAAO;AAAA,IACT,OAAO,OAAO,EAAE,MAAM,MAAG;AAAA,MAAG;AAAA,KAAS;AAAA,IAC1C,IAAI,iBAAiB;AAAA,MAAc,MAAM;AAAA,IACzC,MAAM,IAAI,aAAa,eAAe;AAAA,YACtC;AAAA,IAAU,OAAO,YAAY;AAAA;AAAA,EAC/B,IAAI,CAAC;AAAA,IAAM,OAAO,CAAC;AAAA,EACnB,IAAI;AAAA,IAAE,OAAO,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IAAK,MAAM;AAAA,IAAE,MAAM,IAAI,aAAa,eAAe;AAAA;AAAA;AAGzF,SAAS,qBAAqB,CAAC,SAAoC;AAAA,EACjE,MAAM,QAAQ,QAAQ,QAAQ,gBAAgB;AAAA,EAC9C,IAAI,OAAO,UAAU,YAAY,MAAM,SAAS,KAAK,MAAM,SAAS,OAAO,MAAM,KAAK,MAAM;AAAA,IAAO,MAAM,IAAI,aAAa,6BAA6B;AAAA,EACvJ,OAAO;AAAA;AAGT,SAAS,KAAK,CAAC,SAAyC;AAAA,EACtD,IAAI,QAAQ,WAAW;AAAA,IAAU,MAAM,IAAI,aAAa,QAAQ,MAAM;AAAA,EACtE,IAAI,CAAC,QAAQ;AAAA,IAAa,MAAM,IAAI,aAAa,iBAAiB;AAAA,EAClE,IAAI,CAAC,QAAQ,UAAU;AAAA,IAAW,MAAM,IAAI,aAAa,kBAAkB;AAAA,EAC3E,IAAI,CAAC,OAAO,SAAS,QAAQ,SAAS;AAAA,IAAG,MAAM,IAAI,aAAa,iBAAiB;AAAA,EACjF,OAAO,EAAE,SAAS,QAAQ,YAAY,WAAW,QAAQ,WAAqB,SAAS,EAAE,eAAe,UAAU,QAAQ,eAAe,sBAAsB,QAAQ,SAAS,UAAU,EAAE;AAAA;AAG9L,SAAS,aAAa,CAAC,SAAwB,KAAsB;AAAA,EACnE,OAAO,QAAQ,cAAc,aAAa,QAAQ,aAAa,MAAM;AAAA;AAAA;AAGvE,MAAM,eAAwC;AAAA,EAef;AAAA,EAA2C;AAAA,EAd/D;AAAA,EACA;AAAA,EACQ;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc,mBAAmB,YAAW;AAAA,EAC5C,WAAW,IAAI;AAAA,EACf,qBAAqB,IAAI;AAAA,EACzB,cAAc,IAAI;AAAA,EAClB;AAAA,EACA;AAAA,EACT,WAAW;AAAA,EACF;AAAA,EAEjB,WAAW,CAAkB,MAA2C,OAA4B,CAAC,GAAG;AAAA,IAA3E;AAAA,IAA2C;AAAA,IACtE,KAAK,MAAM,KAAK,OAAO,KAAK;AAAA,IAC5B,KAAK,WAAW,IAAI,aAAa,KAAK,aAAa,MAAM,CAAC,KAAK,YAAY,CAAC,KAAK,OAAO,OAAO;AAAA,IAC/F,KAAK,WAAW,IAAI,oBAAoB,KAAK,QAAQ,IAAI;AAAA,IACzD,KAAK,QAAQ,IAAI,aAAa;AAAA,MAC5B,WAAW,KAAK;AAAA,MAChB,KAAK,KAAK;AAAA,MACV,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK,YAAY;AAAA,MAC7B,YAAY,CAAC,IAAI,WAAW,KAAK,WAAW,IAAI,MAAM;AAAA,MACtD,cAAc,CAAC,IAAI,YAAY,KAAK,SAAS,aAAa,IAAI,OAAO;AAAA,IACvE,CAAC;AAAA,IACD,KAAK,YAAY,IAAI,mBAAmB,KAAK,UAAU,KAAK,OAAO,KAAK,YAAY,QAAQ,KAAK,KAAK,KAAK,cAAc;AAAA,IACzH,KAAK,gBAAgB,MAAM;AAAA,MAAO,KAAK,QAAQ;AAAA;AAAA,IAC/C,IAAI,KAAK,OAAO;AAAA,MAAS,KAAK,WAAW;AAAA,IACpC;AAAA,WAAK,OAAO,iBAAiB,SAAS,KAAK,eAAe,EAAE,MAAM,KAAK,CAAC;AAAA,IAC7E,KAAK,MAAM,KAAK,SAAS;AAAA,IACzB,KAAK,MAAM,KAAK,SAAS;AAAA,IACzB,KAAK,UAAU,KAAK,QAAQ,aAAa,OAAO,YAAY,KAAK,IAAI,IAAI,iBAAe,CAAC,YAAY,MAAM,CAAC,SAAkB,YAAiB;AAAA,MAC7I,MAAM,QAAQ,KAAK,mBAAmB,QAAQ,MAAM;AAAA,MACpD,IAAI,CAAC,OAAO,WAAW,CAAC,MAAM,WAAW,MAAM,QAAQ,WAAW;AAAA,QAAiB,MAAM,IAAI,aAAa,6BAA6B;AAAA,MACvI,OAAO,YAAY,OAAO,SAAS,KAAI,MAAM,SAAS,MAAM,SAAS,SAAS,KAAI,MAAM,SAAS,QAAQ,YAAY,IAAI,CAAC,MAAM,QAAQ,QAAQ,QAAQ,MAAM,CAAC,EAAC,EAAC,CAAC;AAAA,KACnK,CAAC,CAAC,CAAQ;AAAA;AAAA,EAGL,WAAW,CAAC,QAA4B;AAAA,IAC9C,IAAI,KAAK,YAAY,KAAK,KAAK,OAAO;AAAA,MAAS,MAAM,IAAI,aAAa,UAAU;AAAA,IAChF,IAAI,QAAQ;AAAA,MAAS,MAAM,IAAI,aAAa,mBAAmB;AAAA;AAAA,OAG3D,MAAK,GAAkB;AAAA,IAC3B,KAAK,YAAY;AAAA,IACjB,MAAM,KAAK,SAAS,KAAK;AAAA,IACzB,KAAK,YAAY;AAAA,IACjB,KAAK,UAAU,MAAM;AAAA;AAAA,OAGT,QAAO,CAAC,IAAY,QAA6C;AAAA,IAC7E,SAAS,UAAU,EAAG,UAAU,KAAK,WAAW;AAAA,MAC9C,KAAK,YAAY,MAAM;AAAA,MACvB,MAAM,UAAU,MAAM,KAAK,SAAS,IAAI,EAAE;AAAA,MAC1C,KAAK,YAAY,MAAM;AAAA,MACvB,IAAI,QAAQ,WAAW;AAAA,QAAU,MAAM,IAAI,aAAa,QAAQ,MAAM;AAAA,MACtE,IAAI,CAAC,cAAc,SAAS,KAAK,IAAI,CAAC;AAAA,QAAG,OAAO;AAAA,MAChD,IAAI,CAAC,QAAQ;AAAA,QAAc,MAAM,IAAI,aAAa,iBAAiB;AAAA,MACnE,MAAM,OAAO,MAAM,KAAK,SAAS,eAAe,IAAI,KAAK,aAAa,KAAK,IAAI,IAAI,eAAe;AAAA,MAClG,KAAK,YAAY,MAAM;AAAA,MACvB,IAAI,CAAC,KAAK,UAAU;AAAA,QAClB,MAAM,UAAU,IAAI,QAAc,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QACjG;AAAA,MACF;AAAA,MACA,MAAM,aAAa,KAAK,QAAQ;AAAA,MAChC,IAAI;AAAA,QACF,MAAM,QAAQ,MAAM,kBAAkB,KAAK,QAAQ,cAAwB,EAAE,WAAW,KAAK,KAAK,WAAW,OAAO,CAAC;AAAA,QACrH,KAAK,YAAY,MAAM;AAAA,QACvB,MAAM,UAAU,MAAM,KAAK,SAAS,mBAAmB,IAAI,OAAO,EAAE,OAAO,KAAK,aAAa,WAAW,CAAC;AAAA,QACzG,KAAK,YAAY,MAAM;AAAA,QACvB,OAAO;AAAA,QACP,OAAO,OAAO;AAAA,QACd,IAAI,KAAK,YAAY,KAAK,KAAK,OAAO;AAAA,UAAS,MAAM,IAAI,aAAa,UAAU;AAAA,QAChF,MAAM,YAAa,MAA4B;AAAA,QAC/C,IAAI,cAAc,wBAAwB;AAAA,UACxC,MAAM,SAAS,MAAM,KAAK,SAAS,kBAAkB,IAAI,KAAK,aAAa,UAAU,EAAE,MAAM,MAAM,KAAK;AAAA,UACxG,IAAI,CAAC,QAAQ;AAAA,YACX,MAAM,SAAS,MAAM,KAAK,SAAS,IAAI,EAAE,EAAE,MAAM,MAAG;AAAA,cAAG;AAAA,aAAS;AAAA,YAChE,IAAI,QAAQ,WAAW;AAAA,cAAW,MAAM,IAAI,aAAa,SAAS;AAAA,YAClE,IAAI,QAAQ,WAAW;AAAA,cAAY,MAAM,IAAI,aAAa,UAAU;AAAA,UACtE;AAAA,UACA,MAAM,IAAI,aAAa,iBAAiB;AAAA,QAC1C;AAAA,QACA,IAAI,iBAAiB,qBAAqB;AAAA,UACxC,MAAM,KAAK,SAAS,eAAe,IAAI,KAAK,aAAa,UAAU;AAAA,UACnE,MAAM,UAAU,KAAK;AAAA,QACvB;AAAA,QACA,MAAM,WAAW,MAAM,KAAK,SAAS,eAAe,IAAI,KAAK,aAAa,UAAU;AAAA,QACpF,IAAI,CAAC,UAAU;AAAA,UACb,MAAM,SAAS,MAAM,KAAK,SAAS,IAAI,EAAE,EAAE,MAAM,MAAG;AAAA,YAAG;AAAA,WAAS;AAAA,UAChE,IAAI,QAAQ,WAAW;AAAA,YAAW,MAAM,IAAI,aAAa,SAAS;AAAA,UAClE,IAAI,QAAQ,WAAW;AAAA,YAAY,MAAM,IAAI,aAAa,UAAU;AAAA,UACpE,IAAI,QAAQ,eAAe;AAAA,YAAY,MAAM,IAAI,aAAa,eAAe;AAAA,QAC/E;AAAA,QACA,IAAI,iBAAiB;AAAA,UAAc,MAAM;AAAA,QACzC,MAAM,IAAI,aAAa,gBAAgB;AAAA;AAAA,IAE3C;AAAA,IACA,MAAM,IAAI,aAAa,qBAAqB;AAAA;AAAA,OAGhC,WAAU,CAAC,IAAY,QAA+C;AAAA,IAClF,KAAK,YAAY,MAAM;AAAA,IACvB,MAAM,UAAU,MAAM,KAAK,SAAS,IAAI,EAAE;AAAA,IAC1C,KAAK,YAAY,MAAM;AAAA,IACvB,IAAI,QAAQ,WAAW;AAAA,MAAU,MAAM,IAAI,aAAa,QAAQ,MAAM;AAAA,IACtE,IAAI,CAAC,cAAc,SAAS,KAAK,IAAI,CAAC,GAAG;AAAA,MAAE,KAAK,YAAY,MAAM;AAAA,MAAG,OAAO,MAAM,OAAO;AAAA,IAAG;AAAA,IAC5F,IAAI,SAAS,KAAK,SAAS,IAAI,EAAE;AAAA,IACjC,IAAI,CAAC,QAAQ;AAAA,MACX,MAAM,aAAa,IAAI;AAAA,MACvB,MAAM,cAAc,MAAM,WAAW,MAAM,UAAU;AAAA,MACrD,KAAK,KAAK,OAAO,iBAAiB,SAAS,aAAa,EAAE,MAAM,KAAK,CAAC;AAAA,MACtE,KAAK,mBAAmB,IAAI,IAAI,UAAU;AAAA,MAC1C,SAAS,KAAK,QAAQ,IAAI,WAAW,MAAM,EAAE,QAAQ,MAAM;AAAA,QACzD,KAAK,KAAK,OAAO,oBAAoB,SAAS,WAAW;AAAA,QACzD,KAAK,mBAAmB,OAAO,EAAE;AAAA,QACjC,KAAK,SAAS,OAAO,EAAE;AAAA,OACxB;AAAA,MACD,KAAK,SAAS,IAAI,IAAI,MAAM;AAAA,IAC9B;AAAA,IACA,MAAM,UAAU,MAAM,UAAU,QAAQ,QAAQ,KAAK,KAAK,MAAM;AAAA,IAChE,KAAK,YAAY,MAAM;AAAA,IACvB,OAAO,MAAM,OAAO;AAAA;AAAA,OAGR,YAAW,CAAC,OAAsB,MAAuB,WAAoD;AAAA,IACzH,KAAK,YAAY;AAAA,IACjB,IAAI,CAAC,UAAU;AAAA,MAAG,MAAM,IAAI,aAAa,eAAe;AAAA,IACxD,MAAM,UAAU,KAAK,eAAe,YAChC,MAAM,KAAK,SAAS,OAAO,MAAM,UAAU,SAAS,WAAW,OAAO,MAAM,UAAU,CAAC,IACvF,MAAM,KAAK,SAAS,QAAQ,KAAK,YAAY,OAAO,KAAK,OAAqB,MAAM,UAAU,CAAC;AAAA,IACnG,IAAI,CAAC,UAAU;AAAA,MAAG,MAAM,IAAI,aAAa,eAAe;AAAA,IACxD,KAAK,MAAM,kBAAkB,QAAQ,EAAE;AAAA,IACvC,OAAO,gBAAgB,OAAO;AAAA;AAAA,OAGlB,WAAU,CAAC,YAAiE;AAAA,IACxF,OAAO,eAAe,YAAY,YAAY,MAAM,KAAK,SAAS,eAAe,UAAU;AAAA;AAAA,EAGrF,QAAQ,CAAC,SAAqE;AAAA,IACpF,OAAO,gBAAgB,QAAQ,SAAS,QAAQ,eAAe,QAAQ,QAAQ,KAAK,YAAY,MAAM;AAAA;AAAA,OAG1F,YAAW,CAAC,YAAkD;AAAA,IAC1E,MAAM,UAAU,MAAM,KAAK,SAAS,YAAY,YAAY,MAAM,KAAK,WAAW,UAAU,CAAC;AAAA,IACxF,KAAK,SAAS,eAAe,QAAQ,WAAW,CAAC,OAAO,MAAM,UAAU,KAAK,YAAY,OAAO,MAAM,KAAK,CAAC,EAAE,MAAM,MAAG;AAAA,MAAG;AAAA,KAAS;AAAA,IACxI,OAAO;AAAA;AAAA,EAGD,eAAe,CAAC,SAA0B;AAAA,IAChD,MAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAAA,IAC/B,MAAM,UAAU,CAAC,GAAG,IAAI,aAAa,QAAQ,CAAC;AAAA,IAC9C,IAAI,QAAQ,WAAW,KAAK,QAAQ,KAAK,OAAO;AAAA,MAAc,MAAM,IAAI,aAAa,eAAe;AAAA,IACpG,OAAO,aAAa,QAAQ,GAAG,IAAI,GAAG;AAAA;AAAA,EAGhC,QAAQ,GAAqC;AAAA,IACnD,MAAM,SAAS,CAAC,YAAiF,OAAO,YAAsC;AAAA,MAC5I,IAAI;AAAA,QAAE,KAAK,YAAY,QAAQ,aAAa;AAAA,QAAG,OAAO,MAAM,QAAQ,OAAO;AAAA,QAAK,OAAO,OAAO;AAAA,QAAE,OAAO,cAAc,KAAK;AAAA;AAAA;AAAA,IAE5H,OAAO;AAAA,MACL,EAAE,MAAM,aAAa,SAAS,CAAC,KAAK,GAAG,SAAS,gBAAgB,QAAQ,OAAO,YAAY,aAAa,EAAE,UAAU,MAAM,KAAK,SAAS,KAAK,EAAE,CAAC,CAAC,EAAE;AAAA,MACnJ,EAAE,MAAM,mBAAmB,SAAS,CAAC,KAAK,GAAG,SAAS,mBAAmB,QAAQ,OAAO,OAAO,YAAY,aAAa,MAAM,KAAK,MAAM,IAAI,KAAK,gBAAgB,QAAQ,OAAO,GAAG,QAAQ,aAAa,CAAC,CAAC,EAAE;AAAA,MAC7M,EAAE,MAAM,yBAAyB,SAAS,CAAC,MAAM,GAAG,SAAS,qBAAqB,QAAQ,OAAO,OAAO,YAAY;AAAA,QAClH,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QACxC,UAAU,MAAM,CAAC,cAAc,mBAAmB,UAAU,CAAC;AAAA,QAC7D,MAAM,aAAa,aAAa,KAAK,YAAY,GAAG;AAAA,QACpD,MAAM,kBAAkB,aAAa,KAAK,iBAAiB,GAAG;AAAA,QAC9D,IAAI,CAAC,wEAAwE,KAAK,eAAe;AAAA,UAAG,MAAM,IAAI,aAAa,eAAe;AAAA,QAC1I,MAAM,WAAW,aAAa,KAAK,UAAU,GAAG;AAAA,QAChD,IAAI,WAAW,KAAK,QAAQ;AAAA,UAAG,MAAM,IAAI,aAAa,eAAe;AAAA,QACrE,MAAM,UAAU,gBAAgB,MAAM,KAAK,SAAS,IAAI,UAAU,CAAC,EAAE;AAAA,QACrE,IAAI,SAAS;AAAA,UACX,IAAI,QAAQ,oBAAoB,mBAAmB,QAAQ,aAAa;AAAA,YAAU,MAAM,IAAI,aAAa,mBAAmB;AAAA,UAC5H,KAAK,MAAM,oBAAoB,YAAY,iBAAiB,QAAQ;AAAA,QACtE;AAAA,QACA,MAAM,SAAS,MAAM,KAAK,MAAM,QAAQ,YAAY,iBAAiB,UAAU,QAAQ,eAAe;AAAA,UACpG,eAAe,cAAY,KAAK,SAAS,mBAAmB,YAAY,iBAAiB,UAAU,KAAK,IAAI,CAAC;AAAA,QAC/G,CAAC;AAAA,QACD,IAAI,OAAO,YAAY;AAAA,UAAyB,MAAM,KAAK,SAAS,gBAAgB,YAAY,eAAe;AAAA,QAC/G,OAAO,aAAa,MAAM;AAAA,OAC3B,EAAE;AAAA,MACH,EAAE,MAAM,wBAAwB,SAAS,CAAC,MAAM,GAAG,SAAS,uBAAuB,QAAQ,OAAO,OAAM,YAAW;AAAA,QACjH,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QACxC,UAAU,MAAM,CAAC,cAAc,SAAS,CAAC;AAAA,QACzC,IAAI,OAAO,KAAK,YAAY;AAAA,UAAW,MAAM,IAAI,aAAa,eAAe;AAAA,QAC7E,OAAO,aAAa,EAAE,SAAS,gBAAgB,MAAM,KAAK,SAAS,oBAAoB,aAAa,KAAK,YAAY,GAAG,GAAG,KAAK,OAAO,CAAC,EAAE,CAAC;AAAA,OAC5I,EAAE;AAAA,MACH,EAAE,MAAM,mBAAmB,SAAS,CAAC,MAAM,GAAG,SAAS,eAAe,QAAQ,OAAO,OAAO,YAAY;AAAA,QACtG,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QAAG,UAAU,MAAM,CAAC,YAAY,CAAC;AAAA,QACzE,MAAM,UAAU,MAAM,KAAK,SAAS,IAAI,aAAa,KAAK,YAAY,GAAG,CAAC;AAAA,QAC1E,IAAI,CAAC,gBAAgB,OAAO,EAAE;AAAA,UAAW,MAAM,IAAI,aAAa,QAAQ,WAAW,WAAW,oBAAoB,QAAQ,MAAM;AAAA,QAChI,MAAM,QAAuB,EAAE,QAAQ,gBAAgB,gBAAgB,EAAE,YAAY,QAAQ,GAAG,EAAE;AAAA,QAClG,OAAO,aAAa,KAAK;AAAA,OAC1B,EAAE;AAAA,MACH,EAAE,MAAM,iBAAiB,SAAS,CAAC,MAAM,GAAG,SAAS,oBAAoB,QAAQ,OAAO,OAAO,YAAY;AAAA,QACzG,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QAAG,UAAU,MAAM,CAAC,YAAY,CAAC;AAAA,QACzE,OAAO,aAAa,MAAM,KAAK,YAAY,cAAa,KAAK,YAAY,GAAG,CAAC,CAAC;AAAA,OAC/E,EAAE;AAAA,MACH,EAAE,MAAM,eAAe,SAAS,CAAC,MAAM,GAAG,SAAS,kBAAkB,QAAQ,OAAO,OAAO,YAAY;AAAA,QACrG,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QAAG,UAAU,MAAM,CAAC,YAAY,CAAC;AAAA,QACzE,MAAM,aAAa,cAAa,KAAK,YAAY,GAAG;AAAA,QACpD,MAAM,UAAU,KAAK,SAAS,UAAU,UAAU;AAAA,QAClD,IAAI;AAAA,UAAE,IAAI,eAAe;AAAA,YAAW,KAAK,SAAS,SAAS,QAAQ,WAAW,MAAM,KAAK,WAAW,UAAU,CAAe;AAAA,UAC7H,OAAO,OAAO;AAAA,UAAE,KAAK,SAAS,OAAO,QAAQ,SAAS;AAAA,UAAG,MAAM;AAAA;AAAA,QAC/D,OAAO,aAAa,OAAO;AAAA,OAC5B,EAAE;AAAA,MACH,EAAE,MAAM,iBAAiB,SAAS,CAAC,KAAK,GAAG,SAAS,kBAAkB,QAAQ,OAAO,OAAO,YAAY;AAAA,QACtG,MAAM,MAAM,IAAI,IAAI,QAAQ,QAAQ,GAAG;AAAA,QACvC,MAAM,SAAS,IAAI,aAAa,OAAO,WAAW;AAAA,QAClD,IAAI,OAAO,WAAW;AAAA,UAAG,MAAM,IAAI,aAAa,eAAe;AAAA,QAC/D,OAAO,aAAa,KAAK,SAAS,OAAO,aAAa,OAAO,IAAI,GAAG,CAAC,CAAC;AAAA,OACvE,EAAE;AAAA,MACH,EAAE,MAAM,mBAAmB,SAAS,CAAC,MAAM,GAAG,SAAS,qBAAqB,QAAQ,OAAO,OAAO,YAAY;AAAA,QAC5G,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QAAG,UAAU,MAAM,CAAC,aAAa,aAAa,CAAC;AAAA,QACvF,MAAM,YAAY,aAAa,KAAK,WAAW,GAAG;AAAA,QAClD,MAAM,SAAS,KAAK,SAAS,OAAO,SAAS;AAAA,QAC7C,IAAI,OAAO,UAAU;AAAA,UAAW,OAAO,aAAa,MAAM;AAAA,QAC1D,MAAM,SAAS,MAAM,KAAK,SAAS,aAAa,WAAW,aAAa,KAAK,aAAa,IAAI,GAAG,CAAC,OAAO,MAAM,UAAU,KAAK,YAAY,OAAO,MAAM,KAAK,CAAC;AAAA,QAC7J,OAAO,aAAa,EAAE,SAAS,OAAO,OAAO,CAAC;AAAA,OAC/C,EAAE;AAAA,MACH,EAAE,MAAM,0BAA0B,SAAS,CAAC,MAAM,GAAG,SAAS,uBAAuB,QAAQ,OAAO,OAAO,YAAY;AAAA,QACrH,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QACxC,UAAU,MAAM,CAAC,WAAW,CAAC;AAAA,QAC7B,MAAM,SAAS,KAAK,SAAS,OAAO,aAAa,KAAK,WAAW,GAAG,CAAC;AAAA,QACrE,IAAI,OAAO,UAAU;AAAA,UAAW,OAAO,aAAa,MAAM;AAAA,QAC1D,MAAM,SAAS,MAAM,KAAK,SAAS,eAAe,aAAa,KAAK,WAAW,GAAG,GAAG,CAAC,OAAO,MAAM,UAAU,KAAK,YAAY,OAAO,MAAM,KAAK,CAAC;AAAA,QACjJ,OAAO,aAAa,EAAE,SAAS,OAAO,OAAO,CAAC;AAAA,OAC/C,EAAE;AAAA,MACH,EAAE,MAAM,iBAAiB,SAAS,CAAC,MAAM,GAAG,SAAS,eAAe,QAAQ,OAAO,OAAO,YAAY;AAAA,QACpG,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QAAG,UAAU,MAAM,CAAC,WAAW,CAAC;AAAA,QACxE,OAAO,aAAa,EAAE,WAAW,KAAK,SAAS,OAAO,aAAa,KAAK,WAAW,GAAG,CAAC,EAAE,CAAC;AAAA,OAC3F,EAAE;AAAA,MACH,EAAE,MAAM,qBAAqB,SAAS,CAAC,MAAM,GAAG,SAAS,kBAAkB,QAAQ,OAAO,OAAO,YAAY;AAAA,QAC3G,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QAAG,UAAU,MAAM,CAAC,YAAY,CAAC;AAAA,QACzE,MAAM,aAAa,aAAa,KAAK,YAAY,GAAG;AAAA,QACpD,MAAM,UAAU,MAAM,KAAK,SAAS,UAAU,YAAY,UAAU;AAAA,QACpE,KAAK,MAAM,kBAAkB,UAAU;AAAA,QACvC,OAAO,aAAa,EAAE,SAAS,gBAAgB,OAAO,EAAE,CAAC;AAAA,OAC1D,EAAE;AAAA,MACH,EAAE,MAAM,oBAAoB,SAAS,CAAC,MAAM,GAAG,SAAS,iBAAiB,QAAQ,OAAO,OAAO,YAAY;AAAA,QACzG,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QAAG,UAAU,MAAM,CAAC,YAAY,CAAC;AAAA,QACzE,MAAM,aAAa,aAAa,KAAK,YAAY,GAAG;AAAA,QACpD,MAAM,UAAU,MAAM,KAAK,SAAS,OAAO,UAAU;AAAA,QACrD,KAAK,MAAM,kBAAkB,UAAU;AAAA,QACvC,OAAO,aAAa,EAAE,SAAS,gBAAgB,OAAO,EAAE,CAAC;AAAA,OAC1D,EAAE;AAAA,MACH,EAAE,MAAM,oBAAoB,SAAS,CAAC,MAAM,GAAG,SAAS,iBAAiB,QAAQ,OAAO,OAAO,YAAY;AAAA,QACzG,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QAAG,UAAU,MAAM,CAAC,cAAc,OAAO,CAAC;AAAA,QAClF,OAAO,aAAa,EAAE,SAAS,gBAAgB,MAAM,KAAK,SAAS,OAAO,aAAa,KAAK,YAAY,GAAG,GAAG,aAAa,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;AAAA,OAC3I,EAAE;AAAA,MACH,EAAE,MAAM,oBAAoB,SAAS,CAAC,MAAM,GAAG,SAAS,iBAAiB,QAAQ,OAAO,OAAO,YAAY;AAAA,QACzG,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;AAAA,QAAG,UAAU,MAAM,CAAC,YAAY,CAAC;AAAA,QACzE,MAAM,aAAa,aAAa,KAAK,YAAY,GAAG;AAAA,QACpD,MAAM,UAAU,MAAM,KAAK,SAAS,UAAU,YAAY,SAAS;AAAA,QACnE,KAAK,MAAM,kBAAkB,UAAU;AAAA,QACvC,OAAO,aAAa,EAAE,SAAS,gBAAgB,OAAO,EAAE,CAAC;AAAA,OAC1D,EAAE;AAAA,IACL;AAAA;AAAA,EAGM,QAAQ,GAAuI;AAAA,IACrJ,OAAO;AAAA,MACL,EAAE,MAAM,iBAAiB,SAAS,iBAAiB,QAAQ,OAAO,UAAU,YAAY;AAAA,QACtF,IAAI;AAAA,UAAE,KAAK,YAAY,QAAQ,QAAQ,MAAM;AAAA,UAAG,OAAO,MAAM,KAAK,WAAW,sBAAsB,OAAO,GAAG,QAAQ,QAAQ,MAAM;AAAA,UAAK,OAAO,OAAO;AAAA,UAAE,MAAM,UAAU,KAAK;AAAA;AAAA,QAC7K;AAAA,MACF,EAAE,MAAM,gBAAgB,SAAS,gBAAgB,QAAQ,OAAO,SAAS,YAAY;AAAA,QACnF,IAAI;AAAA,UACF,KAAK,YAAY,QAAQ,QAAQ,MAAM;AAAA,UACvC,MAAM,OAAO,OAAO,OAAO;AAAA,UAAG,UAAU,MAAM,CAAC,SAAS,CAAC;AAAA,UACzD,OAAO,EAAE,UAAU,MAAM,KAAK,SAAS,aAAa,sBAAsB,OAAO,GAAG,gBAAgB,KAAK,OAAO,CAAC,EAAE;AAAA,UACnH,OAAO,OAAO;AAAA,UAAE,MAAM,UAAU,KAAK;AAAA;AAAA,QACvC;AAAA,IACJ;AAAA;AAAA,OAGI,QAAO,GAAkB;AAAA,IAC7B,IAAI,KAAK;AAAA,MAAU;AAAA,IACnB,KAAK,WAAW;AAAA,IAChB,KAAK,YAAY,MAAM,UAAU;AAAA,IACjC,KAAK,KAAK,OAAO,oBAAoB,SAAS,KAAK,aAAa;AAAA,IAChE,WAAW,cAAc,KAAK,mBAAmB,OAAO;AAAA,MAAG,WAAW,MAAM,UAAU;AAAA,IACtF,KAAK,SAAS,QAAQ;AAAA,IACtB,KAAK,UAAU,QAAQ;AAAA,IACvB,KAAK,MAAM,QAAQ;AAAA,IACnB,KAAK,SAAS,MAAM;AAAA;AAExB;AAEO,SAAS,aAAa,CAAC,SAA6B,eAAoC,CAAC,GAAkB;AAAA,EAAE,OAAO,IAAI,eAAe,SAAS,YAAY;AAAA;AAE5J,IAAM,MAAM,OAAO,OAAO;AAAA,EAC/B,EAAE,MAAM,aAAa,SAAS,CAAC,KAAK,GAAG,SAAS,eAAe;AAAA,EAC/D,EAAE,MAAM,mBAAmB,SAAS,CAAC,KAAK,GAAG,SAAS,kBAAkB;AAAA,EACxE,EAAE,MAAM,yBAAyB,SAAS,CAAC,MAAM,GAAG,SAAS,oBAAoB;AAAA,EACjF,EAAE,MAAM,wBAAwB,SAAS,CAAC,MAAM,GAAG,SAAS,sBAAsB;AAAA,EAClF,EAAE,MAAM,mBAAmB,SAAS,CAAC,MAAM,GAAG,SAAS,cAAc;AAAA,EACrE,EAAE,MAAM,iBAAiB,SAAS,CAAC,MAAM,GAAG,SAAS,mBAAmB;AAAA,EACxE,EAAE,MAAM,eAAe,SAAS,CAAC,MAAM,GAAG,SAAS,iBAAiB;AAAA,EACpE,EAAE,MAAM,iBAAiB,SAAS,CAAC,KAAK,GAAG,SAAS,iBAAiB;AAAA,EACrE,EAAE,MAAM,mBAAmB,SAAS,CAAC,MAAM,GAAG,SAAS,oBAAoB;AAAA,EAC3E,EAAE,MAAM,0BAA0B,SAAS,CAAC,MAAM,GAAG,SAAS,sBAAsB;AAAA,EACpF,EAAE,MAAM,iBAAiB,SAAS,CAAC,MAAM,GAAG,SAAS,cAAc;AAAA,EACnE,EAAE,MAAM,qBAAqB,SAAS,CAAC,MAAM,GAAG,SAAS,iBAAiB;AAAA,EAC1E,EAAE,MAAM,oBAAoB,SAAS,CAAC,MAAM,GAAG,SAAS,gBAAgB;AAAA,EACxE,EAAE,MAAM,oBAAoB,SAAS,CAAC,MAAM,GAAG,SAAS,gBAAgB;AAAA,EACxE,EAAE,MAAM,oBAAoB,SAAS,CAAC,MAAM,GAAG,SAAS,gBAAgB;AAC1E,CAAU;AACH,IAAM,MAAM,OAAO,OAAO,CAAC,EAAE,MAAM,iBAAiB,SAAS,gBAAgB,GAAG,EAAE,MAAM,gBAAgB,SAAS,eAAe,CAAC,CAAU;AAC3I,IAAM,aAAa;AACnB,IAAM,aAAa;AAC1B,IAAe,oBAAE,cAAc;",
|
|
21
|
-
"debugId": "
|
|
21
|
+
"mappings": "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",
|
|
22
|
+
"debugId": "08B71A7DC584C3AB64756E2164756E21",
|
|
22
23
|
"names": []
|
|
23
24
|
}
|