@phone-use/sdk 0.1.0 → 0.2.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/{backend-Cbr2tIN-.d.mts → backend-CkJkkw5Z.d.mts} +6 -6
- package/dist/{device-BzPnHvQy.mjs → device-Xsy_LPUF.mjs} +2 -2
- package/dist/device-Xsy_LPUF.mjs.map +1 -0
- package/dist/index.d.mts +73 -13
- package/dist/index.mjs +162 -8
- package/dist/index.mjs.map +1 -1
- package/dist/testing.d.mts +6 -6
- package/dist/testing.mjs +5 -5
- package/dist/testing.mjs.map +1 -1
- package/package.json +15 -1
- package/src/actions.ts +6 -6
- package/src/backend.ts +4 -5
- package/src/backends/agent-device.ts +2 -3
- package/src/backends/device-runner.ts +205 -0
- package/src/backends/ios.ts +4 -4
- package/src/config.ts +4 -5
- package/src/device.ts +3 -3
- package/src/errors.ts +3 -3
- package/src/exec.ts +1 -1
- package/src/index.ts +4 -3
- package/src/lifecycle.ts +5 -5
- package/src/observe.ts +1 -1
- package/src/secrets.ts +2 -2
- package/src/testing.ts +4 -4
- package/dist/device-BzPnHvQy.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"device-BzPnHvQy.mjs","names":[],"sources":["../src/errors.ts","../src/backend.ts","../src/device.ts"],"sourcesContent":["import { isAgentDeviceError } from 'agent-device';\n\n/**\n * Stable machine-readable error codes carried by every {@link PhoneUseError}.\n *\n * Codes are deliberately string-identical to agent-device's where a concept\n * maps 1:1 (DEVICE_NOT_FOUND, SESSION_NOT_FOUND, ...) so existing harness\n * checks like `(e as {code?: string}).code === 'SESSION_NOT_FOUND'` keep\n * working unchanged across the normalization boundary.\n */\nexport type PhoneUseErrorCode =\n | 'DEVICE_NOT_FOUND'\n | 'DEVICE_IN_USE'\n | 'SESSION_NOT_FOUND'\n | 'TIMEOUT'\n | 'ACTION_FAILED'\n | 'UNSUPPORTED_CAPABILITY'\n | 'BACKEND_NOT_FOUND'\n | 'ABORTED'\n | 'UNKNOWN';\n\n/** Structured, code-specific context attached to a {@link PhoneUseError}. */\nexport type PhoneUseErrorDetails = Record<string, unknown> & {\n /** Preserved from agent-device details.hint — describeError renders it. */\n hint?: string | undefined;\n /** The raw backend code when we collapse to ACTION_FAILED. */\n backendCode?: string | undefined;\n};\n\n/**\n * Root of the typed error tree (docs/19 §Artifacts, errors; docs/20 item 2).\n * Every backend method rejects only with PhoneUseError subclasses; agent-device\n * (or any transport) errors are normalized at the boundary by\n * {@link toPhoneUseError} so no backend type ever reaches the public API. Each\n * error carries a stable `code` and an explicit `retryable` flag — the field\n * agent loops need to decide retry-vs-replan.\n */\nexport class PhoneUseError extends Error {\n /** Stable machine-readable code — the field to branch on. */\n readonly code: PhoneUseErrorCode;\n /** Whether retrying the same call can plausibly succeed. */\n readonly retryable: boolean;\n /** Optional structured context (hint, raw backend code, ...). */\n readonly details?: PhoneUseErrorDetails | undefined;\n\n constructor(\n message: string,\n opts: {\n code: PhoneUseErrorCode;\n retryable: boolean;\n details?: PhoneUseErrorDetails | undefined;\n cause?: unknown;\n },\n ) {\n super(message, opts.cause === undefined ? undefined : { cause: opts.cause });\n this.name = new.target.name;\n this.code = opts.code;\n this.retryable = opts.retryable;\n this.details = opts.details;\n }\n}\n\n/** No device matched the selection (`DEVICE_NOT_FOUND`, not retryable). */\nexport class DeviceNotFoundError extends PhoneUseError {\n constructor(message: string, opts: { details?: PhoneUseErrorDetails | undefined; cause?: unknown } = {}) {\n super(message, { code: 'DEVICE_NOT_FOUND', retryable: false, ...opts });\n }\n}\n\n/** The device is held by another session (`DEVICE_IN_USE`, retryable). */\nexport class DeviceInUseError extends PhoneUseError {\n constructor(message: string, opts: { details?: PhoneUseErrorDetails | undefined; cause?: unknown } = {}) {\n super(message, { code: 'DEVICE_IN_USE', retryable: true, ...opts });\n }\n}\n\n/** No live session — the device/session was closed (`SESSION_NOT_FOUND`, not retryable). */\nexport class SessionNotFoundError extends PhoneUseError {\n constructor(message: string, opts: { details?: PhoneUseErrorDetails | undefined; cause?: unknown } = {}) {\n super(message, { code: 'SESSION_NOT_FOUND', retryable: false, ...opts });\n }\n}\n\n/** A deadline elapsed before the operation completed (`TIMEOUT`, retryable). */\nexport class TimeoutError extends PhoneUseError {\n constructor(message: string, opts: { details?: PhoneUseErrorDetails | undefined; cause?: unknown } = {}) {\n super(message, { code: 'TIMEOUT', retryable: true, ...opts });\n }\n}\n\n/** A device action failed to execute (`ACTION_FAILED`, retryable). */\nexport class ActionFailedError extends PhoneUseError {\n constructor(message: string, opts: { details?: PhoneUseErrorDetails | undefined; cause?: unknown } = {}) {\n super(message, { code: 'ACTION_FAILED', retryable: true, ...opts });\n }\n}\n\n/** The backend does not implement the capability (`UNSUPPORTED_CAPABILITY`, not retryable). */\nexport class UnsupportedCapabilityError extends PhoneUseError {\n /** The backend that rejected the call. */\n readonly backend: string;\n /** The missing capability. */\n readonly capability: string;\n\n constructor(opts: { backend: string; capability: string; cause?: unknown }) {\n super(`backend \"${opts.backend}\" does not support \"${opts.capability}\"`, {\n code: 'UNSUPPORTED_CAPABILITY',\n retryable: false,\n details: { backend: opts.backend, capability: opts.capability },\n ...(opts.cause === undefined ? {} : { cause: opts.cause }),\n });\n this.backend = opts.backend;\n this.capability = opts.capability;\n }\n}\n\n/**\n * The caller's AbortSignal fired (`ABORTED`, not retryable). Abort is caller\n * control flow, not a device outcome — never retried.\n */\nexport class AbortedError extends PhoneUseError {\n constructor(message = 'aborted by caller', opts: { cause?: unknown } = {}) {\n super(message, { code: 'ABORTED', retryable: false, ...opts });\n }\n}\n\nconst TIMEOUT_RE = /\\btime[d ]?\\s?out\\b|\\btimeout\\b/i;\n\n/**\n * Boundary normalizer: ANY thrown value → PhoneUseError. agent-device AppError\n * codes map per the table below; an existing PhoneUseError passes through\n * untouched; unknown values wrap as UNKNOWN (not retryable). The original\n * error always rides on `cause`; details (including hint) are preserved.\n */\nexport function toPhoneUseError(\n err: unknown,\n ctx: { backend?: string; capability?: string } = {},\n): PhoneUseError {\n if (err instanceof PhoneUseError) return err;\n\n if (isAgentDeviceError(err)) {\n const e = err as Error & { code?: string; details?: Record<string, unknown> };\n const message = e.message || String(e.code ?? 'agent-device error');\n const details: PhoneUseErrorDetails = { ...(e.details ?? {}) };\n const opts = { details, cause: err };\n // Timeout is a shape, not a code, in agent-device — heuristic on message.\n // Flagged in docs/20: Mac verification is the arbiter for this mapping.\n if (TIMEOUT_RE.test(message)) return new TimeoutError(message, opts);\n switch (e.code) {\n case 'DEVICE_NOT_FOUND':\n return new DeviceNotFoundError(message, opts);\n case 'DEVICE_IN_USE':\n return new DeviceInUseError(message, opts);\n case 'SESSION_NOT_FOUND':\n return new SessionNotFoundError(message, opts);\n case 'UNSUPPORTED_PLATFORM':\n case 'UNSUPPORTED_OPERATION':\n case 'NOT_IMPLEMENTED':\n return new UnsupportedCapabilityError({\n backend: ctx.backend ?? 'unknown',\n capability: ctx.capability ?? String(e.code),\n cause: err,\n });\n default:\n return new ActionFailedError(message, {\n details: { ...details, backendCode: e.code === undefined ? undefined : String(e.code) },\n cause: err,\n });\n }\n }\n\n if (err instanceof Error) {\n if (TIMEOUT_RE.test(err.message)) return new TimeoutError(err.message, { cause: err });\n return new PhoneUseError(err.message, { code: 'UNKNOWN', retryable: false, cause: err });\n }\n return new PhoneUseError(String(err), { code: 'UNKNOWN', retryable: false, cause: err });\n}\n","import type { DeviceConfig } from './config.ts';\nimport type {\n AlertAction,\n BackendAlertResult,\n Capability,\n OpenAppResult,\n PressTarget,\n ScrollDirection,\n Snapshot,\n} from './device.ts';\nimport { PhoneUseError, UnsupportedCapabilityError } from './errors.ts';\n\n/**\n * The backend contract (docs/19 §Backend contract): a STRUCTURAL interface —\n * any object with these methods is a backend — plus an optional\n * {@link BaseDeviceBackend} class with the plumbing done (Appium BaseDriver\n * ergonomics). Methods reject only with PhoneUseError subclasses; backends\n * normalize their transport's errors at the boundary.\n */\nexport interface DeviceBackend {\n /** Stable backend identifier, e.g. `\"agent-device\"`. */\n readonly backendName: string;\n /** The capabilities this backend actually implements. */\n readonly capabilities: ReadonlySet<Capability>;\n\n /** Capture the accessibility tree of the frontmost app. */\n snapshot(opts?: { interactiveOnly?: boolean | undefined; depth?: number | undefined }): Promise<Snapshot>;\n /** Save a screenshot to `path` (optionally with `@ref` overlays drawn). */\n screenshot(opts: { path: string; overlayRefs?: boolean | undefined }): Promise<{ path: string }>;\n /** Tap an element ref or raw coordinates. */\n press(target: PressTarget): Promise<void>;\n /** Long-press an element ref. */\n longPress(ref: string, durationMs?: number): Promise<void>;\n /** Focus an element and replace its text. */\n fill(ref: string, text: string): Promise<void>;\n /** Type into whatever currently has keyboard focus. */\n typeText(text: string): Promise<void>;\n /** Press a hardware/keyboard key (Return only, this cycle). */\n pressKey(key: 'return'): Promise<void>;\n /** Scroll the active scroll view one step. */\n scroll(direction: ScrollDirection): Promise<void>;\n /** Coordinate drag: touch down at (x,y), move by (dx,dy). Operates picker wheels, sliders, carousels. */\n pan(x: number, y: number, dx: number, dy: number, durationMs?: number): Promise<void>;\n /** Block until `text` appears on screen or the timeout elapses. */\n waitForText(text: string, timeoutMs?: number): Promise<void>;\n /** Read/accept/dismiss the app's own alert via the transport's alert command. */\n systemAlert(action: AlertAction): Promise<BackendAlertResult>;\n /** Go to the home screen. */\n home(): Promise<void>;\n /** Navigate back (hardware back / nav-bar back). */\n back(): Promise<void>;\n /** Open an app by name/bundle id, or a URL (deep link). */\n openApp(opts: {\n app?: string | undefined;\n url?: string | undefined;\n relaunch?: boolean | undefined;\n }): Promise<OpenAppResult>;\n /** List installed app bundle ids. */\n listApps(): Promise<string[]>;\n /** Close the transport session (idempotent; safe when none is open). */\n closeSession(): Promise<void>;\n}\n\n/**\n * Optional plumbing base: every method rejects with a typed\n * UnsupportedCapabilityError until overridden. Subclasses declare their\n * capability set and override exactly what they support.\n */\nexport abstract class BaseDeviceBackend implements DeviceBackend {\n readonly backendName: string;\n readonly capabilities: ReadonlySet<Capability>;\n\n protected constructor(backendName: string, capabilities: Iterable<Capability>) {\n this.backendName = backendName;\n this.capabilities = new Set(capabilities);\n }\n\n protected unsupported(capability: Capability): UnsupportedCapabilityError {\n return new UnsupportedCapabilityError({ backend: this.backendName, capability });\n }\n\n /** Throws UnsupportedCapabilityError unless this backend declares `capability`. */\n requireCapability(capability: Capability): void {\n if (!this.capabilities.has(capability)) throw this.unsupported(capability);\n }\n\n snapshot(_opts?: { interactiveOnly?: boolean | undefined; depth?: number | undefined }): Promise<Snapshot> {\n return Promise.reject(this.unsupported('snapshot'));\n }\n screenshot(_opts: { path: string; overlayRefs?: boolean | undefined }): Promise<{ path: string }> {\n return Promise.reject(this.unsupported('screenshot'));\n }\n press(_target: PressTarget): Promise<void> {\n return Promise.reject(this.unsupported('press'));\n }\n longPress(_ref: string, _durationMs?: number): Promise<void> {\n return Promise.reject(this.unsupported('longPress'));\n }\n fill(_ref: string, _text: string): Promise<void> {\n return Promise.reject(this.unsupported('fill'));\n }\n typeText(_text: string): Promise<void> {\n return Promise.reject(this.unsupported('type'));\n }\n pressKey(_key: 'return'): Promise<void> {\n return Promise.reject(this.unsupported('key'));\n }\n scroll(_direction: ScrollDirection): Promise<void> {\n return Promise.reject(this.unsupported('scroll'));\n }\n pan(_x: number, _y: number, _dx: number, _dy: number, _durationMs?: number): Promise<void> {\n return Promise.reject(this.unsupported('pan'));\n }\n waitForText(_text: string, _timeoutMs?: number): Promise<void> {\n return Promise.reject(this.unsupported('waitForText'));\n }\n systemAlert(_action: AlertAction): Promise<BackendAlertResult> {\n return Promise.reject(this.unsupported('alert'));\n }\n home(): Promise<void> {\n return Promise.reject(this.unsupported('home'));\n }\n back(): Promise<void> {\n return Promise.reject(this.unsupported('back'));\n }\n openApp(_opts: {\n app?: string | undefined;\n url?: string | undefined;\n relaunch?: boolean | undefined;\n }): Promise<OpenAppResult> {\n return Promise.reject(this.unsupported('openApp'));\n }\n listApps(): Promise<string[]> {\n return Promise.reject(this.unsupported('listApps'));\n }\n closeSession(): Promise<void> {\n return Promise.reject(this.unsupported('closeSession'));\n }\n}\n\n// ---------------------------------------------------------------------------\n// Runtime backend registry (registerBackend + phone-backend-* convention,\n// docs/19). A deliberate module-level Map: this IS the registry — mirrored on\n// permissions.ts's documented pattern; the item-2 grep audit is scoped to\n// driver code.\n// ---------------------------------------------------------------------------\n\n/** Builds a backend from an optional {@link DeviceConfig}. */\nexport type BackendFactory = (config?: DeviceConfig) => DeviceBackend | Promise<DeviceBackend>;\n\nconst factories = new Map<string, BackendFactory>();\n\n/**\n * Register a backend factory under a unique name (the `phone-backend-*`\n * convention for third parties). Throws if the name is already taken.\n */\nexport function registerBackend(name: string, factory: BackendFactory): void {\n if (factories.has(name)) {\n throw new PhoneUseError(`backend \"${name}\" is already registered`, {\n code: 'ACTION_FAILED',\n retryable: false,\n });\n }\n factories.set(name, factory);\n}\n\n/** Look up a registered factory by name; throws `BACKEND_NOT_FOUND` if absent. */\nexport function getBackendFactory(name: string): BackendFactory {\n const factory = factories.get(name);\n if (!factory) {\n throw new PhoneUseError(\n `no backend named \"${name}\" — registered: ${[...factories.keys()].join(', ') || '(none)'}`,\n {\n code: 'BACKEND_NOT_FOUND',\n retryable: false,\n },\n );\n }\n return factory;\n}\n\n/** Names of every registered backend, in registration order. */\nexport function listBackends(): string[] {\n return [...factories.keys()];\n}\n","// ---------------------------------------------------------------------------\n// Shared device types — the SDK's own vocabulary, structurally compatible with\n// agent-device's snapshot nodes but never importing its types (docs/20 item 2:\n// no backend type in the public API). Every optional is `| undefined` so\n// narrower backend types assign structurally under exactOptionalPropertyTypes.\n// ---------------------------------------------------------------------------\n\n/** Element geometry in screen points (same space as screenshot pixels at @1x). */\nexport type Rect = { x: number; y: number; width: number; height: number };\n\n/**\n * One accessibility-tree node as reported by a backend snapshot. The SDK's own\n * vocabulary — structurally compatible with agent-device's nodes but never\n * importing its types (docs/20 item 2: no backend type in the public API).\n */\nexport type SnapshotNode = {\n ref?: string | undefined;\n type?: string | undefined;\n role?: string | undefined;\n label?: string | undefined;\n value?: string | undefined;\n identifier?: string | undefined;\n enabled?: boolean | undefined;\n selected?: boolean | undefined;\n focused?: boolean | undefined;\n interactionBlocked?: string | undefined;\n rect?: Rect | undefined;\n};\n\n/** One backend snapshot: the node list plus the frontmost app when known. */\nexport type Snapshot = {\n nodes: SnapshotNode[];\n appName?: string | undefined;\n appBundleId?: string | undefined;\n};\n\n/** Scroll gesture direction. */\nexport type ScrollDirection = 'up' | 'down' | 'left' | 'right';\n\n/** A press target: an element ref from a snapshot, or raw screen coordinates. */\nexport type PressTarget = { ref: string } | { x: number; y: number };\n\n/** What to do with a system alert: read it, accept it, or dismiss it. */\nexport type AlertAction = 'get' | 'accept' | 'dismiss';\n\n/** Raw result of a backend's system-alert command. */\nexport type BackendAlertResult = {\n alert?:\n | { title?: string | undefined; message?: string | undefined; buttons?: string[] | undefined }\n | null\n | undefined;\n handled?: boolean | undefined;\n button?: string | undefined;\n};\n\n/** What a backend reports after opening an app or URL. */\nexport type OpenAppResult = { appName?: string | undefined; appBundleId?: string | undefined };\n\n/** A backend feature a caller can query via `backend.capabilities`. */\nexport type Capability =\n | 'snapshot'\n | 'screenshot'\n | 'press'\n | 'longPress'\n | 'fill'\n | 'type'\n | 'key'\n | 'scroll'\n | 'pan'\n | 'waitForText'\n | 'alert'\n | 'home'\n | 'back'\n | 'openApp'\n | 'openUrl'\n | 'listApps'\n | 'closeSession';\n\n/** Every capability — what a full backend (agent-device iOS) declares. */\nexport const ALL_CAPABILITIES: readonly Capability[] = [\n 'snapshot',\n 'screenshot',\n 'press',\n 'longPress',\n 'fill',\n 'type',\n 'key',\n 'scroll',\n 'pan',\n 'waitForText',\n 'alert',\n 'home',\n 'back',\n 'openApp',\n 'openUrl',\n 'listApps',\n 'closeSession',\n];\n"],"mappings":";;;;;;;;;;AAqCA,IAAa,gBAAb,cAAmC,MAAM;;CAEvC;;CAEA;;CAEA;CAEA,YACE,SACA,MAMA;EACA,MAAM,SAAS,KAAK,UAAU,KAAA,IAAY,KAAA,IAAY,EAAE,OAAO,KAAK,MAAM,CAAC;EAC3E,KAAK,OAAO,IAAI,OAAO;EACvB,KAAK,OAAO,KAAK;EACjB,KAAK,YAAY,KAAK;EACtB,KAAK,UAAU,KAAK;CACtB;AACF;;AAGA,IAAa,sBAAb,cAAyC,cAAc;CACrD,YAAY,SAAiB,OAAwE,CAAC,GAAG;EACvG,MAAM,SAAS;GAAE,MAAM;GAAoB,WAAW;GAAO,GAAG;EAAK,CAAC;CACxE;AACF;;AAGA,IAAa,mBAAb,cAAsC,cAAc;CAClD,YAAY,SAAiB,OAAwE,CAAC,GAAG;EACvG,MAAM,SAAS;GAAE,MAAM;GAAiB,WAAW;GAAM,GAAG;EAAK,CAAC;CACpE;AACF;;AAGA,IAAa,uBAAb,cAA0C,cAAc;CACtD,YAAY,SAAiB,OAAwE,CAAC,GAAG;EACvG,MAAM,SAAS;GAAE,MAAM;GAAqB,WAAW;GAAO,GAAG;EAAK,CAAC;CACzE;AACF;;AAGA,IAAa,eAAb,cAAkC,cAAc;CAC9C,YAAY,SAAiB,OAAwE,CAAC,GAAG;EACvG,MAAM,SAAS;GAAE,MAAM;GAAW,WAAW;GAAM,GAAG;EAAK,CAAC;CAC9D;AACF;;AAGA,IAAa,oBAAb,cAAuC,cAAc;CACnD,YAAY,SAAiB,OAAwE,CAAC,GAAG;EACvG,MAAM,SAAS;GAAE,MAAM;GAAiB,WAAW;GAAM,GAAG;EAAK,CAAC;CACpE;AACF;;AAGA,IAAa,6BAAb,cAAgD,cAAc;;CAE5D;;CAEA;CAEA,YAAY,MAAgE;EAC1E,MAAM,YAAY,KAAK,QAAQ,sBAAsB,KAAK,WAAW,IAAI;GACvE,MAAM;GACN,WAAW;GACX,SAAS;IAAE,SAAS,KAAK;IAAS,YAAY,KAAK;GAAW;GAC9D,GAAI,KAAK,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;EAC1D,CAAC;EACD,KAAK,UAAU,KAAK;EACpB,KAAK,aAAa,KAAK;CACzB;AACF;;;;;AAMA,IAAa,eAAb,cAAkC,cAAc;CAC9C,YAAY,UAAU,qBAAqB,OAA4B,CAAC,GAAG;EACzE,MAAM,SAAS;GAAE,MAAM;GAAW,WAAW;GAAO,GAAG;EAAK,CAAC;CAC/D;AACF;AAEA,MAAM,aAAa;;;;;;;AAQnB,SAAgB,gBACd,KACA,MAAiD,CAAC,GACnC;CACf,IAAI,eAAe,eAAe,OAAO;CAEzC,IAAI,mBAAmB,GAAG,GAAG;EAC3B,MAAM,IAAI;EACV,MAAM,UAAU,EAAE,WAAW,OAAO,EAAE,QAAQ,oBAAoB;EAClE,MAAM,UAAgC,EAAE,GAAI,EAAE,WAAW,CAAC,EAAG;EAC7D,MAAM,OAAO;GAAE;GAAS,OAAO;EAAI;EAGnC,IAAI,WAAW,KAAK,OAAO,GAAG,OAAO,IAAI,aAAa,SAAS,IAAI;EACnE,QAAQ,EAAE,MAAV;GACE,KAAK,oBACH,OAAO,IAAI,oBAAoB,SAAS,IAAI;GAC9C,KAAK,iBACH,OAAO,IAAI,iBAAiB,SAAS,IAAI;GAC3C,KAAK,qBACH,OAAO,IAAI,qBAAqB,SAAS,IAAI;GAC/C,KAAK;GACL,KAAK;GACL,KAAK,mBACH,OAAO,IAAI,2BAA2B;IACpC,SAAS,IAAI,WAAW;IACxB,YAAY,IAAI,cAAc,OAAO,EAAE,IAAI;IAC3C,OAAO;GACT,CAAC;GACH,SACE,OAAO,IAAI,kBAAkB,SAAS;IACpC,SAAS;KAAE,GAAG;KAAS,aAAa,EAAE,SAAS,KAAA,IAAY,KAAA,IAAY,OAAO,EAAE,IAAI;IAAE;IACtF,OAAO;GACT,CAAC;EACL;CACF;CAEA,IAAI,eAAe,OAAO;EACxB,IAAI,WAAW,KAAK,IAAI,OAAO,GAAG,OAAO,IAAI,aAAa,IAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EACrF,OAAO,IAAI,cAAc,IAAI,SAAS;GAAE,MAAM;GAAW,WAAW;GAAO,OAAO;EAAI,CAAC;CACzF;CACA,OAAO,IAAI,cAAc,OAAO,GAAG,GAAG;EAAE,MAAM;EAAW,WAAW;EAAO,OAAO;CAAI,CAAC;AACzF;;;;;;;;AC5GA,IAAsB,oBAAtB,MAAiE;CAC/D;CACA;CAEA,YAAsB,aAAqB,cAAoC;EAC7E,KAAK,cAAc;EACnB,KAAK,eAAe,IAAI,IAAI,YAAY;CAC1C;CAEA,YAAsB,YAAoD;EACxE,OAAO,IAAI,2BAA2B;GAAE,SAAS,KAAK;GAAa;EAAW,CAAC;CACjF;;CAGA,kBAAkB,YAA8B;EAC9C,IAAI,CAAC,KAAK,aAAa,IAAI,UAAU,GAAG,MAAM,KAAK,YAAY,UAAU;CAC3E;CAEA,SAAS,OAAkG;EACzG,OAAO,QAAQ,OAAO,KAAK,YAAY,UAAU,CAAC;CACpD;CACA,WAAW,OAAuF;EAChG,OAAO,QAAQ,OAAO,KAAK,YAAY,YAAY,CAAC;CACtD;CACA,MAAM,SAAqC;EACzC,OAAO,QAAQ,OAAO,KAAK,YAAY,OAAO,CAAC;CACjD;CACA,UAAU,MAAc,aAAqC;EAC3D,OAAO,QAAQ,OAAO,KAAK,YAAY,WAAW,CAAC;CACrD;CACA,KAAK,MAAc,OAA8B;EAC/C,OAAO,QAAQ,OAAO,KAAK,YAAY,MAAM,CAAC;CAChD;CACA,SAAS,OAA8B;EACrC,OAAO,QAAQ,OAAO,KAAK,YAAY,MAAM,CAAC;CAChD;CACA,SAAS,MAA+B;EACtC,OAAO,QAAQ,OAAO,KAAK,YAAY,KAAK,CAAC;CAC/C;CACA,OAAO,YAA4C;EACjD,OAAO,QAAQ,OAAO,KAAK,YAAY,QAAQ,CAAC;CAClD;CACA,IAAI,IAAY,IAAY,KAAa,KAAa,aAAqC;EACzF,OAAO,QAAQ,OAAO,KAAK,YAAY,KAAK,CAAC;CAC/C;CACA,YAAY,OAAe,YAAoC;EAC7D,OAAO,QAAQ,OAAO,KAAK,YAAY,aAAa,CAAC;CACvD;CACA,YAAY,SAAmD;EAC7D,OAAO,QAAQ,OAAO,KAAK,YAAY,OAAO,CAAC;CACjD;CACA,OAAsB;EACpB,OAAO,QAAQ,OAAO,KAAK,YAAY,MAAM,CAAC;CAChD;CACA,OAAsB;EACpB,OAAO,QAAQ,OAAO,KAAK,YAAY,MAAM,CAAC;CAChD;CACA,QAAQ,OAImB;EACzB,OAAO,QAAQ,OAAO,KAAK,YAAY,SAAS,CAAC;CACnD;CACA,WAA8B;EAC5B,OAAO,QAAQ,OAAO,KAAK,YAAY,UAAU,CAAC;CACpD;CACA,eAA8B;EAC5B,OAAO,QAAQ,OAAO,KAAK,YAAY,cAAc,CAAC;CACxD;AACF;AAYA,MAAM,4BAAY,IAAI,IAA4B;;;;;AAMlD,SAAgB,gBAAgB,MAAc,SAA+B;CAC3E,IAAI,UAAU,IAAI,IAAI,GACpB,MAAM,IAAI,cAAc,YAAY,KAAK,0BAA0B;EACjE,MAAM;EACN,WAAW;CACb,CAAC;CAEH,UAAU,IAAI,MAAM,OAAO;AAC7B;;AAGA,SAAgB,kBAAkB,MAA8B;CAC9D,MAAM,UAAU,UAAU,IAAI,IAAI;CAClC,IAAI,CAAC,SACH,MAAM,IAAI,cACR,qBAAqB,KAAK,kBAAkB,CAAC,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,YAChF;EACE,MAAM;EACN,WAAW;CACb,CACF;CAEF,OAAO;AACT;;AAGA,SAAgB,eAAyB;CACvC,OAAO,CAAC,GAAG,UAAU,KAAK,CAAC;AAC7B;;;;ACzGA,MAAa,mBAA0C;CACrD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF"}
|