@versionone/agility-sdk 1.0.0-alpha.4 → 1.0.0-alpha.6
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/CHANGELOG.md +62 -6
- package/README.md +8 -6
- package/dist/index.cjs +101 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +169 -96
- package/dist/index.d.ts +169 -96
- package/dist/index.js +101 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/errors.ts","../src/core/fetchTransport.ts","../src/types/oid.ts","../src/wire/assetApi.ts","../src/wire/select.ts","../src/wire/attachment.ts","../src/services/attachments.ts","../src/services/guard.ts","../src/services/batch.ts","../src/wire/fields.ts","../src/services/fields.ts","../src/types/asset.ts","../src/services/resolve.ts","../src/wire/meta.ts","../src/services/schema.ts","../src/wire/loc2.ts","../src/wire/queryV1.ts","../src/wire/rest1.ts","../src/client.ts"],"sourcesContent":["export { AgilityApiClient } from \"./client\";\nexport type { ClientOptions, Me, Page, PagesOptions } from \"./client\";\nexport { ApiError, UsageError, WrappedError, kindOf } from \"./core/errors\";\nexport type { ErrorKind } from \"./core/errors\";\nexport { createFetchTransport } from \"./core/fetchTransport\";\nexport type { FetchTransportConfig, UnauthorizedContext, UnauthorizedDecision } from \"./core/fetchTransport\";\nexport type { ClientConfig } from \"./core/clientConfig\";\nexport type { RequestBody, RequestOptions, ResponseType, Transport } from \"./core/transport\";\n\n// The model: what things are.\nexport type { Asset, AttributeValue, CustomAttributes, DateString, Oid, Ref, AssetStateValue } from \"./types/asset\";\nexport { ASSET_STATE_CODES, assetStateOf } from \"./types/asset\";\nexport { isOidToken, momentless, parseOid, toOid, typeOfOid } from \"./types/oid\";\nexport type { OidParts } from \"./types/oid\";\nexport type { AssetType, AttributeDefinition, AttributeLookup, AttributeType, AttributeTokenRef, AssetTypeToken, Metamodel } from \"./types/metamodel\";\nexport type * from \"./types/assets/index\";\nexport type { CreateType, CustomList, From, RowOf, RowsOf, SelectKey, SelectPath, SelectValue, Selected, TypeOf } from \"./types/query\";\n\n// The wire layer: one module per endpoint.\nexport { assetApi, rest1, meta, loc2, queryV1, attachment, fields } from \"./wire\";\nexport type { OperationResult, Template } from \"./wire/rest1\";\nexport type { FieldsOf } from \"./services/fields\";\nexport { importantName } from \"./services/fields\";\nexport type { Bytes, EmbeddedImage } from \"./wire/attachment\";\nexport * as select from \"./wire/select\";\nexport type { AssetApiResponse, Command, CommandBody, CommandFailureDetail, Outcome, CommandValue, CreateBody, ExecuteBody, QueryBody, UpdateBody, ReadOptions, RowContext, SendOptions } from \"./wire/assetApi\";\nexport { CommandFailureError, parseViolation } from \"./wire/assetApi\";\nexport type { Violation } from \"./wire/assetApi\";\nexport type { AssetDocument, AssetsDocument, ReadParams, ReadResult } from \"./wire/rest1\";\nexport type { Localizations, LocalizeOptions } from \"./wire/loc2\";\n\n// Services: what to do.\nexport { Schema, TypeCache } from \"./services/schema\";\nexport { AttachmentUploadError, INLINE_LIMIT } from \"./services/attachments\";\nexport type { AddOptions as AttachmentAddOptions, AttachmentInfo } from \"./services/attachments\";\nexport { CHUNK as RESOLVE_CHUNK, NUMBER_ROOTS, isAssetNumber, resolveNumbers, resolveRef } from \"./services/resolve\";\nexport type { Resolution, ResolvedAsset } from \"./services/resolve\";\nexport { UNGUARDABLE_TYPES, UnguardableError, guard, sendGuarded, stampsOf, touchedBy, unguardable } from \"./services/guard\";\nexport type { GuardedResult, Unguardable } from \"./services/guard\";\nexport { BatchRecordError, BatchSendError, INVERSE, describe as describeBatch, namesOf, reverseOf, reversible, runBatch, snapshot } from \"./services/batch\";\nexport type { BatchOptions, Described, NameLookupFailure, Named, Receipt, Reverse } from \"./services/batch\";\n","/**\n * Every error the SDK throws is an ApiError, and every ApiError has a\n * `kind`: the one word a caller branches on. `status` and `code` say what\n * exactly happened; `kind` says what to do about it.\n *\n * auth 401: re-authenticate (the transport's onUnauthorized hook ran first)\n * forbidden 403: the credential is fine, the permission is not\n * notFound 404, or a NOT_FOUND from a service\n * invalid the request was understood and refused: 400, a rejected query, too large\n * transient no answer, or a 5xx/408/429: the same request may succeed later\n * aborted the caller's signal ended it\n * commandFailure api/asset answered 200 with failed commands inside (CommandFailureError)\n * protocol the server answered something the SDK cannot read\n * usage a mistake caught before any request (UsageError): nothing was sent, so\n * do not blame the server — fix the call (status is 0 here)\n * unknown none of the above\n */\nexport type ErrorKind = \"auth\" | \"forbidden\" | \"notFound\" | \"invalid\" | \"transient\" | \"aborted\" | \"commandFailure\" | \"protocol\" | \"usage\" | \"unknown\";\n\n/** The kind an HTTP status and an SDK code imply. A code wins over a status. */\nexport function kindOf(status: number, code?: string): ErrorKind {\n switch (code) {\n case \"ABORTED\": return \"aborted\";\n case \"TIMEOUT\":\n case \"NETWORK_ERROR\": return \"transient\";\n case \"BAD_JSON\":\n case \"BAD_RESPONSE\": return \"protocol\";\n case \"USAGE\": return \"usage\";\n case \"CommandFailure\": return \"commandFailure\";\n case \"QUERY_REJECTED\":\n case \"TOO_LARGE\": return \"invalid\";\n case \"NOT_FOUND\": return \"notFound\";\n }\n if (status === 401) return \"auth\";\n if (status === 403) return \"forbidden\";\n if (status === 404) return \"notFound\";\n if (status === 408 || status === 429 || status >= 500) return \"transient\";\n if (status >= 400) return \"invalid\";\n return \"unknown\";\n}\n\nconst causeOf = (details: unknown): unknown => (details && typeof details === \"object\" && \"cause\" in details ? (details as { cause: unknown }).cause : undefined);\n\nexport class ApiError extends Error {\n /** The HTTP status; 0 when no answer came back (network, timeout, abort, usage). */\n readonly status: number;\n readonly code?: string;\n readonly details?: unknown;\n readonly kind: ErrorKind;\n\n constructor(message: string, status: number, code?: string, details?: unknown, kind: ErrorKind = kindOf(status, code)) {\n const cause = causeOf(details);\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"ApiError\";\n this.status = status;\n this.code = code;\n this.details = details;\n this.kind = kind;\n }\n}\n\n/**\n * A mistake in the call, caught before any request is sent: an unpaged\n * query, an empty batch, a string that is not an OID token. Nothing on the\n * server has happened; fix the call. (A TypeError would say the same, but\n * one `instanceof ApiError` then covers everything the SDK throws.)\n */\nexport class UsageError extends ApiError {\n constructor(message: string, details?: unknown) {\n super(message, 0, \"USAGE\", details, \"usage\");\n this.name = \"UsageError\";\n }\n}\n\n/**\n * An error raised around another: a batch send that failed, an upload\n * that failed after the create. Its status and kind are the cause's when\n * the cause is an ApiError, so a caller still branches on `kind`.\n */\nexport class WrappedError extends ApiError {\n constructor(message: string, code: string, cause: unknown, details?: Record<string, unknown>) {\n const inner = cause instanceof ApiError ? cause : undefined;\n super(message, inner?.status ?? 0, code, { ...details, cause }, inner?.kind ?? \"unknown\");\n this.name = \"WrappedError\";\n }\n}\n","import { ApiError } from \"./errors\";\nimport type { RequestBody, RequestOptions, ResponseType, Transport } from \"./transport\";\n\n/**\n * The HTTP layer, and nothing above it: it knows how to build a URL, send a\n * body in the shape it was given, read a response in the shape it was asked\n * for, and turn a failure into an ApiError. It does not know what an asset\n * is. The wire layer (one module per endpoint) knows the envelopes; the\n * model layer knows the types.\n *\n * Retries live here because this is the only place that can tell a network\n * failure from an answer, but they are narrow on purpose: only requests the\n * caller marks idempotent (every GET is; a POST to api/asset is not — a\n * retried batch write after a timeout is a double write), and only on a\n * network error or a 5xx. A 4xx is an answer and is never retried.\n */\nexport interface FetchTransportConfig {\n baseUrl: string;\n /** A ready Authorization header value — \"Bearer …\" or \"Basic …\". Wins over accessToken. */\n authorization?: string;\n /** An access token; sent as \"Bearer <token>\". */\n accessToken?: string;\n defaultHeaders?: Record<string, string>;\n /**\n * Client-side ceiling per attempt. Generous by default: the politeness rule\n * is about the work a request asks of the server, not about client\n * impatience, and a slow or recovering host should not be hammered by\n * timeouts that turn into retries.\n */\n timeoutMs?: number;\n /** Extra attempts after the first, for idempotent requests only. Default 0. */\n retries?: number;\n fetchImpl?: typeof fetch;\n /**\n * fetch's credentials mode. A browser app on the instance's own origin\n * that authenticates with the session cookie sets \"same-origin\" or\n * \"include\" (pair it with defaultHeaders { \"X-Requested-With\":\n * \"XMLHttpRequest\" } so the server answers 401 rather than a login page).\n * Left unset, fetch's default applies.\n */\n credentials?: RequestCredentials;\n /**\n * Called when the server answers 401 (or a status in unauthorizedStatuses):\n * the place to re-authenticate — open a login popup, re-run setup. Resolve\n * \"retry\" to send the request once more, \"fail\" to throw the error.\n *\n * A retry is offered only for an idempotent request (every GET; a write the\n * caller marked idempotent). A plain api/asset write is never resent\n * automatically, even after a 401: the hook still runs, so the session\n * can be repaired, and the caller decides whether to send again.\n */\n onUnauthorized?: (context: UnauthorizedContext) => UnauthorizedDecision | Promise<UnauthorizedDecision>;\n /** Which statuses call onUnauthorized. Default [401]; a cookie-session app may add 403. */\n unauthorizedStatuses?: readonly number[];\n}\n\nexport type UnauthorizedDecision = \"retry\" | \"fail\";\n\nexport interface UnauthorizedContext {\n error: ApiError;\n request: RequestOptions;\n /** Whether a \"retry\" will be honoured: false for a non-idempotent write. */\n retryable: boolean;\n}\n\n/** The ApiError a caller's abort turns into. */\nfunction abortedError(signal: AbortSignal): ApiError {\n return new ApiError(\"Request aborted\", 0, \"ABORTED\", { cause: signal.reason });\n}\n\nfunction buildUrl(baseUrl: string, path: string, query?: RequestOptions[\"query\"]): string {\n const normalizedBase = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const normalizedPath = path.startsWith(\"/\") ? path.slice(1) : path;\n const url = new URL(normalizedPath, normalizedBase);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) url.searchParams.set(key, String(value));\n }\n }\n return url.toString();\n}\n\n/** The body as fetch wants it, with the content type it implies. */\nfunction encodeBody(body: RequestBody | undefined, contentType: string | undefined): { body?: BodyInit; contentType?: string } {\n if (body === undefined) return {};\n if (typeof body === \"string\") return { body, contentType: contentType ?? \"text/plain\" };\n if (body instanceof Uint8Array || body instanceof ArrayBuffer) {\n return { body: body as BodyInit, contentType: contentType ?? \"application/octet-stream\" };\n }\n // A form is handed to fetch as is: it writes the multipart boundary itself.\n if (typeof FormData !== \"undefined\" && body instanceof FormData) return { body };\n // A Blob (a browser File, say) is bytes with a type of its own.\n if (typeof Blob !== \"undefined\" && body instanceof Blob) return { body, contentType: contentType ?? (body.type || \"application/octet-stream\") };\n return { body: JSON.stringify(body), contentType: contentType ?? \"application/json\" };\n}\n\nasync function readBody(response: Response, responseType: ResponseType): Promise<unknown> {\n if (responseType === \"bytes\") return new Uint8Array(await response.arrayBuffer());\n if (responseType === \"text\") return response.text();\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (responseType === \"json\" || contentType.includes(\"json\")) {\n const text = await response.text();\n if (!text) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n if (responseType === \"json\") throw new ApiError(\"Response is not JSON\", response.status, \"BAD_JSON\", { body: text.slice(0, 500) });\n return text;\n }\n }\n return response.text();\n}\n\n/**\n * The message of an error response, from the shapes the Agility endpoints\n * actually send: rest-1's { _type: \"Error\", error, exceptions: [{ message }] },\n * api/asset's { Exceptions: [\"…\"] } (a request it could not parse — 400\n * with the parser's message since 2026-11, an opaque 500 before), a bare\n * { message }, or text.\n */\nfunction messageOf(data: unknown, status: number): string {\n if (data && typeof data === \"object\") {\n const d = data as Record<string, unknown>;\n const first = Array.isArray(d.exceptions) && d.exceptions[0] && typeof d.exceptions[0] === \"object\" ? (d.exceptions[0] as Record<string, unknown>).message : undefined;\n const listed = Array.isArray(d.Exceptions) ? d.Exceptions.filter((x): x is string => typeof x === \"string\" && !!x).join(\"; \") : undefined;\n for (const candidate of [d.error, first, listed, d.message]) {\n if (typeof candidate === \"string\" && candidate) return candidate;\n }\n }\n if (typeof data === \"string\" && data.trim()) return data.trim().slice(0, 200);\n return `HTTP ${status}`;\n}\n\nconst delay = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport function createFetchTransport(config: FetchTransportConfig): Transport {\n const fetchImpl = config.fetchImpl ?? fetch;\n const timeoutMs = config.timeoutMs ?? 60_000;\n const retries = Math.max(0, config.retries ?? 0);\n const authorization = config.authorization ?? (config.accessToken ? `Bearer ${config.accessToken}` : undefined);\n const unauthorizedStatuses = config.unauthorizedStatuses ?? [401];\n\n return {\n async request<T>(options: RequestOptions): Promise<T> {\n const url = buildUrl(config.baseUrl, options.path, options.query);\n const { body, contentType } = encodeBody(options.body, options.contentType);\n const headers: Record<string, string> = { accept: \"application/json\", ...config.defaultHeaders, ...options.headers };\n // A bodiless request carries no content type: rest-1 rejects a GET that claims JSON.\n if (contentType) headers[\"content-type\"] = contentType;\n if (authorization) headers.authorization = authorization;\n const responseType: ResponseType = options.responseType ?? \"auto\";\n const idempotent = options.idempotent ?? options.method === \"GET\";\n const attempts = idempotent ? retries + 1 : 1;\n\n const callerSignal = options.signal;\n\n let lastError: unknown;\n let reauthorized = false;\n for (let attempt = 0; attempt < attempts; attempt += 1) {\n if (callerSignal?.aborted) throw abortedError(callerSignal);\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n const onAbort = () => controller.abort();\n callerSignal?.addEventListener(\"abort\", onAbort, { once: true });\n const settle = () => {\n clearTimeout(timeoutId);\n callerSignal?.removeEventListener(\"abort\", onAbort);\n };\n let response: Response;\n try {\n const init: RequestInit = { method: options.method, headers, body, signal: controller.signal };\n if (config.credentials) init.credentials = config.credentials;\n response = await fetchImpl(url, init);\n } catch (error) {\n settle();\n // The caller gave up: final, whatever attempt this was.\n if (callerSignal?.aborted) throw abortedError(callerSignal);\n // Network failure or timeout: the only case a retry can help.\n lastError = error instanceof Error && error.name === \"AbortError\"\n ? new ApiError(`Timed out after ${timeoutMs} ms`, 0, \"TIMEOUT\", { cause: error })\n : new ApiError(error instanceof Error ? error.message : String(error), 0, \"NETWORK_ERROR\", { cause: error });\n if (attempt + 1 < attempts) await delay(150 * (attempt + 1));\n continue;\n }\n\n try {\n if (response.ok) {\n options.onResponse?.({ status: response.status, headers: response.headers });\n return (await readBody(response, responseType)) as T;\n }\n\n // An answer, not a failure to get one. 5xx may be retried when\n // idempotent; anything else is final.\n const data = await readBody(response, responseType === \"bytes\" ? \"text\" : responseType === \"json\" ? \"auto\" : responseType);\n lastError = new ApiError(messageOf(data, response.status), response.status, undefined, data);\n } catch (error) {\n if (callerSignal?.aborted) throw abortedError(callerSignal);\n throw error;\n } finally {\n settle();\n }\n\n if (config.onUnauthorized && !reauthorized && unauthorizedStatuses.includes(response.status)) {\n // One re-authentication per request: a second refusal is final.\n reauthorized = true;\n const decision = await config.onUnauthorized({ error: lastError as ApiError, request: options, retryable: idempotent });\n if (callerSignal?.aborted) throw abortedError(callerSignal);\n if (decision === \"retry\" && idempotent) {\n // Not counted against `retries`: those are for failures to get an answer.\n attempt -= 1;\n continue;\n }\n break;\n }\n if (response.status >= 500 && attempt + 1 < attempts) {\n await delay(150 * (attempt + 1));\n continue;\n }\n break;\n }\n throw lastError instanceof ApiError ? lastError : new ApiError(\"Unknown transport error\", 0, \"UNKNOWN_ERROR\", { cause: lastError });\n }\n };\n}\n","/**\n * OID tokens, the one spelling every endpoint shares: \"Story:1234\", or with\n * a moment, \"Story:1234:5678\". The model carries the momentless form except\n * where the moment is the identity (a history row). Every consumer had its\n * own copy of these (agility-rooms' AssetOidHelper, ossum-ui's toMomentless,\n * gh-v1's momentless, v1sdk 2.x's Oid class); this is the one they share.\n */\nimport { UsageError } from \"../core/errors\";\nimport type { Oid } from \"./asset\";\n\nexport interface OidParts {\n type: string;\n id: number;\n /** The moment, when the token carries one. */\n moment: number | null;\n}\n\nconst OID_TOKEN = /^([A-Za-z][A-Za-z0-9_]*):(\\d+)(?::(\\d+))?$/;\n\n/** Is this an OID token? \"Story:1234\" and \"Story:1234:5678\" are; \"S-1234\" and \"Story\" are not. */\nexport function isOidToken(value: unknown): value is Oid {\n return typeof value === \"string\" && OID_TOKEN.test(value);\n}\n\n/** The parts of an OID token. Throws on anything that is not one. */\nexport function parseOid(token: string): OidParts {\n const m = OID_TOKEN.exec(token);\n if (!m) throw new UsageError(`\"${token}\" is not an OID token (Story:1234)`);\n return { type: m[1]!, id: Number(m[2]), moment: m[3] === undefined ? null : Number(m[3]) };\n}\n\n/** An OID token without its moment: \"Story:1234:5678\" -> \"Story:1234\". Anything that is not a token is returned as is. */\nexport function momentless(token: string): Oid {\n const m = OID_TOKEN.exec(token);\n return m ? `${m[1]}:${m[2]}` : token;\n}\n\n/** The asset type of an OID token: \"Story:1234\" -> \"Story\". */\nexport function typeOfOid(token: string): string {\n return parseOid(token).type;\n}\n\n/** An OID token from its parts. */\nexport function toOid(type: string, id: number, moment?: number | null): Oid {\n return moment == null ? `${type}:${id}` : `${type}:${id}:${moment}`;\n}\n","/**\n * The api/asset (Bulk API) wire module: exactly what the endpoint takes and\n * returns, and the translation between that and the model.\n *\n * The model is endpoint-agnostic: a relation is a Ref ({ _oid }), whatever\n * endpoint it came from or is going to. This module is where api/asset's\n * spellings live — a relation value written as an OID string (or an array\n * of them), one aliased command per array element, `previewOnly` on the\n * query string, YAML as a text body — so callers never learn them.\n *\n * Verified shapes (https://docs.digital.ai/agility-api/apis/asset-bulk, and\n * its errors page for commandFailures):\n * - response: requestId, createdDate, completedDate, duration,\n * durationSeconds, complete, processing, assetsCreated/assetsModified/\n * assetsOperatedOn { oidTokens, count }, commandFailures { commands,\n * count } with each entry the echoed command (its alias replaced by a\n * generated one) plus error { message, sourceCommandIndex, stackTrace? }\n * — sourceCommandIndex is the only reliable key back to the request —\n * and queryResult { results, resultMetaData, count } with results\n * POSITIONAL, one array per query command in request order.\n * - a batch commits per command: a later failure does not undo an\n * earlier success, and the HTTP status is 200 either way.\n * - preview (?previewOnly=true) returns the projection: creates echoed,\n * bare query-scoped updates and executes expanded to one command per\n * matched asset, aliased ones echoed unexpanded.\n */\nimport { ApiError, UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Asset, Oid, Ref } from \"../types/asset\";\nimport type { AssetTypeToken, AttributeLookup, AttributeTokenRef, AttributeType } from \"../types/metamodel\";\nimport type { CreateType, From, SelectPath, TypeOf } from \"../types/query\";\nimport { momentless } from \"../types/oid\";\nimport { fromTypeOf, resolvePath, type PathResolution } from \"./select\";\n\nexport { momentless };\n\n// ---- what the endpoint takes ------------------------------------------------\n\n/** A value in a command as the MODEL writes it: scalars, Refs, lists of either, or a nested command. */\nexport type CommandValue = string | number | boolean | null | Ref | CommandValue[] | { [key: string]: CommandValue };\n\nexport interface CreateBody { AssetType: CreateType; [attribute: string]: CommandValue }\n/**\n * A query. Written with a literal `from`, `select` completes from that\n * type's attributes and the rows come back typed by what was selected\n * (src/types/query.ts); written from variables, it is what it always was.\n */\nexport interface QueryBody<F extends string = string> {\n from: F | From;\n select?: (SelectPath<TypeOf<F>> | QueryBody)[];\n filter?: string[];\n where?: Record<string, string>;\n with?: Record<string, CommandValue>;\n sort?: string[];\n page?: { size: number; start: number };\n find?: string;\n findin?: string[];\n asof?: string;\n /** Ask api/asset for the total number of matches (query.v1 ignores it); read it with queryPage. */\n needTotal?: boolean;\n /** Group the rows by a relation: each result row is then a group, its rows under `_children` (translated like any row of `from`). */\n group?: (string | { from: string; [key: string]: unknown })[];\n}\n/**\n * An update. Each key of `update` is an attribute; its value replaces a\n * scalar or a single relation (null clears it). A multi-value relation is\n * changed with `{ add: [...], remove: [...] }`. A plain list does NOT\n * replace a multi-value relation: the server ADDS its members, like rest-1's\n * `act: \"add\"` (seen live on v1sdktesting, 2026-11-07). To set one exactly,\n * remove what should go and add what should come. A change comment goes in\n * the update node as `ChangeComment`.\n */\nexport interface UpdateBody { from: From; filter?: string[]; where?: Record<string, string>; with?: Record<string, CommandValue>; update: Record<string, CommandValue> }\n/**\n * An operation (QuickClose, Inactivate, Reactivate, Delete, …), optionally\n * with arguments. It cannot carry a change comment. Agility refuses to\n * Delete a closed asset (Violation'AssetCannotDeleteClosed): Reactivate it\n * first, as batch.reversible does.\n */\nexport interface ExecuteBody { from: From; filter?: string[]; where?: Record<string, string>; with?: Record<string, CommandValue>; execute: string | { op: string; args?: Record<string, CommandValue>; list?: Record<string, CommandValue>[] } }\nexport type CommandBody = CreateBody | QueryBody | UpdateBody | ExecuteBody;\n\n/** An alias key: \"@story\". */\nexport type Alias = `@${string}`;\n/** A command as sent: aliased ({ \"@x\": body }) or bare (the body itself). */\nexport type Command = { [alias: Alias]: CommandBody } | CommandBody;\n\n// ---- what the endpoint returns ----------------------------------------------\n\nexport interface OidTokens { oidTokens: Oid[]; count: number }\nexport interface CommandError { message: string; sourceCommandIndex?: number; stackTrace?: string }\n/** The echoed command (under a generated alias) plus the error. */\nexport type CommandFailure = { error: CommandError | string } & Record<string, unknown>;\nexport interface AssetApiResponse<Row extends Asset = Asset> {\n requestId: string;\n createdDate: string;\n completedDate: string;\n duration: string;\n durationSeconds: number;\n complete: boolean;\n processing: boolean;\n assetsCreated: OidTokens;\n assetsModified: OidTokens;\n assetsOperatedOn: OidTokens;\n commandFailures: { commands: CommandFailure[]; count: number };\n /**\n * One slot per query command, in request order; [] where a query matched\n * nothing. The server DROPS the slot of a query that failed, shifting the\n * later ones up (live, 2026-11-04); send puts the slot back as null, so a\n * caller's positions hold and a failure never reads as an empty result.\n */\n queryResult: { results: (Row[] | null)[]; resultMetaData: unknown[]; count: number };\n}\n\n// ---- translation ------------------------------------------------------------\n\nconst isRef = (v: unknown): v is Ref => !!v && typeof v === \"object\" && !Array.isArray(v) && \"_oid\" in v && typeof (v as Ref)._oid === \"string\";\n\n/**\n * A model value as api/asset wants it written: a Ref becomes its OID token,\n * a list of Refs a list of tokens, and everything else is left as is —\n * strings (OID tokens, monikers, alias references like \"@story\") pass\n * through untouched, and nested command bodies are translated recursively.\n */\nexport function toWireValue(value: CommandValue): unknown {\n if (isRef(value)) return momentless(value._oid);\n if (Array.isArray(value)) return value.map(toWireValue);\n if (value && typeof value === \"object\") return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, toWireValue(v)]));\n return value;\n}\n\n/** A batch as api/asset wants it. */\nexport const toWire = (commands: Command[]): unknown[] => commands.map((c) => toWireValue(c as CommandValue));\n\n/**\n * What a row is translated against: the schema, and the type of the rows.\n * Without it a row is passed through with only its OIDs normalised, which\n * is the endpoint's own spelling: every scalar a string, a sub-selected\n * single relation a one-element list.\n */\nexport interface RowContext { lookup: AttributeLookup; type: AssetTypeToken }\n\n/**\n * A query row as the model carries it. The endpoint spells every scalar as a\n * string (\"5\", \"False\") and a single relation selected with a sub-select as\n * a one-element list ([{ _oid }], or [] when unset); with a schema each key\n * is resolved to its attribute and translated — Numeric, LongInt and Rank\n * to number, Boolean to boolean, [x] to x and [] to null on a single\n * relation, { _oid: \"NULL\" } (an unset single relation) to null,\n * an @Count to number, and a sub-select's rows recursively by their own\n * type. Everywhere, OIDs lose their moment. A key the schema cannot resolve\n * is left as sent.\n */\nexport function fromWireRow<Row extends Asset = Asset>(row: Record<string, unknown>, context?: RowContext): Row {\n const out: Record<string, unknown> = {};\n // A `group` query answers with group rows: the group's key as `_oid` and\n // the grouped rows under `_children`. The children are rows of the query's\n // own type (or group rows again, for nested groups), so they translate\n // with the same context. No attribute is called _children, so its presence\n // is what marks a group row; a \"NULL\" key is the group of rows with the\n // relation unset, and reads as null like any unset relation.\n const grouped = Array.isArray(row._children);\n for (const [k, v] of Object.entries(row)) {\n if (grouped && k === \"_children\") out[k] = (v as unknown[]).map((child) => (child && typeof child === \"object\" ? fromWireRow(child as Record<string, unknown>, context) : child));\n else if (grouped && k === \"_oid\" && v === \"NULL\") out[k] = null;\n else if (k === \"_oid\" && typeof v === \"string\") out[k] = momentless(v);\n else out[k] = context ? translate(v, resolvePath(context.lookup, context.type, k), context.lookup) : fromWireValue(v);\n }\n return out as Row;\n}\n/**\n * An unset single relation selected without a sub-select: the endpoint\n * sends { _oid: \"NULL\" } (seen live on TeamRoom.Team, 2026-11-06). The\n * model reads it as null, never as a Ref to an asset called NULL.\n */\nconst isNullRef = (value: unknown): boolean => isRef(value) && value._oid === \"NULL\";\n\nfunction fromWireValue(value: unknown): unknown {\n if (isNullRef(value)) return null;\n if (isRef(value)) return { ...value, _oid: momentless(value._oid) };\n if (Array.isArray(value)) return value.map(fromWireValue);\n return value;\n}\n\nfunction translate(value: unknown, resolution: PathResolution, lookup: AttributeLookup): unknown {\n if (resolution.kind !== \"resolved\") return fromWireValue(value);\n if (resolution.aggregate) return toNumber(value);\n const definition = resolution.definition!;\n if (definition.AttributeType === \"Relation\") {\n const context = resolution.valueType ? { lookup, type: resolution.valueType } : undefined;\n const one = (x: unknown): unknown => (isNullRef(x) ? null : isRef(x) ? fromWireRow(x as Record<string, unknown>, context) : fromWireValue(x));\n if (resolution.multi) return (Array.isArray(value) ? value : value == null ? [] : [value]).filter((x) => !isNullRef(x)).map(one);\n if (Array.isArray(value)) return value.length ? one(value[0]) : null;\n return value == null ? null : one(value);\n }\n const one = (x: unknown): unknown => scalar(x, definition.AttributeType);\n return resolution.multi && Array.isArray(value) ? value.map(one) : one(value);\n}\n\n/** A scalar as the model carries it, from the string the endpoint sent. A value that does not parse is left as sent. */\nfunction scalar(value: unknown, type: AttributeType): unknown {\n if (value == null) return null;\n switch (type) {\n case \"Numeric\":\n case \"LongInt\":\n case \"Rank\": // a 32-bit integer sent as a string (\"-2000000000\"); sorts as a number\n return toNumber(value);\n case \"Boolean\":\n return value === true || value === \"True\" || value === \"true\" ? true : value === false || value === \"False\" || value === \"false\" ? false : value;\n default:\n return value;\n }\n}\nfunction toNumber(value: unknown): unknown {\n if (value == null) return null;\n if (typeof value === \"number\") return value;\n const n = typeof value === \"string\" && value.trim() !== \"\" ? Number(value) : NaN;\n return Number.isNaN(n) ? value : n;\n}\n\n/**\n * One failed command, normalised. `index` is the zero-based position, in\n * the batch as sent, of the command that produced the failure (the server's\n * sourceCommandIndex — the echoed alias is replaced by a generated one, so\n * the index is the only key back to the request); null when the server gave\n * none. Several failures can share one index: a failed create fails every\n * descendant it would have parented, and the first entry is the root cause.\n * `message` is the server's text, often an apostrophe-delimited token\n * (\"Violation'Invalid'Epic.Scope\") a caller can branch on or run through\n * loc-2 — but an unknown attribute reads differently in `select` and in\n * `where`, so match on text with care. stackTrace is never kept: only\n * internal development builds send it.\n */\nexport interface CommandFailureDetail {\n index: number | null;\n message: string;\n echoed: Record<string, unknown>;\n /** The message read as a validation violation, when it is one. */\n violation: Violation | null;\n}\n\n/**\n * A validation failure as api/asset words it: `Violation'<Rule>'<tag>`,\n * where the rule is Required, Invalid, AssetCannotDeleteClosed, … and the\n * rest, when present, names what was violated. The attribute form is a\n * loc-2 tag (`AttributeDefinition'Scope'Story`, live 2026-11-12), which\n * `client.localize` turns into the attribute's label; an older spelling is\n * the token itself (`Epic.Scope`). Both read as `attribute: \"Story.Scope\"`.\n */\nexport interface Violation {\n rule: string;\n /** \"Story.Scope\" when the violation names an attribute; null otherwise. */\n attribute: AttributeTokenRef | null;\n /** The loc-2 tag naming what was violated (`AttributeDefinition'Scope'Story`), when the message carries one; null for the token spelling. */\n tag: string | null;\n}\n\n/** The violation a failure message describes, or null when it is not one. */\nexport function parseViolation(message: string): Violation | null {\n const parts = message.trim().split(\"'\");\n if (parts[0] !== \"Violation\" || !parts[1]) return null;\n const rule = parts[1], rest = parts.slice(2).filter((p) => p !== \"\");\n if (rest[0] === \"AttributeDefinition\" && rest[1] && rest[2]) return { rule, attribute: `${rest[2]}.${rest[1]}`, tag: rest.join(\"'\") };\n // The older spelling names the attribute by its token (\"Epic.Scope\"): not a loc-2 tag, so `tag` is null there.\n const token = rest.length === 1 && /^[A-Za-z][A-Za-z0-9_]*\\.[A-Za-z][A-Za-z0-9_]*$/.test(rest[0]!) ? (rest[0] as AttributeTokenRef) : null;\n return { rule, attribute: token, tag: !token && rest.length > 1 ? rest.join(\"'\") : null };\n}\n\n/** The failures of a response, normalised: index and message, always both. */\nexport function failuresOf<Row extends Asset = Asset>(response: AssetApiResponse<Row>): CommandFailureDetail[] {\n return (response.commandFailures?.commands ?? []).map(({ error, ...echoed }) => ({\n index: typeof error === \"object\" && error && typeof error.sourceCommandIndex === \"number\" ? error.sourceCommandIndex : null,\n message: typeof error === \"string\" ? error : error?.message || \"command failed\",\n echoed,\n violation: parseViolation(typeof error === \"string\" ? error : error?.message || \"\")\n }));\n}\n\n/** What a batch did, in the model's terms: the services read this, never the envelope. */\nexport interface Outcome<Row extends Asset = Asset> {\n /** The server's id for the request: what to quote when asking about a batch. Null for an outcome merged from several sends. */\n requestId: string | null;\n created: Oid[];\n modified: Oid[];\n operated: Oid[];\n failures: CommandFailureDetail[];\n /** One slot per query, in request order; null where the query failed. */\n queryResults: (Row[] | null)[];\n durationSeconds: number | null;\n}\n\n/**\n * The outcome of a (translated) response: OIDs momentless, failures\n * normalised. Every field has a default, so a partial envelope (a test fake\n * that sends only queryResult) still yields a complete Outcome; consumers'\n * fakes rely on that, and the unit tests keep it so.\n */\nexport function outcomeOf<Row extends Asset = Asset>(response: AssetApiResponse<Row>): Outcome<Row> {\n return {\n requestId: typeof response.requestId === \"string\" && response.requestId ? response.requestId : null,\n created: (response.assetsCreated?.oidTokens ?? []).map(momentless),\n modified: (response.assetsModified?.oidTokens ?? []).map(momentless),\n operated: (response.assetsOperatedOn?.oidTokens ?? []).map(momentless),\n failures: failuresOf(response),\n queryResults: response.queryResult?.results ?? [],\n durationSeconds: typeof response.durationSeconds === \"number\" ? response.durationSeconds : null\n };\n}\n\n/** An outcome with nothing in it, to merge several sends into. */\nexport const emptyOutcome = <Row extends Asset = Asset>(): Outcome<Row> => ({ requestId: null, created: [], modified: [], operated: [], failures: [], queryResults: [], durationSeconds: null });\n\n/**\n * Add one send's outcome to another's, for a batch sent in several\n * requests. `offset` is how many commands were sent before this one, so a\n * failure's index stays a position in everything sent.\n */\nexport function mergeOutcome<Row extends Asset = Asset>(into: Outcome<Row>, done: Outcome<Row>, offset: number): Outcome<Row> {\n into.created.push(...done.created);\n into.modified.push(...done.modified);\n into.operated.push(...done.operated);\n into.failures.push(...done.failures.map((f) => ({ ...f, index: f.index === null ? null : f.index + offset })));\n into.queryResults.push(...done.queryResults);\n into.requestId = null; // several sends, several ids: none is \"the\" request\n if (done.durationSeconds !== null) into.durationSeconds = (into.durationSeconds ?? 0) + done.durationSeconds;\n return into;\n}\n\n/**\n * A batch in which at least one command failed. api/asset answers 200 and\n * commits per command, so this is not an HTTP failure and not all-or-\n * nothing: `response` is the whole (translated) envelope, with whatever did\n * succeed — created OIDs, modified OIDs, query rows — and `failures` says\n * which commands did not, by index. The message joins the failures'\n * messages, root cause first, so a log line reads like the server's own\n * words. To retry, correct and resend `response.commandFailures.commands`\n * verbatim: each entry is a complete command under its alias wrapper, the\n * succeeded commands are absent, so nothing is applied twice. Resending the\n * original batch is not safe. (Echoed execute failures do not resend\n * cleanly; rewrite them as from-addressed executes.)\n */\nexport class CommandFailureError<Row extends Asset = Asset> extends ApiError {\n readonly failures: CommandFailureDetail[];\n readonly response: AssetApiResponse<Row>;\n /** What the batch did, in the model's terms: the commands that succeeded are committed. */\n readonly outcome: Outcome<Row>;\n\n constructor(response: AssetApiResponse<Row>, failures: CommandFailureDetail[] = failuresOf(response)) {\n super(failures.map((f) => f.message).join(\"; \") || \"command failed\", 200, \"CommandFailure\", failures);\n this.name = \"CommandFailureError\";\n this.failures = failures;\n this.response = response;\n this.outcome = outcomeOf(response);\n }\n}\n\n// ---- the calls --------------------------------------------------------------\n\nexport interface ReadOptions {\n /** The schema to translate rows with; the types the queries touch must already be loaded (Schema.ensureFor). Without it, rows keep the endpoint's spelling. */\n lookup?: AttributeLookup;\n}\n\nexport interface SendOptions extends ReadOptions {\n /** Return the projection instead of executing (?previewOnly=true). */\n previewOnly?: boolean;\n /**\n * Throw a CommandFailureError when any command failed, instead of\n * returning the envelope with failures inside it. The commands that\n * succeeded are committed either way; the error carries the response.\n */\n throwOnFailure?: boolean;\n /**\n * The caller has made this batch safe to send twice (a guarded batch with\n * no creates: services/guard) and says so; the transport may then retry it\n * after a network failure or a 5xx. Never set it for a plain batch: a\n * retried write after a timeout is a double write.\n */\n idempotent?: boolean;\n}\n\n/** A command's body, aliased or bare. */\nconst bodyOf = (c: Command): unknown => { const keys = Object.keys(c); return keys.length === 1 && keys[0]!.startsWith(\"@\") ? (c as Record<string, unknown>)[keys[0]!] : c; };\nconst isQuery = (body: unknown): body is QueryBody => !!body && typeof body === \"object\" && typeof (body as QueryBody).from === \"string\" && !(\"update\" in body) && !(\"execute\" in body) && !(\"AssetType\" in body);\n/** The query commands of a batch, in order, each with its index in the batch. */\nfunction queriesIn(commands: Command[]): { body: QueryBody; index: number }[] {\n return commands.flatMap((c, index) => { const body = bodyOf(c); return isQuery(body) ? [{ body, index }] : []; });\n}\n\n/**\n * The server's results, one slot per query again. It sends a slot for every\n * query that ran (an empty match included) and none for a query that\n * failed; a failure names its command by sourceCommandIndex, so the failed\n * queries are known and the rest fill in order. Null when the counts\n * disagree: the positions cannot be trusted, and the caller decides what\n * that means rather than this guessing.\n */\nfunction realign<T>(sent: { index: number }[], results: T[], failed: Set<number>): (T | null)[] | null {\n const expected = sent.filter((q) => !failed.has(q.index)).length;\n if (results.length !== expected) return null;\n let next = 0;\n return sent.map((q) => (failed.has(q.index) ? null : results[next++]!));\n}\n\n/**\n * Send a batch. The response is the envelope; per-command failures are\n * inside it (failuresOf reads them), or thrown as a CommandFailureError with\n * throwOnFailure. Query rows are translated, each by its query's type when a\n * schema is given.\n */\nexport async function send<Row extends Asset = Asset>(transport: Transport, commands: Command[], options: SendOptions = {}): Promise<AssetApiResponse<Row>> {\n const response = await transport.request<AssetApiResponse<Row>>({\n method: \"POST\",\n path: \"/api/asset\",\n query: options.previewOnly ? { previewOnly: \"true\" } : undefined,\n body: toWire(commands),\n responseType: \"json\",\n idempotent: options.idempotent === true\n });\n // A preview answers with the projection, not an envelope.\n if (options.previewOnly) return response;\n const queries = queriesIn(commands);\n const failures = failuresOf(response);\n const failed = new Set(failures.flatMap((f) => (f.index === null ? [] : [f.index])));\n const results = response.queryResult?.results ?? [];\n let aligned = realign(queries, results, failed);\n if (!aligned) {\n // A failure without a sourceCommandIndex may be one of the queries, so\n // no row can be placed with confidence: every slot is null, never a\n // misplaced row, and the failures themselves are the answer (thrown\n // with throwOnFailure, as every read asks). With no such failure, the\n // server's answer is inconsistent, and that is an error of its own.\n if (!failures.some((f) => f.index === null)) throw new ApiError(`api/asset returned ${results.length} query results for ${queries.filter((q) => !failed.has(q.index)).length} queries that did not fail; cannot tell which result belongs to which query`, 200, \"BAD_RESPONSE\", response);\n aligned = queries.map(() => null);\n }\n const contextOf = (i: number): RowContext | undefined => {\n const type = options.lookup ? fromTypeOf(queries[i]!.body.from, commands) : null;\n return type ? { lookup: options.lookup!, type } : undefined;\n };\n const translated: AssetApiResponse<Row> = { ...response, queryResult: { ...response.queryResult, results: aligned!.map((rows, i) => rows && rows.map((r) => fromWireRow<Row>(r as Record<string, unknown>, contextOf(i)))) } };\n if (options.throwOnFailure && translated.commandFailures?.count) throw new CommandFailureError(translated);\n return translated;\n}\n\n/** Preview a batch: the projection, one command per asset the server would touch. */\nexport async function preview(transport: Transport, commands: Command[]): Promise<Command[]> {\n return transport.request<Command[]>({ method: \"POST\", path: \"/api/asset\", query: { previewOnly: \"true\" }, body: toWire(commands), responseType: \"json\" });\n}\n\n/**\n * Send YAML as written. api/asset parses it server-side (a single document\n * or several separated by ---); with previewOnly the parsed commands come\n * back as JSON, which is how a caller gets YAML parsed without a parser.\n */\nexport async function sendYaml<Row extends Asset = Asset>(transport: Transport, yaml: string, options: SendOptions = {}): Promise<AssetApiResponse<Row> | Command[]> {\n return transport.request({ method: \"POST\", path: \"/api/asset\", query: options.previewOnly ? { previewOnly: \"true\" } : undefined, body: yaml, contentType: \"text/yaml\", responseType: \"json\" });\n}\n\n/** One query, its rows. A page is required: no read of api/asset is unbounded. */\nexport async function query<Row extends Asset = Asset>(transport: Transport, q: QueryBody, options: ReadOptions = {}): Promise<Row[]> {\n const [rows] = await queries<Row>(transport, [q], options);\n return rows ?? [];\n}\n\n/**\n * One page of a query, with the total number of matches (api/asset reports\n * it when asked with needTotal; `total` is null when it does not) and\n * whether more pages follow.\n */\nexport async function queryPage<Row extends Asset = Asset>(transport: Transport, q: QueryBody, options: ReadOptions = {}): Promise<{ rows: Row[]; total: number | null; more: boolean }> {\n if (!q.page) throw new UsageError(`query of ${q.from} without a page: every api/asset read must be bounded`);\n const response = await send<Row>(transport, [{ ...q, needTotal: true }], { ...options, throwOnFailure: true });\n const rows = response.queryResult.results[0] ?? [];\n const reported = (response.queryResult as { resultMetaData?: { total?: unknown }[] }).resultMetaData?.[0]?.total;\n const total = typeof reported === \"number\" ? reported : null;\n return { rows, total, more: total === null ? rows.length === q.page.size : q.page.start + rows.length < total };\n}\n\n/**\n * Several queries in one request; one array of rows per query, in order, []\n * where a query matched nothing. A query the server rejected (a bad select\n * token, a malformed filter) throws a CommandFailureError rather than\n * reading as [] — a failure must never look like an empty result.\n */\nexport async function queries<Row extends Asset = Asset>(transport: Transport, qs: QueryBody[], options: ReadOptions = {}): Promise<Row[][]> {\n for (const q of qs) if (!q.page) throw new UsageError(`query of ${q.from} without a page: every api/asset read must be bounded`);\n const response = await send<Row>(transport, qs, { ...options, throwOnFailure: true });\n return qs.map((_, i) => response.queryResult.results[i] ?? []);\n}\n","/**\n * Select paths, resolved against the schema: what type of value a key in a\n * query row carries. api/asset and query.v1 spell every scalar as a string\n * and a sub-selected single relation as a one-element list, so translating\n * a row into the model needs the attribute behind each key. The grammar of\n * a select path (V1Query.g, as the docs publish it):\n *\n * Attribute Estimate\n * Relation.Attribute Status.Name one hop, or many\n * Relation:Downcast Children:Task the relation narrowed to a subtype\n * Relation[filter] BlockingIssues[AssetState!='Closed']\n * Relation.@Aggregate Owners.@Count a number, always\n *\n * and a sub-select `{ from: <path>, select: [...] }` whose key in the row is\n * its `from`. A path is resolved hop by hop; a hop through a multi-value\n * relation makes the value a list.\n */\nimport type { AssetTypeToken, AttributeDefinition, AttributeLookup } from \"../types/metamodel\";\nimport { isOidToken, typeOfOid } from \"../types/oid\";\n\nexport type Aggregate = \"Count\" | \"DistinctCount\" | \"Sum\" | \"Avg\" | \"Min\" | \"Max\";\n\nexport type PathResolution =\n | {\n kind: \"resolved\";\n /** The attribute the path ends on; null for an aggregate. */\n definition: AttributeDefinition | null;\n /** For a relation, the type of the value (after any downcast); for a scalar, the type that defines it. */\n valueType: AssetTypeToken | null;\n /** True when any hop fans out: the value is a list. */\n multi: boolean;\n aggregate: Aggregate | null;\n }\n /** The lookup has not loaded this type; load it and resolve again. */\n | { kind: \"needs\"; type: AssetTypeToken }\n /** Not a path the schema knows (a missing attribute, a scalar mid-path): leave the value as sent. */\n | { kind: \"unknown\"; at: string };\n\ninterface Segment { name: string; downcast: string | null; aggregate: Aggregate | null }\n\n/** Split a path on \".\" outside brackets and quotes, then read each segment. */\nexport function segmentsOf(path: string): Segment[] {\n const parts: string[] = [];\n let depth = 0, quote: string | null = null, current = \"\";\n for (const ch of path) {\n if (quote) { current += ch; if (ch === quote) quote = null; continue; }\n if (ch === \"'\" || ch === '\"') { quote = ch; current += ch; continue; }\n if (ch === \"[\") depth += 1;\n if (ch === \"]\") depth -= 1;\n if (ch === \".\" && depth === 0) { parts.push(current); current = \"\"; continue; }\n current += ch;\n }\n parts.push(current);\n return parts.map((raw) => {\n if (raw.startsWith(\"@\")) return { name: raw, downcast: null, aggregate: raw.slice(1) as Aggregate };\n const bare = raw.replace(/\\[[\\s\\S]*\\]$/, \"\"); // a trailing [filter] narrows rows, not the type\n const colon = bare.indexOf(\":\");\n return colon < 0 ? { name: bare, downcast: null, aggregate: null } : { name: bare.slice(0, colon), downcast: bare.slice(colon + 1) || null, aggregate: null };\n });\n}\n\n/** An attribute of a type, by its bare name; undefined when the type is not loaded, null when the type has no such attribute. */\nexport function attributeOf(lookup: AttributeLookup, type: AssetTypeToken, name: string): AttributeDefinition | null | undefined {\n const t = lookup.assetType(type);\n if (t === undefined) return undefined;\n if (t === null) return null;\n return t.Attributes[`${type}.${name}`] ?? Object.values(t.Attributes).find((a) => a.Name === name) ?? null;\n}\n\n/** What a select path yields on rows of `type`. */\nexport function resolvePath(lookup: AttributeLookup, type: AssetTypeToken, path: string): PathResolution {\n const segments = segmentsOf(path);\n let current = type, multi = false, last: AttributeDefinition | null = null;\n for (const [i, seg] of segments.entries()) {\n if (seg.aggregate) {\n return i === segments.length - 1 ? { kind: \"resolved\", definition: null, valueType: null, multi: false, aggregate: seg.aggregate } : { kind: \"unknown\", at: path };\n }\n const def = attributeOf(lookup, current, seg.name);\n if (def === undefined) return { kind: \"needs\", type: current };\n if (def === null) return { kind: \"unknown\", at: `${current}.${seg.name}` };\n if (def.AttributeType !== \"Relation\") {\n return i === segments.length - 1 ? { kind: \"resolved\", definition: def, valueType: current, multi, aggregate: null } : { kind: \"unknown\", at: path };\n }\n multi ||= def.IsMultivalue;\n const next = seg.downcast ?? def.RelatedAsset;\n if (!next) return { kind: \"unknown\", at: `${current}.${seg.name}` };\n current = next;\n last = def;\n }\n return { kind: \"resolved\", definition: last, valueType: current, multi, aggregate: null };\n}\n\n/** The minimum of a query this module needs to see: where it reads from and what it selects. */\nexport interface SelectShape { from: string; select?: (string | SelectShape)[] }\n\n/**\n * The asset type a query's `from` reads: a type token as is, the type of an\n * OID token, or the AssetType of the aliased create earlier in the batch.\n * Null when it cannot be told (an alias to a query, say).\n */\nexport function fromTypeOf(from: string, batch: readonly unknown[] = []): AssetTypeToken | null {\n const fromOid = isOidToken(from) ? typeOfOid(from) : null;\n if (fromOid) return fromOid;\n if (from.startsWith(\"@\")) {\n for (const command of batch) {\n const body = (command as Record<string, unknown>)?.[from];\n const assetType = body && typeof body === \"object\" ? (body as Record<string, unknown>).AssetType : undefined;\n if (typeof assetType === \"string\") return assetType;\n }\n return null;\n }\n return from;\n}\n\n/**\n * The types the lookup must load before every key of this query's rows can\n * be resolved — empty when it can resolve them all now. A lazy schema loads\n * these and asks again; a path that still does not resolve is unknown, not\n * missing, and is left alone.\n */\nexport function typesNeeded(lookup: AttributeLookup, query: SelectShape, type: AssetTypeToken): Set<AssetTypeToken> {\n const needed = new Set<AssetTypeToken>();\n if (lookup.assetType(type) === undefined) { needed.add(type); return needed; }\n for (const entry of query.select ?? []) {\n const path = typeof entry === \"string\" ? entry : entry.from;\n const r = resolvePath(lookup, type, path);\n if (r.kind === \"needs\") needed.add(r.type);\n else if (r.kind === \"resolved\" && typeof entry !== \"string\" && r.valueType) for (const t of typesNeeded(lookup, entry, r.valueType)) needed.add(t);\n }\n return needed;\n}\n","/**\n * The attachment wire module: the files an asset carries. Two endpoints and\n * one MVC route, none of them the data API:\n *\n * attachment.img/<id> GET the bytes; POST bytes to replace them\n * embedded.img/<id> GET an image embedded in rich text\n * EmbeddedImage.mvc/Upload POST multipart { image, oidToken } → an EmbeddedImage\n *\n * Addressed by the numeric id, not the OID token — the one place in the API\n * that does. Bytes travel as Uint8Array, ArrayBuffer or Blob, so this works\n * in Node and the browser alike (no Buffer).\n *\n * Verified against the API-testing instance (2026-11-07):\n * - GET attachment.img/<id> answers the bytes with the Attachment's\n * ContentType and `Content-Disposition: inline; filename=\"…\"`; 404 for\n * an id that does not exist. POST raw bytes (any content type) answers\n * 200 with an empty body and replaces them.\n * - An Attachment create requires Content (empty is allowed, absent is\n * Violation'Required'…'Content'); Base64 Content in the create stores\n * the bytes in one request, and selecting Content reads them back as\n * Base64.\n * - EmbeddedImage.mvc/Upload takes token auth and answers text/html:\n * `<textarea>{\"Url\":\"<base>/embedded.img/<id>\",\"Key\":\"EmbeddedImage:<id>\"}</textarea>`.\n * An EmbeddedImage cannot be deleted (no Delete operation).\n */\nimport { ApiError, UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Oid } from \"../types/asset\";\n\n/** Bytes as a caller has them: a Uint8Array, an ArrayBuffer, or a Blob (a browser File). */\nexport type Bytes = Uint8Array | ArrayBuffer | Blob;\n\n/** Bytes as a Uint8Array, whatever they came as. */\nexport async function toUint8Array(data: Bytes): Promise<Uint8Array> {\n if (data instanceof Uint8Array) return data;\n if (data instanceof ArrayBuffer) return new Uint8Array(data);\n return new Uint8Array(await data.arrayBuffer());\n}\n\n/** Base64 without Buffer, in chunks so a large file does not overflow the call stack. */\nexport function toBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i += 0x8000) binary += String.fromCharCode(...bytes.subarray(i, i + 0x8000));\n return btoa(binary);\n}\n\nexport function fromBase64(text: string): Uint8Array {\n const binary = atob(text);\n const out = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);\n return out;\n}\n\n/** The numeric id from \"Attachment:5678\", \"Attachment:5678:999\" (a moment) or \"5678\". */\nexport function numericId(spec: Oid | string | number): string {\n const m = /^(?:[A-Za-z]+:)?(\\d+)(?::\\d+)?$/.exec(String(spec).trim());\n if (!m) throw new UsageError(`\"${spec}\" is not an asset id (5678, or an OID token such as Attachment:5678)`);\n return m[1]!;\n}\n\nconst join = (baseUrl: string, path: string): string => `${baseUrl.replace(/\\/+$/, \"\")}/${path}`;\n\n/** Where a browser opens or downloads an attachment's bytes. */\nexport const attachmentUrl = (baseUrl: string, id: Oid | string | number): string => join(baseUrl, `attachment.img/${numericId(id)}`);\n/** Where an embedded image is served from. */\nexport const embeddedImageUrl = (baseUrl: string, id: Oid | string | number): string => join(baseUrl, `embedded.img/${numericId(id)}`);\n\n/**\n * Rich text with every `embedded.img/<id>` image reference rewritten to the\n * instance's absolute URL — what Agility's own editor stores — whatever\n * host, path or quoting the reference had before.\n */\nexport function normalizeEmbeddedImageUrls(html: string, baseUrl: string): string {\n return html.replace(/(\\bsrc\\s*=\\s*)([\"'])([^\"']*?embedded\\.img\\/(\\d+)[^\"']*)\\2/gi, (_m, attr: string, quote: string, _url: string, id: string) => `${attr}${quote}${embeddedImageUrl(baseUrl, id)}${quote}`);\n}\n\n/** The endpoint's statuses, named: 404 missing, 413 larger than the server's maximum request length. */\nfunction named(error: unknown, what: string): unknown {\n if (!(error instanceof ApiError)) return error;\n if (error.status === 404) return new ApiError(`${what}: not found`, 404, \"NOT_FOUND\", error.details);\n if (error.status === 413) return new ApiError(`${what}: larger than the server's maximum request length`, 413, \"TOO_LARGE\", error.details);\n return error;\n}\n\n/** An attachment's bytes. */\nexport async function getBytes(transport: Transport, id: Oid | string | number): Promise<Uint8Array> {\n const n = numericId(id);\n try {\n return await transport.request<Uint8Array>({ method: \"GET\", path: `/attachment.img/${n}`, responseType: \"bytes\" });\n } catch (error) {\n throw named(error, `attachment ${n}`);\n }\n}\n\n/** An attachment's bytes with the type and filename the server sent them with (Content-Type, Content-Disposition), when it did. */\nexport async function getFile(transport: Transport, id: Oid | string | number): Promise<{ bytes: Uint8Array; contentType: string | null; filename: string | null }> {\n const n = numericId(id);\n let contentType: string | null = null, filename: string | null = null;\n const onResponse = ({ headers }: { headers: { get(name: string): string | null } }) => {\n contentType = headers.get(\"content-type\");\n const disposition = headers.get(\"content-disposition\") ?? \"\";\n const encoded = /filename\\*=UTF-8''([^;]+)/i.exec(disposition)?.[1];\n filename = encoded ? decodeURIComponent(encoded) : /filename=\"?([^\";]+)\"?/i.exec(disposition)?.[1] ?? null;\n };\n try {\n const bytes = await transport.request<Uint8Array>({ method: \"GET\", path: `/attachment.img/${n}`, responseType: \"bytes\", onResponse });\n return { bytes, contentType, filename };\n } catch (error) {\n throw named(error, `attachment ${n}`);\n }\n}\n\n/** Replace an attachment's bytes. The Attachment asset (name, filename, content type) is unchanged. */\nexport async function putBytes(transport: Transport, id: Oid | string | number, data: Bytes, contentType = \"application/octet-stream\"): Promise<void> {\n const n = numericId(id);\n const body = data instanceof Blob ? data : await toUint8Array(data);\n try {\n await transport.request({ method: \"POST\", path: `/attachment.img/${n}`, body, contentType: data instanceof Blob && data.type ? data.type : contentType, responseType: \"text\" });\n } catch (error) {\n throw named(error, `attachment ${n}`);\n }\n}\n\nexport interface EmbeddedImage { oid: Oid; id: string; url: string }\n\n/**\n * Upload an image to embed in an asset's rich text. The answer is the\n * image's URL — put it in an `<img src>` — and its EmbeddedImage OID.\n */\nexport async function uploadEmbeddedImage(transport: Transport, asset: Oid, data: Bytes, options: { filename?: string; contentType?: string } = {}): Promise<EmbeddedImage> {\n const blob = data instanceof Blob ? data : new Blob([(await toUint8Array(data)) as Uint8Array<ArrayBuffer>], { type: options.contentType ?? \"application/octet-stream\" });\n const form = new FormData();\n form.append(\"image\", blob, options.filename ?? \"image\");\n form.append(\"oidToken\", asset);\n let html: string;\n try {\n html = await transport.request<string>({ method: \"POST\", path: \"/EmbeddedImage.mvc/Upload\", body: form, responseType: \"text\" });\n } catch (error) {\n throw named(error, `embedded image for ${asset}`);\n }\n const inner = /<textarea[^>]*>([\\s\\S]*?)<\\/textarea>/i.exec(html)?.[1];\n let payload: { Url?: unknown; Key?: unknown } | undefined;\n try {\n payload = inner ? JSON.parse(inner.replace(/"/g, '\"').replace(/</g, \"<\").replace(/>/g, \">\").replace(/&/g, \"&\")) : undefined;\n } catch { /* reported below */ }\n if (!payload || typeof payload.Url !== \"string\") throw new ApiError(\"EmbeddedImage.mvc/Upload did not answer with an image URL\", 200, \"BAD_RESPONSE\", html.slice(0, 500));\n const id = /embedded\\.img\\/(\\d+)/.exec(payload.Url)?.[1] ?? (typeof payload.Key === \"string\" ? numericId(payload.Key) : undefined);\n if (!id) throw new ApiError(\"EmbeddedImage.mvc/Upload answered a URL without an image id\", 200, \"BAD_RESPONSE\", payload);\n return { oid: typeof payload.Key === \"string\" ? payload.Key : `EmbeddedImage:${id}`, id, url: payload.Url };\n}\n","/**\n * The attachments service: the files attached to an asset, as part of\n * changing that asset like any other attribute. The metadata lives on an\n * Attachment asset (api/asset); the bytes live behind attachment.img\n * (wire/attachment). Consumers never call either directly.\n *\n * Two ways in for the bytes, chosen by size:\n * - inline: one api/asset create with Content as Base64. One request,\n * what agility-rooms does; the JSON is a third larger than the file.\n * - two-step, as the docs prescribe for anything not tiny: create the\n * Attachment with empty Content, then POST the raw bytes. A failed\n * upload leaves an empty Attachment, which is reported, not hidden.\n *\n * Listing never selects Content: across many attachments that would Base64\n * every file into one response. Reading one file's bytes goes through\n * attachment.img.\n */\nimport { ApiError, WrappedError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Oid } from \"../types/asset\";\nimport { momentless } from \"../types/oid\";\nimport * as assetApi from \"../wire/assetApi\";\nimport { getFile, numericId, putBytes, toBase64, toUint8Array, type Bytes } from \"../wire/attachment\";\n\n/** Files up to this size go inline by default; larger ones in two steps. */\nexport const INLINE_LIMIT = 1_000_000;\n\nexport interface AttachmentInfo {\n oid: Oid;\n /** The numeric id attachment.img addresses it by. */\n id: string;\n name: string | null;\n filename: string | null;\n contentType: string | null;\n description: string | null;\n createDate: string | null;\n createdBy: string | null;\n}\n\ntype Row = { _oid: string; Name?: string | null; Filename?: string | null; ContentType?: string | null; Description?: string | null; CreateDate?: string | null; \"CreatedBy.Name\"?: string | null };\nconst SELECT = [\"Name\", \"Filename\", \"ContentType\", \"Description\", \"CreateDate\", \"CreatedBy.Name\"];\nconst infoOf = (r: Row): AttachmentInfo => {\n const oid = momentless(r._oid);\n return { oid, id: numericId(oid), name: r.Name ?? null, filename: r.Filename ?? null, contentType: r.ContentType ?? null, description: r.Description ?? null, createDate: r.CreateDate ?? null, createdBy: r[\"CreatedBy.Name\"] ?? null };\n};\n\n/** One page of the files attached to an asset, newest first, metadata only, with the total and whether more pages follow. */\nexport async function page(transport: Transport, asset: Oid, options: { page?: { size: number; start: number } } = {}): Promise<{ attachments: AttachmentInfo[]; total: number | null; more: boolean }> {\n const { rows, total, more } = await assetApi.queryPage(transport, { from: \"Attachment\", select: SELECT, filter: [\"Asset=$asset\"], with: { $asset: momentless(asset) }, sort: [\"-CreateDate\"], page: options.page ?? { size: 50, start: 0 } });\n return { attachments: rows.map((r) => infoOf(r as unknown as Row)), total, more };\n}\n\n/** The files attached to an asset, newest first, metadata only (one page; `page` also gives the total). */\nexport async function list(transport: Transport, asset: Oid, options: { page?: { size: number; start: number } } = {}): Promise<AttachmentInfo[]> {\n const rows = await assetApi.query(transport, { from: \"Attachment\", select: SELECT, filter: [\"Asset=$asset\"], with: { $asset: momentless(asset) }, sort: [\"-CreateDate\"], page: options.page ?? { size: 50, start: 0 } });\n return rows.map((r) => infoOf(r as unknown as Row));\n}\n\n/** One attachment's metadata, or null when there is none with that id. */\nexport async function info(transport: Transport, id: Oid | string | number): Promise<AttachmentInfo | null> {\n const [row] = await assetApi.query(transport, { from: \"Attachment\", select: SELECT, filter: [\"ID=$id\"], with: { $id: `Attachment:${numericId(id)}` }, page: { size: 1, start: 0 } });\n return row ? infoOf(row as unknown as Row) : null;\n}\n\n/**\n * One attachment: its metadata and its bytes. `contentType` is the type the\n * server sent the bytes with, falling back to the Attachment's recorded\n * one; `recordedContentType` is always the latter.\n */\nexport async function get(transport: Transport, id: Oid | string | number): Promise<AttachmentInfo & { bytes: Uint8Array; recordedContentType: string | null }> {\n const meta = await info(transport, id);\n if (!meta) throw new ApiError(`attachment ${numericId(id)}: not found`, 404, \"NOT_FOUND\");\n const file = await getFile(transport, meta.id);\n return { ...meta, bytes: file.bytes, contentType: file.contentType ?? meta.contentType, recordedContentType: meta.contentType };\n}\n\nexport interface AddOptions {\n filename: string;\n /** Defaults to the Blob's type, then application/octet-stream. */\n contentType?: string;\n /** Defaults to the filename. */\n name?: string;\n description?: string;\n /** Inline (one request) up to this many bytes, two-step above. Default INLINE_LIMIT. */\n inlineLimit?: number;\n}\n\n/** An Attachment was created but its bytes could not be uploaded: it exists, empty. Remove it or upload again with `put`. */\nexport class AttachmentUploadError extends WrappedError {\n constructor(readonly attachment: AttachmentInfo, cause: unknown) {\n super(`${attachment.oid} was created on its asset with no content, and uploading the file failed: ${cause instanceof Error ? cause.message : String(cause)}`, \"ATTACHMENT_UPLOAD\", cause);\n this.name = \"AttachmentUploadError\";\n }\n}\n\n/** Attach a file to an asset. Inline up to `inlineLimit` bytes, two-step above it. */\nexport async function add(transport: Transport, asset: Oid, data: Bytes, options: AddOptions): Promise<AttachmentInfo> {\n const bytes = await toUint8Array(data);\n const contentType = options.contentType ?? (typeof Blob !== \"undefined\" && data instanceof Blob && data.type ? data.type : \"application/octet-stream\");\n const inline = bytes.length <= (options.inlineLimit ?? INLINE_LIMIT);\n const create: assetApi.CreateBody = { AssetType: \"Attachment\", Asset: momentless(asset), Name: options.name ?? options.filename, Filename: options.filename, ContentType: contentType, Content: inline ? toBase64(bytes) : \"\" };\n if (options.description) create.Description = options.description;\n const oid = assetApi.outcomeOf(await assetApi.send(transport, [create], { throwOnFailure: true })).created[0]!;\n const created: AttachmentInfo = { oid, id: numericId(oid), name: String(create.Name), filename: options.filename, contentType, description: options.description ?? null, createDate: null, createdBy: null };\n if (!inline) {\n try {\n await putBytes(transport, created.id, bytes, contentType);\n } catch (error) {\n throw new AttachmentUploadError(created, error);\n }\n }\n return created;\n}\n\n/** Replace an attachment's bytes. */\nexport async function put(transport: Transport, id: Oid | string | number, data: Bytes, contentType?: string): Promise<void> {\n await putBytes(transport, id, data, contentType);\n}\n\n/** Delete an attachment. */\nexport async function remove(transport: Transport, id: Oid | string | number): Promise<void> {\n await assetApi.send(transport, [{ from: `Attachment:${numericId(id)}`, execute: \"Delete\" }], { throwOnFailure: true });\n}\n","/**\n * The guard: an api/asset batch sent as a compare-and-set, so a change only\n * lands on an asset nobody else has changed since it was read. Ported from\n * gh-v1's lib/batch.js `guarded()`, with a different stamp.\n *\n * How: preview the batch (the server's projection expands every query-\n * scoped update and execute into one command per asset), read each touched\n * asset's ChangeDate, and send each per-asset command as a query-scoped one\n * filtered on its ID and that ChangeDate. An asset changed in between has a\n * newer ChangeDate, matches nothing, and is left alone; the response's\n * modified/operated lists say which assets the batch actually touched, so\n * the rest are `skipped`.\n *\n * The stamp, settled live on 2026-11-04 (test/integration/guard.test.ts):\n * - ChangeDate as a filter LITERAL is a true compare-and-set: the value\n * just read matches, a stale one matches nothing, and resending the same\n * guarded batch writes nothing the second time.\n * - ChangeDate as a `with` VARIABLE never matches, not even the value just\n * read back — so this is the one place a value is spliced into filter\n * text. It is the server's own timestamp, checked against a strict date\n * pattern first, so it cannot carry grammar. The ID stays a variable.\n * - Moment is NOT a stamp: `Moment=<an earlier moment of this asset>`\n * selects the asset as it was then (as-of), and an update scoped by it\n * lands on the current asset. A Moment guard guards nothing. Proven for\n * writes on 2026-11-11: an update filtered on a stale Moment previews as\n * one command and applies, overwriting the change made in between\n * (\"why not Moment, on a write\"; versionone/VersionOne.SDK.JavaScript#51).\n * Every type has ChangeDate except the Ideas product's (Idea*), which keeps\n * no history and cannot be guarded.\n *\n * A guarded batch without creates is safe to send twice — an applied\n * command has advanced the ChangeDate, so a resend matches nothing — and is\n * sent marked idempotent (spec 000 §6).\n */\nimport { ApiError, UsageError, WrappedError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Asset, Oid } from \"../types/asset\";\nimport type { AssetTypeToken } from \"../types/metamodel\";\nimport { momentless, typeOfOid } from \"../types/oid\";\nimport * as assetApi from \"../wire/assetApi\";\nimport type { Command, CommandValue, ExecuteBody } from \"../wire/assetApi\";\n\n/** OIDs per ChangeDate read: bounded, never one giant filter. */\nexport const CHUNK = 100;\n\n/** Types with no ChangeDate (the Ideas product keeps no history): nothing of theirs can be guarded. */\nexport const UNGUARDABLE_TYPES: readonly AssetTypeToken[] = [\"Idea\", \"IdeaChangeSet\", \"IdeaStatus\", \"IdeaComment\", \"IdeaCategory\", \"IdeaForum\", \"IdeaUser\"];\n\n/** Why a command cannot be sent guarded, by its index in the batch. */\nexport interface Unguardable { index: number; reason: string }\n\n/** A batch the guard will not send, rather than send unguarded without saying so. */\nexport class UnguardableError extends UsageError {\n readonly reasons: Unguardable[];\n constructor(reasons: Unguardable[]) {\n super(`cannot guard this batch: ${reasons.map((r) => `command ${r.index}: ${r.reason}`).join(\"; \")}`);\n this.name = \"UnguardableError\";\n this.reasons = reasons;\n }\n}\n\n// ---- reading commands ----------------------------------------------------------\n\n/** The alias and body of an aliased command, or null for a bare one. */\nexport function aliased(command: Command): { alias: string; body: Record<string, unknown> } | null {\n const keys = Object.keys(command);\n return keys.length === 1 && keys[0]!.startsWith(\"@\") ? { alias: keys[0]!, body: (command as Record<string, Record<string, unknown>>)[keys[0]!]! } : null;\n}\nconst bodyOf = (c: Command): Record<string, unknown> => aliased(c)?.body ?? (c as Record<string, unknown>);\nconst isObject = (v: unknown): v is Record<string, unknown> => !!v && typeof v === \"object\" && !Array.isArray(v);\n/** A relation value that is itself a create: the projection normalises these away, so they cannot be guarded. */\nconst isCreateValue = (v: unknown): boolean =>\n (isObject(v) && \"AssetType\" in v) || (Array.isArray(v) && v.some(isCreateValue)) || (isObject(v) && ([] as unknown[]).concat(v.add ?? []).some(isCreateValue));\n\n/** The commands of a batch the guard cannot cover, and why. Empty means it can. */\nexport function unguardable(commands: Command[]): Unguardable[] {\n const out: Unguardable[] = [];\n commands.forEach((c, index) => {\n const a = aliased(c);\n const body = bodyOf(c);\n const writes = \"update\" in body || \"execute\" in body;\n if (a && writes) out.push({ index, reason: `${a.alias} is an aliased ${\"update\" in body ? \"update\" : \"execute\"}: preview does not expand it, so it cannot be read or guarded per asset` });\n else if (!a && writes && typeof body.from === \"string\" && body.from.startsWith(\"@\")) out.push({ index, reason: `a bare update or execute from an alias (${body.from}) is rejected by the server; alias the command itself` });\n if (isObject(body.update) && Object.values(body.update).some(isCreateValue)) out.push({ index, reason: \"an update that creates assets inline: the projection normalises the creates away\" });\n });\n return out;\n}\n\n/** A projected per-asset command: the asset and what is done to it. */\ninterface PerAsset { oid: Oid; update?: Record<string, CommandValue>; execute?: CommandValue }\nfunction perAsset(projected: Command): PerAsset | null {\n const body = bodyOf(projected);\n return typeof body.oid === \"string\" && (\"update\" in body || \"execute\" in body)\n ? { oid: momentless(body.oid), update: body.update as Record<string, CommandValue> | undefined, execute: body.execute as CommandValue | undefined }\n : null;\n}\n\n/** The assets a projection updates or operates on, once each, in order. */\nexport const touchedBy = (projected: Command[]): Oid[] => [...new Set(projected.flatMap((p) => { const x = perAsset(p); return x ? [x.oid] : []; }))];\n\n// ---- the stamp -----------------------------------------------------------------\n\n/** A ChangeDate as the server writes it: 2026-11-04T16:49:40.12 (trailing zeros trimmed, no zone). */\nconst STAMP = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$/;\n\n/** Each asset's current ChangeDate, one bounded query per type and chunk. An asset that no longer exists is absent. */\nexport async function stampsOf(transport: Transport, oids: readonly Oid[]): Promise<Record<Oid, string>> {\n const byType = new Map<string, Oid[]>();\n for (const oid of new Set(oids.map(momentless))) { const t = typeOfOid(oid); byType.set(t, [...(byType.get(t) ?? []), oid]); }\n const out: Record<Oid, string> = {};\n for (const [type, list] of byType) {\n if (UNGUARDABLE_TYPES.includes(type)) continue;\n for (let i = 0; i < list.length; i += CHUNK) {\n const part = list.slice(i, i + CHUNK);\n const rows = await assetApi.query<Asset & { ChangeDate?: string }>(transport, { from: type, select: [\"ChangeDate\"], filter: [\"ID=$oids\"], with: { $oids: part }, page: { size: part.length, start: 0 } });\n for (const r of rows) if (r.ChangeDate != null) out[momentless(r._oid)] = String(r.ChangeDate);\n }\n }\n return out;\n}\n\n/**\n * The batch to send: the projection, each per-asset update or execute\n * rewritten as a query-scoped command on its ID and ChangeDate. Creates and\n * queries pass through as the projection echoed them. An asset with no\n * stamp (gone since the preview) is left out and reported as skipped.\n */\nexport function guard(projected: Command[], stamps: Readonly<Record<Oid, string>>): { commands: Command[]; unstamped: Oid[] } {\n const commands: Command[] = [], unstamped: Oid[] = [];\n for (const p of projected) {\n const x = perAsset(p);\n if (!x) { commands.push(p); continue; }\n const stamp = stamps[x.oid];\n if (stamp === undefined) { unstamped.push(x.oid); continue; }\n if (!STAMP.test(stamp)) throw new ApiError(`${x.oid}: ChangeDate ${JSON.stringify(stamp)} is not a timestamp; refusing to put it in a filter`, 200, \"BAD_RESPONSE\", { oid: x.oid, stamp });\n // The literal is deliberate: as a `with` variable a ChangeDate never compares equal (see above).\n const scope = { from: typeOfOid(x.oid), filter: [\"ID=$oid\", `ChangeDate='${stamp}'`], with: { $oid: x.oid } };\n commands.push(x.update ? { ...scope, update: x.update } : { ...scope, execute: x.execute as ExecuteBody[\"execute\"] });\n }\n return { commands, unstamped };\n}\n\n// ---- passes --------------------------------------------------------------------\n\n/**\n * A projection split into passes: the k-th per-asset command for each asset\n * goes in pass k; creates and queries ride in pass 0. One pass is the usual\n * case. Two commands on one asset (a reverse batch's Reactivate then Delete,\n * say) cannot share a pass: both would be stamped with the ChangeDate read\n * before the batch, the first would advance it, and the second would match\n * nothing — silently skipped.\n */\nexport function passesOf(projected: Command[]): Command[][] {\n const seen = new Map<Oid, number>();\n const passes: Command[][] = [[]];\n for (const p of projected) {\n const x = perAsset(p);\n const k = x ? seen.get(x.oid) ?? 0 : 0;\n if (x) seen.set(x.oid, k + 1);\n (passes[k] ??= []).push(p);\n }\n return passes;\n}\n\n/** A guarded send that failed after some passes applied: `outcome` and `sent` say what did. */\nexport class GuardedPassError extends WrappedError {\n constructor(cause: unknown, readonly outcome: assetApi.Outcome, readonly sent: Command[], readonly pass: number) {\n super(`guarded send failed in pass ${pass + 1}${pass ? \" (earlier passes applied)\" : \"\"}: ${cause instanceof Error ? cause.message : String(cause)}`, \"GUARDED_PASS\", cause);\n this.name = \"GuardedPassError\";\n }\n}\n\n/**\n * Send a projection guarded, pass by pass. Pass 0 is guarded on `stamps`\n * (read before the batch). A later pass sends an asset's next command only\n * if its previous one applied, guarded on the ChangeDate read again just\n * after it — so the chain stays a compare-and-set, with one narrow window\n * between our write and that read. An asset whose earlier command was\n * skipped is skipped for the rest of the batch. Failure indexes are\n * positions in `sent` (all passes, in order). A send that fails in the\n * first pass throws as it would alone; in a later pass it throws a\n * GuardedPassError carrying what the earlier passes did.\n */\nexport async function sendPasses<Row extends Asset = Asset>(transport: Transport, projected: Command[], stamps: Readonly<Record<Oid, string>>, options: Pick<assetApi.SendOptions, \"lookup\" | \"throwOnFailure\"> = {}): Promise<{ outcome: assetApi.Outcome<Row>; sent: Command[]; unstamped: Oid[] }> {\n const passes = passesOf(projected);\n const outcome = assetApi.emptyOutcome<Row>();\n const sent: Command[] = [], unstamped: Oid[] = [];\n let applied = new Set<Oid>();\n for (const [k, pass] of passes.entries()) {\n let current: { commands: Command[]; unstamped: Oid[] };\n if (k === 0) current = guard(pass, stamps);\n else {\n // Only assets whose previous command applied go on, stamped afresh.\n const eligible = pass.filter((p) => applied.has(perAsset(p)!.oid));\n current = guard(eligible, await stampsOf(transport, eligible.map((p) => perAsset(p)!.oid)));\n }\n const commands = current.commands;\n unstamped.push(...current.unstamped);\n if (!commands.length) break;\n const offset = sent.length;\n let done: assetApi.Outcome<Row>;\n try {\n const creates = commands.some((c) => \"AssetType\" in bodyOf(c));\n done = assetApi.outcomeOf(await assetApi.send<Row>(transport, commands, { ...options, idempotent: !creates }));\n } catch (error) {\n // Nothing applied yet: the error is the whole story, as for a single send.\n if (k === 0) throw error;\n throw new GuardedPassError(error, outcome, sent, k);\n }\n sent.push(...commands);\n assetApi.mergeOutcome(outcome, done, offset);\n applied = new Set([...done.modified, ...done.operated].map(momentless));\n }\n return { outcome, sent, unstamped: [...new Set(unstamped)] };\n}\n\n// ---- the whole move --------------------------------------------------------------\n\nexport interface GuardedResult<Row extends Asset = Asset> {\n /** What the batch did: created, modified, operated, failures, query rows. */\n outcome: assetApi.Outcome<Row>;\n /** The server's projection the guard was built from. */\n projected: Command[];\n /** The batch as sent. */\n sent: Command[];\n /** Every asset the projection would update or operate on. */\n touched: Oid[];\n /** Each touched asset's ChangeDate when read: the stamp it was guarded on. */\n stamps: Record<Oid, string>;\n /**\n * Touched assets the batch left alone: changed or gone since they were\n * read — or their command failed, which `outcome.failures` says.\n */\n skipped: Oid[];\n}\n\n/**\n * Preview, stamp, send guarded. Throws UnguardableError, before any request,\n * for a batch the guard cannot cover; send such a batch with assetApi.send,\n * knowingly.\n */\nexport async function sendGuarded<Row extends Asset = Asset>(transport: Transport, commands: Command[], options: Pick<assetApi.SendOptions, \"lookup\" | \"throwOnFailure\"> = {}): Promise<GuardedResult<Row>> {\n const refused = unguardable(commands);\n if (refused.length) throw new UnguardableError(refused);\n const projected = await assetApi.preview(transport, commands);\n const touched = touchedBy(projected);\n const ideas = touched.filter((oid) => UNGUARDABLE_TYPES.includes(typeOfOid(oid)));\n if (ideas.length) throw new UnguardableError(ideas.map((oid) => ({ index: -1, reason: `${oid}: ${typeOfOid(oid)} has no ChangeDate` })));\n const stamps = await stampsOf(transport, touched);\n const { outcome, sent, unstamped } = await sendPasses<Row>(transport, projected, stamps, options);\n const done = new Set([...outcome.modified, ...outcome.operated]);\n return { outcome, projected, sent, touched, stamps, skipped: [...new Set([...unstamped, ...touched.filter((oid) => !done.has(oid))])] };\n}\n","/**\n * The batch service: an api/asset batch sent with a record of what it did.\n * Ported from gh-v1's lib/batch.js — preview, describe, snapshot, send\n * (guarded by default), receipt, reverse — minus what is the CLI's: file\n * I/O, console output, permalinks and the confirm prompt (a callback here).\n *\n * A receipt is what the response alone is not: the request as sent, the\n * server's projection (one command per asset it would touch), a BEFORE\n * snapshot of exactly the attributes each projected update names (and the\n * AssetState of each execute, and every touched asset's ChangeDate) taken\n * just before sending, and from those, what a person needs afterwards: the\n * created assets with their aliases, numbers and names; the touched assets;\n * which were skipped by the guard; and a reverse batch that undoes what\n * succeeded, best effort, with a note for anything it cannot.\n *\n * Closing a workitem cascades: Core's Inactivate and QuickClose also close\n * its open descendants, and Reactivate reopens only the asset it names. So\n * before a batch that closes, the receipt records each closing target's\n * open descendants; after it, the ones the close actually closed; and the\n * reverse reopens the parent, then those, top down.\n *\n * The snapshot keeps the endpoint's spelling (strings, relations as OID\n * tokens) on purpose: it is what a reverse batch writes back.\n */\nimport { UsageError, WrappedError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Asset, Oid } from \"../types/asset\";\nimport type { AssetTypeToken } from \"../types/metamodel\";\nimport { momentless, typeOfOid } from \"../types/oid\";\nimport * as assetApi from \"../wire/assetApi\";\nimport type { Command, CommandValue } from \"../wire/assetApi\";\nimport { aliased, guard, GuardedPassError, passesOf, sendPasses, stampsOf, touchedBy, unguardable, UnguardableError } from \"./guard\";\nimport type { Schema } from \"./schema\";\n\n/** OIDs per lookup query: bounded, never one giant filter. */\nexport const CHUNK = 100;\n\n// ---- describing a batch ----------------------------------------------------------\n\nexport interface Described {\n creates: { index: number; alias: string | null; type: string; name: string | null }[];\n queries: { index: number; from: string }[];\n updates: { oid: Oid; attributes: Record<string, CommandValue> }[];\n executes: { oid: Oid; op: string; args: Record<string, CommandValue> }[];\n /**\n * Aliased updates and executes: preview does not expand them, so they\n * have no per-asset entry above, no snapshot and no reverse. They are\n * work all the same, sent as written (only with guard: false).\n */\n deferred: { index: number; alias: string; from: string; kind: \"update\" | \"execute\" }[];\n}\n\nconst bodyOf = (c: Command): Record<string, unknown> => aliased(c)?.body ?? (c as Record<string, unknown>);\n\n/** What a batch does: creates and queries read off the request; updates and executes, per asset, off the projection. */\nexport function describe(commands: Command[], projected: Command[]): Described {\n const out: Described = { creates: [], queries: [], updates: [], executes: [], deferred: [] };\n commands.forEach((c, index) => {\n const a = aliased(c), body = bodyOf(c);\n if (a && typeof body.from === \"string\" && (\"update\" in body || \"execute\" in body)) out.deferred.push({ index, alias: a.alias, from: body.from, kind: \"update\" in body ? \"update\" : \"execute\" });\n else if (typeof body.AssetType === \"string\") out.creates.push({ index, alias: a?.alias ?? null, type: body.AssetType, name: typeof body.Name === \"string\" ? body.Name : null });\n else if (typeof body.from === \"string\" && !(\"update\" in body) && !(\"execute\" in body)) out.queries.push({ index, from: body.from });\n });\n for (const p of projected) {\n const body = bodyOf(p);\n if (typeof body.oid !== \"string\") continue;\n const oid = momentless(body.oid);\n if (body.update && typeof body.update === \"object\") out.updates.push({ oid, attributes: body.update as Record<string, CommandValue> });\n else if (body.execute !== undefined) {\n const e = body.execute as string | { op: string; args?: Record<string, CommandValue> };\n out.executes.push({ oid, op: typeof e === \"string\" ? e : e.op, args: typeof e === \"string\" ? {} : e.args ?? {} });\n }\n }\n return out;\n}\n\n// ---- reading assets --------------------------------------------------------------\n\nconst byType = (oids: Iterable<Oid>): Map<AssetTypeToken, Oid[]> => {\n const out = new Map<AssetTypeToken, Oid[]>();\n for (const oid of new Set([...oids].map(momentless))) out.set(typeOfOid(oid), [...(out.get(typeOfOid(oid)) ?? []), oid]);\n return out;\n};\nconst chunks = <T>(list: T[]): T[][] => Array.from({ length: Math.ceil(list.length / CHUNK) }, (_, i) => list.slice(i * CHUNK, (i + 1) * CHUNK));\n/** A relation as a reverse batch writes it: OID tokens. */\nconst plain = (v: unknown): unknown =>\n Array.isArray(v) ? v.map(plain) : v && typeof v === \"object\" && \"_oid\" in v ? momentless(String((v as { _oid: unknown })._oid)) : v ?? null;\n\nexport interface Named { number: string | null; name: string | null }\n\n/** Told about a name lookup that failed: the type, the assets left unnamed, and why. */\nexport type NameLookupFailure = (failure: { type: AssetTypeToken; oids: Oid[]; error: unknown }) => void;\n\n/**\n * Numbers and names, one bounded query per type and chunk, asking each type\n * only for what the schema says it has (a Conversation has neither, and\n * asking fails the query). Cosmetic: a lookup that fails leaves those assets\n * unnamed rather than failing a batch that may already be sent, and is\n * reported to `onFailure` so a caller can say so.\n */\nexport async function namesOf(transport: Transport, schema: Schema, oids: Iterable<Oid>, onFailure?: NameLookupFailure): Promise<Map<Oid, Named>> {\n const out = new Map<Oid, Named>();\n for (const [type, list] of byType(oids)) {\n let select: string[];\n try {\n await schema.load(type);\n select = [\"Name\", \"Number\"].filter((a) => schema.attribute(type, a));\n } catch (error) {\n onFailure?.({ type, oids: list, error });\n continue;\n }\n if (!select.length) continue;\n for (const part of chunks(list)) {\n try {\n const rows = await assetApi.query<Asset & { Name?: string; Number?: string }>(transport, { from: type, select, filter: [\"ID=$oids\"], with: { $oids: part }, page: { size: part.length, start: 0 } });\n for (const r of rows) out.set(momentless(r._oid), { number: r.Number ?? null, name: r.Name ?? null });\n } catch (error) {\n onFailure?.({ type, oids: part, error });\n }\n }\n }\n return out;\n}\n\n/** The values about to be overwritten: each update's named attributes, each execute's AssetState, and every touched asset's ChangeDate. */\nexport async function snapshot(transport: Transport, described: Described): Promise<Record<Oid, Record<string, unknown>>> {\n const wanted = new Map<Oid, Set<string>>();\n const want = (oid: Oid, attrs: string[]) => { const s = wanted.get(oid) ?? new Set<string>(); attrs.forEach((a) => s.add(a)); wanted.set(oid, s); };\n for (const u of described.updates) want(u.oid, [...Object.keys(u.attributes), \"ChangeDate\"]);\n for (const e of described.executes) want(e.oid, [\"AssetState\", \"ChangeDate\"]);\n const before: Record<Oid, Record<string, unknown>> = {};\n for (const [type, oids] of byType(wanted.keys())) {\n const select = [...new Set(oids.flatMap((o) => [...wanted.get(o)!]))];\n for (const part of chunks(oids)) {\n const rows = await assetApi.query<Asset>(transport, { from: type, select, filter: [\"ID=$oids\"], with: { $oids: part }, page: { size: part.length, start: 0 } });\n for (const r of rows) {\n const oid = momentless(r._oid), row = r as unknown as Record<string, unknown>;\n before[oid] = Object.fromEntries([...wanted.get(oid)!].map((a) => [a, plain(row[a])]));\n }\n }\n }\n return before;\n}\n\n// ---- undoing it --------------------------------------------------------------------\n\n/** The known inverse operations. Anything else is reported, not guessed. */\nexport const INVERSE: Readonly<Record<string, string>> = { Inactivate: \"Reactivate\", QuickClose: \"Reactivate\", Reactivate: \"Inactivate\", Delete: \"Undelete\", Undelete: \"Delete\" };\n\n/** Operations that close an asset's open descendants along with it (Core's close cascade). */\nexport const CASCADING: ReadonlySet<string> = new Set([\"Inactivate\", \"QuickClose\"]);\n\n/** How deep a cascade is followed: Epic → sub-Epic → Story → Task is four. */\nconst CASCADE_DEPTH = 8;\n\n/**\n * Each root's open descendants, top down (children, then grandchildren, …),\n * through the Children relation of the types that have one. One bounded\n * query per type and chunk for each level's children, and one for their\n * states. A root whose type has no Children has none.\n */\nexport async function openDescendantsOf(transport: Transport, schema: Schema, roots: Oid[]): Promise<Record<Oid, Oid[]>> {\n const out: Record<Oid, Oid[]> = {};\n const rootOf = new Map<Oid, Oid>(roots.map((r) => [momentless(r), momentless(r)]));\n const seen = new Set(rootOf.keys());\n let frontier = [...rootOf.keys()];\n for (let depth = 0; depth < CASCADE_DEPTH && frontier.length; depth += 1) {\n const children = new Map<Oid, Oid>(); // child → its root\n for (const [type, list] of byType(frontier)) {\n await schema.load(type);\n if (!schema.attribute(type, \"Children\")) continue;\n for (const part of chunks(list)) {\n const rows = await assetApi.query<Asset & { Children?: unknown }>(transport, { from: type, select: [\"Children\"], filter: [\"ID=$oids\"], with: { $oids: part }, page: { size: part.length, start: 0 } });\n for (const r of rows) {\n const parent = momentless(r._oid);\n for (const c of ([] as unknown[]).concat(plain(r.Children) ?? [])) {\n const child = momentless(String(c));\n if (seen.has(child)) continue;\n seen.add(child);\n children.set(child, rootOf.get(parent)!);\n }\n }\n }\n }\n const states = children.size ? await statesOf(transport, [...children.keys()]) : {};\n frontier = [];\n for (const [child, root] of children) {\n if (states[child] === undefined || isClosed(states[child])) continue; // gone, or closed already: not the cascade's\n rootOf.set(child, root);\n (out[root] ??= []).push(child);\n frontier.push(child);\n }\n }\n return out;\n}\n\nexport interface Reverse { commands: Command[]; notes: string[] }\n\n/** What reverseOf can know beyond the response, each optional. */\nexport interface ReverseContext {\n /** Per closing target, its open descendants before the batch (Receipt.openDescendants). */\n openDescendants?: Record<Oid, Oid[]>;\n /** Per closing target, the descendants the close closed (Receipt.cascaded); undefined when they could not be read back. */\n cascaded?: Record<Oid, Oid[]>;\n /** Can this type do this operation? Undefined is \"don't know\", and the command is kept. */\n canOperate?: (type: AssetTypeToken, op: string) => boolean | undefined;\n}\n\n/**\n * A batch that undoes what the response says succeeded — best effort. Only\n * what the response confirms is reversed (membership in it, not command\n * index, decides): updated attributes put back from the snapshot, the\n * inverse operation where one is known (and, for a close, the descendants\n * it closed reopened after it, top down), created assets deleted (newest\n * first). An operation a type does not have, by `context.canOperate`, is\n * a note rather than a command the server would refuse.\n */\nexport function reverseOf(described: Described, before: Record<Oid, Record<string, unknown>>, done: { created: Oid[]; modified: Oid[]; operated: Oid[] }, context: ReverseContext = {}): Reverse {\n const commands: Command[] = [], notes: string[] = [];\n const cannot = (oid: Oid, op: string) => context.canOperate?.(typeOfOid(oid), op) === false;\n const modified = new Set(done.modified.map(momentless)), operated = new Set(done.operated.map(momentless));\n for (const u of described.updates) {\n if (!modified.has(u.oid)) continue;\n const was = before[u.oid];\n if (!was) { notes.push(`${u.oid}: no snapshot, cannot restore`); continue; }\n const update: Record<string, CommandValue> = {};\n for (const [attr, change] of Object.entries(u.attributes)) {\n const prior = was[attr];\n const c = change && typeof change === \"object\" && !Array.isArray(change) ? change as { add?: CommandValue; remove?: CommandValue } : {};\n const add = ([] as CommandValue[]).concat(c.add ?? []), remove = ([] as CommandValue[]).concat(c.remove ?? []);\n if (Array.isArray(prior)) {\n const added = add.filter((v) => !prior.includes(v)), removed = remove.filter((v) => prior.includes(v));\n if (added.length || removed.length) update[attr] = { add: removed, remove: added };\n } else if (prior === undefined) notes.push(`${u.oid}.${attr}: not in snapshot, cannot restore`);\n else update[attr] = prior as CommandValue; // a scalar or single relation: put the old value back (null clears)\n }\n if (Object.keys(update).length) commands.push({ from: u.oid, update });\n }\n for (const e of described.executes) {\n if (!operated.has(e.oid)) continue;\n const inverse = INVERSE[e.op];\n if (!inverse) { notes.push(`${e.oid}: ${e.op} has no known inverse (was ${String(before[e.oid]?.AssetState ?? \"?\")})`); continue; }\n if (cannot(e.oid, inverse)) { notes.push(`${e.oid}: ${typeOfOid(e.oid)} has no ${inverse} operation, so its ${e.op} is not reversed`); continue; }\n commands.push({ from: e.oid, execute: inverse });\n if (!CASCADING.has(e.op)) continue;\n const open = context.openDescendants?.[e.oid] ?? [];\n const closed = context.cascaded ? context.cascaded[e.oid] ?? [] : undefined;\n if (closed === undefined) {\n if (open.length) notes.push(`${e.oid}: ${e.op} may also have closed ${open.length} open descendant${open.length === 1 ? \"\" : \"s\"} (${open.join(\", \")}); they could not be read back, so they are not reopened`);\n continue;\n }\n for (const d of closed) {\n if (cannot(d, \"Reactivate\")) notes.push(`${d}: closed with ${e.oid}, but ${typeOfOid(d)} has no Reactivate operation`);\n else commands.push({ from: d, execute: \"Reactivate\" });\n }\n if (closed.length) notes.push(`${e.oid}: ${e.op} also closed ${closed.join(\", \")}; reopened after it`);\n }\n for (const oid of [...done.created].reverse().map(momentless)) {\n if (cannot(oid, \"Delete\")) notes.push(`${oid}: ${typeOfOid(oid)} has no Delete operation, so it is not deleted${typeOfOid(oid) === \"Conversation\" ? \" (the server removes a Conversation once its last Expression is deleted)\" : \"\"}`);\n else commands.push({ from: oid, execute: \"Delete\" });\n }\n for (const d of described.deferred ?? []) notes.push(`command ${d.index} (${d.alias}): an aliased ${d.kind} of ${d.from}, sent as written with no snapshot; not reversed`);\n if (commands.length) notes.unshift(\"restores the state recorded at snapshotAt; anything that changed between then and sentAt is not reflected, and a scalar restored to null is cleared, not unset\");\n return { commands, notes };\n}\n\n// ---- the receipt -----------------------------------------------------------------------\n\nexport interface Receipt {\n receipt: 1;\n request: Command[];\n previewedAt: string;\n preview: Command[];\n described: Described;\n /** Numbers and names of the assets the preview touches, looked up before confirm. */\n names: Record<Oid, Named>;\n snapshotAt?: string;\n /** Before values per touched asset, ChangeDate included: what the guard compared and the reverse restores. */\n before: Record<Oid, Record<string, unknown>>;\n /** Was the batch sent? False for a preview, a declined confirm, or nothing to do. */\n sent: boolean;\n guarded: boolean;\n /** The batch as sent (the guarded projection, or the request as written). */\n sentCommands?: Command[];\n sentAt?: string;\n /** What the server says the batch did. */\n outcome?: assetApi.Outcome;\n created: ({ alias: string | null; type: string; oid: Oid } & Named)[];\n touched: ({ oid: Oid } & Named)[];\n /** ChangeDate of everything the batch touched, just after it: the stamp a later reverse checks for drift. */\n after: Record<Oid, string>;\n /** Touched assets the guard left alone: changed or gone since the snapshot. Not the ones whose command failed: those are in `failed`. */\n skipped: Oid[];\n /** Touched assets whose command the server reports as failed (outcome.failures says why). */\n failed: Oid[];\n /** Per asset the batch closes (Inactivate, QuickClose): its open descendants at the snapshot, top down. */\n openDescendants: Record<Oid, Oid[]>;\n /** Per asset the batch closed: the descendants the close closed with it, read back after the send. */\n cascaded: Record<Oid, Oid[]>;\n reverse: Reverse;\n /** What the record could not do and why: a name lookup that failed, deferred commands sent unsnapshotted. */\n notes: string[];\n}\n\n/**\n * The batch was sent and the server's outcome is on the receipt\n * (`receipt.sent`, `receipt.outcome`, `receipt.reverse`), but reading the\n * assets back afterwards failed, so `receipt.after` is incomplete: keep the\n * receipt, and know that a reverse built from it cannot check every asset\n * for changes made since.\n */\nexport class BatchRecordError extends WrappedError {\n readonly receipt: Receipt;\n constructor(cause: unknown, receipt: Receipt) {\n super(`the batch was sent and its outcome recorded, but reading the assets back afterwards failed, so receipt.after is incomplete: ${cause instanceof Error ? cause.message : String(cause)}`, \"BATCH_RECORD\", cause);\n this.name = \"BatchRecordError\";\n this.receipt = receipt;\n }\n}\n\n/** The send itself failed (a timeout, a 5xx): whether the server applied it is unknown. The receipt holds everything up to the attempt. */\nexport class BatchSendError extends WrappedError {\n readonly receipt: Receipt;\n constructor(cause: unknown, receipt: Receipt) {\n super(`the batch send failed; whether the server applied it is unknown: ${cause instanceof Error ? cause.message : String(cause)}`, \"BATCH_SEND\", cause);\n this.name = \"BatchSendError\";\n this.receipt = receipt;\n }\n}\n\nexport interface BatchOptions {\n /** Send as a compare-and-set (default). An unguardable batch then throws UnguardableError before any request; pass false to send it as written. */\n guard?: boolean;\n /** Stop after the snapshot and send nothing: the receipt says what would happen. */\n dryRun?: boolean;\n /** Asked after the snapshot, before the send, with the touched assets' names on the receipt; false sends nothing. */\n confirm?: (receipt: Receipt) => boolean | Promise<boolean>;\n}\n\nconst now = (): string => new Date().toISOString();\n\n/** Preview, describe, name, snapshot, (confirm,) send, receipt. */\nexport async function runBatch(transport: Transport, schema: Schema, commands: Command[], options: BatchOptions = {}): Promise<Receipt> {\n const useGuard = options.guard ?? true;\n if (!commands.length) throw new UsageError(\"the batch is empty\");\n const refused = unguardable(commands);\n const fatal = refused.filter((r) => r.reason.includes(\"rejected by the server\"));\n if (fatal.length || (useGuard && refused.length)) throw new UnguardableError(useGuard ? refused : fatal);\n\n const notes: string[] = [];\n const noteFailure: NameLookupFailure = ({ type, oids, error }) =>\n notes.push(`could not look up Name for ${oids.length} ${type} asset${oids.length === 1 ? \"\" : \"s\"}: ${error instanceof Error ? error.message : String(error)}`);\n const previewedAt = now();\n const projected = await assetApi.preview(transport, commands);\n const described = describe(commands, projected);\n const touched = touchedBy(projected);\n const names = await namesOf(transport, schema, touched, noteFailure);\n const receipt: Receipt = { receipt: 1, request: commands, previewedAt, preview: projected, described, names: Object.fromEntries(names), before: {}, sent: false, guarded: false, created: [], touched: [], after: {}, skipped: [], failed: [], openDescendants: {}, cascaded: {}, reverse: { commands: [], notes: [] }, notes };\n const nothing = !described.creates.length && !described.updates.length && !described.executes.length && !described.queries.length && !described.deferred.length;\n if (nothing) return receipt;\n for (const d of described.deferred) notes.push(`command ${d.index} (${d.alias}): an aliased ${d.kind}, which preview does not expand; sent as written, not snapshotted, not reversible`);\n receipt.snapshotAt = now();\n receipt.before = await snapshot(transport, described);\n const closing = described.executes.filter((e) => CASCADING.has(e.op)).map((e) => e.oid);\n if (closing.length) receipt.openDescendants = await openDescendantsOf(transport, schema, closing);\n if (options.dryRun) return receipt;\n if (options.confirm && !(await options.confirm(receipt))) return receipt;\n\n let unstamped: Oid[] = [];\n receipt.guarded = useGuard;\n receipt.sentAt = now();\n let done: assetApi.Outcome;\n try {\n if (useGuard) {\n // Guarded pass by pass: a second command on the same asset (Reactivate\n // then Delete in a reverse) goes only if the first applied (guard.ts).\n const stamps = Object.fromEntries(Object.entries(receipt.before).flatMap(([oid, v]) => (typeof v.ChangeDate === \"string\" ? [[oid, v.ChangeDate]] : [])));\n receipt.sentCommands = guard(passesOf(projected)[0]!, stamps).commands; // what the first pass sends; replaced below by everything sent\n const result = await sendPasses(transport, projected, stamps);\n ({ outcome: done, unstamped } = result);\n receipt.sentCommands = result.sent;\n } else {\n receipt.sentCommands = commands;\n done = assetApi.outcomeOf(await assetApi.send(transport, commands));\n }\n } catch (error) {\n if (error instanceof GuardedPassError) {\n // Earlier passes applied: the receipt says so, and what failed after.\n receipt.sent = true;\n receipt.outcome = error.outcome;\n receipt.sentCommands = error.sent;\n }\n throw new BatchSendError(error, receipt);\n }\n receipt.sent = true;\n receipt.outcome = done;\n\n // The record, from the response alone: nothing below this block can lose it.\n const hit = [...new Set([...done.modified, ...done.operated])];\n const unnamed = { number: null, name: null };\n receipt.created = done.created.map((oid, i) => ({ alias: described.creates[i]?.alias ?? null, type: described.creates[i]?.type ?? typeOfOid(oid), oid, ...unnamed }));\n receipt.touched = hit.map((oid) => ({ oid, ...(names.get(oid) ?? unnamed) }));\n // A failed command names its asset in what was sent: the guard's\n // with.$oid, or the from of a per-asset command sent as written.\n const sentAs = receipt.sentCommands ?? [];\n const oidOfSent = (i: number | null): Oid | null => {\n const body = i === null ? undefined : (sentAs[i] ? bodyOf(sentAs[i]!) : undefined);\n const id = (body?.with as { $oid?: unknown } | undefined)?.$oid ?? body?.from;\n return typeof id === \"string\" && id.includes(\":\") ? momentless(id) : null;\n };\n receipt.failed = [...new Set(done.failures.map((f) => oidOfSent(f.index)).filter((oid): oid is Oid => !!oid && touched.includes(oid) && !hit.includes(oid)))];\n receipt.skipped = useGuard ? [...new Set([...unstamped, ...touched.filter((oid) => !hit.includes(oid) && !receipt.failed.includes(oid))])] : [];\n // What each type can do, from the definitions already loaded (or loadable):\n // an unknown answer keeps the command, as before.\n for (const type of new Set([...done.created, ...hit].map((oid) => typeOfOid(momentless(oid))))) await schema.load(type).catch(() => null);\n const canOperate = (type: AssetTypeToken, op: string) => schema.canOperate(type, op);\n const operatedNow = new Set(done.operated.map(momentless));\n const closed = Object.keys(receipt.openDescendants).filter((oid) => operatedNow.has(oid) && receipt.openDescendants[oid]!.length);\n // Until the cascade is read back, the reverse says what it could not reopen.\n receipt.reverse = reverseOf(described, receipt.before, done, { openDescendants: receipt.openDescendants, cascaded: closed.length ? undefined : {}, canOperate });\n\n // Decoration, read back from the server. Names are cosmetic (a failure is\n // a note); the after stamps are not, so a failure there throws with the\n // receipt, outcome and all.\n try {\n if (closed.length) {\n // The descendants the close closed: open at the snapshot, closed now.\n const states = await statesOf(transport, closed.flatMap((oid) => receipt.openDescendants[oid]!));\n receipt.cascaded = Object.fromEntries(closed.map((oid) => [oid, receipt.openDescendants[oid]!.filter((d) => isClosed(states[d]))]));\n receipt.reverse = reverseOf(described, receipt.before, done, { openDescendants: receipt.openDescendants, cascaded: receipt.cascaded, canOperate });\n }\n const more = await namesOf(transport, schema, [...done.created, ...hit.filter((oid) => !names.has(oid))], noteFailure);\n receipt.created = receipt.created.map((c) => ({ ...c, ...(more.get(c.oid) ?? unnamed) }));\n receipt.touched = receipt.touched.map((t) => (names.has(t.oid) ? t : { ...t, ...(more.get(t.oid) ?? unnamed) }));\n // The cascade's descendants too: a later reverse reopens them, and checks them for changes first.\n const all = [...new Set([...done.created, ...hit, ...Object.values(receipt.cascaded).flat()])];\n receipt.after = all.length ? await stampsOf(transport, all) : {};\n } catch (error) {\n throw new BatchRecordError(error, receipt);\n }\n return receipt;\n}\n\n/** Each asset's AssetState by name (\"Active\", \"Closed\"), one bounded query per type and chunk. An asset that no longer exists is absent. */\nasync function statesOf(transport: Transport, oids: Oid[]): Promise<Record<Oid, string>> {\n const out: Record<Oid, string> = {};\n for (const [type, list] of byType(oids)) {\n for (const part of chunks(list)) {\n const rows = await assetApi.query<Asset & { AssetState?: unknown }>(transport, { from: type, select: [\"AssetState\"], filter: [\"ID=$oids\"], with: { $oids: part }, page: { size: part.length, start: 0 } });\n for (const r of rows) if (r.AssetState != null) out[momentless(r._oid)] = String(r.AssetState);\n }\n }\n return out;\n}\n\n/** AssetState as the endpoint spells a closed asset: by name, or by Core's code (128). */\nconst isClosed = (state: string | undefined): boolean => state === \"Closed\" || state === \"128\";\n\n/**\n * A receipt's reverse batch, minus the assets someone changed since the\n * batch (their ChangeDate is no longer the one recorded just after it),\n * unless `force`. Send what it returns with runBatch like any batch.\n *\n * Agility refuses to Delete a closed asset (Violation'AssetCannotDeleteClosed),\n * so a Delete of an asset that is closed now gets a Reactivate just before\n * it: two commands on one asset, which runBatch sends in two guarded passes\n * (the Delete only if the Reactivate applied). `reactivated` lists them.\n */\nexport async function reversible(transport: Transport, receipt: Pick<Receipt, \"reverse\" | \"after\">, options: { force?: boolean } = {}): Promise<{ commands: Command[]; drifted: { oid: Oid; was: string; now: string | null }[]; reactivated: Oid[] }> {\n const targets = receipt.reverse.commands.map((c) => momentless(String(bodyOf(c).from)));\n const now = await stampsOf(transport, targets.filter((oid) => receipt.after[oid] !== undefined));\n const drifted = targets.flatMap((oid) => (receipt.after[oid] !== undefined && now[oid] !== receipt.after[oid] ? [{ oid, was: receipt.after[oid]!, now: now[oid] ?? null }] : []));\n const skip = new Set(options.force ? [] : drifted.map((d) => d.oid));\n const kept = receipt.reverse.commands.filter((c) => !skip.has(momentless(String(bodyOf(c).from))));\n const deletes = kept.flatMap((c) => (bodyOf(c).execute === \"Delete\" ? [momentless(String(bodyOf(c).from))] : []));\n const states = deletes.length ? await statesOf(transport, deletes) : {};\n const reactivated = deletes.filter((oid) => isClosed(states[oid]));\n const commands = kept.flatMap((c) => {\n const body = bodyOf(c), oid = momentless(String(body.from));\n return body.execute === \"Delete\" && reactivated.includes(oid) ? [{ from: oid, execute: \"Reactivate\" } as Command, c] : [c];\n });\n return { commands, drifted, reactivated };\n}\n","/**\n * The field-visibility wire module: which attributes the product shows for\n * an asset type in a scope. Two GET endpoints, both answering attribute\n * NAMES, narrower than everything meta.v1 reports — the workspace's\n * configuration (which custom fields are displayed, say) is applied only\n * here. Verified against the API-testing instance and Core's\n * DisplayedFieldsController (2026-11-14):\n *\n * api/visibleFields?scopeOid=Scope:0&assetTypeToken=Story&assetTypeToken=Defect\n * Both parameters REPEAT (not comma lists). Answers one entry per\n * type, { assetType, fields }, fields sorted and de-duplicated, custom\n * fields included once configured for display. A global asset type\n * (no scope context) ignores scopeOid; mixing global and non-global\n * types is 400 \"Cannot mix global and non-global asset types\"; an\n * unknown type is 400.\n * api/visibleFieldsByAsset?oidToken=Story:1234\n * The same for one asset, its own Scope as the context; a flat list.\n * An asset of a global type (a Member) answers 500 on the instance.\n */\nimport { ApiError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Oid } from \"../types/asset\";\nimport type { AssetTypeToken } from \"../types/metamodel\";\nimport { momentless } from \"../types/oid\";\n\ninterface VisibleFieldsEntry { assetType: string; fields: string[] }\n\n/** The attributes shown for each type in the scopes given: a map from type token to sorted attribute names. */\nexport async function visibleFields(transport: Transport, types: readonly AssetTypeToken[], scopes: readonly Oid[]): Promise<Record<AssetTypeToken, string[]>> {\n if (!types.length) return {};\n // The endpoint wants repeated keys; the transport's query map cannot spell that, so the string is built here.\n const params = [...scopes.map((s) => `scopeOid=${encodeURIComponent(momentless(s))}`), ...types.map((t) => `assetTypeToken=${encodeURIComponent(t)}`)].join(\"&\");\n const answer = await transport.request<unknown>({ method: \"GET\", path: `/api/visibleFields?${params}`, responseType: \"json\" });\n if (!Array.isArray(answer)) throw new ApiError(\"api/visibleFields did not answer a list\", 200, \"BAD_RESPONSE\", answer);\n const out: Record<AssetTypeToken, string[]> = {};\n for (const entry of answer as VisibleFieldsEntry[]) if (entry && typeof entry.assetType === \"string\") out[entry.assetType] = Array.isArray(entry.fields) ? entry.fields.filter((f): f is string => typeof f === \"string\") : [];\n return out;\n}\n\n/** The attributes shown for one asset, in its own Scope. */\nexport async function visibleFieldsByAsset(transport: Transport, oid: Oid): Promise<string[]> {\n const answer = await transport.request<unknown>({ method: \"GET\", path: \"/api/visibleFieldsByAsset\", query: { oidToken: momentless(oid) }, responseType: \"json\" });\n if (!Array.isArray(answer)) throw new ApiError(\"api/visibleFieldsByAsset did not answer a list\", 200, \"BAD_RESPONSE\", answer);\n return answer.filter((f): f is string => typeof f === \"string\");\n}\n","/**\n * The fields service: what a form for an asset type in a scope needs to\n * know, from three sources the API keeps apart —\n * - meta.v1 (through the schema): which attributes are REQUIRED to\n * create one (IsRequired and writable: Name and Scope on a Story);\n * - api/visibleFields: which attributes the product SHOWS for the type\n * in that scope, custom fields included once configured;\n * - the scope's Scheme: its IMPORTANT fields (Scheme.ImportantFields, a\n * list of attribute tokens) and whether they are enforced at close\n * (Scheme.IsRequiredAtClose).\n * One call, one answer, every list spelled as bare attribute names.\n */\nimport type { Transport } from \"../core/transport\";\nimport type { Asset, Oid, Ref } from \"../types/asset\";\nimport type { AssetTypeToken } from \"../types/metamodel\";\nimport { momentless } from \"../types/oid\";\nimport * as assetApi from \"../wire/assetApi\";\nimport * as fields from \"../wire/fields\";\nimport type { Schema } from \"./schema\";\n\nexport interface FieldsOf {\n type: AssetTypeToken;\n scope: Oid;\n /** The scope's Scheme; null when the scope has none. */\n scheme: Oid | null;\n /** Attributes the server requires on a create (meta: IsRequired, writable). */\n required: string[];\n /** Attributes the product shows for the type in this scope (api/visibleFields). */\n visible: string[];\n /** The scheme's important fields that belong to this type (or an ancestor); [] when the scheme names none. */\n important: string[];\n /** Whether the scheme enforces its important fields when an asset is closed. */\n requiredAtClose: boolean;\n}\n\ntype SchemeRow = Asset & { Scheme?: (Ref & { ImportantFields?: unknown; IsRequiredAtClose?: unknown }) | null };\n\n/** The ancestors of a type, itself first, from the loaded schema. */\nasync function lineage(schema: Schema, type: AssetTypeToken): Promise<AssetTypeToken[]> {\n const out: AssetTypeToken[] = [];\n for (let t: AssetTypeToken | undefined = type; t && !out.includes(t); ) {\n out.push(t);\n const def = await schema.load(t);\n t = def?.Base;\n }\n return out;\n}\n\n/**\n * An important-field token as the scheme spells it (\"Story.Owners\", or a\n * bare \"Owners\") reduced to the attribute name when it belongs to one of\n * the types given; null otherwise.\n */\nexport function importantName(token: string, types: readonly AssetTypeToken[]): string | null {\n const dot = token.indexOf(\".\");\n if (dot < 0) return token;\n return types.includes(token.slice(0, dot)) ? token.slice(dot + 1) : null;\n}\n\n/** Required, visible and important attributes for creating or editing an asset of `type` in `scope`. */\nexport async function describe(transport: Transport, schema: Schema, type: AssetTypeToken, scope: Oid): Promise<FieldsOf> {\n const scopeOid = momentless(scope);\n const types = await lineage(schema, type);\n const definition = await schema.load(type);\n const required = definition ? Object.values(definition.Attributes).filter((a) => a.IsRequired && !a.IsReadOnly).map((a) => a.Name).sort() : [];\n const [visible, [row]] = await Promise.all([\n fields.visibleFields(transport, [type], [scopeOid]),\n assetApi.query<SchemeRow>(transport, { from: \"Scope\", select: [{ from: \"Scheme\", select: [\"ImportantFields\", \"IsRequiredAtClose\"] }], filter: [\"ID=$scope\"], with: { $scope: scopeOid }, page: { size: 1, start: 0 } }, { lookup: schema })\n ]);\n const scheme = row?.Scheme ?? null;\n const tokens = Array.isArray(scheme?.ImportantFields) ? scheme.ImportantFields.filter((t): t is string => typeof t === \"string\") : [];\n const important = [...new Set(tokens.map((t) => importantName(t, types)).filter((n): n is string => !!n))].sort();\n return {\n type,\n scope: scopeOid,\n scheme: scheme ? momentless(scheme._oid) : null,\n required,\n visible: visible[type] ?? [],\n important,\n requiredAtClose: scheme?.IsRequiredAtClose === true\n };\n}\n","/**\n * The hand-written roots the generated asset types build on. Everything\n * else under src/types/assets is generated from the metamodel.\n *\n * These are MODEL types: one shape, wherever an asset came from or is going.\n * A relation is a Ref here whether api/asset will write it as an OID string\n * or query.v1 read it back as { _oid }; the wire layer translates.\n */\n\n/** An OID token, momentless: \"Story:1234\". */\nexport type Oid = string;\n\n/** An ISO-8601 date-time as the API renders it, e.g. \"2026-09-06T13:52:51.903\". */\nexport type DateString = string;\n\n/**\n * An AssetState as the model carries it: the names of Core's AssetState\n * enum (VersionOne/AssetState.cs: Future 0, Active 64, Closed 128, Dead 192,\n * OldBrokenDownStory 208, Deprecated 254, Deleted 255). rest-1 renders the\n * number and query.v1 the name; the wire layer normalises to the name.\n */\nexport type AssetStateValue = \"Future\" | \"Active\" | \"Closed\" | \"Dead\" | \"Template\" | \"OldBrokenDownStory\" | \"Deprecated\" | \"Deleted\";\n\n/** Core's AssetState codes, by name — the rest-1 rendering. */\nexport const ASSET_STATE_CODES: Record<AssetStateValue, number> = { Future: 0, Active: 64, Closed: 128, Dead: 192, Template: 200, OldBrokenDownStory: 208, Deprecated: 254, Deleted: 255 };\n\nconst STATE_OF_CODE: Record<number, AssetStateValue> = Object.fromEntries(Object.entries(ASSET_STATE_CODES).map(([name, code]) => [code, name as AssetStateValue]));\n\n/**\n * An AssetState by name, whichever way the endpoint spelled it: api/asset\n * and query.v1 send the name (\"Closed\") for most states but the code for a\n * few (\"200\", a template), and rest-1 always sends the number. An unknown\n * code is left as sent.\n */\nexport function assetStateOf(value: unknown): AssetStateValue | string | null {\n if (value == null) return null;\n const code = typeof value === \"number\" ? value : typeof value === \"string\" && /^\\d+$/.test(value) ? Number(value) : NaN;\n return Number.isNaN(code) ? String(value) : STATE_OF_CODE[code] ?? String(value);\n}\n\n/**\n * A reference to another asset: always at least its OID, plus whatever a\n * select pulled through (Owners.Name lands on the Ref as Name).\n */\nexport type Ref<T extends Asset = Asset> = { _oid: Oid } & Partial<Omit<T, \"_oid\">>;\n\n/** The value types an attribute can carry in the model. */\nexport type AttributeValue = string | number | boolean | null | Ref | Ref[];\n\n/**\n * Custom attributes are not generated: they differ per instance. One is\n * named with the Custom_ prefix; the reciprocal side of a custom relation,\n * which the server adds on the related type, with ReciprocalOf_ (live\n * 2026-11-12: `Custom_Demo_List.ReciprocalOf_Story_Custom_Demo_Single_List`).\n * The root carries both.\n */\nexport interface CustomAttributes {\n [custom: `Custom_${string}`]: AttributeValue | undefined;\n [reciprocal: `ReciprocalOf_${string}`]: AttributeValue | undefined;\n}\n\n/** The root every generated asset type extends. */\nexport interface Asset extends CustomAttributes {\n _oid: Oid;\n}\n","/**\n * The resolve service: what a person types (an asset number, an OID token)\n * turned into the asset it names. Ported from gh-v1's lib/resolve.js\n * (resolveAssets, resolveAssetRef), minus the prompting, which stays in the\n * CLI.\n *\n * Which type a number's prefix belongs to is the instance's business (the\n * prefixes are configurable), so there is no client-side prefix map: every\n * type whose Number attribute is its own definition is a \"number root\", and\n * one api/asset request asks each root for all the numbers at once. Workitem\n * is one root and covers every workitem type, custom ones included; the rest\n * come from the metamodel (test/unit/resolve.test.ts recomputes the list\n * from metamodel.json, so it cannot drift).\n *\n * Numbers travel as a `with` list, never spliced into the filter text: a\n * value is then data, not grammar (an em dash in a filter literal fails to\n * parse; the same value as a variable does not — live, 2026-11-04). Number\n * matching on the server is case-insensitive.\n */\nimport { UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport { assetStateOf, type Asset, type AssetStateValue, type Oid } from \"../types/asset\";\nimport type { TypeCache } from \"./schema\";\nimport type { AssetTypeToken } from \"../types/metamodel\";\nimport { isOidToken, momentless, typeOfOid } from \"../types/oid\";\nimport * as assetApi from \"../wire/assetApi\";\n\n/**\n * Types whose Number attribute is their own definition (no Base), from the\n * canned metamodel, each with what it can be asked for: Number always, Name\n * and AssetState where the type has them (ExternalActionInvocation has\n * neither, Grant no Name — an unknown select token fails the query).\n */\nexport const NUMBER_ROOTS: Readonly<Record<AssetTypeToken, readonly string[]>> = {\n Environment: [\"Number\", \"Name\", \"AssetState\"],\n ExternalActionInvocation: [\"Number\"],\n Goal: [\"Number\", \"Name\", \"AssetState\"],\n Grant: [\"Number\", \"AssetState\"],\n Issue: [\"Number\", \"Name\", \"AssetState\"],\n Milestone: [\"Number\", \"Name\", \"AssetState\"],\n Okr: [\"Number\", \"Name\", \"AssetState\"],\n OkrSession: [\"Number\", \"Name\", \"AssetState\"],\n RegressionPlan: [\"Number\", \"Name\", \"AssetState\"],\n RegressionSuite: [\"Number\", \"Name\", \"AssetState\"],\n RegressionTest: [\"Number\", \"Name\", \"AssetState\"],\n Request: [\"Number\", \"Name\", \"AssetState\"],\n Roadmap: [\"Number\", \"Name\", \"AssetState\"],\n StrategicTheme: [\"Number\", \"Name\", \"AssetState\"],\n Topic: [\"Number\", \"Name\", \"AssetState\"],\n Workitem: [\"Number\", \"Name\", \"AssetState\"]\n};\n\n/**\n * An asset number as a person types one: a prefix and digits (S-1234,\n * TK-12). Prefixes are instance configuration, so any length is accepted;\n * a false positive (\"UTF-8\") costs nothing but a `missing`. Scanning prose\n * for numbers (commit messages) wants a stricter pattern, and is the\n * caller's.\n */\nexport const isAssetNumber = (text: string): boolean => /^[A-Za-z]+-\\d+$/.test(text.trim());\n\n/** How many numbers one request asks about: bounded, never one giant filter. */\nexport const CHUNK = 100;\n\nexport interface ResolvedAsset {\n /** The number as the server spells it; null for a ref given as an OID token. */\n number: string | null;\n oid: Oid;\n type: AssetTypeToken;\n name: string | null;\n assetState: AssetStateValue | null;\n}\n\nexport interface Resolution {\n /** In the order the numbers were asked for, one per distinct number found. */\n found: ResolvedAsset[];\n /** Numbers no root knows, as they were asked for. */\n missing: string[];\n}\n\n// Roots an instance turned out not to have, asked once, then left out. With a\n// TypeCache (the client passes its schema's) that is the cache's own record of\n// types the instance lacks (null), so clients that share a cache share it;\n// without one, it is remembered per transport.\nconst absentRoots = new WeakMap<Transport, Set<string>>();\n\ninterface Absent { has(root: string): boolean; add(root: string): void }\nconst absentFor = (transport: Transport, types?: TypeCache): Absent => {\n if (types) return { has: (root) => types.types.get(root) === null, add: (root) => { types.types.set(root, null); } };\n const set = absentRoots.get(transport) ?? new Set<string>();\n absentRoots.set(transport, set);\n return set;\n};\nconst UNKNOWN_TYPE = /^Unknown AssetType: (\\S+)/;\n\ntype Row = Asset & { Name?: string | null; Number?: string; AssetState?: unknown };\n\nasync function askRoots(transport: Transport, numbers: string[], types?: TypeCache): Promise<Row[]> {\n const absent = absentFor(transport, types);\n for (let attempt = 0; ; attempt += 1) {\n const roots = Object.keys(NUMBER_ROOTS).filter((r) => !absent.has(r));\n try {\n const results = await assetApi.queries<Row>(transport, roots.map((from) => ({\n from,\n select: [...NUMBER_ROOTS[from]!],\n filter: [\"Number=$numbers\"],\n with: { $numbers: numbers },\n page: { size: numbers.length, start: 0 }\n })));\n return results.flat();\n } catch (error) {\n // An instance without one of the roots answers \"Unknown AssetType\" for\n // that query alone. Remember it and ask again without it — once; any\n // other failure is the caller's to see.\n const unknown = error instanceof assetApi.CommandFailureError ? error.failures.map((f) => UNKNOWN_TYPE.exec(f.message)?.[1]) : [];\n if (attempt > 0 || !unknown.length || unknown.some((t) => !t || !roots.includes(t))) throw error;\n for (const t of unknown) absent.add(t!);\n }\n }\n}\n\n/** Resolve asset numbers in one request per hundred numbers. Not found is not an error: it is `missing`. */\nexport async function resolveNumbers(transport: Transport, numbers: readonly string[], options: { types?: TypeCache } = {}): Promise<Resolution> {\n const firsts = new Map<string, string>();\n for (const n of numbers) if (!firsts.has(n.trim().toUpperCase())) firsts.set(n.trim().toUpperCase(), n.trim());\n const asked = [...firsts.values()];\n const invalid = asked.filter((n) => !isAssetNumber(n));\n if (invalid.length) throw new UsageError(`not asset numbers (expected a prefix and digits, S-1234): ${invalid.join(\", \")}`);\n const byNumber = new Map<string, ResolvedAsset>();\n for (let i = 0; i < asked.length; i += CHUNK) {\n for (const r of await askRoots(transport, asked.slice(i, i + CHUNK), options.types)) {\n if (!r.Number || byNumber.has(r.Number.toUpperCase())) continue;\n const oid = momentless(r._oid);\n byNumber.set(r.Number.toUpperCase(), { number: r.Number, oid, type: typeOfOid(oid), name: r.Name ?? null, assetState: assetStateOf(r.AssetState) as AssetStateValue | null });\n }\n }\n return {\n found: asked.flatMap((n) => byNumber.get(n.toUpperCase()) ?? []),\n missing: asked.filter((n) => !byNumber.has(n.toUpperCase()))\n };\n}\n\n/**\n * One asset by whichever shape the person has: an OID token (Story:1234 —\n * used as is, no request, so `number` and `name` are null) or a number\n * (resolved; null when no root knows it). Anything else is a TypeError.\n */\nexport async function resolveRef(transport: Transport, spec: string, options: { types?: TypeCache } = {}): Promise<ResolvedAsset | null> {\n const text = spec.trim();\n if (isOidToken(text)) { const oid = momentless(text); return { number: null, oid, type: typeOfOid(oid), name: null, assetState: null }; }\n if (isAssetNumber(text)) return (await resolveNumbers(transport, [text], options)).found[0] ?? null;\n throw new UsageError(`\"${spec}\" is neither an asset number (S-1234) nor an OID token (Story:1234)`);\n}\n","/**\n * The meta.v1 wire module: what the endpoint delivers, and the translation\n * into the metamodel types (src/types/metamodel.ts).\n *\n * meta.v1 describes the instance's schema. Three reads:\n * GET /meta.v1 the whole metamodel (large: ~7 MB, 165 types)\n * GET /meta.v1/<Type> one asset type with its attributes\n * GET /meta.v1/<Type>/<Attribute> one attribute definition\n *\n * The delivered document is its own vocabulary — Token, DisplayName,\n * IsMultivalue, RelatedAsset, Base — and NOT the attribute set of the\n * metamodel's own AttributeDefinition asset type (NativeValue, IsBasic, …).\n * The hand-written types model the delivered document. References inside\n * it arrive as { href, tokenref } or { href, nameref }; the model keeps the\n * token. An attribute the type defines itself has no Base; an inherited one\n * names the defining ancestor's attribute.\n */\nimport { UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { AssetType, AssetTypeToken, AttributeDefinition, AttributeTokenRef, AttributeType, Metamodel } from \"../types/metamodel\";\n\n// ---- what the endpoint delivers ------------------------------------------------\n\nexport interface TokenRef { href: string; tokenref: AttributeTokenRef }\nexport interface NameRef { href: string; nameref: AssetTypeToken }\n\nexport interface AttributeDefinitionDocument {\n HREF?: string;\n _type: \"AttributeDefinition\";\n Name: string;\n Token: AttributeTokenRef;\n DisplayName: string;\n AttributeType: AttributeType;\n IsReadOnly: boolean;\n IsRequired: boolean;\n IsMultivalue: boolean;\n IsCanned: boolean;\n IsCustom: boolean;\n /** Present on an inherited attribute: the defining ancestor's attribute. */\n Base?: TokenRef;\n ReciprocalRelation?: TokenRef;\n OrderByAttribute?: TokenRef;\n DisplayByAttribute?: TokenRef;\n /** Present on a Relation. */\n RelatedAsset?: NameRef;\n}\n\nexport interface AssetTypeDocument {\n HREF?: string;\n Version?: string;\n _type: \"AssetType\";\n Token: AssetTypeToken;\n /** The delivered Name is a reference to the type's Name attribute; the token is the name. */\n Name: TokenRef | string;\n DisplayName: string;\n Abstract: boolean;\n /** Absent on a root type. */\n Base?: NameRef;\n DefaultOrderBy?: TokenRef;\n DefaultDisplayBy?: TokenRef;\n ShortName?: TokenRef;\n Description?: TokenRef;\n Attributes: Record<string, AttributeDefinitionDocument>;\n Operations?: Record<string, unknown>;\n Rules?: Record<string, unknown>;\n}\n\nexport interface MetamodelDocument {\n HREF?: string;\n Version: string;\n AssetTypes: Record<string, AssetTypeDocument>;\n}\n\n// ---- translation ----------------------------------------------------------------\n\nexport function toAttributeDefinition(doc: AttributeDefinitionDocument): AttributeDefinition {\n return {\n _type: \"AttributeDefinition\",\n Name: doc.Name,\n Token: doc.Token,\n DisplayName: doc.DisplayName,\n AttributeType: doc.AttributeType,\n IsReadOnly: doc.IsReadOnly,\n IsRequired: doc.IsRequired,\n IsMultivalue: doc.IsMultivalue,\n IsCanned: doc.IsCanned,\n IsCustom: doc.IsCustom,\n ...(doc.Base ? { Base: doc.Base.tokenref } : {}),\n ...(doc.ReciprocalRelation ? { ReciprocalRelation: doc.ReciprocalRelation.tokenref } : {}),\n ...(doc.OrderByAttribute ? { OrderByAttribute: doc.OrderByAttribute.tokenref } : {}),\n ...(doc.DisplayByAttribute ? { DisplayByAttribute: doc.DisplayByAttribute.tokenref } : {}),\n ...(doc.RelatedAsset ? { RelatedAsset: doc.RelatedAsset.nameref } : {})\n };\n}\n\nexport function toAssetType(doc: AssetTypeDocument): AssetType {\n return {\n _type: \"AssetType\",\n Name: doc.Token,\n Token: doc.Token,\n DisplayName: doc.DisplayName,\n Abstract: doc.Abstract,\n ...(doc.Base ? { Base: doc.Base.nameref } : {}),\n ...(doc.DefaultOrderBy ? { DefaultOrderBy: doc.DefaultOrderBy.tokenref } : {}),\n ...(doc.DefaultDisplayBy ? { DefaultDisplayBy: doc.DefaultDisplayBy.tokenref } : {}),\n ...(doc.ShortName ? { ShortName: doc.ShortName.tokenref } : {}),\n Attributes: Object.fromEntries(Object.entries(doc.Attributes ?? {}).map(([key, value]) => [key, toAttributeDefinition(value)])),\n ...(doc.Operations ? { Operations: Object.keys(doc.Operations).map((token) => token.slice(token.indexOf(\".\") + 1)) } : {})\n };\n}\n\nexport function toMetamodel(doc: MetamodelDocument): Metamodel {\n return { Version: doc.Version, AssetTypes: Object.fromEntries(Object.entries(doc.AssetTypes).map(([key, value]) => [key, toAssetType(value)])) };\n}\n\n/** Is this a metamodel document as meta.v1 delivers it? (A downloaded metamodel.json, say.) */\nexport function isMetamodelDocument(value: unknown): value is MetamodelDocument {\n return !!value && typeof value === \"object\" && typeof (value as MetamodelDocument).Version === \"string\" && !!(value as MetamodelDocument).AssetTypes && typeof (value as MetamodelDocument).AssetTypes === \"object\";\n}\n\n// ---- the calls ------------------------------------------------------------------\n\nexport async function getMetamodel(transport: Transport): Promise<Metamodel> {\n return toMetamodel(await transport.request<MetamodelDocument>({ method: \"GET\", path: \"/meta.v1\", responseType: \"json\" }));\n}\n\nexport async function getAssetType(transport: Transport, token: AssetTypeToken): Promise<AssetType> {\n return toAssetType(await transport.request<AssetTypeDocument>({ method: \"GET\", path: `/meta.v1/${encodeURIComponent(token)}`, responseType: \"json\" }));\n}\n\nexport async function getAttributeDefinition(transport: Transport, tokenref: AttributeTokenRef): Promise<AttributeDefinition> {\n const [type, attribute] = tokenref.split(\".\");\n if (!type || !attribute) throw new UsageError(`\"${tokenref}\" is not an attribute token (\"Story.Name\")`);\n return toAttributeDefinition(await transport.request<AttributeDefinitionDocument>({ method: \"GET\", path: `/meta.v1/${encodeURIComponent(type)}/${encodeURIComponent(attribute)}`, responseType: \"json\" }));\n}\n","/**\n * The schema service: the instance's asset types, loaded from meta.v1 one\n * type at a time as queries need them, and handed to the wire layer as the\n * AttributeLookup it translates rows with.\n *\n * Why lazy: the whole metamodel is ~7 MB and 165 types, and a consumer\n * touches a dozen. Why a service and not the wire module: loading is\n * asynchronous and cross-cutting (one cache per client, in-flight requests\n * deduplicated — the pattern agility-rooms' useMetaDefinitionStore proves),\n * while translation is synchronous and per row. A schema can also be seeded\n * from a metamodel document (a committed metamodel.json, or one read with\n * meta.getMetamodel) and then needs no transport at all.\n */\nimport { ApiError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { AssetType, AssetTypeToken, AttributeDefinition, AttributeLookup, Metamodel } from \"../types/metamodel\";\nimport * as meta from \"../wire/meta\";\nimport { attributeOf, fromTypeOf, typesNeeded, type SelectShape } from \"../wire/select\";\n\n/**\n * The type definitions loaded from one instance, shareable by any number of\n * schemas. A definition does not depend on who read it, so a server that\n * builds a client per user (each with that user's token) can give them all\n * one cache per instance: each type is fetched once, through whichever\n * client needed it first, and concurrent loads of a type share one request.\n */\nexport class TypeCache {\n /** Loaded types; null records that the instance has no such type, so it is not asked for again. */\n readonly types = new Map<AssetTypeToken, AssetType | null>();\n readonly loading = new Map<AssetTypeToken, Promise<AssetType | null>>();\n\n /** A cache seeded from a metamodel document. */\n static fromMetamodel(metamodel: Metamodel): TypeCache {\n const cache = new TypeCache();\n for (const [token, type] of Object.entries(metamodel.AssetTypes)) cache.types.set(token, type);\n return cache;\n }\n}\n\nexport class Schema implements AttributeLookup {\n private readonly types: Map<AssetTypeToken, AssetType | null>;\n private readonly loading: Map<AssetTypeToken, Promise<AssetType | null>>;\n /** Where this schema keeps what it loads; pass it to another schema to share it. */\n readonly cache: TypeCache;\n\n constructor(private readonly transport?: Transport, seed?: Metamodel, cache: TypeCache = new TypeCache()) {\n this.cache = cache;\n this.types = cache.types;\n this.loading = cache.loading;\n if (seed) for (const [token, type] of Object.entries(seed.AssetTypes)) if (!this.types.has(token)) this.types.set(token, type);\n }\n\n /** The same cache, loading anything missing through another transport (another user's credentials). */\n withTransport(transport: Transport): Schema {\n return new Schema(transport, undefined, this.cache);\n }\n\n /** A complete schema from a metamodel document; nothing is ever fetched. */\n static fromMetamodel(metamodel: Metamodel): Schema {\n return new Schema(undefined, metamodel);\n }\n\n /** The type, null when the instance has none, undefined when not loaded yet. */\n assetType(token: AssetTypeToken): AssetType | null | undefined {\n return this.types.has(token) ? this.types.get(token)! : undefined;\n }\n\n /** An attribute by bare name; undefined when the type is not loaded, null when it has no such attribute. */\n attribute(type: AssetTypeToken, name: string): AttributeDefinition | null | undefined {\n return attributeOf(this, type, name);\n }\n\n /**\n * Can the type do this operation (Delete, Reactivate, …)? Undefined when\n * the type is not loaded or its definition carries no operations, so a\n * caller can tell \"no\" from \"don't know\".\n */\n canOperate(type: AssetTypeToken, op: string): boolean | undefined {\n const t = this.assetType(type);\n return t?.Operations ? t.Operations.includes(op) : undefined;\n }\n\n /** The tokens loaded so far. */\n get loaded(): AssetTypeToken[] {\n return [...this.types.entries()].filter(([, t]) => t !== null).map(([token]) => token);\n }\n\n /**\n * Load one type from meta.v1 (once; concurrent callers share the request).\n * A type the instance does not have resolves to null and is remembered;\n * any other failure (auth, network) is thrown, not swallowed.\n */\n async load(token: AssetTypeToken): Promise<AssetType | null> {\n if (this.types.has(token)) return this.types.get(token)!;\n const inFlight = this.loading.get(token);\n if (inFlight) return inFlight;\n if (!this.transport) { this.types.set(token, null); return null; }\n const request = meta.getAssetType(this.transport, token)\n .catch((error: unknown) => { if (error instanceof ApiError && error.status === 404) return null; throw error; })\n .then((type) => { this.types.set(token, type); return type; })\n .finally(() => this.loading.delete(token));\n this.loading.set(token, request);\n return request;\n }\n\n /**\n * Load whatever the queries in a batch need to have their rows translated:\n * the `from` types, then the types behind every relation hop and sub-select,\n * until nothing more is needed. Non-query commands are ignored.\n */\n async ensureFor(commands: readonly unknown[]): Promise<void> {\n for (const command of commands) {\n const query = queryOf(command);\n if (!query) continue;\n const type = fromTypeOf(query.from, commands);\n if (!type) continue;\n for (let round = 0; round < 32; round += 1) {\n const needed = [...typesNeeded(this, query, type)].filter((t) => !this.types.has(t));\n if (!needed.length) break;\n await Promise.all(needed.map((t) => this.load(t)));\n }\n }\n }\n}\n\n/** The query body of a command (bare or aliased), or null when it is not a query. */\nexport function queryOf(command: unknown): SelectShape | null {\n if (!command || typeof command !== \"object\") return null;\n const keys = Object.keys(command);\n const body = (keys.length === 1 && keys[0]!.startsWith(\"@\") ? (command as Record<string, unknown>)[keys[0]!] : command) as Record<string, unknown>;\n if (!body || typeof body !== \"object\" || typeof body.from !== \"string\") return null;\n if (\"update\" in body || \"execute\" in body || \"AssetType\" in body) return null;\n return body as unknown as SelectShape;\n}\n","/**\n * The loc-2.v1 wire module: localized labels for Agility's tags.\n *\n * Verified shapes (https://docs.digital.ai/agility-api/apis/loc-2-v1, and a\n * live instance 2026-11-04):\n * - The whole raw query string is the payload, parsed as LSON (lenient\n * JSON) — no name=value. An array in gives an object out, keyed by the\n * tags exactly as sent, duplicates collapsed; a scalar in gives a bare\n * string. This module only ever sends the array form.\n * - Tags hold tics (AttributeDefinition'Name'Story) and may hold spaces,\n * commas or `]`, which split a bare LSON token; a tag starting with a\n * tic reads as a quote. Every tag is therefore sent double-quoted —\n * JSON.stringify of the list is valid LSON, escapes and non-ASCII\n * included (round-tripped live).\n * - GET for a list that fits a URL; POST of the same payload, URL-encoded\n * as the body, for a long one. Identical results.\n * - Accept-Language picks the culture (only its first entry is read; a\n * neutral culture expands to its default specific one; absent or\n * unparseable means the invariant culture).\n * - No authentication: an Authorization header is ignored.\n * - A tag that matches nothing resolves to itself. There is no \"missing\"\n * and no error for it, so a typo is indistinguishable from an\n * untranslated tag; this module does not pretend otherwise.\n * - Errors are text/plain, not JSON (a 500 \"Server Error\" for an element\n * that is not a string, which the string[] signature rules out).\n */\nimport { ApiError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\n\n/** A tag-to-label map, keyed by each tag exactly as sent. */\nexport type Localizations = Record<string, string>;\n\nexport interface LocalizeOptions {\n /** Accept-Language for the request: \"fr-CA\", \"de\". Omitted: the server's invariant culture. */\n culture?: string;\n /**\n * The longest encoded payload sent as a GET; longer lists are POSTed.\n * Conservative by default: IIS rejects a query string past 2048\n * characters unless an instance raises the limit.\n */\n maxGetLength?: number;\n}\n\nexport const DEFAULT_MAX_GET_LENGTH = 2000;\n\n/** The payload as loc-2.v1 parses it: a JSON array of the tags, which is valid LSON. */\nexport const toLson = (tags: readonly string[]): string => JSON.stringify(tags);\n\n/**\n * Labels for a list of tags, in one request: a map keyed by each tag as\n * sent. An empty list asks nothing of the server and answers {}.\n */\nexport async function localize(transport: Transport, tags: readonly string[], options: LocalizeOptions = {}): Promise<Localizations> {\n const unique = [...new Set(tags)];\n if (!unique.length) return {};\n const encoded = encodeURIComponent(toLson(unique));\n const headers = options.culture ? { \"Accept-Language\": options.culture } : undefined;\n const result = encoded.length <= (options.maxGetLength ?? DEFAULT_MAX_GET_LENGTH)\n ? await transport.request<unknown>({ method: \"GET\", path: `/loc-2.v1?${encoded}`, headers, responseType: \"json\" })\n // A POST here is a read: safe to send again after a network failure or a 5xx.\n : await transport.request<unknown>({ method: \"POST\", path: \"/loc-2.v1\", headers, body: encoded, contentType: \"application/x-www-form-urlencoded\", responseType: \"json\", idempotent: true });\n if (!result || typeof result !== \"object\" || Array.isArray(result)) throw new ApiError(`loc-2.v1 answered an array of tags with ${JSON.stringify(result)?.slice(0, 100)}, not an object`, 200, \"BAD_RESPONSE\", result);\n return result as Localizations;\n}\n\n/** One tag's label. Sent in the array form like every other call, so parsing stays uniform. */\nexport async function localizeOne(transport: Transport, tag: string, options: LocalizeOptions = {}): Promise<string> {\n const map = await localize(transport, [tag], options);\n return map[tag] ?? tag;\n}\n","/**\n * The query.v1 wire module: reads only. The endpoint takes the same query\n * bodies as api/asset's query commands and answers with nothing but the\n * rows — an array with one array of rows per query, in request order — so\n * it is the simplest place to explore what a query does. api/asset can do\n * everything query.v1 does (and write); query.v1 can never write.\n *\n * Verified against the API-testing instance (2026-11-06):\n * - POST a query body, or an array of them (or YAML documents separated by\n * ---); the answer is [[row, …], …], [] for a query that matched nothing.\n * - rows are spelled exactly as api/asset spells them: every scalar a\n * string (\"2\", \"True\"), a relation { _oid }, a multi-value relation a\n * list, a sub-selected single relation a list. So they translate through\n * the same schema the same way.\n * - one bad query fails the whole request: 400 with rest-1's error shape,\n * { error: \"Bad Request\", exceptions: [{ type, message }, …] }, and no\n * rows at all. The useful text is in exceptions, not error.\n * - a filter literal with an em dash fails here too; a `with` variable\n * carrying the same value works.\n *\n * Because the endpoint cannot change anything, a request is sent idempotent:\n * the transport may retry it after a network failure or a 5xx like a GET.\n */\nimport { ApiError, UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Asset } from \"../types/asset\";\nimport { fromWireRow, type QueryBody, type ReadOptions, type RowContext } from \"./assetApi\";\nimport { fromTypeOf } from \"./select\";\n\n/** The error query.v1 sends for a query it refused: the exceptions' messages, joined. */\nfunction rejected(error: ApiError): ApiError {\n const details = error.details as { exceptions?: { message?: unknown }[] } | undefined;\n const messages = (details?.exceptions ?? []).map((e) => e?.message).filter((m): m is string => typeof m === \"string\" && !!m);\n return messages.length ? new ApiError(messages.join(\"; \"), error.status, \"QUERY_REJECTED\", error.details) : error;\n}\n\n/**\n * Several queries in one request; one array of rows per query, in order, []\n * where a query matched nothing. A page is required on every query. A\n * query the server refuses throws (an ApiError coded QUERY_REJECTED, with\n * the server's messages) — never an empty result.\n */\nexport async function queries<Row extends Asset = Asset>(transport: Transport, qs: QueryBody[], options: ReadOptions = {}): Promise<Row[][]> {\n for (const q of qs) if (!q.page) throw new UsageError(`query of ${q.from} without a page: every query.v1 read must be bounded`);\n if (!qs.length) return [];\n let response: unknown;\n try {\n response = await transport.request<unknown>({ method: \"POST\", path: \"/query.v1\", body: qs, responseType: \"json\", idempotent: true });\n } catch (error) {\n throw error instanceof ApiError && error.status === 400 ? rejected(error) : error;\n }\n if (!Array.isArray(response) || response.length !== qs.length || !response.every(Array.isArray)) {\n throw new ApiError(`query.v1 answered with ${Array.isArray(response) ? `${response.length} results` : \"no result list\"} for ${qs.length} queries`, 200, \"BAD_RESPONSE\", response);\n }\n return qs.map((q, i) => {\n const type = options.lookup ? fromTypeOf(q.from, qs) : null;\n const context: RowContext | undefined = type ? { lookup: options.lookup!, type } : undefined;\n return (response as Record<string, unknown>[][])[i]!.map((row) => fromWireRow<Row>(row, context));\n });\n}\n\n/** One query, its rows. */\nexport async function query<Row extends Asset = Asset>(transport: Transport, q: QueryBody, options: ReadOptions = {}): Promise<Row[]> {\n const [rows] = await queries<Row>(transport, [q], options);\n return rows ?? [];\n}\n","/**\n * The rest-1.v1 wire module: what the endpoint takes and returns, and the\n * translation into the model. rest-1 is the endpoint with the most\n * translation, which is exactly why none of it may leak past this file.\n *\n * Reads (all GET, JSON asked for by Accept):\n * /rest-1.v1/Data/<Type> a list; where, sel, find, findin, sort, page (size,start), deleted, needTotal, with, asof\n * (taken as a query's `filter`/`select`; `where`/`sel` are rest-1's spellings, translated here)\n * /rest-1.v1/Data/<Type>/<id> one asset\n * /rest-1.v1/Hist/<Type>[/<id>] history: the same shape, one row per moment, ids carrying the moment\n * /rest-1.v1/New/<Type>?ctx=<oid> a template: the asset the type's initializer would create in that\n * context (Core runs the type's IAssetInitializer with ctx as the\n * context OID — a Timebox gets the next sprint name, dates after the\n * schedule's last timebox, the schedule, a state and the owner; live\n * 2026-11-14). Same document shape, id \"\", every attribute with act \"set\".\n *\n * Two writes, kept narrow: rest-1 carries nothing api/asset does, except\n * POST /rest-1.v1/Data/<Type>/<id>?op=<Operation> the operation's RESULT, which api/asset drops:\n * Copy answers the new asset's id (Story:146979:194422), any other\n * operation the source at its new moment; an unknown operation is 400\n * \"Unknown Operation 'Story.NoSuchOp'\" (live 2026-11-14).\n *\n * What it returns, verified against a dev instance (2026-09-07):\n * { _type: \"Assets\"|\"History\", total?, pageSize, pageStart, Assets: [\n * { _type: \"Asset\", href, id: \"Story:2104\"|\"Story:2104:2797\", Attributes: {\n * Name: { _type: \"Attribute\", name, value }, scalar; multi-value as an array\n * Owners: { _type: \"Relation\", name, value: [{ _type: \"Asset\", href, idref }] } multi-value relation\n * Super: { _type: \"Relation\", name, value: { _type: \"Asset\", href, idref } | null } single relation\n * } } ] }\n * - `total` only with needTotal=true (else absent; -1 in some renderings).\n * - AssetState is the NUMBER (Core's AssetState enum); the model wants the name.\n * - a type-qualified sel (Story.Number on BaseAsset) arrives keyed by its plain name (Number).\n * - selecting a relation also brings its display columns (Owners.Name,\n * Owners.Nickname, Status.Name) uninvited; they are folded onto the Refs.\n * - a page is required by this module: no Data read is unbounded.\n */\nimport { ApiError, UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport { assetStateOf, type Asset, type Oid, type Ref } from \"../types/asset\";\nimport { momentless } from \"../types/oid\";\n\nexport { momentless };\n\n// ---- what the endpoint returns -------------------------------------------\n\nexport interface AssetRefDocument { _type: \"Asset\"; href: string; idref: Oid }\nexport interface AttributeDocument { _type: \"Attribute\"; name: string; value: unknown }\nexport interface RelationDocument { _type: \"Relation\"; name: string; value: AssetRefDocument | AssetRefDocument[] | null }\nexport interface AssetDocument { _type: \"Asset\"; href: string; id: string; Attributes?: Record<string, AttributeDocument | RelationDocument> }\nexport interface AssetsDocument { _type: \"Assets\" | \"History\"; total?: number; pageSize: number; pageStart: number; Assets: AssetDocument[] }\n\n// ---- what the endpoint takes ---------------------------------------------\n\nexport interface ReadParams {\n /** Attributes to select, as a query's `select`; a type-qualified name (Story.Number) reaches a subtype's attribute from a base type. */\n select?: string[];\n /** @deprecated rest-1's own spelling of `select`; kept for one alpha. */\n sel?: string[];\n /** Filter terms, as a query's `filter`, joined with ';' (AND). */\n filter?: string[];\n /** @deprecated rest-1's own spelling of `filter`; kept for one alpha. */\n where?: string[];\n /** The filter context: { $oids: [...] } — sent in rest-1's spelling, $name=a,b|$other=c. */\n with?: Record<string, string | string[]>;\n find?: string;\n findin?: string[];\n sort?: string[];\n /** Required. size first, then start. */\n page: { size: number; start: number };\n deleted?: boolean;\n needTotal?: boolean;\n asof?: string;\n}\n\n// ---- translation -----------------------------------------------------------\n\n\nconst toRef = (doc: AssetRefDocument): Ref => ({ _oid: momentless(doc.idref) });\n\n/**\n * One rest-1 asset as the model carries it. Relations become Refs; the\n * display columns rest-1 adds beside a selected relation (Owners.Name) are\n * folded onto those Refs by position, and kept under their dotted key too\n * for a caller that asked for them by name; AssetState becomes its name;\n * everything else is the value as sent. The row's own _oid keeps its\n * moment only on a history read (it is the moment that identifies the row).\n */\nexport function fromAssetDocument<Row extends Asset = Asset>(doc: AssetDocument, { history = false } = {}): Row {\n const out: Record<string, unknown> = { _oid: history ? doc.id : momentless(doc.id) };\n const attrs = doc.Attributes ?? {};\n for (const [key, a] of Object.entries(attrs)) {\n if (a._type === \"Relation\") {\n out[key] = Array.isArray(a.value) ? a.value.map(toRef) : a.value ? toRef(a.value) : null;\n } else if (key === \"AssetState\" && typeof a.value === \"number\") {\n out[key] = assetStateOf(a.value);\n } else {\n out[key] = a.value;\n }\n }\n // Fold \"Rel.Attr\" columns onto the Ref(s) of a selected relation.\n for (const [key, a] of Object.entries(attrs)) {\n const dot = key.indexOf(\".\");\n if (dot < 0 || a._type !== \"Attribute\") continue;\n const rel = key.slice(0, dot), attr = key.slice(dot + 1);\n if (attr.includes(\".\")) continue; // deeper paths stay as columns only\n const target = out[rel];\n const values = a.value;\n if (Array.isArray(target) && Array.isArray(values)) target.forEach((ref, i) => { if (ref && typeof ref === \"object\") (ref as Record<string, unknown>)[attr] = values[i]; });\n else if (target && typeof target === \"object\" && !Array.isArray(target) && !Array.isArray(a.value)) (target as Record<string, unknown>)[attr] = a.value;\n }\n return out as Row;\n}\n\n/** The query string rest-1 wants, from the model's parameters. */\nexport function toQuery(params: ReadParams): Record<string, string | undefined> {\n return {\n sel: (params.select ?? params.sel)?.join(\",\"),\n where: (params.filter ?? params.where)?.length ? (params.filter ?? params.where)!.join(\";\") : undefined,\n with: params.with ? Object.entries(params.with).map(([k, v]) => `${k}=${[].concat(v as never).join(\",\")}`).join(\"|\") : undefined,\n find: params.find,\n findin: params.findin?.join(\",\"),\n sort: params.sort?.join(\",\"),\n page: `${params.page.size},${params.page.start}`,\n deleted: params.deleted === undefined ? undefined : String(params.deleted),\n needTotal: params.needTotal === undefined ? undefined : String(params.needTotal),\n asof: params.asof\n };\n}\n\n// ---- the calls -------------------------------------------------------------\n\nexport interface ReadResult<Row extends Asset = Asset> { rows: Row[]; total: number | null; pageSize: number; pageStart: number }\n\nasync function read<Row extends Asset>(transport: Transport, path: string, params: ReadParams, history: boolean): Promise<ReadResult<Row>> {\n if (!params.page) throw new UsageError(`rest-1 read of ${path} without a page: every read must be bounded`);\n const doc = await transport.request<AssetsDocument>({ method: \"GET\", path, query: toQuery(params), responseType: \"json\" });\n return { rows: (doc.Assets ?? []).map((a) => fromAssetDocument<Row>(a, { history })), total: typeof doc.total === \"number\" && doc.total >= 0 ? doc.total : null, pageSize: doc.pageSize, pageStart: doc.pageStart };\n}\n\n/** A bounded list read of a type. */\nexport const list = <Row extends Asset = Asset>(transport: Transport, type: string, params: ReadParams): Promise<ReadResult<Row>> =>\n read<Row>(transport, `/rest-1.v1/Data/${encodeURIComponent(type)}`, params, false);\n\n/** One asset by OID. */\nexport async function get<Row extends Asset = Asset>(transport: Transport, oid: Oid, select?: string[]): Promise<Row> {\n const [type, id] = momentless(oid).split(\":\");\n const doc = await transport.request<AssetDocument>({ method: \"GET\", path: `/rest-1.v1/Data/${encodeURIComponent(type!)}/${encodeURIComponent(id!)}`, query: { sel: select?.join(\",\") }, responseType: \"json\" });\n return fromAssetDocument<Row>(doc);\n}\n\n/**\n * What an operation answered with: the asset the server returned, as an\n * OID token — for Copy the copy, for anything else the operated asset —\n * and the moment the server stamped on it.\n */\nexport interface OperationResult { oid: Oid; moment: string | null }\n\n/**\n * Run an operation (Copy, Inactivate, …) through rest-1, for its result.\n * api/asset's `execute` performs the same operations but reports only the\n * operated asset, so a Copy's new OID is unobservable there; rest-1 answers\n * it. Not idempotent: never retried.\n */\nexport async function operate(transport: Transport, oid: Oid, op: string): Promise<OperationResult> {\n const [type, id] = momentless(oid).split(\":\");\n if (!type || !id) throw new UsageError(`\"${oid}\" is not an OID token (Story:1234)`);\n const doc = await transport.request<AssetDocument>({ method: \"POST\", path: `/rest-1.v1/Data/${encodeURIComponent(type)}/${encodeURIComponent(id)}`, query: { op }, responseType: \"json\" });\n if (!doc || typeof doc.id !== \"string\" || !doc.id) throw new ApiError(`rest-1 ${op} on ${oid} did not answer with an asset`, 200, \"BAD_RESPONSE\", doc);\n const moment = doc.id.split(\":\")[2] ?? null;\n return { oid: momentless(doc.id), moment };\n}\n\n/** A new asset's template as the model carries it: the attributes the initializer set, no `_oid`. */\nexport type Template<Row extends Asset = Asset> = Partial<Omit<Row, \"_oid\">>;\n\n/**\n * The template for a new asset of `type` in a context (a Scope, a parent\n * asset): what the server's initializer would fill in — defaults nothing\n * else exposes. Idempotent, like any GET. Without a context the template\n * is empty, and an unknown context is echoed back, not refused.\n */\nexport async function template<Row extends Asset = Asset>(transport: Transport, type: string, options: { ctx?: Oid } = {}): Promise<Template<Row>> {\n const doc = await transport.request<AssetDocument>({ method: \"GET\", path: `/rest-1.v1/New/${encodeURIComponent(type)}`, query: { ctx: options.ctx ? momentless(options.ctx) : undefined }, responseType: \"json\" });\n const { _oid: _ignored, ...values } = fromAssetDocument<Row>({ ...doc, id: doc.id || `${type}:0` });\n return values as Template<Row>;\n}\n\n/** A bounded history read: one row per moment, _oid carrying the moment. */\nexport const history = <Row extends Asset = Asset>(transport: Transport, target: string, params: ReadParams): Promise<ReadResult<Row>> => {\n const [type, id] = target.split(\":\");\n const path = id ? `/rest-1.v1/Hist/${encodeURIComponent(type!)}/${encodeURIComponent(id)}` : `/rest-1.v1/Hist/${encodeURIComponent(type!)}`;\n return read<Row>(transport, path, params, true);\n};\n","import type { ClientConfig } from \"./core/clientConfig\";\nimport { ApiError, UsageError } from \"./core/errors\";\nimport { createFetchTransport } from \"./core/fetchTransport\";\nimport type { Transport } from \"./core/transport\";\nimport * as attachments from \"./services/attachments\";\nimport * as batch from \"./services/batch\";\nimport * as fieldsService from \"./services/fields\";\nimport * as guard from \"./services/guard\";\nimport * as resolve from \"./services/resolve\";\nimport { Schema, type TypeCache } from \"./services/schema\";\nimport type { Asset, Oid } from \"./types/asset\";\nimport type { Member } from \"./types/assets/Member\";\nimport type { Metamodel } from \"./types/metamodel\";\nimport type { From, RowOf, RowsOf, Selected, SelectPath, TypeOf } from \"./types/query\";\nimport { isOidToken, momentless } from \"./types/oid\";\nimport { isAssetNumber } from \"./services/resolve\";\nimport * as assetApi from \"./wire/assetApi\";\nimport * as attachment from \"./wire/attachment\";\nimport * as fields from \"./wire/fields\";\nimport * as loc2 from \"./wire/loc2\";\nimport * as meta from \"./wire/meta\";\nimport * as queryV1 from \"./wire/queryV1\";\nimport * as rest1 from \"./wire/rest1\";\n\nexport interface ClientOptions {\n /** Bring your own transport (a fake in tests, an instrumented one in an app). */\n transport?: Transport;\n /**\n * Seed the schema so no type is fetched: a metamodel document as\n * meta.getMetamodel returns it, or the committed metamodel.json run\n * through meta.toMetamodel. Without it, types are loaded from meta.v1 as\n * queries first touch them.\n */\n metamodel?: Metamodel;\n /** Share an existing schema (and its cache) instead of starting a new one. */\n schema?: Schema;\n /**\n * Share loaded type definitions with other clients of the same instance,\n * whatever their credentials: this client's schema keeps its types in\n * `types` and loads anything missing through this client's transport.\n * A server that builds a client per user keeps one TypeCache per instance.\n */\n types?: TypeCache;\n}\n\n/** One page of rows, with the total number of matches when the server reports it, and whether more pages follow. */\nexport interface Page<Row extends Asset = Asset> { rows: Row[]; total: number | null; more: boolean }\n\nexport interface PagesOptions {\n /**\n * The most rows to read across all pages: the iteration stops there, and\n * the last page is cut to fit. Default 1000. Every read is bounded; a\n * caller that truly wants everything says how many that is.\n */\n limit?: number;\n}\n\n/** What `me` answers: the member the credentials belong to. */\nexport type Me = Pick<Member, \"_oid\" | \"Name\" | \"Username\" | \"Nickname\" | \"Email\">;\n\nconst DEFAULT_LIMIT = 1000;\nconst ME_SELECT = [\"Name\", \"Username\", \"Nickname\", \"Email\"];\n\n/**\n * The client: one transport, one schema, and the wire modules bound to\n * them. Every read goes through the schema so its rows arrive in the\n * model's shape (numbers as numbers, a single relation as one Ref), and\n * every write answers in the model's terms (an Outcome, never an envelope).\n *\n * Reads: `query`, `queries`, `get`, `queryPage`, `pages`, `all`, `me`. A\n * query body is the same everywhere; the client picks the endpoint.\n * query.v1 answers rows alone — the lightest response, and read-only by\n * construction, so a request can be resent like a GET — but its shape has\n * nowhere to put a total; api/asset reports one (`needTotal`) beside the\n * rows, which is why `queryPage` goes there and `query` does not. rest-1\n * sits behind `data` for what neither does: deleted assets, history, a\n * new asset's template, an operation's result. Writes: `assets.send`,\n * `assets.sendGuarded`, `batch.run`, `copy`. Services: `resolve`,\n * `fields`, `attachments`, `embeddedImages`, `schema`, `localize`, `urls`.\n */\nexport class AgilityApiClient {\n readonly transport: Transport;\n readonly schema: Schema;\n\n constructor(config: ClientConfig, options: ClientOptions | Transport = {}) {\n // A bare Transport as the second argument is the older spelling; keep it working.\n const opts: ClientOptions = \"request\" in options ? { transport: options } : options;\n this.transport = opts.transport ?? createFetchTransport({\n baseUrl: config.baseUrl,\n authorization: config.authorization,\n accessToken: config.accessToken,\n timeoutMs: config.timeoutMs,\n retries: config.retries,\n defaultHeaders: config.defaultHeaders,\n credentials: config.credentials,\n onUnauthorized: config.onUnauthorized,\n unauthorizedStatuses: config.unauthorizedStatuses\n });\n this.config = config;\n this.schema = opts.schema ?? new Schema(this.transport, opts.metamodel, opts.types);\n }\n\n private readonly config: ClientConfig;\n\n /**\n * The same client, with every request it sends tied to `signal`: abort it\n * (on navigation, say) and in-flight requests end with an ApiError coded\n * ABORTED. The schema and its cache are shared; a type load that other\n * callers are waiting on is not cancelled.\n */\n withSignal(signal: AbortSignal): AgilityApiClient {\n const base = this.transport;\n const transport: Transport = { request: (options) => base.request({ ...options, signal: options.signal ?? signal }) };\n return new AgilityApiClient(this.config, { transport, schema: this.schema });\n }\n\n // ---- reads ------------------------------------------------------------------\n\n /**\n * One query, its rows, translated. Sent to query.v1: it cannot write, so\n * the request is marked idempotent and the transport may resend it after\n * a network failure or a 5xx — when `retries` is set above its default\n * of 0. A page is required; a query the server refuses throws an\n * ApiError (kind \"invalid\", code QUERY_REJECTED; `message` holds the\n * server's sentences, `details` its whole error document), never an\n * empty result.\n */\n query<const F extends From, const Q extends assetApi.QueryBody<F>>(q: Q & assetApi.QueryBody<F>): Promise<RowOf<Q>[]>;\n query<Row extends Asset = Asset>(q: assetApi.QueryBody): Promise<Row[]>;\n async query(q: assetApi.QueryBody): Promise<Asset[]> {\n await this.schema.ensureFor([q]);\n return queryV1.query(this.transport, q, { lookup: this.schema });\n }\n\n /** Several queries in one request; one array of rows per query, in order. */\n queries<const Qs extends readonly assetApi.QueryBody[]>(qs: Qs): Promise<RowsOf<Qs>>;\n queries<Row extends Asset = Asset>(qs: assetApi.QueryBody[]): Promise<Row[][]>;\n async queries(qs: readonly assetApi.QueryBody[]): Promise<Asset[][]> {\n await this.schema.ensureFor(qs);\n return queryV1.queries(this.transport, [...qs], { lookup: this.schema });\n }\n\n /**\n * One asset by OID token, with the attributes selected, or null when no\n * asset has that OID. (`select` omitted: just the OID, which tells you it\n * exists.)\n */\n get<const O extends string, const S extends readonly (SelectPath<TypeOf<O>> | assetApi.QueryBody)[]>(oid: O, select: S): Promise<Selected<TypeOf<O>, S> | null>;\n get<Row extends Asset = Asset>(oid: Oid, select?: assetApi.QueryBody[\"select\"]): Promise<Row | null>;\n async get(oid: Oid, select?: assetApi.QueryBody[\"select\"]): Promise<Asset | null> {\n const rows = await this.query({ from: momentless(oid), ...(select ? { select } : {}), page: { size: 1, start: 0 } });\n return rows[0] ?? null;\n }\n\n /**\n * One page with its total: api/asset reports the number of matches when\n * asked (query.v1 does not), so this read goes there. `total` is null\n * when the server did not say; `more` is then whether the page was full.\n */\n queryPage<const F extends From, const Q extends assetApi.QueryBody<F>>(q: Q & assetApi.QueryBody<F>): Promise<Page<RowOf<Q>>>;\n queryPage<Row extends Asset = Asset>(q: assetApi.QueryBody): Promise<Page<Row>>;\n async queryPage(q: assetApi.QueryBody): Promise<Page> {\n await this.schema.ensureFor([q]);\n return assetApi.queryPage(this.transport, q, { lookup: this.schema });\n }\n\n /**\n * The query page by page, as an async iterator, up to `limit` rows in\n * all (default 1000): `page.start` advances by `page.size` from where the\n * query starts, and the iteration ends at a short page or at the limit.\n * Each page is a plain read on query.v1, so a long walk survives a\n * transient failure like any GET.\n */\n pages<const F extends From, const Q extends assetApi.QueryBody<F>>(q: Q & assetApi.QueryBody<F>, options?: PagesOptions): AsyncGenerator<RowOf<Q>[], void, undefined>;\n pages<Row extends Asset = Asset>(q: assetApi.QueryBody, options?: PagesOptions): AsyncGenerator<Row[], void, undefined>;\n async *pages(q: assetApi.QueryBody, options: PagesOptions = {}): AsyncGenerator<Asset[], void, undefined> {\n if (!q.page) throw new UsageError(`query of ${q.from} without a page: every read must be bounded`);\n const limit = options.limit ?? DEFAULT_LIMIT;\n const size = q.page.size;\n let start = q.page.start, read = 0;\n while (read < limit) {\n const want = Math.min(size, limit - read);\n const rows = await this.query({ ...q, page: { size: want, start } });\n if (rows.length) yield rows;\n read += rows.length;\n start += rows.length;\n if (rows.length < want) return;\n }\n }\n\n /** Every row of the query up to `limit` (default 1000), read page by page. */\n all<const F extends From, const Q extends assetApi.QueryBody<F>>(q: Q & assetApi.QueryBody<F>, options?: PagesOptions): Promise<RowOf<Q>[]>;\n all<Row extends Asset = Asset>(q: assetApi.QueryBody, options?: PagesOptions): Promise<Row[]>;\n async all(q: assetApi.QueryBody, options: PagesOptions = {}): Promise<Asset[]> {\n const out: Asset[] = [];\n for await (const page of this.pages(q, options)) out.push(...page);\n return out;\n }\n\n /** The member these credentials belong to (Member.IsSelf, live 2026-11-12): what a comment's Author is. */\n async me(): Promise<Me> {\n const [row] = await this.query<Me>({ from: \"Member\", select: ME_SELECT, filter: [\"IsSelf='true'\"], page: { size: 1, start: 0 } });\n if (!row) throw new ApiError(\"the server knows no member for these credentials\", 0, \"NOT_FOUND\");\n return row;\n }\n\n // ---- the endpoints behind the reads -----------------------------------------------\n\n /** meta.v1: the instance's schema, raw. (The translated, cached view is `schema`.) */\n readonly meta = {\n metamodel: () => meta.getMetamodel(this.transport),\n assetType: (token: string) => meta.getAssetType(this.transport, token),\n attributeDefinition: (tokenref: `${string}.${string}`) => meta.getAttributeDefinition(this.transport, tokenref)\n };\n\n /**\n * loc-2.v1: labels for tags, in one request (meta's DisplayName values are\n * tags, and so is a violation's `tag`). An unmatched tag comes back as\n * itself; the server never says \"missing\", so neither does this.\n */\n localize(tags: readonly string[], options?: loc2.LocalizeOptions): Promise<loc2.Localizations> {\n return loc2.localize(this.transport, tags, options);\n }\n\n /**\n * rest-1.v1, for what the other endpoints cannot do: deleted assets\n * (`deleted: true`), one asset by OID without a page, history (one row\n * per moment), a new asset's template (`template`: what the type's\n * initializer fills in for a context — a Timebox's next name and dates,\n * a Story's carry-over from a Request), and an operation's result\n * (`operate`: api/asset performs a Copy but never says what it made;\n * rest-1 answers the new OID). Parameters are spelled as a query's\n * (`select`, `filter`).\n */\n readonly data = {\n list: <Row extends Asset = Asset>(type: string, params: rest1.ReadParams) => rest1.list<Row>(this.transport, type, params),\n get: <Row extends Asset = Asset>(oid: string, select?: string[]) => rest1.get<Row>(this.transport, oid, select),\n history: <Row extends Asset = Asset>(target: string, params: rest1.ReadParams) => rest1.history<Row>(this.transport, target, params),\n template: <F extends From>(type: F, options?: { ctx?: Oid }) => rest1.template<TypeOf<F>>(this.transport, type, options),\n operate: (oid: Oid, op: string) => rest1.operate(this.transport, oid, op)\n };\n\n /** Copy an asset (the server's Copy operation) and answer the copy's OID: the one thing api/asset's `execute: \"Copy\"` does not say. */\n async copy(oid: Oid): Promise<Oid> {\n return (await rest1.operate(this.transport, oid, \"Copy\")).oid;\n }\n\n /**\n * What a form needs for an asset type in a scope: the attributes the\n * server requires to create one (meta), the ones the product shows there\n * (api/visibleFields, custom fields included once configured), and the\n * scope's scheme's important fields and whether they are enforced at\n * close. `visible` alone answers for several types and scopes at once.\n */\n readonly fields = {\n describe: (type: From, scope: Oid) => fieldsService.describe(this.transport, this.schema, type, scope),\n visible: (types: readonly From[], scopes: readonly Oid[]) => fields.visibleFields(this.transport, types, scopes),\n visibleByAsset: (oid: Oid) => fields.visibleFieldsByAsset(this.transport, oid)\n };\n\n /** @deprecated since 1.0.0-alpha.3: use `client.query` / `client.queries` (the same endpoint, query.v1; only the name moved). Removed in 1.0.0. */\n readonly queryV1 = {\n query: <Row extends Asset = Asset>(q: assetApi.QueryBody) => this.query<Row>(q),\n queries: <Row extends Asset = Asset>(qs: assetApi.QueryBody[]) => this.queries<Row>(qs)\n };\n\n // ---- writes -----------------------------------------------------------------------\n\n /** api/asset: batches, answered in the model's terms. */\n readonly assets = {\n /**\n * Send a batch. The Outcome says what it did — created, modified and\n * operated OIDs, failures by index (each with its parsed violation),\n * query rows per query command — and never the envelope. api/asset\n * commits per command and answers 200 either way, so a failed command\n * is in `failures`, or thrown as a CommandFailureError with\n * `throwOnFailure` (the error carries the same Outcome).\n */\n send: async <Row extends Asset = Asset>(commands: assetApi.Command[], options?: Omit<assetApi.SendOptions, \"lookup\" | \"previewOnly\">): Promise<assetApi.Outcome<Row>> => {\n await this.schema.ensureFor(commands);\n return assetApi.outcomeOf(await assetApi.send<Row>(this.transport, commands, { ...options, lookup: this.schema }));\n },\n /** The server's projection of a batch: one command per asset it would touch, nothing applied. */\n preview: (commands: assetApi.Command[]) => assetApi.preview(this.transport, commands),\n /**\n * Send as a compare-and-set: each asset is changed only if nobody has\n * changed it since the preview read it; the rest come back `skipped`.\n * Throws UnguardableError, before any request, for shapes it cannot\n * cover.\n */\n sendGuarded: async <Row extends Asset = Asset>(commands: assetApi.Command[], options?: Pick<assetApi.SendOptions, \"throwOnFailure\">) => {\n await this.schema.ensureFor(commands);\n return guard.sendGuarded<Row>(this.transport, commands, { ...options, lookup: this.schema });\n },\n /** @deprecated since 1.0.0-alpha.3: use `client.query` (rows, through query.v1) or `client.queryPage` (rows and a total, through api/asset as this does). Removed in 1.0.0. */\n query: async <Row extends Asset = Asset>(q: assetApi.QueryBody) => {\n await this.schema.ensureFor([q]);\n return assetApi.query<Row>(this.transport, q, { lookup: this.schema });\n },\n /** @deprecated since 1.0.0-alpha.3: use `client.queries`. Removed in 1.0.0. */\n queries: async <Row extends Asset = Asset>(qs: assetApi.QueryBody[]) => {\n await this.schema.ensureFor(qs);\n return assetApi.queries<Row>(this.transport, qs, { lookup: this.schema });\n }\n };\n\n /**\n * Services: what a person types, turned into assets. Numbers resolve in\n * one api/asset request across every number root; an OID token is taken\n * as is.\n */\n readonly resolve = {\n numbers: (numbers: readonly string[]) => resolve.resolveNumbers(this.transport, numbers, { types: this.schema.cache }),\n ref: (spec: string) => resolve.resolveRef(this.transport, spec, { types: this.schema.cache })\n };\n\n /**\n * A batch with a record: preview, snapshot what it overwrites, (confirm,)\n * send guarded, and a receipt with created/touched/skipped assets and a\n * reverse batch. `reversible` drops from a receipt's reverse the assets\n * changed since, unless forced.\n */\n readonly batch = {\n run: (commands: assetApi.Command[], options?: batch.BatchOptions) => batch.runBatch(this.transport, this.schema, commands, options),\n reversible: (receipt: Pick<batch.Receipt, \"reverse\" | \"after\">, options?: { force?: boolean }) => batch.reversible(this.transport, receipt, options)\n };\n\n /**\n * The files attached to assets: metadata on Attachment assets, bytes\n * through attachment.img. `add` sends a small file inline (one request)\n * and a large one in two steps.\n */\n readonly attachments = {\n list: (asset: string, options?: { page?: { size: number; start: number } }) => attachments.list(this.transport, asset, options),\n page: (asset: string, options?: { page?: { size: number; start: number } }) => attachments.page(this.transport, asset, options),\n info: (id: string | number) => attachments.info(this.transport, id),\n get: (id: string | number) => attachments.get(this.transport, id),\n add: (asset: string, data: attachment.Bytes, options: attachments.AddOptions) => attachments.add(this.transport, asset, data, options),\n put: (id: string | number, data: attachment.Bytes, contentType?: string) => attachments.put(this.transport, id, data, contentType),\n remove: (id: string | number) => attachments.remove(this.transport, id),\n /** @deprecated since 1.0.0-alpha.3: `client.urls.attachment`. Removed in 1.0.0. */\n url: (id: string | number) => this.urls.attachment(id)\n };\n\n /**\n * Images embedded in an asset's rich text (Description and other long\n * text). `upload` returns the URL to put in an <img src>; `normalize`\n * rewrites every embedded.img reference in some HTML to this instance's\n * absolute URL, as Agility's own editor stores it. They cannot be deleted.\n */\n readonly embeddedImages = {\n upload: (asset: string, data: attachment.Bytes, options?: { filename?: string; contentType?: string }) => attachment.uploadEmbeddedImage(this.transport, asset, data, options),\n /** @deprecated since 1.0.0-alpha.3: `client.urls.embeddedImage`. Removed in 1.0.0. */\n url: (id: string | number) => this.urls.embeddedImage(id),\n normalize: (html: string) => attachment.normalizeEmbeddedImageUrls(html, this.config.baseUrl)\n };\n\n /** Where a browser opens things on this instance: an asset's page, an attachment's bytes, an embedded image. */\n readonly urls = {\n /**\n * The asset's page, from an OID token or an asset Number (S-01001,\n * what a person typed and what a message shows): assetdetail.v1\n * resolves either and redirects to the type's own detail page; a signed-\n * out reader lands there after logging in. Anything else is a UsageError.\n */\n asset: (ref: Oid | string) => {\n const base = this.config.baseUrl.replace(/\\/+$/, \"\");\n const text = ref.trim();\n if (isOidToken(text)) return `${base}/assetdetail.v1?oid=${momentless(text)}`;\n if (isAssetNumber(text)) return `${base}/assetdetail.v1?Number=${encodeURIComponent(text)}`;\n throw new UsageError(`\"${ref}\" is neither an OID token (Story:1234) nor an asset number (S-1234)`);\n },\n attachment: (id: string | number) => attachment.attachmentUrl(this.config.baseUrl, id),\n embeddedImage: (id: string | number) => attachment.embeddedImageUrl(this.config.baseUrl, id)\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACoBO,SAAS,OAAO,QAAgB,MAA0B;AAC/D,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAW,aAAO;AAAA,IACvB,KAAK;AAAA,IACL,KAAK;AAAiB,aAAO;AAAA,IAC7B,KAAK;AAAA,IACL,KAAK;AAAgB,aAAO;AAAA,IAC5B,KAAK;AAAS,aAAO;AAAA,IACrB,KAAK;AAAkB,aAAO;AAAA,IAC9B,KAAK;AAAA,IACL,KAAK;AAAa,aAAO;AAAA,IACzB,KAAK;AAAa,aAAO;AAAA,EAC3B;AACA,MAAI,WAAW,IAAK,QAAO;AAC3B,MAAI,WAAW,IAAK,QAAO;AAC3B,MAAI,WAAW,IAAK,QAAO;AAC3B,MAAI,WAAW,OAAO,WAAW,OAAO,UAAU,IAAK,QAAO;AAC9D,MAAI,UAAU,IAAK,QAAO;AAC1B,SAAO;AACT;AAEA,IAAM,UAAU,CAAC,YAA+B,WAAW,OAAO,YAAY,YAAY,WAAW,UAAW,QAA+B,QAAQ;AAEhJ,IAAM,WAAN,cAAuB,MAAM;AAAA;AAAA,EAEzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAiB,QAAgB,MAAe,SAAmB,OAAkB,OAAO,QAAQ,IAAI,GAAG;AACrH,UAAM,QAAQ,QAAQ,OAAO;AAC7B,UAAM,SAAS,UAAU,SAAY,SAAY,EAAE,MAAM,CAAC;AAC1D,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,SAAK,UAAU;AACf,SAAK,OAAO;AAAA,EACd;AACF;AAQO,IAAM,aAAN,cAAyB,SAAS;AAAA,EACvC,YAAY,SAAiB,SAAmB;AAC9C,UAAM,SAAS,GAAG,SAAS,SAAS,OAAO;AAC3C,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,eAAN,cAA2B,SAAS;AAAA,EACzC,YAAY,SAAiB,MAAc,OAAgB,SAAmC;AAC5F,UAAM,QAAQ,iBAAiB,WAAW,QAAQ;AAClD,UAAM,SAAS,OAAO,UAAU,GAAG,MAAM,EAAE,GAAG,SAAS,MAAM,GAAG,OAAO,QAAQ,SAAS;AACxF,SAAK,OAAO;AAAA,EACd;AACF;;;ACnBA,SAAS,aAAa,QAA+B;AACnD,SAAO,IAAI,SAAS,mBAAmB,GAAG,WAAW,EAAE,OAAO,OAAO,OAAO,CAAC;AAC/E;AAEA,SAAS,SAAS,SAAiB,MAAcC,QAAyC;AACxF,QAAM,iBAAiB,QAAQ,SAAS,GAAG,IAAI,UAAU,GAAG,OAAO;AACnE,QAAM,iBAAiB,KAAK,WAAW,GAAG,IAAI,KAAK,MAAM,CAAC,IAAI;AAC9D,QAAM,MAAM,IAAI,IAAI,gBAAgB,cAAc;AAClD,MAAIA,QAAO;AACT,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQA,MAAK,GAAG;AAChD,UAAI,UAAU,UAAa,UAAU,KAAM,KAAI,aAAa,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IACpF;AAAA,EACF;AACA,SAAO,IAAI,SAAS;AACtB;AAGA,SAAS,WAAW,MAA+B,aAA4E;AAC7H,MAAI,SAAS,OAAW,QAAO,CAAC;AAChC,MAAI,OAAO,SAAS,SAAU,QAAO,EAAE,MAAM,aAAa,eAAe,aAAa;AACtF,MAAI,gBAAgB,cAAc,gBAAgB,aAAa;AAC7D,WAAO,EAAE,MAAwB,aAAa,eAAe,2BAA2B;AAAA,EAC1F;AAEA,MAAI,OAAO,aAAa,eAAe,gBAAgB,SAAU,QAAO,EAAE,KAAK;AAE/E,MAAI,OAAO,SAAS,eAAe,gBAAgB,KAAM,QAAO,EAAE,MAAM,aAAa,gBAAgB,KAAK,QAAQ,4BAA4B;AAC9I,SAAO,EAAE,MAAM,KAAK,UAAU,IAAI,GAAG,aAAa,eAAe,mBAAmB;AACtF;AAEA,eAAe,SAAS,UAAoB,cAA8C;AACxF,MAAI,iBAAiB,QAAS,QAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;AAChF,MAAI,iBAAiB,OAAQ,QAAO,SAAS,KAAK;AAClD,QAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,MAAI,iBAAiB,UAAU,YAAY,SAAS,MAAM,GAAG;AAC3D,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,KAAM,QAAO;AAClB,QAAI;AACF,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,QAAQ;AACN,UAAI,iBAAiB,OAAQ,OAAM,IAAI,SAAS,wBAAwB,SAAS,QAAQ,YAAY,EAAE,MAAM,KAAK,MAAM,GAAG,GAAG,EAAE,CAAC;AACjI,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO,SAAS,KAAK;AACvB;AASA,SAAS,UAAU,MAAe,QAAwB;AACxD,MAAI,QAAQ,OAAO,SAAS,UAAU;AACpC,UAAM,IAAI;AACV,UAAM,QAAQ,MAAM,QAAQ,EAAE,UAAU,KAAK,EAAE,WAAW,CAAC,KAAK,OAAO,EAAE,WAAW,CAAC,MAAM,WAAY,EAAE,WAAW,CAAC,EAA8B,UAAU;AAC7J,UAAM,SAAS,MAAM,QAAQ,EAAE,UAAU,IAAI,EAAE,WAAW,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AAChI,eAAW,aAAa,CAAC,EAAE,OAAO,OAAO,QAAQ,EAAE,OAAO,GAAG;AAC3D,UAAI,OAAO,cAAc,YAAY,UAAW,QAAO;AAAA,IACzD;AAAA,EACF;AACA,MAAI,OAAO,SAAS,YAAY,KAAK,KAAK,EAAG,QAAO,KAAK,KAAK,EAAE,MAAM,GAAG,GAAG;AAC5E,SAAO,QAAQ,MAAM;AACvB;AAEA,IAAM,QAAQ,CAAC,OAA8B,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAEtF,SAAS,qBAAqB,QAAyC;AAC5E,QAAM,YAAY,OAAO,aAAa;AACtC,QAAM,YAAY,OAAO,aAAa;AACtC,QAAM,UAAU,KAAK,IAAI,GAAG,OAAO,WAAW,CAAC;AAC/C,QAAM,gBAAgB,OAAO,kBAAkB,OAAO,cAAc,UAAU,OAAO,WAAW,KAAK;AACrG,QAAM,uBAAuB,OAAO,wBAAwB,CAAC,GAAG;AAEhE,SAAO;AAAA,IACL,MAAM,QAAW,SAAqC;AACpD,YAAM,MAAM,SAAS,OAAO,SAAS,QAAQ,MAAM,QAAQ,KAAK;AAChE,YAAM,EAAE,MAAM,YAAY,IAAI,WAAW,QAAQ,MAAM,QAAQ,WAAW;AAC1E,YAAM,UAAkC,EAAE,QAAQ,oBAAoB,GAAG,OAAO,gBAAgB,GAAG,QAAQ,QAAQ;AAEnH,UAAI,YAAa,SAAQ,cAAc,IAAI;AAC3C,UAAI,cAAe,SAAQ,gBAAgB;AAC3C,YAAM,eAA6B,QAAQ,gBAAgB;AAC3D,YAAM,aAAa,QAAQ,cAAc,QAAQ,WAAW;AAC5D,YAAM,WAAW,aAAa,UAAU,IAAI;AAE5C,YAAM,eAAe,QAAQ;AAE7B,UAAI;AACJ,UAAI,eAAe;AACnB,eAAS,UAAU,GAAG,UAAU,UAAU,WAAW,GAAG;AACtD,YAAI,cAAc,QAAS,OAAM,aAAa,YAAY;AAC1D,cAAM,aAAa,IAAI,gBAAgB;AACvC,cAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS;AAChE,cAAM,UAAU,MAAM,WAAW,MAAM;AACvC,sBAAc,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAC/D,cAAM,SAAS,MAAM;AACnB,uBAAa,SAAS;AACtB,wBAAc,oBAAoB,SAAS,OAAO;AAAA,QACpD;AACA,YAAI;AACJ,YAAI;AACF,gBAAM,OAAoB,EAAE,QAAQ,QAAQ,QAAQ,SAAS,MAAM,QAAQ,WAAW,OAAO;AAC7F,cAAI,OAAO,YAAa,MAAK,cAAc,OAAO;AAClD,qBAAW,MAAM,UAAU,KAAK,IAAI;AAAA,QACtC,SAAS,OAAO;AACd,iBAAO;AAEP,cAAI,cAAc,QAAS,OAAM,aAAa,YAAY;AAE1D,sBAAY,iBAAiB,SAAS,MAAM,SAAS,eACjD,IAAI,SAAS,mBAAmB,SAAS,OAAO,GAAG,WAAW,EAAE,OAAO,MAAM,CAAC,IAC9E,IAAI,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG,GAAG,iBAAiB,EAAE,OAAO,MAAM,CAAC;AAC7G,cAAI,UAAU,IAAI,SAAU,OAAM,MAAM,OAAO,UAAU,EAAE;AAC3D;AAAA,QACF;AAEA,YAAI;AACF,cAAI,SAAS,IAAI;AACf,oBAAQ,aAAa,EAAE,QAAQ,SAAS,QAAQ,SAAS,SAAS,QAAQ,CAAC;AAC3E,mBAAQ,MAAM,SAAS,UAAU,YAAY;AAAA,UAC/C;AAIA,gBAAM,OAAO,MAAM,SAAS,UAAU,iBAAiB,UAAU,SAAS,iBAAiB,SAAS,SAAS,YAAY;AACzH,sBAAY,IAAI,SAAS,UAAU,MAAM,SAAS,MAAM,GAAG,SAAS,QAAQ,QAAW,IAAI;AAAA,QAC7F,SAAS,OAAO;AACd,cAAI,cAAc,QAAS,OAAM,aAAa,YAAY;AAC1D,gBAAM;AAAA,QACR,UAAE;AACA,iBAAO;AAAA,QACT;AAEA,YAAI,OAAO,kBAAkB,CAAC,gBAAgB,qBAAqB,SAAS,SAAS,MAAM,GAAG;AAE5F,yBAAe;AACf,gBAAM,WAAW,MAAM,OAAO,eAAe,EAAE,OAAO,WAAuB,SAAS,SAAS,WAAW,WAAW,CAAC;AACtH,cAAI,cAAc,QAAS,OAAM,aAAa,YAAY;AAC1D,cAAI,aAAa,WAAW,YAAY;AAEtC,uBAAW;AACX;AAAA,UACF;AACA;AAAA,QACF;AACA,YAAI,SAAS,UAAU,OAAO,UAAU,IAAI,UAAU;AACpD,gBAAM,MAAM,OAAO,UAAU,EAAE;AAC/B;AAAA,QACF;AACA;AAAA,MACF;AACA,YAAM,qBAAqB,WAAW,YAAY,IAAI,SAAS,2BAA2B,GAAG,iBAAiB,EAAE,OAAO,UAAU,CAAC;AAAA,IACpI;AAAA,EACF;AACF;;;AC9MA,IAAM,YAAY;AAGX,SAAS,WAAW,OAA8B;AACvD,SAAO,OAAO,UAAU,YAAY,UAAU,KAAK,KAAK;AAC1D;AAGO,SAAS,SAAS,OAAyB;AAChD,QAAM,IAAI,UAAU,KAAK,KAAK;AAC9B,MAAI,CAAC,EAAG,OAAM,IAAI,WAAW,IAAI,KAAK,oCAAoC;AAC1E,SAAO,EAAE,MAAM,EAAE,CAAC,GAAI,IAAI,OAAO,EAAE,CAAC,CAAC,GAAG,QAAQ,EAAE,CAAC,MAAM,SAAY,OAAO,OAAO,EAAE,CAAC,CAAC,EAAE;AAC3F;AAGO,SAAS,WAAW,OAAoB;AAC7C,QAAM,IAAI,UAAU,KAAK,KAAK;AAC9B,SAAO,IAAI,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK;AACjC;AAGO,SAAS,UAAU,OAAuB;AAC/C,SAAO,SAAS,KAAK,EAAE;AACzB;AAGO,SAAS,MAAM,MAAc,IAAY,QAA6B;AAC3E,SAAO,UAAU,OAAO,GAAG,IAAI,IAAI,EAAE,KAAK,GAAG,IAAI,IAAI,EAAE,IAAI,MAAM;AACnE;;;AC7CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyCO,SAAS,WAAW,MAAyB;AAClD,QAAM,QAAkB,CAAC;AACzB,MAAI,QAAQ,GAAG,QAAuB,MAAM,UAAU;AACtD,aAAW,MAAM,MAAM;AACrB,QAAI,OAAO;AAAE,iBAAW;AAAI,UAAI,OAAO,MAAO,SAAQ;AAAM;AAAA,IAAU;AACtE,QAAI,OAAO,OAAO,OAAO,KAAK;AAAE,cAAQ;AAAI,iBAAW;AAAI;AAAA,IAAU;AACrE,QAAI,OAAO,IAAK,UAAS;AACzB,QAAI,OAAO,IAAK,UAAS;AACzB,QAAI,OAAO,OAAO,UAAU,GAAG;AAAE,YAAM,KAAK,OAAO;AAAG,gBAAU;AAAI;AAAA,IAAU;AAC9E,eAAW;AAAA,EACb;AACA,QAAM,KAAK,OAAO;AAClB,SAAO,MAAM,IAAI,CAAC,QAAQ;AACxB,QAAI,IAAI,WAAW,GAAG,EAAG,QAAO,EAAE,MAAM,KAAK,UAAU,MAAM,WAAW,IAAI,MAAM,CAAC,EAAe;AAClG,UAAM,OAAO,IAAI,QAAQ,gBAAgB,EAAE;AAC3C,UAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,WAAO,QAAQ,IAAI,EAAE,MAAM,MAAM,UAAU,MAAM,WAAW,KAAK,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,KAAK,GAAG,UAAU,KAAK,MAAM,QAAQ,CAAC,KAAK,MAAM,WAAW,KAAK;AAAA,EAC9J,CAAC;AACH;AAGO,SAAS,YAAY,QAAyB,MAAsB,MAAsD;AAC/H,QAAM,IAAI,OAAO,UAAU,IAAI;AAC/B,MAAI,MAAM,OAAW,QAAO;AAC5B,MAAI,MAAM,KAAM,QAAO;AACvB,SAAO,EAAE,WAAW,GAAG,IAAI,IAAI,IAAI,EAAE,KAAK,OAAO,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK;AACxG;AAGO,SAAS,YAAY,QAAyB,MAAsB,MAA8B;AACvG,QAAM,WAAW,WAAW,IAAI;AAChC,MAAI,UAAU,MAAM,QAAQ,OAAO,OAAmC;AACtE,aAAW,CAAC,GAAG,GAAG,KAAK,SAAS,QAAQ,GAAG;AACzC,QAAI,IAAI,WAAW;AACjB,aAAO,MAAM,SAAS,SAAS,IAAI,EAAE,MAAM,YAAY,YAAY,MAAM,WAAW,MAAM,OAAO,OAAO,WAAW,IAAI,UAAU,IAAI,EAAE,MAAM,WAAW,IAAI,KAAK;AAAA,IACnK;AACA,UAAM,MAAM,YAAY,QAAQ,SAAS,IAAI,IAAI;AACjD,QAAI,QAAQ,OAAW,QAAO,EAAE,MAAM,SAAS,MAAM,QAAQ;AAC7D,QAAI,QAAQ,KAAM,QAAO,EAAE,MAAM,WAAW,IAAI,GAAG,OAAO,IAAI,IAAI,IAAI,GAAG;AACzE,QAAI,IAAI,kBAAkB,YAAY;AACpC,aAAO,MAAM,SAAS,SAAS,IAAI,EAAE,MAAM,YAAY,YAAY,KAAK,WAAW,SAAS,OAAO,WAAW,KAAK,IAAI,EAAE,MAAM,WAAW,IAAI,KAAK;AAAA,IACrJ;AACA,cAAU,IAAI;AACd,UAAM,OAAO,IAAI,YAAY,IAAI;AACjC,QAAI,CAAC,KAAM,QAAO,EAAE,MAAM,WAAW,IAAI,GAAG,OAAO,IAAI,IAAI,IAAI,GAAG;AAClE,cAAU;AACV,WAAO;AAAA,EACT;AACA,SAAO,EAAE,MAAM,YAAY,YAAY,MAAM,WAAW,SAAS,OAAO,WAAW,KAAK;AAC1F;AAUO,SAAS,WAAW,MAAc,QAA4B,CAAC,GAA0B;AAC9F,QAAM,UAAU,WAAW,IAAI,IAAI,UAAU,IAAI,IAAI;AACrD,MAAI,QAAS,QAAO;AACpB,MAAI,KAAK,WAAW,GAAG,GAAG;AACxB,eAAW,WAAW,OAAO;AAC3B,YAAM,OAAQ,UAAsC,IAAI;AACxD,YAAM,YAAY,QAAQ,OAAO,SAAS,WAAY,KAAiC,YAAY;AACnG,UAAI,OAAO,cAAc,SAAU,QAAO;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAQO,SAAS,YAAY,QAAyBC,QAAoB,MAA2C;AAClH,QAAM,SAAS,oBAAI,IAAoB;AACvC,MAAI,OAAO,UAAU,IAAI,MAAM,QAAW;AAAE,WAAO,IAAI,IAAI;AAAG,WAAO;AAAA,EAAQ;AAC7E,aAAW,SAASA,OAAM,UAAU,CAAC,GAAG;AACtC,UAAM,OAAO,OAAO,UAAU,WAAW,QAAQ,MAAM;AACvD,UAAM,IAAI,YAAY,QAAQ,MAAM,IAAI;AACxC,QAAI,EAAE,SAAS,QAAS,QAAO,IAAI,EAAE,IAAI;AAAA,aAChC,EAAE,SAAS,cAAc,OAAO,UAAU,YAAY,EAAE,UAAW,YAAW,KAAK,YAAY,QAAQ,OAAO,EAAE,SAAS,EAAG,QAAO,IAAI,CAAC;AAAA,EACnJ;AACA,SAAO;AACT;;;ADdA,IAAM,QAAQ,CAAC,MAAyB,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC,KAAK,UAAU,KAAK,OAAQ,EAAU,SAAS;AAQhI,SAAS,YAAY,OAA8B;AACxD,MAAI,MAAM,KAAK,EAAG,QAAO,WAAW,MAAM,IAAI;AAC9C,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,WAAW;AACtD,MAAI,SAAS,OAAO,UAAU,SAAU,QAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;AAC5H,SAAO;AACT;AAGO,IAAM,SAAS,CAAC,aAAmC,SAAS,IAAI,CAAC,MAAM,YAAY,CAAiB,CAAC;AAqBrG,SAAS,YAAuC,KAA8B,SAA2B;AAC9G,QAAM,MAA+B,CAAC;AAOtC,QAAM,UAAU,MAAM,QAAQ,IAAI,SAAS;AAC3C,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAG,GAAG;AACxC,QAAI,WAAW,MAAM,YAAa,KAAI,CAAC,IAAK,EAAgB,IAAI,CAAC,UAAW,SAAS,OAAO,UAAU,WAAW,YAAY,OAAkC,OAAO,IAAI,KAAM;AAAA,aACvK,WAAW,MAAM,UAAU,MAAM,OAAQ,KAAI,CAAC,IAAI;AAAA,aAClD,MAAM,UAAU,OAAO,MAAM,SAAU,KAAI,CAAC,IAAI,WAAW,CAAC;AAAA,QAChE,KAAI,CAAC,IAAI,UAAU,UAAU,GAAG,YAAY,QAAQ,QAAQ,QAAQ,MAAM,CAAC,GAAG,QAAQ,MAAM,IAAI,cAAc,CAAC;AAAA,EACtH;AACA,SAAO;AACT;AAMA,IAAM,YAAY,CAAC,UAA4B,MAAM,KAAK,KAAK,MAAM,SAAS;AAE9E,SAAS,cAAc,OAAyB;AAC9C,MAAI,UAAU,KAAK,EAAG,QAAO;AAC7B,MAAI,MAAM,KAAK,EAAG,QAAO,EAAE,GAAG,OAAO,MAAM,WAAW,MAAM,IAAI,EAAE;AAClE,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,aAAa;AACxD,SAAO;AACT;AAEA,SAAS,UAAU,OAAgB,YAA4B,QAAkC;AAC/F,MAAI,WAAW,SAAS,WAAY,QAAO,cAAc,KAAK;AAC9D,MAAI,WAAW,UAAW,QAAO,SAAS,KAAK;AAC/C,QAAM,aAAa,WAAW;AAC9B,MAAI,WAAW,kBAAkB,YAAY;AAC3C,UAAM,UAAU,WAAW,YAAY,EAAE,QAAQ,MAAM,WAAW,UAAU,IAAI;AAChF,UAAMC,OAAM,CAAC,MAAyB,UAAU,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,YAAY,GAA8B,OAAO,IAAI,cAAc,CAAC;AAC3I,QAAI,WAAW,MAAO,SAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,SAAS,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,IAAIA,IAAG;AAC/H,QAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,SAASA,KAAI,MAAM,CAAC,CAAC,IAAI;AAChE,WAAO,SAAS,OAAO,OAAOA,KAAI,KAAK;AAAA,EACzC;AACA,QAAM,MAAM,CAAC,MAAwB,OAAO,GAAG,WAAW,aAAa;AACvE,SAAO,WAAW,SAAS,MAAM,QAAQ,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,IAAI,KAAK;AAC9E;AAGA,SAAS,OAAO,OAAgB,MAA8B;AAC5D,MAAI,SAAS,KAAM,QAAO;AAC1B,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,SAAS,KAAK;AAAA,IACvB,KAAK;AACH,aAAO,UAAU,QAAQ,UAAU,UAAU,UAAU,SAAS,OAAO,UAAU,SAAS,UAAU,WAAW,UAAU,UAAU,QAAQ;AAAA,IAC7I;AACE,aAAO;AAAA,EACX;AACF;AACA,SAAS,SAAS,OAAyB;AACzC,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,IAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI;AAC7E,SAAO,OAAO,MAAM,CAAC,IAAI,QAAQ;AACnC;AAwCO,SAAS,eAAe,SAAmC;AAChE,QAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,GAAG;AACtC,MAAI,MAAM,CAAC,MAAM,eAAe,CAAC,MAAM,CAAC,EAAG,QAAO;AAClD,QAAM,OAAO,MAAM,CAAC,GAAG,OAAO,MAAM,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AACnE,MAAI,KAAK,CAAC,MAAM,yBAAyB,KAAK,CAAC,KAAK,KAAK,CAAC,EAAG,QAAO,EAAE,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,KAAK,GAAG,EAAE;AAEpI,QAAM,QAAQ,KAAK,WAAW,KAAK,iDAAiD,KAAK,KAAK,CAAC,CAAE,IAAK,KAAK,CAAC,IAA0B;AACtI,SAAO,EAAE,MAAM,WAAW,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK;AAC1F;AAGO,SAAS,WAAsC,UAAyD;AAC7G,UAAQ,SAAS,iBAAiB,YAAY,CAAC,GAAG,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,OAAO;AAAA,IAC/E,OAAO,OAAO,UAAU,YAAY,SAAS,OAAO,MAAM,uBAAuB,WAAW,MAAM,qBAAqB;AAAA,IACvH,SAAS,OAAO,UAAU,WAAW,QAAQ,OAAO,WAAW;AAAA,IAC/D;AAAA,IACA,WAAW,eAAe,OAAO,UAAU,WAAW,QAAQ,OAAO,WAAW,EAAE;AAAA,EACpF,EAAE;AACJ;AAqBO,SAAS,UAAqC,UAA+C;AAClG,SAAO;AAAA,IACL,WAAW,OAAO,SAAS,cAAc,YAAY,SAAS,YAAY,SAAS,YAAY;AAAA,IAC/F,UAAU,SAAS,eAAe,aAAa,CAAC,GAAG,IAAI,UAAU;AAAA,IACjE,WAAW,SAAS,gBAAgB,aAAa,CAAC,GAAG,IAAI,UAAU;AAAA,IACnE,WAAW,SAAS,kBAAkB,aAAa,CAAC,GAAG,IAAI,UAAU;AAAA,IACrE,UAAU,WAAW,QAAQ;AAAA,IAC7B,cAAc,SAAS,aAAa,WAAW,CAAC;AAAA,IAChD,iBAAiB,OAAO,SAAS,oBAAoB,WAAW,SAAS,kBAAkB;AAAA,EAC7F;AACF;AAGO,IAAM,eAAe,OAAgD,EAAE,WAAW,MAAM,SAAS,CAAC,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC,GAAG,cAAc,CAAC,GAAG,iBAAiB,KAAK;AAOvL,SAAS,aAAwC,MAAoB,MAAoB,QAA8B;AAC5H,OAAK,QAAQ,KAAK,GAAG,KAAK,OAAO;AACjC,OAAK,SAAS,KAAK,GAAG,KAAK,QAAQ;AACnC,OAAK,SAAS,KAAK,GAAG,KAAK,QAAQ;AACnC,OAAK,SAAS,KAAK,GAAG,KAAK,SAAS,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,UAAU,OAAO,OAAO,EAAE,QAAQ,OAAO,EAAE,CAAC;AAC7G,OAAK,aAAa,KAAK,GAAG,KAAK,YAAY;AAC3C,OAAK,YAAY;AACjB,MAAI,KAAK,oBAAoB,KAAM,MAAK,mBAAmB,KAAK,mBAAmB,KAAK,KAAK;AAC7F,SAAO;AACT;AAeO,IAAM,sBAAN,cAA6D,SAAS;AAAA,EAClE;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EAET,YAAY,UAAiC,WAAmC,WAAW,QAAQ,GAAG;AACpG,UAAM,SAAS,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,kBAAkB,KAAK,kBAAkB,QAAQ;AACpG,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,UAAU,UAAU,QAAQ;AAAA,EACnC;AACF;AA4BA,IAAM,SAAS,CAAC,MAAwB;AAAE,QAAM,OAAO,OAAO,KAAK,CAAC;AAAG,SAAO,KAAK,WAAW,KAAK,KAAK,CAAC,EAAG,WAAW,GAAG,IAAK,EAA8B,KAAK,CAAC,CAAE,IAAI;AAAG;AAC5K,IAAM,UAAU,CAAC,SAAqC,CAAC,CAAC,QAAQ,OAAO,SAAS,YAAY,OAAQ,KAAmB,SAAS,YAAY,EAAE,YAAY,SAAS,EAAE,aAAa,SAAS,EAAE,eAAe;AAE5M,SAAS,UAAU,UAA2D;AAC5E,SAAO,SAAS,QAAQ,CAAC,GAAG,UAAU;AAAE,UAAM,OAAO,OAAO,CAAC;AAAG,WAAO,QAAQ,IAAI,IAAI,CAAC,EAAE,MAAM,MAAM,CAAC,IAAI,CAAC;AAAA,EAAG,CAAC;AAClH;AAUA,SAAS,QAAW,MAA2B,SAAc,QAA0C;AACrG,QAAM,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,KAAK,CAAC,EAAE;AAC1D,MAAI,QAAQ,WAAW,SAAU,QAAO;AACxC,MAAI,OAAO;AACX,SAAO,KAAK,IAAI,CAAC,MAAO,OAAO,IAAI,EAAE,KAAK,IAAI,OAAO,QAAQ,MAAM,CAAG;AACxE;AAQA,eAAsB,KAAgC,WAAsB,UAAqB,UAAuB,CAAC,GAAmC;AAC1J,QAAM,WAAW,MAAM,UAAU,QAA+B;AAAA,IAC9D,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO,QAAQ,cAAc,EAAE,aAAa,OAAO,IAAI;AAAA,IACvD,MAAM,OAAO,QAAQ;AAAA,IACrB,cAAc;AAAA,IACd,YAAY,QAAQ,eAAe;AAAA,EACrC,CAAC;AAED,MAAI,QAAQ,YAAa,QAAO;AAChC,QAAMC,WAAU,UAAU,QAAQ;AAClC,QAAM,WAAW,WAAW,QAAQ;AACpC,QAAM,SAAS,IAAI,IAAI,SAAS,QAAQ,CAAC,MAAO,EAAE,UAAU,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,CAAE,CAAC;AACnF,QAAM,UAAU,SAAS,aAAa,WAAW,CAAC;AAClD,MAAI,UAAU,QAAQA,UAAS,SAAS,MAAM;AAC9C,MAAI,CAAC,SAAS;AAMZ,QAAI,CAAC,SAAS,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI,EAAG,OAAM,IAAI,SAAS,sBAAsB,QAAQ,MAAM,sBAAsBA,SAAQ,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,KAAK,CAAC,EAAE,MAAM,+EAA+E,KAAK,gBAAgB,QAAQ;AACxR,cAAUA,SAAQ,IAAI,MAAM,IAAI;AAAA,EAClC;AACA,QAAM,YAAY,CAAC,MAAsC;AACvD,UAAM,OAAO,QAAQ,SAAS,WAAWA,SAAQ,CAAC,EAAG,KAAK,MAAM,QAAQ,IAAI;AAC5E,WAAO,OAAO,EAAE,QAAQ,QAAQ,QAAS,KAAK,IAAI;AAAA,EACpD;AACA,QAAM,aAAoC,EAAE,GAAG,UAAU,aAAa,EAAE,GAAG,SAAS,aAAa,SAAS,QAAS,IAAI,CAAC,MAAM,MAAM,QAAQ,KAAK,IAAI,CAAC,MAAM,YAAiB,GAA8B,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;AAC7N,MAAI,QAAQ,kBAAkB,WAAW,iBAAiB,MAAO,OAAM,IAAI,oBAAoB,UAAU;AACzG,SAAO;AACT;AAGA,eAAsB,QAAQ,WAAsB,UAAyC;AAC3F,SAAO,UAAU,QAAmB,EAAE,QAAQ,QAAQ,MAAM,cAAc,OAAO,EAAE,aAAa,OAAO,GAAG,MAAM,OAAO,QAAQ,GAAG,cAAc,OAAO,CAAC;AAC1J;AAOA,eAAsB,SAAoC,WAAsB,MAAc,UAAuB,CAAC,GAA+C;AACnK,SAAO,UAAU,QAAQ,EAAE,QAAQ,QAAQ,MAAM,cAAc,OAAO,QAAQ,cAAc,EAAE,aAAa,OAAO,IAAI,QAAW,MAAM,MAAM,aAAa,aAAa,cAAc,OAAO,CAAC;AAC/L;AAGA,eAAsB,MAAiC,WAAsB,GAAc,UAAuB,CAAC,GAAmB;AACpI,QAAM,CAAC,IAAI,IAAI,MAAM,QAAa,WAAW,CAAC,CAAC,GAAG,OAAO;AACzD,SAAO,QAAQ,CAAC;AAClB;AAOA,eAAsB,UAAqC,WAAsB,GAAc,UAAuB,CAAC,GAAkE;AACvL,MAAI,CAAC,EAAE,KAAM,OAAM,IAAI,WAAW,YAAY,EAAE,IAAI,uDAAuD;AAC3G,QAAM,WAAW,MAAM,KAAU,WAAW,CAAC,EAAE,GAAG,GAAG,WAAW,KAAK,CAAC,GAAG,EAAE,GAAG,SAAS,gBAAgB,KAAK,CAAC;AAC7G,QAAM,OAAO,SAAS,YAAY,QAAQ,CAAC,KAAK,CAAC;AACjD,QAAM,WAAY,SAAS,YAA2D,iBAAiB,CAAC,GAAG;AAC3G,QAAM,QAAQ,OAAO,aAAa,WAAW,WAAW;AACxD,SAAO,EAAE,MAAM,OAAO,MAAM,UAAU,OAAO,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,KAAK,SAAS,MAAM;AAChH;AAQA,eAAsB,QAAmC,WAAsB,IAAiB,UAAuB,CAAC,GAAqB;AAC3I,aAAW,KAAK,GAAI,KAAI,CAAC,EAAE,KAAM,OAAM,IAAI,WAAW,YAAY,EAAE,IAAI,uDAAuD;AAC/H,QAAM,WAAW,MAAM,KAAU,WAAW,IAAI,EAAE,GAAG,SAAS,gBAAgB,KAAK,CAAC;AACpF,SAAO,GAAG,IAAI,CAAC,GAAG,MAAM,SAAS,YAAY,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC/D;;;AExeA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCA,eAAsB,aAAa,MAAkC;AACnE,MAAI,gBAAgB,WAAY,QAAO;AACvC,MAAI,gBAAgB,YAAa,QAAO,IAAI,WAAW,IAAI;AAC3D,SAAO,IAAI,WAAW,MAAM,KAAK,YAAY,CAAC;AAChD;AAGO,SAAS,SAAS,OAA2B;AAClD,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,MAAQ,WAAU,OAAO,aAAa,GAAG,MAAM,SAAS,GAAG,IAAI,KAAM,CAAC;AAC7G,SAAO,KAAK,MAAM;AACpB;AAEO,SAAS,WAAW,MAA0B;AACnD,QAAM,SAAS,KAAK,IAAI;AACxB,QAAM,MAAM,IAAI,WAAW,OAAO,MAAM;AACxC,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,EAAG,KAAI,CAAC,IAAI,OAAO,WAAW,CAAC;AACvE,SAAO;AACT;AAGO,SAAS,UAAU,MAAqC;AAC7D,QAAM,IAAI,kCAAkC,KAAK,OAAO,IAAI,EAAE,KAAK,CAAC;AACpE,MAAI,CAAC,EAAG,OAAM,IAAI,WAAW,IAAI,IAAI,sEAAsE;AAC3G,SAAO,EAAE,CAAC;AACZ;AAEA,IAAM,OAAO,CAAC,SAAiB,SAAyB,GAAG,QAAQ,QAAQ,QAAQ,EAAE,CAAC,IAAI,IAAI;AAGvF,IAAM,gBAAgB,CAAC,SAAiB,OAAsC,KAAK,SAAS,kBAAkB,UAAU,EAAE,CAAC,EAAE;AAE7H,IAAM,mBAAmB,CAAC,SAAiB,OAAsC,KAAK,SAAS,gBAAgB,UAAU,EAAE,CAAC,EAAE;AAO9H,SAAS,2BAA2B,MAAc,SAAyB;AAChF,SAAO,KAAK,QAAQ,+DAA+D,CAAC,IAAI,MAAc,OAAe,MAAc,OAAe,GAAG,IAAI,GAAG,KAAK,GAAG,iBAAiB,SAAS,EAAE,CAAC,GAAG,KAAK,EAAE;AAC7M;AAGA,SAAS,MAAM,OAAgB,MAAuB;AACpD,MAAI,EAAE,iBAAiB,UAAW,QAAO;AACzC,MAAI,MAAM,WAAW,IAAK,QAAO,IAAI,SAAS,GAAG,IAAI,eAAe,KAAK,aAAa,MAAM,OAAO;AACnG,MAAI,MAAM,WAAW,IAAK,QAAO,IAAI,SAAS,GAAG,IAAI,qDAAqD,KAAK,aAAa,MAAM,OAAO;AACzI,SAAO;AACT;AAGA,eAAsB,SAAS,WAAsB,IAAgD;AACnG,QAAM,IAAI,UAAU,EAAE;AACtB,MAAI;AACF,WAAO,MAAM,UAAU,QAAoB,EAAE,QAAQ,OAAO,MAAM,mBAAmB,CAAC,IAAI,cAAc,QAAQ,CAAC;AAAA,EACnH,SAAS,OAAO;AACd,UAAM,MAAM,OAAO,cAAc,CAAC,EAAE;AAAA,EACtC;AACF;AAGA,eAAsB,QAAQ,WAAsB,IAAgH;AAClK,QAAM,IAAI,UAAU,EAAE;AACtB,MAAI,cAA6B,MAAM,WAA0B;AACjE,QAAM,aAAa,CAAC,EAAE,QAAQ,MAAyD;AACrF,kBAAc,QAAQ,IAAI,cAAc;AACxC,UAAM,cAAc,QAAQ,IAAI,qBAAqB,KAAK;AAC1D,UAAM,UAAU,6BAA6B,KAAK,WAAW,IAAI,CAAC;AAClE,eAAW,UAAU,mBAAmB,OAAO,IAAI,yBAAyB,KAAK,WAAW,IAAI,CAAC,KAAK;AAAA,EACxG;AACA,MAAI;AACF,UAAM,QAAQ,MAAM,UAAU,QAAoB,EAAE,QAAQ,OAAO,MAAM,mBAAmB,CAAC,IAAI,cAAc,SAAS,WAAW,CAAC;AACpI,WAAO,EAAE,OAAO,aAAa,SAAS;AAAA,EACxC,SAAS,OAAO;AACd,UAAM,MAAM,OAAO,cAAc,CAAC,EAAE;AAAA,EACtC;AACF;AAGA,eAAsB,SAAS,WAAsB,IAA2B,MAAa,cAAc,4BAA2C;AACpJ,QAAM,IAAI,UAAU,EAAE;AACtB,QAAM,OAAO,gBAAgB,OAAO,OAAO,MAAM,aAAa,IAAI;AAClE,MAAI;AACF,UAAM,UAAU,QAAQ,EAAE,QAAQ,QAAQ,MAAM,mBAAmB,CAAC,IAAI,MAAM,aAAa,gBAAgB,QAAQ,KAAK,OAAO,KAAK,OAAO,aAAa,cAAc,OAAO,CAAC;AAAA,EAChL,SAAS,OAAO;AACd,UAAM,MAAM,OAAO,cAAc,CAAC,EAAE;AAAA,EACtC;AACF;AAQA,eAAsB,oBAAoB,WAAsB,OAAY,MAAa,UAAuD,CAAC,GAA2B;AAC1K,QAAM,OAAO,gBAAgB,OAAO,OAAO,IAAI,KAAK,CAAE,MAAM,aAAa,IAAI,CAA6B,GAAG,EAAE,MAAM,QAAQ,eAAe,2BAA2B,CAAC;AACxK,QAAM,OAAO,IAAI,SAAS;AAC1B,OAAK,OAAO,SAAS,MAAM,QAAQ,YAAY,OAAO;AACtD,OAAK,OAAO,YAAY,KAAK;AAC7B,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,UAAU,QAAgB,EAAE,QAAQ,QAAQ,MAAM,6BAA6B,MAAM,MAAM,cAAc,OAAO,CAAC;AAAA,EAChI,SAAS,OAAO;AACd,UAAM,MAAM,OAAO,sBAAsB,KAAK,EAAE;AAAA,EAClD;AACA,QAAM,QAAQ,yCAAyC,KAAK,IAAI,IAAI,CAAC;AACrE,MAAI;AACJ,MAAI;AACF,cAAU,QAAQ,KAAK,MAAM,MAAM,QAAQ,WAAW,GAAG,EAAE,QAAQ,SAAS,GAAG,EAAE,QAAQ,SAAS,GAAG,EAAE,QAAQ,UAAU,GAAG,CAAC,IAAI;AAAA,EACnI,QAAQ;AAAA,EAAuB;AAC/B,MAAI,CAAC,WAAW,OAAO,QAAQ,QAAQ,SAAU,OAAM,IAAI,SAAS,6DAA6D,KAAK,gBAAgB,KAAK,MAAM,GAAG,GAAG,CAAC;AACxK,QAAM,KAAK,uBAAuB,KAAK,QAAQ,GAAG,IAAI,CAAC,MAAM,OAAO,QAAQ,QAAQ,WAAW,UAAU,QAAQ,GAAG,IAAI;AACxH,MAAI,CAAC,GAAI,OAAM,IAAI,SAAS,+DAA+D,KAAK,gBAAgB,OAAO;AACvH,SAAO,EAAE,KAAK,OAAO,QAAQ,QAAQ,WAAW,QAAQ,MAAM,iBAAiB,EAAE,IAAI,IAAI,KAAK,QAAQ,IAAI;AAC5G;;;AC5HO,IAAM,eAAe;AAe5B,IAAM,SAAS,CAAC,QAAQ,YAAY,eAAe,eAAe,cAAc,gBAAgB;AAChG,IAAM,SAAS,CAAC,MAA2B;AACzC,QAAM,MAAM,WAAW,EAAE,IAAI;AAC7B,SAAO,EAAE,KAAK,IAAI,UAAU,GAAG,GAAG,MAAM,EAAE,QAAQ,MAAM,UAAU,EAAE,YAAY,MAAM,aAAa,EAAE,eAAe,MAAM,aAAa,EAAE,eAAe,MAAM,YAAY,EAAE,cAAc,MAAM,WAAW,EAAE,gBAAgB,KAAK,KAAK;AACzO;AAGA,eAAsB,KAAK,WAAsB,OAAY,UAAsD,CAAC,GAAoF;AACtM,QAAM,EAAE,MAAM,OAAO,KAAK,IAAI,MAAe,UAAU,WAAW,EAAE,MAAM,cAAc,QAAQ,QAAQ,QAAQ,CAAC,cAAc,GAAG,MAAM,EAAE,QAAQ,WAAW,KAAK,EAAE,GAAG,MAAM,CAAC,aAAa,GAAG,MAAM,QAAQ,QAAQ,EAAE,MAAM,IAAI,OAAO,EAAE,EAAE,CAAC;AAC5O,SAAO,EAAE,aAAa,KAAK,IAAI,CAAC,MAAM,OAAO,CAAmB,CAAC,GAAG,OAAO,KAAK;AAClF;AAGA,eAAsB,KAAK,WAAsB,OAAY,UAAsD,CAAC,GAA8B;AAChJ,QAAM,OAAO,MAAe,MAAM,WAAW,EAAE,MAAM,cAAc,QAAQ,QAAQ,QAAQ,CAAC,cAAc,GAAG,MAAM,EAAE,QAAQ,WAAW,KAAK,EAAE,GAAG,MAAM,CAAC,aAAa,GAAG,MAAM,QAAQ,QAAQ,EAAE,MAAM,IAAI,OAAO,EAAE,EAAE,CAAC;AACvN,SAAO,KAAK,IAAI,CAAC,MAAM,OAAO,CAAmB,CAAC;AACpD;AAGA,eAAsB,KAAK,WAAsB,IAA2D;AAC1G,QAAM,CAAC,GAAG,IAAI,MAAe,MAAM,WAAW,EAAE,MAAM,cAAc,QAAQ,QAAQ,QAAQ,CAAC,QAAQ,GAAG,MAAM,EAAE,KAAK,cAAc,UAAU,EAAE,CAAC,GAAG,GAAG,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,EAAE,CAAC;AACnL,SAAO,MAAM,OAAO,GAAqB,IAAI;AAC/C;AAOA,eAAsB,IAAI,WAAsB,IAAgH;AAC9J,QAAM,OAAO,MAAM,KAAK,WAAW,EAAE;AACrC,MAAI,CAAC,KAAM,OAAM,IAAI,SAAS,cAAc,UAAU,EAAE,CAAC,eAAe,KAAK,WAAW;AACxF,QAAM,OAAO,MAAM,QAAQ,WAAW,KAAK,EAAE;AAC7C,SAAO,EAAE,GAAG,MAAM,OAAO,KAAK,OAAO,aAAa,KAAK,eAAe,KAAK,aAAa,qBAAqB,KAAK,YAAY;AAChI;AAcO,IAAM,wBAAN,cAAoC,aAAa;AAAA,EACtD,YAAqB,YAA4B,OAAgB;AAC/D,UAAM,GAAG,WAAW,GAAG,6EAA6E,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,qBAAqB,KAAK;AADrK;AAEnB,SAAK,OAAO;AAAA,EACd;AAAA,EAHqB;AAIvB;AAGA,eAAsB,IAAI,WAAsB,OAAY,MAAa,SAA8C;AACrH,QAAM,QAAQ,MAAM,aAAa,IAAI;AACrC,QAAM,cAAc,QAAQ,gBAAgB,OAAO,SAAS,eAAe,gBAAgB,QAAQ,KAAK,OAAO,KAAK,OAAO;AAC3H,QAAM,SAAS,MAAM,WAAW,QAAQ,eAAe;AACvD,QAAM,SAA8B,EAAE,WAAW,cAAc,OAAO,WAAW,KAAK,GAAG,MAAM,QAAQ,QAAQ,QAAQ,UAAU,UAAU,QAAQ,UAAU,aAAa,aAAa,SAAS,SAAS,SAAS,KAAK,IAAI,GAAG;AAC9N,MAAI,QAAQ,YAAa,QAAO,cAAc,QAAQ;AACtD,QAAM,MAAe,UAAU,MAAe,KAAK,WAAW,CAAC,MAAM,GAAG,EAAE,gBAAgB,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;AAC5G,QAAM,UAA0B,EAAE,KAAK,IAAI,UAAU,GAAG,GAAG,MAAM,OAAO,OAAO,IAAI,GAAG,UAAU,QAAQ,UAAU,aAAa,aAAa,QAAQ,eAAe,MAAM,YAAY,MAAM,WAAW,KAAK;AAC3M,MAAI,CAAC,QAAQ;AACX,QAAI;AACF,YAAM,SAAS,WAAW,QAAQ,IAAI,OAAO,WAAW;AAAA,IAC1D,SAAS,OAAO;AACd,YAAM,IAAI,sBAAsB,SAAS,KAAK;AAAA,IAChD;AAAA,EACF;AACA,SAAO;AACT;AAGA,eAAsB,IAAI,WAAsB,IAA2B,MAAa,aAAqC;AAC3H,QAAM,SAAS,WAAW,IAAI,MAAM,WAAW;AACjD;AAGA,eAAsB,OAAO,WAAsB,IAA0C;AAC3F,QAAe,KAAK,WAAW,CAAC,EAAE,MAAM,cAAc,UAAU,EAAE,CAAC,IAAI,SAAS,SAAS,CAAC,GAAG,EAAE,gBAAgB,KAAK,CAAC;AACvH;;;AC/EO,IAAM,QAAQ;AAGd,IAAM,oBAA+C,CAAC,QAAQ,iBAAiB,cAAc,eAAe,gBAAgB,aAAa,UAAU;AAMnJ,IAAM,mBAAN,cAA+B,WAAW;AAAA,EACtC;AAAA,EACT,YAAY,SAAwB;AAClC,UAAM,4BAA4B,QAAQ,IAAI,CAAC,MAAM,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AACpG,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;AAKO,SAAS,QAAQ,SAA2E;AACjG,QAAM,OAAO,OAAO,KAAK,OAAO;AAChC,SAAO,KAAK,WAAW,KAAK,KAAK,CAAC,EAAG,WAAW,GAAG,IAAI,EAAE,OAAO,KAAK,CAAC,GAAI,MAAO,QAAoD,KAAK,CAAC,CAAE,EAAG,IAAI;AACtJ;AACA,IAAMC,UAAS,CAAC,MAAwC,QAAQ,CAAC,GAAG,QAAS;AAC7E,IAAM,WAAW,CAAC,MAA6C,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC;AAE/G,IAAM,gBAAgB,CAAC,MACpB,SAAS,CAAC,KAAK,eAAe,KAAO,MAAM,QAAQ,CAAC,KAAK,EAAE,KAAK,aAAa,KAAO,SAAS,CAAC,KAAM,CAAC,EAAgB,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,aAAa;AAGvJ,SAAS,YAAY,UAAoC;AAC9D,QAAM,MAAqB,CAAC;AAC5B,WAAS,QAAQ,CAAC,GAAG,UAAU;AAC7B,UAAM,IAAI,QAAQ,CAAC;AACnB,UAAM,OAAOA,QAAO,CAAC;AACrB,UAAM,SAAS,YAAY,QAAQ,aAAa;AAChD,QAAI,KAAK,OAAQ,KAAI,KAAK,EAAE,OAAO,QAAQ,GAAG,EAAE,KAAK,kBAAkB,YAAY,OAAO,WAAW,SAAS,0EAA0E,CAAC;AAAA,aAChL,CAAC,KAAK,UAAU,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,WAAW,GAAG,EAAG,KAAI,KAAK,EAAE,OAAO,QAAQ,2CAA2C,KAAK,IAAI,wDAAwD,CAAC;AAC5N,QAAI,SAAS,KAAK,MAAM,KAAK,OAAO,OAAO,KAAK,MAAM,EAAE,KAAK,aAAa,EAAG,KAAI,KAAK,EAAE,OAAO,QAAQ,mFAAmF,CAAC;AAAA,EAC7L,CAAC;AACD,SAAO;AACT;AAIA,SAAS,SAAS,WAAqC;AACrD,QAAM,OAAOA,QAAO,SAAS;AAC7B,SAAO,OAAO,KAAK,QAAQ,aAAa,YAAY,QAAQ,aAAa,QACrE,EAAE,KAAK,WAAW,KAAK,GAAG,GAAG,QAAQ,KAAK,QAAoD,SAAS,KAAK,QAAoC,IAChJ;AACN;AAGO,IAAM,YAAY,CAAC,cAAgC,CAAC,GAAG,IAAI,IAAI,UAAU,QAAQ,CAAC,MAAM;AAAE,QAAM,IAAI,SAAS,CAAC;AAAG,SAAO,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;AAAG,CAAC,CAAC,CAAC;AAKpJ,IAAM,QAAQ;AAGd,eAAsB,SAAS,WAAsB,MAAoD;AACvG,QAAMC,UAAS,oBAAI,IAAmB;AACtC,aAAW,OAAO,IAAI,IAAI,KAAK,IAAI,UAAU,CAAC,GAAG;AAAE,UAAM,IAAI,UAAU,GAAG;AAAG,IAAAA,QAAO,IAAI,GAAG,CAAC,GAAIA,QAAO,IAAI,CAAC,KAAK,CAAC,GAAI,GAAG,CAAC;AAAA,EAAG;AAC7H,QAAM,MAA2B,CAAC;AAClC,aAAW,CAAC,MAAMC,KAAI,KAAKD,SAAQ;AACjC,QAAI,kBAAkB,SAAS,IAAI,EAAG;AACtC,aAAS,IAAI,GAAG,IAAIC,MAAK,QAAQ,KAAK,OAAO;AAC3C,YAAM,OAAOA,MAAK,MAAM,GAAG,IAAI,KAAK;AACpC,YAAM,OAAO,MAAe,MAAuC,WAAW,EAAE,MAAM,MAAM,QAAQ,CAAC,YAAY,GAAG,QAAQ,CAAC,UAAU,GAAG,MAAM,EAAE,OAAO,KAAK,GAAG,MAAM,EAAE,MAAM,KAAK,QAAQ,OAAO,EAAE,EAAE,CAAC;AACxM,iBAAW,KAAK,KAAM,KAAI,EAAE,cAAc,KAAM,KAAI,WAAW,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,UAAU;AAAA,IAC/F;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,MAAM,WAAsB,QAAkF;AAC5H,QAAM,WAAsB,CAAC,GAAG,YAAmB,CAAC;AACpD,aAAW,KAAK,WAAW;AACzB,UAAM,IAAI,SAAS,CAAC;AACpB,QAAI,CAAC,GAAG;AAAE,eAAS,KAAK,CAAC;AAAG;AAAA,IAAU;AACtC,UAAM,QAAQ,OAAO,EAAE,GAAG;AAC1B,QAAI,UAAU,QAAW;AAAE,gBAAU,KAAK,EAAE,GAAG;AAAG;AAAA,IAAU;AAC5D,QAAI,CAAC,MAAM,KAAK,KAAK,EAAG,OAAM,IAAI,SAAS,GAAG,EAAE,GAAG,gBAAgB,KAAK,UAAU,KAAK,CAAC,uDAAuD,KAAK,gBAAgB,EAAE,KAAK,EAAE,KAAK,MAAM,CAAC;AAEzL,UAAM,QAAQ,EAAE,MAAM,UAAU,EAAE,GAAG,GAAG,QAAQ,CAAC,WAAW,eAAe,KAAK,GAAG,GAAG,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;AAC5G,aAAS,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,QAAQ,EAAE,OAAO,IAAI,EAAE,GAAG,OAAO,SAAS,EAAE,QAAkC,CAAC;AAAA,EACtH;AACA,SAAO,EAAE,UAAU,UAAU;AAC/B;AAYO,SAAS,SAAS,WAAmC;AAC1D,QAAM,OAAO,oBAAI,IAAiB;AAClC,QAAM,SAAsB,CAAC,CAAC,CAAC;AAC/B,aAAW,KAAK,WAAW;AACzB,UAAM,IAAI,SAAS,CAAC;AACpB,UAAM,IAAI,IAAI,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI;AACrC,QAAI,EAAG,MAAK,IAAI,EAAE,KAAK,IAAI,CAAC;AAC5B,KAAC,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;AAAA,EAC3B;AACA,SAAO;AACT;AAGO,IAAM,mBAAN,cAA+B,aAAa;AAAA,EACjD,YAAY,OAAyB,SAAoC,MAA0B,MAAc;AAC/G,UAAM,+BAA+B,OAAO,CAAC,GAAG,OAAO,8BAA8B,EAAE,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,gBAAgB,KAAK;AADxI;AAAoC;AAA0B;AAEjG,SAAK,OAAO;AAAA,EACd;AAAA,EAHqC;AAAA,EAAoC;AAAA,EAA0B;AAIrG;AAaA,eAAsB,WAAsC,WAAsB,WAAsB,QAAuC,UAAmE,CAAC,GAAmF;AACpS,QAAM,SAAS,SAAS,SAAS;AACjC,QAAM,UAAmB,aAAkB;AAC3C,QAAM,OAAkB,CAAC,GAAG,YAAmB,CAAC;AAChD,MAAI,UAAU,oBAAI,IAAS;AAC3B,aAAW,CAAC,GAAG,IAAI,KAAK,OAAO,QAAQ,GAAG;AACxC,QAAI;AACJ,QAAI,MAAM,EAAG,WAAU,MAAM,MAAM,MAAM;AAAA,SACpC;AAEH,YAAM,WAAW,KAAK,OAAO,CAAC,MAAM,QAAQ,IAAI,SAAS,CAAC,EAAG,GAAG,CAAC;AACjE,gBAAU,MAAM,UAAU,MAAM,SAAS,WAAW,SAAS,IAAI,CAAC,MAAM,SAAS,CAAC,EAAG,GAAG,CAAC,CAAC;AAAA,IAC5F;AACA,UAAM,WAAW,QAAQ;AACzB,cAAU,KAAK,GAAG,QAAQ,SAAS;AACnC,QAAI,CAAC,SAAS,OAAQ;AACtB,UAAM,SAAS,KAAK;AACpB,QAAI;AACJ,QAAI;AACF,YAAM,UAAU,SAAS,KAAK,CAAC,MAAM,eAAeF,QAAO,CAAC,CAAC;AAC7D,aAAgB,UAAU,MAAe,KAAU,WAAW,UAAU,EAAE,GAAG,SAAS,YAAY,CAAC,QAAQ,CAAC,CAAC;AAAA,IAC/G,SAAS,OAAO;AAEd,UAAI,MAAM,EAAG,OAAM;AACnB,YAAM,IAAI,iBAAiB,OAAO,SAAS,MAAM,CAAC;AAAA,IACpD;AACA,SAAK,KAAK,GAAG,QAAQ;AACrB,IAAS,aAAa,SAAS,MAAM,MAAM;AAC3C,cAAU,IAAI,IAAI,CAAC,GAAG,KAAK,UAAU,GAAG,KAAK,QAAQ,EAAE,IAAI,UAAU,CAAC;AAAA,EACxE;AACA,SAAO,EAAE,SAAS,MAAM,WAAW,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,EAAE;AAC7D;AA2BA,eAAsB,YAAuC,WAAsB,UAAqB,UAAmE,CAAC,GAAgC;AAC1M,QAAM,UAAU,YAAY,QAAQ;AACpC,MAAI,QAAQ,OAAQ,OAAM,IAAI,iBAAiB,OAAO;AACtD,QAAM,YAAY,MAAe,QAAQ,WAAW,QAAQ;AAC5D,QAAM,UAAU,UAAU,SAAS;AACnC,QAAM,QAAQ,QAAQ,OAAO,CAAC,QAAQ,kBAAkB,SAAS,UAAU,GAAG,CAAC,CAAC;AAChF,MAAI,MAAM,OAAQ,OAAM,IAAI,iBAAiB,MAAM,IAAI,CAAC,SAAS,EAAE,OAAO,IAAI,QAAQ,GAAG,GAAG,KAAK,UAAU,GAAG,CAAC,qBAAqB,EAAE,CAAC;AACvI,QAAM,SAAS,MAAM,SAAS,WAAW,OAAO;AAChD,QAAM,EAAE,SAAS,MAAM,UAAU,IAAI,MAAM,WAAgB,WAAW,WAAW,QAAQ,OAAO;AAChG,QAAM,OAAO,oBAAI,IAAI,CAAC,GAAG,QAAQ,UAAU,GAAG,QAAQ,QAAQ,CAAC;AAC/D,SAAO,EAAE,SAAS,WAAW,MAAM,SAAS,QAAQ,SAAS,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,WAAW,GAAG,QAAQ,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;AACxI;;;ACzNO,IAAMG,SAAQ;AAiBrB,IAAMC,UAAS,CAAC,MAAwC,QAAQ,CAAC,GAAG,QAAS;AAGtE,SAAS,SAAS,UAAqB,WAAiC;AAC7E,QAAM,MAAiB,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC,GAAG,UAAU,CAAC,GAAG,UAAU,CAAC,EAAE;AAC3F,WAAS,QAAQ,CAAC,GAAG,UAAU;AAC7B,UAAM,IAAI,QAAQ,CAAC,GAAG,OAAOA,QAAO,CAAC;AACrC,QAAI,KAAK,OAAO,KAAK,SAAS,aAAa,YAAY,QAAQ,aAAa,MAAO,KAAI,SAAS,KAAK,EAAE,OAAO,OAAO,EAAE,OAAO,MAAM,KAAK,MAAM,MAAM,YAAY,OAAO,WAAW,UAAU,CAAC;AAAA,aACrL,OAAO,KAAK,cAAc,SAAU,KAAI,QAAQ,KAAK,EAAE,OAAO,OAAO,GAAG,SAAS,MAAM,MAAM,KAAK,WAAW,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,KAAK,CAAC;AAAA,aACrK,OAAO,KAAK,SAAS,YAAY,EAAE,YAAY,SAAS,EAAE,aAAa,MAAO,KAAI,QAAQ,KAAK,EAAE,OAAO,MAAM,KAAK,KAAK,CAAC;AAAA,EACpI,CAAC;AACD,aAAW,KAAK,WAAW;AACzB,UAAM,OAAOA,QAAO,CAAC;AACrB,QAAI,OAAO,KAAK,QAAQ,SAAU;AAClC,UAAM,MAAM,WAAW,KAAK,GAAG;AAC/B,QAAI,KAAK,UAAU,OAAO,KAAK,WAAW,SAAU,KAAI,QAAQ,KAAK,EAAE,KAAK,YAAY,KAAK,OAAuC,CAAC;AAAA,aAC5H,KAAK,YAAY,QAAW;AACnC,YAAM,IAAI,KAAK;AACf,UAAI,SAAS,KAAK,EAAE,KAAK,IAAI,OAAO,MAAM,WAAW,IAAI,EAAE,IAAI,MAAM,OAAO,MAAM,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;AAAA,IAClH;AAAA,EACF;AACA,SAAO;AACT;AAIA,IAAM,SAAS,CAAC,SAAoD;AAClE,QAAM,MAAM,oBAAI,IAA2B;AAC3C,aAAW,OAAO,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,IAAI,UAAU,CAAC,EAAG,KAAI,IAAI,UAAU,GAAG,GAAG,CAAC,GAAI,IAAI,IAAI,UAAU,GAAG,CAAC,KAAK,CAAC,GAAI,GAAG,CAAC;AACvH,SAAO;AACT;AACA,IAAM,SAAS,CAAIC,UAAqB,MAAM,KAAK,EAAE,QAAQ,KAAK,KAAKA,MAAK,SAASF,MAAK,EAAE,GAAG,CAAC,GAAG,MAAME,MAAK,MAAM,IAAIF,SAAQ,IAAI,KAAKA,MAAK,CAAC;AAE/I,IAAM,QAAQ,CAAC,MACb,MAAM,QAAQ,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,KAAK,OAAO,MAAM,YAAY,UAAU,IAAI,WAAW,OAAQ,EAAwB,IAAI,CAAC,IAAI,KAAK;AAczI,eAAsB,QAAQ,WAAsB,QAAgB,MAAqB,WAAyD;AAChJ,QAAM,MAAM,oBAAI,IAAgB;AAChC,aAAW,CAAC,MAAME,KAAI,KAAK,OAAO,IAAI,GAAG;AACvC,QAAI;AACJ,QAAI;AACF,YAAM,OAAO,KAAK,IAAI;AACtB,eAAS,CAAC,QAAQ,QAAQ,EAAE,OAAO,CAAC,MAAM,OAAO,UAAU,MAAM,CAAC,CAAC;AAAA,IACrE,SAAS,OAAO;AACd,kBAAY,EAAE,MAAM,MAAMA,OAAM,MAAM,CAAC;AACvC;AAAA,IACF;AACA,QAAI,CAAC,OAAO,OAAQ;AACpB,eAAW,QAAQ,OAAOA,KAAI,GAAG;AAC/B,UAAI;AACF,cAAM,OAAO,MAAe,MAAkD,WAAW,EAAE,MAAM,MAAM,QAAQ,QAAQ,CAAC,UAAU,GAAG,MAAM,EAAE,OAAO,KAAK,GAAG,MAAM,EAAE,MAAM,KAAK,QAAQ,OAAO,EAAE,EAAE,CAAC;AACnM,mBAAW,KAAK,KAAM,KAAI,IAAI,WAAW,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE,UAAU,MAAM,MAAM,EAAE,QAAQ,KAAK,CAAC;AAAA,MACtG,SAAS,OAAO;AACd,oBAAY,EAAE,MAAM,MAAM,MAAM,MAAM,CAAC;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGA,eAAsB,SAAS,WAAsB,WAAqE;AACxH,QAAM,SAAS,oBAAI,IAAsB;AACzC,QAAM,OAAO,CAAC,KAAU,UAAoB;AAAE,UAAM,IAAI,OAAO,IAAI,GAAG,KAAK,oBAAI,IAAY;AAAG,UAAM,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAAG,WAAO,IAAI,KAAK,CAAC;AAAA,EAAG;AAClJ,aAAW,KAAK,UAAU,QAAS,MAAK,EAAE,KAAK,CAAC,GAAG,OAAO,KAAK,EAAE,UAAU,GAAG,YAAY,CAAC;AAC3F,aAAW,KAAK,UAAU,SAAU,MAAK,EAAE,KAAK,CAAC,cAAc,YAAY,CAAC;AAC5E,QAAM,SAA+C,CAAC;AACtD,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,OAAO,KAAK,CAAC,GAAG;AAChD,UAAM,SAAS,CAAC,GAAG,IAAI,IAAI,KAAK,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,IAAI,CAAC,CAAE,CAAC,CAAC,CAAC;AACpE,eAAW,QAAQ,OAAO,IAAI,GAAG;AAC/B,YAAM,OAAO,MAAe,MAAa,WAAW,EAAE,MAAM,MAAM,QAAQ,QAAQ,CAAC,UAAU,GAAG,MAAM,EAAE,OAAO,KAAK,GAAG,MAAM,EAAE,MAAM,KAAK,QAAQ,OAAO,EAAE,EAAE,CAAC;AAC9J,iBAAW,KAAK,MAAM;AACpB,cAAM,MAAM,WAAW,EAAE,IAAI,GAAG,MAAM;AACtC,eAAO,GAAG,IAAI,OAAO,YAAY,CAAC,GAAG,OAAO,IAAI,GAAG,CAAE,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAKO,IAAM,UAA4C,EAAE,YAAY,cAAc,YAAY,cAAc,YAAY,cAAc,QAAQ,YAAY,UAAU,SAAS;AAGzK,IAAM,YAAiC,oBAAI,IAAI,CAAC,cAAc,YAAY,CAAC;AAGlF,IAAM,gBAAgB;AAQtB,eAAsB,kBAAkB,WAAsB,QAAgB,OAA2C;AACvH,QAAM,MAA0B,CAAC;AACjC,QAAM,SAAS,IAAI,IAAc,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;AACjF,QAAM,OAAO,IAAI,IAAI,OAAO,KAAK,CAAC;AAClC,MAAI,WAAW,CAAC,GAAG,OAAO,KAAK,CAAC;AAChC,WAAS,QAAQ,GAAG,QAAQ,iBAAiB,SAAS,QAAQ,SAAS,GAAG;AACxE,UAAM,WAAW,oBAAI,IAAc;AACnC,eAAW,CAAC,MAAMA,KAAI,KAAK,OAAO,QAAQ,GAAG;AAC3C,YAAM,OAAO,KAAK,IAAI;AACtB,UAAI,CAAC,OAAO,UAAU,MAAM,UAAU,EAAG;AACzC,iBAAW,QAAQ,OAAOA,KAAI,GAAG;AAC/B,cAAM,OAAO,MAAe,MAAsC,WAAW,EAAE,MAAM,MAAM,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,GAAG,MAAM,EAAE,OAAO,KAAK,GAAG,MAAM,EAAE,MAAM,KAAK,QAAQ,OAAO,EAAE,EAAE,CAAC;AACrM,mBAAW,KAAK,MAAM;AACpB,gBAAM,SAAS,WAAW,EAAE,IAAI;AAChC,qBAAW,KAAM,CAAC,EAAgB,OAAO,MAAM,EAAE,QAAQ,KAAK,CAAC,CAAC,GAAG;AACjE,kBAAM,QAAQ,WAAW,OAAO,CAAC,CAAC;AAClC,gBAAI,KAAK,IAAI,KAAK,EAAG;AACrB,iBAAK,IAAI,KAAK;AACd,qBAAS,IAAI,OAAO,OAAO,IAAI,MAAM,CAAE;AAAA,UACzC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,SAAS,OAAO,MAAM,SAAS,WAAW,CAAC,GAAG,SAAS,KAAK,CAAC,CAAC,IAAI,CAAC;AAClF,eAAW,CAAC;AACZ,eAAW,CAAC,OAAO,IAAI,KAAK,UAAU;AACpC,UAAI,OAAO,KAAK,MAAM,UAAa,SAAS,OAAO,KAAK,CAAC,EAAG;AAC5D,aAAO,IAAI,OAAO,IAAI;AACtB,OAAC,IAAI,IAAI,MAAM,CAAC,GAAG,KAAK,KAAK;AAC7B,eAAS,KAAK,KAAK;AAAA,IACrB;AAAA,EACF;AACA,SAAO;AACT;AAuBO,SAAS,UAAU,WAAsB,QAA8C,MAA4D,UAA0B,CAAC,GAAY;AAC/L,QAAM,WAAsB,CAAC,GAAG,QAAkB,CAAC;AACnD,QAAM,SAAS,CAAC,KAAU,OAAe,QAAQ,aAAa,UAAU,GAAG,GAAG,EAAE,MAAM;AACtF,QAAM,WAAW,IAAI,IAAI,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,WAAW,IAAI,IAAI,KAAK,SAAS,IAAI,UAAU,CAAC;AACzG,aAAW,KAAK,UAAU,SAAS;AACjC,QAAI,CAAC,SAAS,IAAI,EAAE,GAAG,EAAG;AAC1B,UAAM,MAAM,OAAO,EAAE,GAAG;AACxB,QAAI,CAAC,KAAK;AAAE,YAAM,KAAK,GAAG,EAAE,GAAG,+BAA+B;AAAG;AAAA,IAAU;AAC3E,UAAM,SAAuC,CAAC;AAC9C,eAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,EAAE,UAAU,GAAG;AACzD,YAAM,QAAQ,IAAI,IAAI;AACtB,YAAM,IAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,IAAI,SAA0D,CAAC;AACtI,YAAMC,OAAO,CAAC,EAAqB,OAAO,EAAE,OAAO,CAAC,CAAC,GAAGC,UAAU,CAAC,EAAqB,OAAO,EAAE,UAAU,CAAC,CAAC;AAC7G,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,cAAM,QAAQD,KAAI,OAAO,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC,GAAG,UAAUC,QAAO,OAAO,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC;AACrG,YAAI,MAAM,UAAU,QAAQ,OAAQ,QAAO,IAAI,IAAI,EAAE,KAAK,SAAS,QAAQ,MAAM;AAAA,MACnF,WAAW,UAAU,OAAW,OAAM,KAAK,GAAG,EAAE,GAAG,IAAI,IAAI,mCAAmC;AAAA,UACzF,QAAO,IAAI,IAAI;AAAA,IACtB;AACA,QAAI,OAAO,KAAK,MAAM,EAAE,OAAQ,UAAS,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;AAAA,EACvE;AACA,aAAW,KAAK,UAAU,UAAU;AAClC,QAAI,CAAC,SAAS,IAAI,EAAE,GAAG,EAAG;AAC1B,UAAM,UAAU,QAAQ,EAAE,EAAE;AAC5B,QAAI,CAAC,SAAS;AAAE,YAAM,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,8BAA8B,OAAO,OAAO,EAAE,GAAG,GAAG,cAAc,GAAG,CAAC,GAAG;AAAG;AAAA,IAAU;AAClI,QAAI,OAAO,EAAE,KAAK,OAAO,GAAG;AAAE,YAAM,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EAAE,GAAG,CAAC,WAAW,OAAO,sBAAsB,EAAE,EAAE,kBAAkB;AAAG;AAAA,IAAU;AACjJ,aAAS,KAAK,EAAE,MAAM,EAAE,KAAK,SAAS,QAAQ,CAAC;AAC/C,QAAI,CAAC,UAAU,IAAI,EAAE,EAAE,EAAG;AAC1B,UAAM,OAAO,QAAQ,kBAAkB,EAAE,GAAG,KAAK,CAAC;AAClD,UAAM,SAAS,QAAQ,WAAW,QAAQ,SAAS,EAAE,GAAG,KAAK,CAAC,IAAI;AAClE,QAAI,WAAW,QAAW;AACxB,UAAI,KAAK,OAAQ,OAAM,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,yBAAyB,KAAK,MAAM,mBAAmB,KAAK,WAAW,IAAI,KAAK,GAAG,KAAK,KAAK,KAAK,IAAI,CAAC,0DAA0D;AAC9M;AAAA,IACF;AACA,eAAW,KAAK,QAAQ;AACtB,UAAI,OAAO,GAAG,YAAY,EAAG,OAAM,KAAK,GAAG,CAAC,iBAAiB,EAAE,GAAG,SAAS,UAAU,CAAC,CAAC,8BAA8B;AAAA,UAChH,UAAS,KAAK,EAAE,MAAM,GAAG,SAAS,aAAa,CAAC;AAAA,IACvD;AACA,QAAI,OAAO,OAAQ,OAAM,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,OAAO,KAAK,IAAI,CAAC,qBAAqB;AAAA,EACvG;AACA,aAAW,OAAO,CAAC,GAAG,KAAK,OAAO,EAAE,QAAQ,EAAE,IAAI,UAAU,GAAG;AAC7D,QAAI,OAAO,KAAK,QAAQ,EAAG,OAAM,KAAK,GAAG,GAAG,KAAK,UAAU,GAAG,CAAC,iDAAiD,UAAU,GAAG,MAAM,iBAAiB,6EAA6E,EAAE,EAAE;AAAA,QAChO,UAAS,KAAK,EAAE,MAAM,KAAK,SAAS,SAAS,CAAC;AAAA,EACrD;AACA,aAAW,KAAK,UAAU,YAAY,CAAC,EAAG,OAAM,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,KAAK,iBAAiB,EAAE,IAAI,OAAO,EAAE,IAAI,kDAAkD;AACzK,MAAI,SAAS,OAAQ,OAAM,QAAQ,gKAAgK;AACnM,SAAO,EAAE,UAAU,MAAM;AAC3B;AA+CO,IAAM,mBAAN,cAA+B,aAAa;AAAA,EACxC;AAAA,EACT,YAAY,OAAgB,SAAkB;AAC5C,UAAM,+HAA+H,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,gBAAgB,KAAK;AACpN,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;AAGO,IAAM,iBAAN,cAA6B,aAAa;AAAA,EACtC;AAAA,EACT,YAAY,OAAgB,SAAkB;AAC5C,UAAM,oEAAoE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,IAAI,cAAc,KAAK;AACvJ,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;AAWA,IAAM,MAAM,OAAc,oBAAI,KAAK,GAAE,YAAY;AAGjD,eAAsB,SAAS,WAAsB,QAAgB,UAAqB,UAAwB,CAAC,GAAqB;AACtI,QAAM,WAAW,QAAQ,SAAS;AAClC,MAAI,CAAC,SAAS,OAAQ,OAAM,IAAI,WAAW,oBAAoB;AAC/D,QAAM,UAAU,YAAY,QAAQ;AACpC,QAAM,QAAQ,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,wBAAwB,CAAC;AAC/E,MAAI,MAAM,UAAW,YAAY,QAAQ,OAAS,OAAM,IAAI,iBAAiB,WAAW,UAAU,KAAK;AAEvG,QAAM,QAAkB,CAAC;AACzB,QAAM,cAAiC,CAAC,EAAE,MAAM,MAAM,MAAM,MAC1D,MAAM,KAAK,8BAA8B,KAAK,MAAM,IAAI,IAAI,SAAS,KAAK,WAAW,IAAI,KAAK,GAAG,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChK,QAAM,cAAc,IAAI;AACxB,QAAM,YAAY,MAAe,QAAQ,WAAW,QAAQ;AAC5D,QAAM,YAAY,SAAS,UAAU,SAAS;AAC9C,QAAM,UAAU,UAAU,SAAS;AACnC,QAAM,QAAQ,MAAM,QAAQ,WAAW,QAAQ,SAAS,WAAW;AACnE,QAAM,UAAmB,EAAE,SAAS,GAAG,SAAS,UAAU,aAAa,SAAS,WAAW,WAAW,OAAO,OAAO,YAAY,KAAK,GAAG,QAAQ,CAAC,GAAG,MAAM,OAAO,SAAS,OAAO,SAAS,CAAC,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,SAAS,CAAC,GAAG,QAAQ,CAAC,GAAG,iBAAiB,CAAC,GAAG,UAAU,CAAC,GAAG,SAAS,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,EAAE,GAAG,MAAM;AAC9T,QAAM,UAAU,CAAC,UAAU,QAAQ,UAAU,CAAC,UAAU,QAAQ,UAAU,CAAC,UAAU,SAAS,UAAU,CAAC,UAAU,QAAQ,UAAU,CAAC,UAAU,SAAS;AACzJ,MAAI,QAAS,QAAO;AACpB,aAAW,KAAK,UAAU,SAAU,OAAM,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,KAAK,iBAAiB,EAAE,IAAI,mFAAmF;AACvL,UAAQ,aAAa,IAAI;AACzB,UAAQ,SAAS,MAAM,SAAS,WAAW,SAAS;AACpD,QAAM,UAAU,UAAU,SAAS,OAAO,CAAC,MAAM,UAAU,IAAI,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG;AACtF,MAAI,QAAQ,OAAQ,SAAQ,kBAAkB,MAAM,kBAAkB,WAAW,QAAQ,OAAO;AAChG,MAAI,QAAQ,OAAQ,QAAO;AAC3B,MAAI,QAAQ,WAAW,CAAE,MAAM,QAAQ,QAAQ,OAAO,EAAI,QAAO;AAEjE,MAAI,YAAmB,CAAC;AACxB,UAAQ,UAAU;AAClB,UAAQ,SAAS,IAAI;AACrB,MAAI;AACJ,MAAI;AACF,QAAI,UAAU;AAGZ,YAAM,SAAS,OAAO,YAAY,OAAO,QAAQ,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAO,OAAO,EAAE,eAAe,WAAW,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,CAAE,CAAC;AACvJ,cAAQ,eAAe,MAAM,SAAS,SAAS,EAAE,CAAC,GAAI,MAAM,EAAE;AAC9D,YAAM,SAAS,MAAM,WAAW,WAAW,WAAW,MAAM;AAC5D,OAAC,EAAE,SAAS,MAAM,UAAU,IAAI;AAChC,cAAQ,eAAe,OAAO;AAAA,IAChC,OAAO;AACL,cAAQ,eAAe;AACvB,aAAgB,UAAU,MAAe,KAAK,WAAW,QAAQ,CAAC;AAAA,IACpE;AAAA,EACF,SAAS,OAAO;AACd,QAAI,iBAAiB,kBAAkB;AAErC,cAAQ,OAAO;AACf,cAAQ,UAAU,MAAM;AACxB,cAAQ,eAAe,MAAM;AAAA,IAC/B;AACA,UAAM,IAAI,eAAe,OAAO,OAAO;AAAA,EACzC;AACA,UAAQ,OAAO;AACf,UAAQ,UAAU;AAGlB,QAAM,MAAM,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,KAAK,UAAU,GAAG,KAAK,QAAQ,CAAC,CAAC;AAC7D,QAAM,UAAU,EAAE,QAAQ,MAAM,MAAM,KAAK;AAC3C,UAAQ,UAAU,KAAK,QAAQ,IAAI,CAAC,KAAK,OAAO,EAAE,OAAO,UAAU,QAAQ,CAAC,GAAG,SAAS,MAAM,MAAM,UAAU,QAAQ,CAAC,GAAG,QAAQ,UAAU,GAAG,GAAG,KAAK,GAAG,QAAQ,EAAE;AACpK,UAAQ,UAAU,IAAI,IAAI,CAAC,SAAS,EAAE,KAAK,GAAI,MAAM,IAAI,GAAG,KAAK,QAAS,EAAE;AAG5E,QAAM,SAAS,QAAQ,gBAAgB,CAAC;AACxC,QAAM,YAAY,CAAC,MAAiC;AAClD,UAAM,OAAO,MAAM,OAAO,SAAa,OAAO,CAAC,IAAIH,QAAO,OAAO,CAAC,CAAE,IAAI;AACxE,UAAM,KAAM,MAAM,MAAyC,QAAQ,MAAM;AACzE,WAAO,OAAO,OAAO,YAAY,GAAG,SAAS,GAAG,IAAI,WAAW,EAAE,IAAI;AAAA,EACvE;AACA,UAAQ,SAAS,CAAC,GAAG,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,QAAoB,CAAC,CAAC,OAAO,QAAQ,SAAS,GAAG,KAAK,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC;AAC5J,UAAQ,UAAU,WAAW,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,WAAW,GAAG,QAAQ,OAAO,CAAC,QAAQ,CAAC,IAAI,SAAS,GAAG,KAAK,CAAC,QAAQ,OAAO,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAG9I,aAAW,QAAQ,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,GAAG,GAAG,EAAE,IAAI,CAAC,QAAQ,UAAU,WAAW,GAAG,CAAC,CAAC,CAAC,EAAG,OAAM,OAAO,KAAK,IAAI,EAAE,MAAM,MAAM,IAAI;AACxI,QAAM,aAAa,CAAC,MAAsB,OAAe,OAAO,WAAW,MAAM,EAAE;AACnF,QAAM,cAAc,IAAI,IAAI,KAAK,SAAS,IAAI,UAAU,CAAC;AACzD,QAAM,SAAS,OAAO,KAAK,QAAQ,eAAe,EAAE,OAAO,CAAC,QAAQ,YAAY,IAAI,GAAG,KAAK,QAAQ,gBAAgB,GAAG,EAAG,MAAM;AAEhI,UAAQ,UAAU,UAAU,WAAW,QAAQ,QAAQ,MAAM,EAAE,iBAAiB,QAAQ,iBAAiB,UAAU,OAAO,SAAS,SAAY,CAAC,GAAG,WAAW,CAAC;AAK/J,MAAI;AACF,QAAI,OAAO,QAAQ;AAEjB,YAAM,SAAS,MAAM,SAAS,WAAW,OAAO,QAAQ,CAAC,QAAQ,QAAQ,gBAAgB,GAAG,CAAE,CAAC;AAC/F,cAAQ,WAAW,OAAO,YAAY,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,QAAQ,gBAAgB,GAAG,EAAG,OAAO,CAAC,MAAM,SAAS,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClI,cAAQ,UAAU,UAAU,WAAW,QAAQ,QAAQ,MAAM,EAAE,iBAAiB,QAAQ,iBAAiB,UAAU,QAAQ,UAAU,WAAW,CAAC;AAAA,IACnJ;AACA,UAAM,OAAO,MAAM,QAAQ,WAAW,QAAQ,CAAC,GAAG,KAAK,SAAS,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,WAAW;AACrH,YAAQ,UAAU,QAAQ,QAAQ,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,GAAI,KAAK,IAAI,EAAE,GAAG,KAAK,QAAS,EAAE;AACxF,YAAQ,UAAU,QAAQ,QAAQ,IAAI,CAAC,MAAO,MAAM,IAAI,EAAE,GAAG,IAAI,IAAI,EAAE,GAAG,GAAG,GAAI,KAAK,IAAI,EAAE,GAAG,KAAK,QAAS,CAAE;AAE/G,UAAM,MAAM,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,KAAK,SAAS,GAAG,KAAK,GAAG,OAAO,OAAO,QAAQ,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;AAC7F,YAAQ,QAAQ,IAAI,SAAS,MAAM,SAAS,WAAW,GAAG,IAAI,CAAC;AAAA,EACjE,SAAS,OAAO;AACd,UAAM,IAAI,iBAAiB,OAAO,OAAO;AAAA,EAC3C;AACA,SAAO;AACT;AAGA,eAAe,SAAS,WAAsB,MAA2C;AACvF,QAAM,MAA2B,CAAC;AAClC,aAAW,CAAC,MAAMC,KAAI,KAAK,OAAO,IAAI,GAAG;AACvC,eAAW,QAAQ,OAAOA,KAAI,GAAG;AAC/B,YAAM,OAAO,MAAe,MAAwC,WAAW,EAAE,MAAM,MAAM,QAAQ,CAAC,YAAY,GAAG,QAAQ,CAAC,UAAU,GAAG,MAAM,EAAE,OAAO,KAAK,GAAG,MAAM,EAAE,MAAM,KAAK,QAAQ,OAAO,EAAE,EAAE,CAAC;AACzM,iBAAW,KAAK,KAAM,KAAI,EAAE,cAAc,KAAM,KAAI,WAAW,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,UAAU;AAAA,IAC/F;AAAA,EACF;AACA,SAAO;AACT;AAGA,IAAM,WAAW,CAAC,UAAuC,UAAU,YAAY,UAAU;AAYzF,eAAsB,WAAW,WAAsB,SAA6C,UAA+B,CAAC,GAAmH;AACrP,QAAM,UAAU,QAAQ,QAAQ,SAAS,IAAI,CAAC,MAAM,WAAW,OAAOD,QAAO,CAAC,EAAE,IAAI,CAAC,CAAC;AACtF,QAAMI,OAAM,MAAM,SAAS,WAAW,QAAQ,OAAO,CAAC,QAAQ,QAAQ,MAAM,GAAG,MAAM,MAAS,CAAC;AAC/F,QAAM,UAAU,QAAQ,QAAQ,CAAC,QAAS,QAAQ,MAAM,GAAG,MAAM,UAAaA,KAAI,GAAG,MAAM,QAAQ,MAAM,GAAG,IAAI,CAAC,EAAE,KAAK,KAAK,QAAQ,MAAM,GAAG,GAAI,KAAKA,KAAI,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,CAAE;AAChL,QAAM,OAAO,IAAI,IAAI,QAAQ,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AACnE,QAAM,OAAO,QAAQ,QAAQ,SAAS,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,WAAW,OAAOJ,QAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AACjG,QAAM,UAAU,KAAK,QAAQ,CAAC,MAAOA,QAAO,CAAC,EAAE,YAAY,WAAW,CAAC,WAAW,OAAOA,QAAO,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAE;AAChH,QAAM,SAAS,QAAQ,SAAS,MAAM,SAAS,WAAW,OAAO,IAAI,CAAC;AACtE,QAAM,cAAc,QAAQ,OAAO,CAAC,QAAQ,SAAS,OAAO,GAAG,CAAC,CAAC;AACjE,QAAM,WAAW,KAAK,QAAQ,CAAC,MAAM;AACnC,UAAM,OAAOA,QAAO,CAAC,GAAG,MAAM,WAAW,OAAO,KAAK,IAAI,CAAC;AAC1D,WAAO,KAAK,YAAY,YAAY,YAAY,SAAS,GAAG,IAAI,CAAC,EAAE,MAAM,KAAK,SAAS,aAAa,GAAc,CAAC,IAAI,CAAC,CAAC;AAAA,EAC3H,CAAC;AACD,SAAO,EAAE,UAAU,SAAS,YAAY;AAC1C;;;ACleA;AAAA;AAAA;AAAA;AAAA;AA4BA,eAAsB,cAAc,WAAsB,OAAkC,QAAmE;AAC7J,MAAI,CAAC,MAAM,OAAQ,QAAO,CAAC;AAE3B,QAAM,SAAS,CAAC,GAAG,OAAO,IAAI,CAAC,MAAM,YAAY,mBAAmB,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,kBAAkB,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,GAAG;AAC/J,QAAM,SAAS,MAAM,UAAU,QAAiB,EAAE,QAAQ,OAAO,MAAM,sBAAsB,MAAM,IAAI,cAAc,OAAO,CAAC;AAC7H,MAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,OAAM,IAAI,SAAS,2CAA2C,KAAK,gBAAgB,MAAM;AACrH,QAAM,MAAwC,CAAC;AAC/C,aAAW,SAAS,OAAgC,KAAI,SAAS,OAAO,MAAM,cAAc,SAAU,KAAI,MAAM,SAAS,IAAI,MAAM,QAAQ,MAAM,MAAM,IAAI,MAAM,OAAO,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IAAI,CAAC;AAC7N,SAAO;AACT;AAGA,eAAsB,qBAAqB,WAAsB,KAA6B;AAC5F,QAAM,SAAS,MAAM,UAAU,QAAiB,EAAE,QAAQ,OAAO,MAAM,6BAA6B,OAAO,EAAE,UAAU,WAAW,GAAG,EAAE,GAAG,cAAc,OAAO,CAAC;AAChK,MAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,OAAM,IAAI,SAAS,kDAAkD,KAAK,gBAAgB,MAAM;AAC5H,SAAO,OAAO,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAChE;;;ACNA,eAAe,QAAQ,QAAgB,MAAiD;AACtF,QAAM,MAAwB,CAAC;AAC/B,WAAS,IAAgC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,KAAK;AACtE,QAAI,KAAK,CAAC;AACV,UAAM,MAAM,MAAM,OAAO,KAAK,CAAC;AAC/B,QAAI,KAAK;AAAA,EACX;AACA,SAAO;AACT;AAOO,SAAS,cAAc,OAAe,OAAiD;AAC5F,QAAM,MAAM,MAAM,QAAQ,GAAG;AAC7B,MAAI,MAAM,EAAG,QAAO;AACpB,SAAO,MAAM,SAAS,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,MAAM,MAAM,MAAM,CAAC,IAAI;AACtE;AAGA,eAAsBK,UAAS,WAAsB,QAAgB,MAAsB,OAA+B;AACxH,QAAM,WAAW,WAAW,KAAK;AACjC,QAAM,QAAQ,MAAM,QAAQ,QAAQ,IAAI;AACxC,QAAM,aAAa,MAAM,OAAO,KAAK,IAAI;AACzC,QAAM,WAAW,aAAa,OAAO,OAAO,WAAW,UAAU,EAAE,OAAO,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAC7I,QAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,IAClC,cAAc,WAAW,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC;AAAA,IACzC,MAAiB,WAAW,EAAE,MAAM,SAAS,QAAQ,CAAC,EAAE,MAAM,UAAU,QAAQ,CAAC,mBAAmB,mBAAmB,EAAE,CAAC,GAAG,QAAQ,CAAC,WAAW,GAAG,MAAM,EAAE,QAAQ,SAAS,GAAG,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,EAAE,GAAG,EAAE,QAAQ,OAAO,CAAC;AAAA,EAC5O,CAAC;AACD,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,SAAS,MAAM,QAAQ,QAAQ,eAAe,IAAI,OAAO,gBAAgB,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IAAI,CAAC;AACpI,QAAM,YAAY,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC,EAAE,OAAO,CAAC,MAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK;AAChH,SAAO;AAAA,IACL;AAAA,IACA,OAAO;AAAA,IACP,QAAQ,SAAS,WAAW,OAAO,IAAI,IAAI;AAAA,IAC3C;AAAA,IACA,SAAS,QAAQ,IAAI,KAAK,CAAC;AAAA,IAC3B;AAAA,IACA,iBAAiB,QAAQ,sBAAsB;AAAA,EACjD;AACF;;;ACzDO,IAAM,oBAAqD,EAAE,QAAQ,GAAG,QAAQ,IAAI,QAAQ,KAAK,MAAM,KAAK,UAAU,KAAK,oBAAoB,KAAK,YAAY,KAAK,SAAS,IAAI;AAEzL,IAAM,gBAAiD,OAAO,YAAY,OAAO,QAAQ,iBAAiB,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAuB,CAAC,CAAC;AAQ3J,SAAS,aAAa,OAAiD;AAC5E,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,OAAO,OAAO,UAAU,WAAW,QAAQ,OAAO,UAAU,YAAY,QAAQ,KAAK,KAAK,IAAI,OAAO,KAAK,IAAI;AACpH,SAAO,OAAO,MAAM,IAAI,IAAI,OAAO,KAAK,IAAI,cAAc,IAAI,KAAK,OAAO,KAAK;AACjF;;;ACLO,IAAM,eAAoE;AAAA,EAC/E,aAAa,CAAC,UAAU,QAAQ,YAAY;AAAA,EAC5C,0BAA0B,CAAC,QAAQ;AAAA,EACnC,MAAM,CAAC,UAAU,QAAQ,YAAY;AAAA,EACrC,OAAO,CAAC,UAAU,YAAY;AAAA,EAC9B,OAAO,CAAC,UAAU,QAAQ,YAAY;AAAA,EACtC,WAAW,CAAC,UAAU,QAAQ,YAAY;AAAA,EAC1C,KAAK,CAAC,UAAU,QAAQ,YAAY;AAAA,EACpC,YAAY,CAAC,UAAU,QAAQ,YAAY;AAAA,EAC3C,gBAAgB,CAAC,UAAU,QAAQ,YAAY;AAAA,EAC/C,iBAAiB,CAAC,UAAU,QAAQ,YAAY;AAAA,EAChD,gBAAgB,CAAC,UAAU,QAAQ,YAAY;AAAA,EAC/C,SAAS,CAAC,UAAU,QAAQ,YAAY;AAAA,EACxC,SAAS,CAAC,UAAU,QAAQ,YAAY;AAAA,EACxC,gBAAgB,CAAC,UAAU,QAAQ,YAAY;AAAA,EAC/C,OAAO,CAAC,UAAU,QAAQ,YAAY;AAAA,EACtC,UAAU,CAAC,UAAU,QAAQ,YAAY;AAC3C;AASO,IAAM,gBAAgB,CAAC,SAA0B,kBAAkB,KAAK,KAAK,KAAK,CAAC;AAGnF,IAAMC,SAAQ;AAsBrB,IAAM,cAAc,oBAAI,QAAgC;AAGxD,IAAM,YAAY,CAAC,WAAsB,UAA8B;AACrE,MAAI,MAAO,QAAO,EAAE,KAAK,CAAC,SAAS,MAAM,MAAM,IAAI,IAAI,MAAM,MAAM,KAAK,CAAC,SAAS;AAAE,UAAM,MAAM,IAAI,MAAM,IAAI;AAAA,EAAG,EAAE;AACnH,QAAM,MAAM,YAAY,IAAI,SAAS,KAAK,oBAAI,IAAY;AAC1D,cAAY,IAAI,WAAW,GAAG;AAC9B,SAAO;AACT;AACA,IAAM,eAAe;AAIrB,eAAe,SAAS,WAAsB,SAAmB,OAAmC;AAClG,QAAM,SAAS,UAAU,WAAW,KAAK;AACzC,WAAS,UAAU,KAAK,WAAW,GAAG;AACpC,UAAM,QAAQ,OAAO,KAAK,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;AACpE,QAAI;AACF,YAAM,UAAU,MAAe,QAAa,WAAW,MAAM,IAAI,CAAC,UAAU;AAAA,QAC1E;AAAA,QACA,QAAQ,CAAC,GAAG,aAAa,IAAI,CAAE;AAAA,QAC/B,QAAQ,CAAC,iBAAiB;AAAA,QAC1B,MAAM,EAAE,UAAU,QAAQ;AAAA,QAC1B,MAAM,EAAE,MAAM,QAAQ,QAAQ,OAAO,EAAE;AAAA,MACzC,EAAE,CAAC;AACH,aAAO,QAAQ,KAAK;AAAA,IACtB,SAAS,OAAO;AAId,YAAM,UAAU,iBAA0B,sBAAsB,MAAM,SAAS,IAAI,CAAC,MAAM,aAAa,KAAK,EAAE,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC;AAChI,UAAI,UAAU,KAAK,CAAC,QAAQ,UAAU,QAAQ,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC,CAAC,EAAG,OAAM;AAC3F,iBAAW,KAAK,QAAS,QAAO,IAAI,CAAE;AAAA,IACxC;AAAA,EACF;AACF;AAGA,eAAsB,eAAe,WAAsB,SAA4B,UAAiC,CAAC,GAAwB;AAC/I,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,KAAK,QAAS,KAAI,CAAC,OAAO,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,EAAG,QAAO,IAAI,EAAE,KAAK,EAAE,YAAY,GAAG,EAAE,KAAK,CAAC;AAC7G,QAAM,QAAQ,CAAC,GAAG,OAAO,OAAO,CAAC;AACjC,QAAM,UAAU,MAAM,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AACrD,MAAI,QAAQ,OAAQ,OAAM,IAAI,WAAW,6DAA6D,QAAQ,KAAK,IAAI,CAAC,EAAE;AAC1H,QAAM,WAAW,oBAAI,IAA2B;AAChD,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAKA,QAAO;AAC5C,eAAW,KAAK,MAAM,SAAS,WAAW,MAAM,MAAM,GAAG,IAAIA,MAAK,GAAG,QAAQ,KAAK,GAAG;AACnF,UAAI,CAAC,EAAE,UAAU,SAAS,IAAI,EAAE,OAAO,YAAY,CAAC,EAAG;AACvD,YAAM,MAAM,WAAW,EAAE,IAAI;AAC7B,eAAS,IAAI,EAAE,OAAO,YAAY,GAAG,EAAE,QAAQ,EAAE,QAAQ,KAAK,MAAM,UAAU,GAAG,GAAG,MAAM,EAAE,QAAQ,MAAM,YAAY,aAAa,EAAE,UAAU,EAA4B,CAAC;AAAA,IAC9K;AAAA,EACF;AACA,SAAO;AAAA,IACL,OAAO,MAAM,QAAQ,CAAC,MAAM,SAAS,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;AAAA,IAC/D,SAAS,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,YAAY,CAAC,CAAC;AAAA,EAC7D;AACF;AAOA,eAAsB,WAAW,WAAsB,MAAc,UAAiC,CAAC,GAAkC;AACvI,QAAM,OAAO,KAAK,KAAK;AACvB,MAAI,WAAW,IAAI,GAAG;AAAE,UAAM,MAAM,WAAW,IAAI;AAAG,WAAO,EAAE,QAAQ,MAAM,KAAK,MAAM,UAAU,GAAG,GAAG,MAAM,MAAM,YAAY,KAAK;AAAA,EAAG;AACxI,MAAI,cAAc,IAAI,EAAG,SAAQ,MAAM,eAAe,WAAW,CAAC,IAAI,GAAG,OAAO,GAAG,MAAM,CAAC,KAAK;AAC/F,QAAM,IAAI,WAAW,IAAI,IAAI,qEAAqE;AACpG;;;ACxJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2EO,SAAS,sBAAsB,KAAuD;AAC3F,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,IAAI;AAAA,IACV,OAAO,IAAI;AAAA,IACX,aAAa,IAAI;AAAA,IACjB,eAAe,IAAI;AAAA,IACnB,YAAY,IAAI;AAAA,IAChB,YAAY,IAAI;AAAA,IAChB,cAAc,IAAI;AAAA,IAClB,UAAU,IAAI;AAAA,IACd,UAAU,IAAI;AAAA,IACd,GAAI,IAAI,OAAO,EAAE,MAAM,IAAI,KAAK,SAAS,IAAI,CAAC;AAAA,IAC9C,GAAI,IAAI,qBAAqB,EAAE,oBAAoB,IAAI,mBAAmB,SAAS,IAAI,CAAC;AAAA,IACxF,GAAI,IAAI,mBAAmB,EAAE,kBAAkB,IAAI,iBAAiB,SAAS,IAAI,CAAC;AAAA,IAClF,GAAI,IAAI,qBAAqB,EAAE,oBAAoB,IAAI,mBAAmB,SAAS,IAAI,CAAC;AAAA,IACxF,GAAI,IAAI,eAAe,EAAE,cAAc,IAAI,aAAa,QAAQ,IAAI,CAAC;AAAA,EACvE;AACF;AAEO,SAAS,YAAY,KAAmC;AAC7D,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,IAAI;AAAA,IACV,OAAO,IAAI;AAAA,IACX,aAAa,IAAI;AAAA,IACjB,UAAU,IAAI;AAAA,IACd,GAAI,IAAI,OAAO,EAAE,MAAM,IAAI,KAAK,QAAQ,IAAI,CAAC;AAAA,IAC7C,GAAI,IAAI,iBAAiB,EAAE,gBAAgB,IAAI,eAAe,SAAS,IAAI,CAAC;AAAA,IAC5E,GAAI,IAAI,mBAAmB,EAAE,kBAAkB,IAAI,iBAAiB,SAAS,IAAI,CAAC;AAAA,IAClF,GAAI,IAAI,YAAY,EAAE,WAAW,IAAI,UAAU,SAAS,IAAI,CAAC;AAAA,IAC7D,YAAY,OAAO,YAAY,OAAO,QAAQ,IAAI,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,sBAAsB,KAAK,CAAC,CAAC,CAAC;AAAA,IAC9H,GAAI,IAAI,aAAa,EAAE,YAAY,OAAO,KAAK,IAAI,UAAU,EAAE,IAAI,CAAC,UAAU,MAAM,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,EAC1H;AACF;AAEO,SAAS,YAAY,KAAmC;AAC7D,SAAO,EAAE,SAAS,IAAI,SAAS,YAAY,OAAO,YAAY,OAAO,QAAQ,IAAI,UAAU,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE;AACjJ;AAGO,SAAS,oBAAoB,OAA4C;AAC9E,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,OAAQ,MAA4B,YAAY,YAAY,CAAC,CAAE,MAA4B,cAAc,OAAQ,MAA4B,eAAe;AAC7M;AAIA,eAAsB,aAAa,WAA0C;AAC3E,SAAO,YAAY,MAAM,UAAU,QAA2B,EAAE,QAAQ,OAAO,MAAM,YAAY,cAAc,OAAO,CAAC,CAAC;AAC1H;AAEA,eAAsB,aAAa,WAAsB,OAA2C;AAClG,SAAO,YAAY,MAAM,UAAU,QAA2B,EAAE,QAAQ,OAAO,MAAM,YAAY,mBAAmB,KAAK,CAAC,IAAI,cAAc,OAAO,CAAC,CAAC;AACvJ;AAEA,eAAsB,uBAAuB,WAAsB,UAA2D;AAC5H,QAAM,CAAC,MAAM,SAAS,IAAI,SAAS,MAAM,GAAG;AAC5C,MAAI,CAAC,QAAQ,CAAC,UAAW,OAAM,IAAI,WAAW,IAAI,QAAQ,4CAA4C;AACtG,SAAO,sBAAsB,MAAM,UAAU,QAAqC,EAAE,QAAQ,OAAO,MAAM,YAAY,mBAAmB,IAAI,CAAC,IAAI,mBAAmB,SAAS,CAAC,IAAI,cAAc,OAAO,CAAC,CAAC;AAC3M;;;AC5GO,IAAM,YAAN,MAAM,WAAU;AAAA;AAAA,EAEZ,QAAQ,oBAAI,IAAsC;AAAA,EAClD,UAAU,oBAAI,IAA+C;AAAA;AAAA,EAGtE,OAAO,cAAc,WAAiC;AACpD,UAAM,QAAQ,IAAI,WAAU;AAC5B,eAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,UAAU,UAAU,EAAG,OAAM,MAAM,IAAI,OAAO,IAAI;AAC7F,WAAO;AAAA,EACT;AACF;AAEO,IAAM,SAAN,MAAM,QAAkC;AAAA,EAM7C,YAA6B,WAAuB,MAAkB,QAAmB,IAAI,UAAU,GAAG;AAA7E;AAC3B,SAAK,QAAQ;AACb,SAAK,QAAQ,MAAM;AACnB,SAAK,UAAU,MAAM;AACrB,QAAI;AAAM,iBAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,KAAK,UAAU,EAAG,KAAI,CAAC,KAAK,MAAM,IAAI,KAAK,EAAG,MAAK,MAAM,IAAI,OAAO,IAAI;AAAA;AAAA,EAC/H;AAAA,EAL6B;AAAA,EALZ;AAAA,EACA;AAAA;AAAA,EAER;AAAA;AAAA,EAUT,cAAc,WAA8B;AAC1C,WAAO,IAAI,QAAO,WAAW,QAAW,KAAK,KAAK;AAAA,EACpD;AAAA;AAAA,EAGA,OAAO,cAAc,WAA8B;AACjD,WAAO,IAAI,QAAO,QAAW,SAAS;AAAA,EACxC;AAAA;AAAA,EAGA,UAAU,OAAqD;AAC7D,WAAO,KAAK,MAAM,IAAI,KAAK,IAAI,KAAK,MAAM,IAAI,KAAK,IAAK;AAAA,EAC1D;AAAA;AAAA,EAGA,UAAU,MAAsB,MAAsD;AACpF,WAAO,YAAY,MAAM,MAAM,IAAI;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,MAAsB,IAAiC;AAChE,UAAM,IAAI,KAAK,UAAU,IAAI;AAC7B,WAAO,GAAG,aAAa,EAAE,WAAW,SAAS,EAAE,IAAI;AAAA,EACrD;AAAA;AAAA,EAGA,IAAI,SAA2B;AAC7B,WAAO,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,MAAM,KAAK;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,KAAK,OAAkD;AAC3D,QAAI,KAAK,MAAM,IAAI,KAAK,EAAG,QAAO,KAAK,MAAM,IAAI,KAAK;AACtD,UAAM,WAAW,KAAK,QAAQ,IAAI,KAAK;AACvC,QAAI,SAAU,QAAO;AACrB,QAAI,CAAC,KAAK,WAAW;AAAE,WAAK,MAAM,IAAI,OAAO,IAAI;AAAG,aAAO;AAAA,IAAM;AACjE,UAAM,UAAe,aAAa,KAAK,WAAW,KAAK,EACpD,MAAM,CAAC,UAAmB;AAAE,UAAI,iBAAiB,YAAY,MAAM,WAAW,IAAK,QAAO;AAAM,YAAM;AAAA,IAAO,CAAC,EAC9G,KAAK,CAAC,SAAS;AAAE,WAAK,MAAM,IAAI,OAAO,IAAI;AAAG,aAAO;AAAA,IAAM,CAAC,EAC5D,QAAQ,MAAM,KAAK,QAAQ,OAAO,KAAK,CAAC;AAC3C,SAAK,QAAQ,IAAI,OAAO,OAAO;AAC/B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAU,UAA6C;AAC3D,eAAW,WAAW,UAAU;AAC9B,YAAMC,SAAQ,QAAQ,OAAO;AAC7B,UAAI,CAACA,OAAO;AACZ,YAAM,OAAO,WAAWA,OAAM,MAAM,QAAQ;AAC5C,UAAI,CAAC,KAAM;AACX,eAAS,QAAQ,GAAG,QAAQ,IAAI,SAAS,GAAG;AAC1C,cAAM,SAAS,CAAC,GAAG,YAAY,MAAMA,QAAO,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;AACnF,YAAI,CAAC,OAAO,OAAQ;AACpB,cAAM,QAAQ,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,QAAQ,SAAsC;AAC5D,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AACpD,QAAM,OAAO,OAAO,KAAK,OAAO;AAChC,QAAM,OAAQ,KAAK,WAAW,KAAK,KAAK,CAAC,EAAG,WAAW,GAAG,IAAK,QAAoC,KAAK,CAAC,CAAE,IAAI;AAC/G,MAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,OAAO,KAAK,SAAS,SAAU,QAAO;AAC/E,MAAI,YAAY,QAAQ,aAAa,QAAQ,eAAe,KAAM,QAAO;AACzE,SAAO;AACT;;;ACrIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2CO,IAAM,yBAAyB;AAG/B,IAAM,SAAS,CAAC,SAAoC,KAAK,UAAU,IAAI;AAM9E,eAAsB,SAAS,WAAsB,MAAyB,UAA2B,CAAC,GAA2B;AACnI,QAAM,SAAS,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC;AAChC,MAAI,CAAC,OAAO,OAAQ,QAAO,CAAC;AAC5B,QAAM,UAAU,mBAAmB,OAAO,MAAM,CAAC;AACjD,QAAM,UAAU,QAAQ,UAAU,EAAE,mBAAmB,QAAQ,QAAQ,IAAI;AAC3E,QAAM,SAAS,QAAQ,WAAW,QAAQ,gBAAgB,0BACtD,MAAM,UAAU,QAAiB,EAAE,QAAQ,OAAO,MAAM,aAAa,OAAO,IAAI,SAAS,cAAc,OAAO,CAAC,IAE/G,MAAM,UAAU,QAAiB,EAAE,QAAQ,QAAQ,MAAM,aAAa,SAAS,MAAM,SAAS,aAAa,qCAAqC,cAAc,QAAQ,YAAY,KAAK,CAAC;AAC5L,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,EAAG,OAAM,IAAI,SAAS,2CAA2C,KAAK,UAAU,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,mBAAmB,KAAK,gBAAgB,MAAM;AACrN,SAAO;AACT;AAGA,eAAsB,YAAY,WAAsB,KAAa,UAA2B,CAAC,GAAoB;AACnH,QAAM,MAAM,MAAM,SAAS,WAAW,CAAC,GAAG,GAAG,OAAO;AACpD,SAAO,IAAI,GAAG,KAAK;AACrB;;;ACrEA;AAAA;AAAA,iBAAAC;AAAA,EAAA,aAAAC;AAAA;AA8BA,SAAS,SAAS,OAA2B;AAC3C,QAAM,UAAU,MAAM;AACtB,QAAM,YAAY,SAAS,cAAc,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,CAAC,CAAC,CAAC;AAC3H,SAAO,SAAS,SAAS,IAAI,SAAS,SAAS,KAAK,IAAI,GAAG,MAAM,QAAQ,kBAAkB,MAAM,OAAO,IAAI;AAC9G;AAQA,eAAsBC,SAAmC,WAAsB,IAAiB,UAAuB,CAAC,GAAqB;AAC3I,aAAW,KAAK,GAAI,KAAI,CAAC,EAAE,KAAM,OAAM,IAAI,WAAW,YAAY,EAAE,IAAI,sDAAsD;AAC9H,MAAI,CAAC,GAAG,OAAQ,QAAO,CAAC;AACxB,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,UAAU,QAAiB,EAAE,QAAQ,QAAQ,MAAM,aAAa,MAAM,IAAI,cAAc,QAAQ,YAAY,KAAK,CAAC;AAAA,EACrI,SAAS,OAAO;AACd,UAAM,iBAAiB,YAAY,MAAM,WAAW,MAAM,SAAS,KAAK,IAAI;AAAA,EAC9E;AACA,MAAI,CAAC,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW,GAAG,UAAU,CAAC,SAAS,MAAM,MAAM,OAAO,GAAG;AAC/F,UAAM,IAAI,SAAS,0BAA0B,MAAM,QAAQ,QAAQ,IAAI,GAAG,SAAS,MAAM,aAAa,gBAAgB,QAAQ,GAAG,MAAM,YAAY,KAAK,gBAAgB,QAAQ;AAAA,EAClL;AACA,SAAO,GAAG,IAAI,CAAC,GAAG,MAAM;AACtB,UAAM,OAAO,QAAQ,SAAS,WAAW,EAAE,MAAM,EAAE,IAAI;AACvD,UAAM,UAAkC,OAAO,EAAE,QAAQ,QAAQ,QAAS,KAAK,IAAI;AACnF,WAAQ,SAAyC,CAAC,EAAG,IAAI,CAAC,QAAQ,YAAiB,KAAK,OAAO,CAAC;AAAA,EAClG,CAAC;AACH;AAGA,eAAsBC,OAAiC,WAAsB,GAAc,UAAuB,CAAC,GAAmB;AACpI,QAAM,CAAC,IAAI,IAAI,MAAMD,SAAa,WAAW,CAAC,CAAC,GAAG,OAAO;AACzD,SAAO,QAAQ,CAAC;AAClB;;;ACjEA;AAAA;AAAA;AAAA,aAAAE;AAAA,EAAA;AAAA,cAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AA6EA,IAAM,QAAQ,CAAC,SAAgC,EAAE,MAAM,WAAW,IAAI,KAAK,EAAE;AAUtE,SAAS,kBAA6C,KAAoB,EAAE,SAAAC,WAAU,MAAM,IAAI,CAAC,GAAQ;AAC9G,QAAM,MAA+B,EAAE,MAAMA,WAAU,IAAI,KAAK,WAAW,IAAI,EAAE,EAAE;AACnF,QAAM,QAAQ,IAAI,cAAc,CAAC;AACjC,aAAW,CAAC,KAAK,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC5C,QAAI,EAAE,UAAU,YAAY;AAC1B,UAAI,GAAG,IAAI,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,EAAE,QAAQ,MAAM,EAAE,KAAK,IAAI;AAAA,IACtF,WAAW,QAAQ,gBAAgB,OAAO,EAAE,UAAU,UAAU;AAC9D,UAAI,GAAG,IAAI,aAAa,EAAE,KAAK;AAAA,IACjC,OAAO;AACL,UAAI,GAAG,IAAI,EAAE;AAAA,IACf;AAAA,EACF;AAEA,aAAW,CAAC,KAAK,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC5C,UAAM,MAAM,IAAI,QAAQ,GAAG;AAC3B,QAAI,MAAM,KAAK,EAAE,UAAU,YAAa;AACxC,UAAM,MAAM,IAAI,MAAM,GAAG,GAAG,GAAG,OAAO,IAAI,MAAM,MAAM,CAAC;AACvD,QAAI,KAAK,SAAS,GAAG,EAAG;AACxB,UAAM,SAAS,IAAI,GAAG;AACtB,UAAM,SAAS,EAAE;AACjB,QAAI,MAAM,QAAQ,MAAM,KAAK,MAAM,QAAQ,MAAM,EAAG,QAAO,QAAQ,CAAC,KAAK,MAAM;AAAE,UAAI,OAAO,OAAO,QAAQ,SAAU,CAAC,IAAgC,IAAI,IAAI,OAAO,CAAC;AAAA,IAAG,CAAC;AAAA,aACjK,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,QAAQ,EAAE,KAAK,EAAG,CAAC,OAAmC,IAAI,IAAI,EAAE;AAAA,EACpJ;AACA,SAAO;AACT;AAGO,SAAS,QAAQ,QAAwD;AAC9E,SAAO;AAAA,IACL,MAAM,OAAO,UAAU,OAAO,MAAM,KAAK,GAAG;AAAA,IAC5C,QAAQ,OAAO,UAAU,OAAO,QAAQ,UAAU,OAAO,UAAU,OAAO,OAAQ,KAAK,GAAG,IAAI;AAAA,IAC9F,MAAM,OAAO,OAAO,OAAO,QAAQ,OAAO,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,CAAU,EAAE,KAAK,GAAG,CAAC,EAAE,EAAE,KAAK,GAAG,IAAI;AAAA,IACvH,MAAM,OAAO;AAAA,IACb,QAAQ,OAAO,QAAQ,KAAK,GAAG;AAAA,IAC/B,MAAM,OAAO,MAAM,KAAK,GAAG;AAAA,IAC3B,MAAM,GAAG,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK;AAAA,IAC9C,SAAS,OAAO,YAAY,SAAY,SAAY,OAAO,OAAO,OAAO;AAAA,IACzE,WAAW,OAAO,cAAc,SAAY,SAAY,OAAO,OAAO,SAAS;AAAA,IAC/E,MAAM,OAAO;AAAA,EACf;AACF;AAMA,eAAe,KAAwB,WAAsB,MAAc,QAAoBA,UAA4C;AACzI,MAAI,CAAC,OAAO,KAAM,OAAM,IAAI,WAAW,kBAAkB,IAAI,6CAA6C;AAC1G,QAAM,MAAM,MAAM,UAAU,QAAwB,EAAE,QAAQ,OAAO,MAAM,OAAO,QAAQ,MAAM,GAAG,cAAc,OAAO,CAAC;AACzH,SAAO,EAAE,OAAO,IAAI,UAAU,CAAC,GAAG,IAAI,CAAC,MAAM,kBAAuB,GAAG,EAAE,SAAAA,SAAQ,CAAC,CAAC,GAAG,OAAO,OAAO,IAAI,UAAU,YAAY,IAAI,SAAS,IAAI,IAAI,QAAQ,MAAM,UAAU,IAAI,UAAU,WAAW,IAAI,UAAU;AACpN;AAGO,IAAMC,QAAO,CAA4B,WAAsB,MAAc,WAClF,KAAU,WAAW,mBAAmB,mBAAmB,IAAI,CAAC,IAAI,QAAQ,KAAK;AAGnF,eAAsBC,KAA+B,WAAsB,KAAU,QAAiC;AACpH,QAAM,CAAC,MAAM,EAAE,IAAI,WAAW,GAAG,EAAE,MAAM,GAAG;AAC5C,QAAM,MAAM,MAAM,UAAU,QAAuB,EAAE,QAAQ,OAAO,MAAM,mBAAmB,mBAAmB,IAAK,CAAC,IAAI,mBAAmB,EAAG,CAAC,IAAI,OAAO,EAAE,KAAK,QAAQ,KAAK,GAAG,EAAE,GAAG,cAAc,OAAO,CAAC;AAC9M,SAAO,kBAAuB,GAAG;AACnC;AAeA,eAAsB,QAAQ,WAAsB,KAAU,IAAsC;AAClG,QAAM,CAAC,MAAM,EAAE,IAAI,WAAW,GAAG,EAAE,MAAM,GAAG;AAC5C,MAAI,CAAC,QAAQ,CAAC,GAAI,OAAM,IAAI,WAAW,IAAI,GAAG,oCAAoC;AAClF,QAAM,MAAM,MAAM,UAAU,QAAuB,EAAE,QAAQ,QAAQ,MAAM,mBAAmB,mBAAmB,IAAI,CAAC,IAAI,mBAAmB,EAAE,CAAC,IAAI,OAAO,EAAE,GAAG,GAAG,cAAc,OAAO,CAAC;AACzL,MAAI,CAAC,OAAO,OAAO,IAAI,OAAO,YAAY,CAAC,IAAI,GAAI,OAAM,IAAI,SAAS,UAAU,EAAE,OAAO,GAAG,iCAAiC,KAAK,gBAAgB,GAAG;AACrJ,QAAM,SAAS,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC,KAAK;AACvC,SAAO,EAAE,KAAK,WAAW,IAAI,EAAE,GAAG,OAAO;AAC3C;AAWA,eAAsB,SAAoC,WAAsB,MAAc,UAAyB,CAAC,GAA2B;AACjJ,QAAM,MAAM,MAAM,UAAU,QAAuB,EAAE,QAAQ,OAAO,MAAM,kBAAkB,mBAAmB,IAAI,CAAC,IAAI,OAAO,EAAE,KAAK,QAAQ,MAAM,WAAW,QAAQ,GAAG,IAAI,OAAU,GAAG,cAAc,OAAO,CAAC;AACjN,QAAM,EAAE,MAAM,UAAU,GAAG,OAAO,IAAI,kBAAuB,EAAE,GAAG,KAAK,IAAI,IAAI,MAAM,GAAG,IAAI,KAAK,CAAC;AAClG,SAAO;AACT;AAGO,IAAM,UAAU,CAA4B,WAAsB,QAAgB,WAAiD;AACxI,QAAM,CAAC,MAAM,EAAE,IAAI,OAAO,MAAM,GAAG;AACnC,QAAM,OAAO,KAAK,mBAAmB,mBAAmB,IAAK,CAAC,IAAI,mBAAmB,EAAE,CAAC,KAAK,mBAAmB,mBAAmB,IAAK,CAAC;AACzI,SAAO,KAAU,WAAW,MAAM,QAAQ,IAAI;AAChD;;;ACpIA,IAAM,gBAAgB;AACtB,IAAM,YAAY,CAAC,QAAQ,YAAY,YAAY,OAAO;AAmBnD,IAAM,mBAAN,MAAM,kBAAiB;AAAA,EACnB;AAAA,EACA;AAAA,EAET,YAAY,QAAsB,UAAqC,CAAC,GAAG;AAEzE,UAAM,OAAsB,aAAa,UAAU,EAAE,WAAW,QAAQ,IAAI;AAC5E,SAAK,YAAY,KAAK,aAAa,qBAAqB;AAAA,MACtD,SAAS,OAAO;AAAA,MAChB,eAAe,OAAO;AAAA,MACtB,aAAa,OAAO;AAAA,MACpB,WAAW,OAAO;AAAA,MAClB,SAAS,OAAO;AAAA,MAChB,gBAAgB,OAAO;AAAA,MACvB,aAAa,OAAO;AAAA,MACpB,gBAAgB,OAAO;AAAA,MACvB,sBAAsB,OAAO;AAAA,IAC/B,CAAC;AACD,SAAK,SAAS;AACd,SAAK,SAAS,KAAK,UAAU,IAAI,OAAO,KAAK,WAAW,KAAK,WAAW,KAAK,KAAK;AAAA,EACpF;AAAA,EAEiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjB,WAAW,QAAuC;AAChD,UAAM,OAAO,KAAK;AAClB,UAAM,YAAuB,EAAE,SAAS,CAAC,YAAY,KAAK,QAAQ,EAAE,GAAG,SAAS,QAAQ,QAAQ,UAAU,OAAO,CAAC,EAAE;AACpH,WAAO,IAAI,kBAAiB,KAAK,QAAQ,EAAE,WAAW,QAAQ,KAAK,OAAO,CAAC;AAAA,EAC7E;AAAA,EAeA,MAAM,MAAM,GAAyC;AACnD,UAAM,KAAK,OAAO,UAAU,CAAC,CAAC,CAAC;AAC/B,WAAeC,OAAM,KAAK,WAAW,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,EACjE;AAAA,EAKA,MAAM,QAAQ,IAAuD;AACnE,UAAM,KAAK,OAAO,UAAU,EAAE;AAC9B,WAAeC,SAAQ,KAAK,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,EACzE;AAAA,EASA,MAAM,IAAI,KAAU,QAA8D;AAChF,UAAM,OAAO,MAAM,KAAK,MAAM,EAAE,MAAM,WAAW,GAAG,GAAG,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,GAAI,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,EAAE,CAAC;AACnH,WAAO,KAAK,CAAC,KAAK;AAAA,EACpB;AAAA,EASA,MAAM,UAAU,GAAsC;AACpD,UAAM,KAAK,OAAO,UAAU,CAAC,CAAC,CAAC;AAC/B,WAAgB,UAAU,KAAK,WAAW,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,EACtE;AAAA,EAWA,OAAO,MAAM,GAAuB,UAAwB,CAAC,GAA6C;AACxG,QAAI,CAAC,EAAE,KAAM,OAAM,IAAI,WAAW,YAAY,EAAE,IAAI,6CAA6C;AACjG,UAAM,QAAQ,QAAQ,SAAS;AAC/B,UAAM,OAAO,EAAE,KAAK;AACpB,QAAI,QAAQ,EAAE,KAAK,OAAOC,QAAO;AACjC,WAAOA,QAAO,OAAO;AACnB,YAAM,OAAO,KAAK,IAAI,MAAM,QAAQA,KAAI;AACxC,YAAM,OAAO,MAAM,KAAK,MAAM,EAAE,GAAG,GAAG,MAAM,EAAE,MAAM,MAAM,MAAM,EAAE,CAAC;AACnE,UAAI,KAAK,OAAQ,OAAM;AACvB,MAAAA,SAAQ,KAAK;AACb,eAAS,KAAK;AACd,UAAI,KAAK,SAAS,KAAM;AAAA,IAC1B;AAAA,EACF;AAAA,EAKA,MAAM,IAAI,GAAuB,UAAwB,CAAC,GAAqB;AAC7E,UAAM,MAAe,CAAC;AACtB,qBAAiBC,SAAQ,KAAK,MAAM,GAAG,OAAO,EAAG,KAAI,KAAK,GAAGA,KAAI;AACjE,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,KAAkB;AACtB,UAAM,CAAC,GAAG,IAAI,MAAM,KAAK,MAAU,EAAE,MAAM,UAAU,QAAQ,WAAW,QAAQ,CAAC,eAAe,GAAG,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,EAAE,CAAC;AAChI,QAAI,CAAC,IAAK,OAAM,IAAI,SAAS,oDAAoD,GAAG,WAAW;AAC/F,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAKS,OAAO;AAAA,IACd,WAAW,MAAW,aAAa,KAAK,SAAS;AAAA,IACjD,WAAW,CAAC,UAAuB,aAAa,KAAK,WAAW,KAAK;AAAA,IACrE,qBAAqB,CAAC,aAAyC,uBAAuB,KAAK,WAAW,QAAQ;AAAA,EAChH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAS,MAAyB,SAA6D;AAC7F,WAAY,SAAS,KAAK,WAAW,MAAM,OAAO;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYS,OAAO;AAAA,IACd,MAAM,CAA4B,MAAc,WAAmCC,MAAU,KAAK,WAAW,MAAM,MAAM;AAAA,IACzH,KAAK,CAA4B,KAAa,WAA4BC,KAAS,KAAK,WAAW,KAAK,MAAM;AAAA,IAC9G,SAAS,CAA4B,QAAgB,WAAmC,QAAa,KAAK,WAAW,QAAQ,MAAM;AAAA,IACnI,UAAU,CAAiB,MAAS,YAAkC,SAAoB,KAAK,WAAW,MAAM,OAAO;AAAA,IACvH,SAAS,CAAC,KAAU,OAAqB,QAAQ,KAAK,WAAW,KAAK,EAAE;AAAA,EAC1E;AAAA;AAAA,EAGA,MAAM,KAAK,KAAwB;AACjC,YAAQ,MAAY,QAAQ,KAAK,WAAW,KAAK,MAAM,GAAG;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASS,SAAS;AAAA,IAChB,UAAU,CAAC,MAAY,UAA6BC,UAAS,KAAK,WAAW,KAAK,QAAQ,MAAM,KAAK;AAAA,IACrG,SAAS,CAAC,OAAwB,WAAkC,cAAc,KAAK,WAAW,OAAO,MAAM;AAAA,IAC/G,gBAAgB,CAAC,QAAoB,qBAAqB,KAAK,WAAW,GAAG;AAAA,EAC/E;AAAA;AAAA,EAGS,UAAU;AAAA,IACjB,OAAO,CAA4B,MAA0B,KAAK,MAAW,CAAC;AAAA,IAC9E,SAAS,CAA4B,OAA6B,KAAK,QAAa,EAAE;AAAA,EACxF;AAAA;AAAA;AAAA,EAKS,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAShB,MAAM,OAAkC,UAA8B,YAAmG;AACvK,YAAM,KAAK,OAAO,UAAU,QAAQ;AACpC,aAAgB,UAAU,MAAe,KAAU,KAAK,WAAW,UAAU,EAAE,GAAG,SAAS,QAAQ,KAAK,OAAO,CAAC,CAAC;AAAA,IACnH;AAAA;AAAA,IAEA,SAAS,CAAC,aAA0C,QAAQ,KAAK,WAAW,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOpF,aAAa,OAAkC,UAA8B,YAA2D;AACtI,YAAM,KAAK,OAAO,UAAU,QAAQ;AACpC,aAAa,YAAiB,KAAK,WAAW,UAAU,EAAE,GAAG,SAAS,QAAQ,KAAK,OAAO,CAAC;AAAA,IAC7F;AAAA;AAAA,IAEA,OAAO,OAAkC,MAA0B;AACjE,YAAM,KAAK,OAAO,UAAU,CAAC,CAAC,CAAC;AAC/B,aAAgB,MAAW,KAAK,WAAW,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,IACvE;AAAA;AAAA,IAEA,SAAS,OAAkC,OAA6B;AACtE,YAAM,KAAK,OAAO,UAAU,EAAE;AAC9B,aAAgB,QAAa,KAAK,WAAW,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,IAC1E;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOS,UAAU;AAAA,IACjB,SAAS,CAAC,YAAuC,eAAe,KAAK,WAAW,SAAS,EAAE,OAAO,KAAK,OAAO,MAAM,CAAC;AAAA,IACrH,KAAK,CAAC,SAAyB,WAAW,KAAK,WAAW,MAAM,EAAE,OAAO,KAAK,OAAO,MAAM,CAAC;AAAA,EAC9F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQS,QAAQ;AAAA,IACf,KAAK,CAAC,UAA8B,YAAuC,SAAS,KAAK,WAAW,KAAK,QAAQ,UAAU,OAAO;AAAA,IAClI,YAAY,CAAC,SAAmD,YAAwC,WAAW,KAAK,WAAW,SAAS,OAAO;AAAA,EACrJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOS,cAAc;AAAA,IACrB,MAAM,CAAC,OAAe,YAAqE,KAAK,KAAK,WAAW,OAAO,OAAO;AAAA,IAC9H,MAAM,CAAC,OAAe,YAAqE,KAAK,KAAK,WAAW,OAAO,OAAO;AAAA,IAC9H,MAAM,CAAC,OAAoC,KAAK,KAAK,WAAW,EAAE;AAAA,IAClE,KAAK,CAAC,OAAoC,IAAI,KAAK,WAAW,EAAE;AAAA,IAChE,KAAK,CAAC,OAAe,MAAwB,YAAgD,IAAI,KAAK,WAAW,OAAO,MAAM,OAAO;AAAA,IACrI,KAAK,CAAC,IAAqB,MAAwB,gBAAqC,IAAI,KAAK,WAAW,IAAI,MAAM,WAAW;AAAA,IACjI,QAAQ,CAAC,OAAoC,OAAO,KAAK,WAAW,EAAE;AAAA;AAAA,IAEtE,KAAK,CAAC,OAAwB,KAAK,KAAK,WAAW,EAAE;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQS,iBAAiB;AAAA,IACxB,QAAQ,CAAC,OAAe,MAAwB,YAAqE,oBAAoB,KAAK,WAAW,OAAO,MAAM,OAAO;AAAA;AAAA,IAE7K,KAAK,CAAC,OAAwB,KAAK,KAAK,cAAc,EAAE;AAAA,IACxD,WAAW,CAAC,SAA4B,2BAA2B,MAAM,KAAK,OAAO,OAAO;AAAA,EAC9F;AAAA;AAAA,EAGS,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOd,OAAO,CAAC,QAAsB;AAC5B,YAAM,OAAO,KAAK,OAAO,QAAQ,QAAQ,QAAQ,EAAE;AACnD,YAAM,OAAO,IAAI,KAAK;AACtB,UAAI,WAAW,IAAI,EAAG,QAAO,GAAG,IAAI,uBAAuB,WAAW,IAAI,CAAC;AAC3E,UAAI,cAAc,IAAI,EAAG,QAAO,GAAG,IAAI,0BAA0B,mBAAmB,IAAI,CAAC;AACzF,YAAM,IAAI,WAAW,IAAI,GAAG,qEAAqE;AAAA,IACnG;AAAA,IACA,YAAY,CAAC,OAAmC,cAAc,KAAK,OAAO,SAAS,EAAE;AAAA,IACrF,eAAe,CAAC,OAAmC,iBAAiB,KAAK,OAAO,SAAS,EAAE;AAAA,EAC7F;AACF;","names":["CHUNK","query","query","one","queries","bodyOf","byType","list","CHUNK","bodyOf","list","add","remove","now","describe","CHUNK","query","queries","query","queries","query","get","list","history","list","get","query","queries","read","page","list","get","describe"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/errors.ts","../src/core/fetchTransport.ts","../src/types/oid.ts","../src/wire/assetApi.ts","../src/wire/select.ts","../src/wire/attachment.ts","../src/services/attachments.ts","../src/services/guard.ts","../src/services/batch.ts","../src/wire/fields.ts","../src/services/fields.ts","../src/types/asset.ts","../src/services/resolve.ts","../src/wire/meta.ts","../src/services/schema.ts","../src/wire/loc2.ts","../src/wire/queryV1.ts","../src/wire/rest1.ts","../src/client.ts"],"sourcesContent":["export { AgilityApiClient } from \"./client\";\nexport type { ClientOptions, Me, Page, PagesOptions } from \"./client\";\nexport { ApiError, UsageError, WrappedError, kindOf } from \"./core/errors\";\nexport type { ErrorKind } from \"./core/errors\";\nexport { createFetchTransport } from \"./core/fetchTransport\";\nexport type { FetchTransportConfig, UnauthorizedContext, UnauthorizedDecision } from \"./core/fetchTransport\";\nexport type { ClientConfig } from \"./core/clientConfig\";\nexport type { RequestBody, RequestOptions, ResponseType, Transport } from \"./core/transport\";\n\n// The model: what things are.\nexport type { Asset, AttributeValue, CustomAttributes, DateString, Oid, Ref, AssetStateValue } from \"./types/asset\";\nexport { ASSET_STATE_CODES, assetStateOf } from \"./types/asset\";\nexport { isOidToken, momentless, parseOid, toOid, typeOfOid } from \"./types/oid\";\nexport type { OidParts } from \"./types/oid\";\nexport type { AssetType, AttributeDefinition, AttributeLookup, AttributeType, AttributeTokenRef, AssetTypeToken, Metamodel } from \"./types/metamodel\";\nexport type * from \"./types/assets/index\";\nexport type { CreateType, CustomList, From, RowOf, RowsOf, SelectKey, SelectPath, SelectValue, Selected, TypeOf } from \"./types/query\";\n\n// The wire layer: one module per endpoint.\nexport { assetApi, rest1, meta, loc2, queryV1, attachment, fields } from \"./wire\";\nexport type { OperationResult, Template } from \"./wire/rest1\";\nexport type { FieldsOf } from \"./services/fields\";\nexport { importantName } from \"./services/fields\";\nexport type { Bytes, EmbeddedImage } from \"./wire/attachment\";\nexport * as select from \"./wire/select\";\nexport type { AssetApiResponse, Command, CommandBody, CommandFailureDetail, Outcome, CommandValue, CreateBody, ExecuteBody, QueryBody, UpdateBody, ReadOptions, RowContext, SendOptions } from \"./wire/assetApi\";\nexport { CommandFailureError, parseViolation } from \"./wire/assetApi\";\nexport type { Violation } from \"./wire/assetApi\";\nexport type { AssetDocument, AssetsDocument, ReadParams, ReadResult } from \"./wire/rest1\";\nexport type { Localizations, LocalizeOptions } from \"./wire/loc2\";\nexport type { ConditionalOptions, Tagged } from \"./wire/meta\";\nexport type { QueryRejection } from \"./wire/queryV1\";\n\n// Services: what to do.\nexport { Schema, TypeCache } from \"./services/schema\";\nexport { AttachmentUploadError, INLINE_LIMIT } from \"./services/attachments\";\nexport type { AddOptions as AttachmentAddOptions, AttachmentInfo } from \"./services/attachments\";\nexport { CHUNK as RESOLVE_CHUNK, NUMBER_ROOTS, isAssetNumber, resolveNumbers, resolveRef } from \"./services/resolve\";\nexport type { Resolution, ResolvedAsset } from \"./services/resolve\";\nexport { UNGUARDABLE_TYPES, UnguardableError, guard, sendGuarded, stampsOf, touchedBy, unguardable } from \"./services/guard\";\nexport type { GuardedResult, Unguardable } from \"./services/guard\";\nexport { BatchRecordError, BatchSendError, INVERSE, describe as describeBatch, namesOf, reverseOf, reversible, runBatch, snapshot } from \"./services/batch\";\nexport type { BatchOptions, Described, NameLookupFailure, Named, Receipt, Reverse } from \"./services/batch\";\n","/**\n * Every error the SDK throws is an ApiError, and every ApiError has a\n * `kind`: the one word a caller branches on. `status` and `code` say what\n * exactly happened; `kind` says what to do about it.\n *\n * auth 401: re-authenticate (the transport's onUnauthorized hook ran first)\n * forbidden 403: the credential is fine, the permission is not\n * notFound 404, or a NOT_FOUND from a service\n * invalid the request was understood and refused: 400, a rejected query, too large\n * transient no answer, or a 5xx/408/429: the same request may succeed later\n * aborted the caller's signal ended it\n * commandFailure api/asset answered 200 with failed commands inside (CommandFailureError)\n * protocol the server answered something the SDK cannot read\n * usage a mistake caught before any request (UsageError): nothing was sent, so\n * do not blame the server — fix the call (status is 0 here)\n * unknown none of the above\n */\nexport type ErrorKind = \"auth\" | \"forbidden\" | \"notFound\" | \"invalid\" | \"transient\" | \"aborted\" | \"commandFailure\" | \"protocol\" | \"usage\" | \"unknown\";\n\n/** The kind an HTTP status and an SDK code imply. A code wins over a status. */\nexport function kindOf(status: number, code?: string): ErrorKind {\n switch (code) {\n case \"ABORTED\": return \"aborted\";\n case \"TIMEOUT\":\n case \"NETWORK_ERROR\": return \"transient\";\n case \"BAD_JSON\":\n case \"BAD_RESPONSE\": return \"protocol\";\n case \"USAGE\": return \"usage\";\n case \"CommandFailure\": return \"commandFailure\";\n case \"QUERY_REJECTED\":\n case \"TOO_LARGE\": return \"invalid\";\n case \"NOT_FOUND\": return \"notFound\";\n }\n if (status === 401) return \"auth\";\n if (status === 403) return \"forbidden\";\n if (status === 404) return \"notFound\";\n if (status === 408 || status === 429 || status >= 500) return \"transient\";\n if (status >= 400) return \"invalid\";\n return \"unknown\";\n}\n\nconst causeOf = (details: unknown): unknown => (details && typeof details === \"object\" && \"cause\" in details ? (details as { cause: unknown }).cause : undefined);\n\nexport class ApiError extends Error {\n /** The HTTP status; 0 when no answer came back (network, timeout, abort, usage). */\n readonly status: number;\n readonly code?: string;\n readonly details?: unknown;\n readonly kind: ErrorKind;\n\n constructor(message: string, status: number, code?: string, details?: unknown, kind: ErrorKind = kindOf(status, code)) {\n const cause = causeOf(details);\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"ApiError\";\n this.status = status;\n this.code = code;\n this.details = details;\n this.kind = kind;\n }\n}\n\n/**\n * A mistake in the call, caught before any request is sent: an unpaged\n * query, an empty batch, a string that is not an OID token. Nothing on the\n * server has happened; fix the call. (A TypeError would say the same, but\n * one `instanceof ApiError` then covers everything the SDK throws.)\n */\nexport class UsageError extends ApiError {\n constructor(message: string, details?: unknown) {\n super(message, 0, \"USAGE\", details, \"usage\");\n this.name = \"UsageError\";\n }\n}\n\n/**\n * An error raised around another: a batch send that failed, an upload\n * that failed after the create. Its status and kind are the cause's when\n * the cause is an ApiError, so a caller still branches on `kind`.\n */\nexport class WrappedError extends ApiError {\n constructor(message: string, code: string, cause: unknown, details?: Record<string, unknown>) {\n const inner = cause instanceof ApiError ? cause : undefined;\n super(message, inner?.status ?? 0, code, { ...details, cause }, inner?.kind ?? \"unknown\");\n this.name = \"WrappedError\";\n }\n}\n","import { ApiError } from \"./errors\";\nimport type { RequestBody, RequestOptions, ResponseType, Transport } from \"./transport\";\n\n/**\n * The HTTP layer, and nothing above it: it knows how to build a URL, send a\n * body in the shape it was given, read a response in the shape it was asked\n * for, and turn a failure into an ApiError. It does not know what an asset\n * is. The wire layer (one module per endpoint) knows the envelopes; the\n * model layer knows the types.\n *\n * Retries live here because this is the only place that can tell a network\n * failure from an answer, but they are narrow on purpose: only requests the\n * caller marks idempotent (every GET is; a POST to api/asset is not — a\n * retried batch write after a timeout is a double write), and only on a\n * network error, a 5xx, or a 429 (the instance throttles per token; it\n * sends no Retry-After, but one is honoured when present, up to 30 s). Any\n * other 4xx is an answer and is never retried.\n */\nexport interface FetchTransportConfig {\n baseUrl: string;\n /** A ready Authorization header value — \"Bearer …\" or \"Basic …\". Wins over accessToken. */\n authorization?: string;\n /** An access token; sent as \"Bearer <token>\". */\n accessToken?: string;\n defaultHeaders?: Record<string, string>;\n /**\n * Client-side ceiling per attempt. Generous by default: the politeness rule\n * is about the work a request asks of the server, not about client\n * impatience, and a slow or recovering host should not be hammered by\n * timeouts that turn into retries.\n */\n timeoutMs?: number;\n /**\n * Extra attempts after the first, for idempotent requests only (a GET,\n * a query.v1 read, a guarded batch that says so), after a network\n * failure or a 5xx. Default 1: one resend, 150 ms later. 0 turns it off.\n * A plain write is never resent whatever this says.\n */\n retries?: number;\n fetchImpl?: typeof fetch;\n /**\n * fetch's credentials mode. A browser app on the instance's own origin\n * that authenticates with the session cookie sets \"same-origin\" or\n * \"include\" (pair it with defaultHeaders { \"X-Requested-With\":\n * \"XMLHttpRequest\" } so the server answers 401 rather than a login page).\n * Left unset, fetch's default applies.\n */\n credentials?: RequestCredentials;\n /**\n * Called when the server answers 401 (or a status in unauthorizedStatuses):\n * the place to re-authenticate — open a login popup, re-run setup. Resolve\n * \"retry\" to send the request once more, \"fail\" to throw the error.\n *\n * A retry is offered only for an idempotent request (every GET; a write the\n * caller marked idempotent). A plain api/asset write is never resent\n * automatically, even after a 401: the hook still runs, so the session\n * can be repaired, and the caller decides whether to send again.\n */\n onUnauthorized?: (context: UnauthorizedContext) => UnauthorizedDecision | Promise<UnauthorizedDecision>;\n /** Which statuses call onUnauthorized. Default [401]; a cookie-session app may add 403. */\n unauthorizedStatuses?: readonly number[];\n}\n\nexport type UnauthorizedDecision = \"retry\" | \"fail\";\n\nexport interface UnauthorizedContext {\n error: ApiError;\n request: RequestOptions;\n /** Whether a \"retry\" will be honoured: false for a non-idempotent write. */\n retryable: boolean;\n}\n\n/** The ApiError a caller's abort turns into. */\nfunction abortedError(signal: AbortSignal): ApiError {\n return new ApiError(\"Request aborted\", 0, \"ABORTED\", { cause: signal.reason });\n}\n\nfunction buildUrl(baseUrl: string, path: string, query?: RequestOptions[\"query\"]): string {\n const normalizedBase = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n const normalizedPath = path.startsWith(\"/\") ? path.slice(1) : path;\n const url = new URL(normalizedPath, normalizedBase);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) url.searchParams.set(key, String(value));\n }\n }\n return url.toString();\n}\n\n/** The body as fetch wants it, with the content type it implies. */\nfunction encodeBody(body: RequestBody | undefined, contentType: string | undefined): { body?: BodyInit; contentType?: string } {\n if (body === undefined) return {};\n if (typeof body === \"string\") return { body, contentType: contentType ?? \"text/plain\" };\n if (body instanceof Uint8Array || body instanceof ArrayBuffer) {\n return { body: body as BodyInit, contentType: contentType ?? \"application/octet-stream\" };\n }\n // A form is handed to fetch as is: it writes the multipart boundary itself.\n if (typeof FormData !== \"undefined\" && body instanceof FormData) return { body };\n // A Blob (a browser File, say) is bytes with a type of its own.\n if (typeof Blob !== \"undefined\" && body instanceof Blob) return { body, contentType: contentType ?? (body.type || \"application/octet-stream\") };\n return { body: JSON.stringify(body), contentType: contentType ?? \"application/json\" };\n}\n\nasync function readBody(response: Response, responseType: ResponseType): Promise<unknown> {\n if (responseType === \"bytes\") return new Uint8Array(await response.arrayBuffer());\n if (responseType === \"text\") return response.text();\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (responseType === \"json\" || contentType.includes(\"json\")) {\n const text = await response.text();\n if (!text) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n if (responseType === \"json\") throw new ApiError(\"Response is not JSON\", response.status, \"BAD_JSON\", { body: text.slice(0, 500) });\n return text;\n }\n }\n return response.text();\n}\n\n/**\n * The message of an error response, from the shapes the Agility endpoints\n * actually send: rest-1's { _type: \"Error\", error, exceptions: [{ message }] },\n * api/asset's { Exceptions: [\"…\"] } (a request it could not parse — 400\n * with the parser's message since 2026-11, an opaque 500 before), a bare\n * { message }, or text.\n */\nfunction messageOf(data: unknown, status: number): string {\n if (data && typeof data === \"object\") {\n const d = data as Record<string, unknown>;\n const first = Array.isArray(d.exceptions) && d.exceptions[0] && typeof d.exceptions[0] === \"object\" ? (d.exceptions[0] as Record<string, unknown>).message : undefined;\n const listed = Array.isArray(d.Exceptions) ? d.Exceptions.filter((x): x is string => typeof x === \"string\" && !!x).join(\"; \") : undefined;\n for (const candidate of [d.error, first, listed, d.message]) {\n if (typeof candidate === \"string\" && candidate) return candidate;\n }\n }\n if (typeof data === \"string\" && data.trim()) return data.trim().slice(0, 200);\n return `HTTP ${status}`;\n}\n\nconst delay = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n/** The longest a Retry-After is honoured before the request is given up instead. */\nconst MAX_RETRY_AFTER_MS = 30_000;\n\n/**\n * How long to wait before resending after a 429 or a 5xx: the server's\n * Retry-After (seconds, or an HTTP date) when it sends one and it is\n * within reason, else a short backoff. Null when the server asks for\n * longer than is reasonable to block a caller for.\n */\nfunction retryDelay(response: { status: number; headers: { get(name: string): string | null } }, attempt: number): number | null {\n const header = response.headers.get(\"retry-after\");\n if (header) {\n const seconds = Number(header);\n const ms = Number.isFinite(seconds) ? seconds * 1000 : Date.parse(header) - Date.now();\n if (Number.isFinite(ms) && ms > MAX_RETRY_AFTER_MS) return null;\n if (Number.isFinite(ms) && ms > 0) return ms;\n }\n return 150 * (attempt + 1);\n}\n\n/** A status the same request may succeed after: too many requests, or a server-side failure. */\nconst retriable = (status: number): boolean => status === 429 || status >= 500;\n\nexport function createFetchTransport(config: FetchTransportConfig): Transport {\n const fetchImpl = config.fetchImpl ?? fetch;\n const timeoutMs = config.timeoutMs ?? 60_000;\n const retries = Math.max(0, config.retries ?? 1);\n const authorization = config.authorization ?? (config.accessToken ? `Bearer ${config.accessToken}` : undefined);\n const unauthorizedStatuses = config.unauthorizedStatuses ?? [401];\n\n return {\n async request<T>(options: RequestOptions): Promise<T> {\n const url = buildUrl(config.baseUrl, options.path, options.query);\n const { body, contentType } = encodeBody(options.body, options.contentType);\n const headers: Record<string, string> = { accept: \"application/json\", ...config.defaultHeaders, ...options.headers };\n // A bodiless request carries no content type: rest-1 rejects a GET that claims JSON.\n if (contentType) headers[\"content-type\"] = contentType;\n if (authorization) headers.authorization = authorization;\n const responseType: ResponseType = options.responseType ?? \"auto\";\n const idempotent = options.idempotent ?? options.method === \"GET\";\n const attempts = idempotent ? retries + 1 : 1;\n\n const callerSignal = options.signal;\n\n let lastError: unknown;\n let reauthorized = false;\n for (let attempt = 0; attempt < attempts; attempt += 1) {\n if (callerSignal?.aborted) throw abortedError(callerSignal);\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n const onAbort = () => controller.abort();\n callerSignal?.addEventListener(\"abort\", onAbort, { once: true });\n const settle = () => {\n clearTimeout(timeoutId);\n callerSignal?.removeEventListener(\"abort\", onAbort);\n };\n let response: Response;\n try {\n const init: RequestInit = { method: options.method, headers, body, signal: controller.signal };\n if (config.credentials) init.credentials = config.credentials;\n response = await fetchImpl(url, init);\n } catch (error) {\n settle();\n // The caller gave up: final, whatever attempt this was.\n if (callerSignal?.aborted) throw abortedError(callerSignal);\n // Network failure or timeout: the only case a retry can help.\n lastError = error instanceof Error && error.name === \"AbortError\"\n ? new ApiError(`Timed out after ${timeoutMs} ms`, 0, \"TIMEOUT\", { cause: error })\n : new ApiError(error instanceof Error ? error.message : String(error), 0, \"NETWORK_ERROR\", { cause: error });\n if (attempt + 1 < attempts) await delay(150 * (attempt + 1));\n continue;\n }\n\n try {\n if (response.ok) {\n options.onResponse?.({ status: response.status, headers: response.headers });\n return (await readBody(response, responseType)) as T;\n }\n if (response.status === 304 && options.acceptNotModified) {\n // The caller asked \"has it changed?\" and the answer is no.\n options.onResponse?.({ status: 304, headers: response.headers });\n return undefined as T;\n }\n\n // An answer, not a failure to get one. 5xx may be retried when\n // idempotent; anything else is final.\n const data = await readBody(response, responseType === \"bytes\" ? \"text\" : responseType === \"json\" ? \"auto\" : responseType);\n lastError = new ApiError(messageOf(data, response.status), response.status, undefined, data);\n } catch (error) {\n if (callerSignal?.aborted) throw abortedError(callerSignal);\n throw error;\n } finally {\n settle();\n }\n\n if (config.onUnauthorized && !reauthorized && unauthorizedStatuses.includes(response.status)) {\n // One re-authentication per request: a second refusal is final.\n reauthorized = true;\n const decision = await config.onUnauthorized({ error: lastError as ApiError, request: options, retryable: idempotent });\n if (callerSignal?.aborted) throw abortedError(callerSignal);\n if (decision === \"retry\" && idempotent) {\n // Not counted against `retries`: those are for failures to get an answer.\n attempt -= 1;\n continue;\n }\n break;\n }\n if (retriable(response.status) && attempt + 1 < attempts) {\n const wait = retryDelay(response, attempt);\n if (wait === null) break;\n await delay(wait);\n continue;\n }\n break;\n }\n throw lastError instanceof ApiError ? lastError : new ApiError(\"Unknown transport error\", 0, \"UNKNOWN_ERROR\", { cause: lastError });\n }\n };\n}\n","/**\n * OID tokens, the one spelling every endpoint shares: \"Story:1234\", or with\n * a moment, \"Story:1234:5678\". The model carries the momentless form except\n * where the moment is the identity (a history row). Every consumer had its\n * own copy of these (a browser app's OID helper, a CLI's `momentless`,\n * v1sdk 2.x's Oid class); this is the one they share.\n */\nimport { UsageError } from \"../core/errors\";\nimport type { Oid } from \"./asset\";\n\nexport interface OidParts {\n type: string;\n id: number;\n /** The moment, when the token carries one. */\n moment: number | null;\n}\n\nconst OID_TOKEN = /^([A-Za-z][A-Za-z0-9_]*):(\\d+)(?::(\\d+))?$/;\n\n/** Is this an OID token? \"Story:1234\" and \"Story:1234:5678\" are; \"S-1234\" and \"Story\" are not. */\nexport function isOidToken(value: unknown): value is Oid {\n return typeof value === \"string\" && OID_TOKEN.test(value);\n}\n\n/** The parts of an OID token. Throws on anything that is not one. */\nexport function parseOid(token: string): OidParts {\n const m = OID_TOKEN.exec(token);\n if (!m) throw new UsageError(`\"${token}\" is not an OID token (Story:1234)`);\n return { type: m[1]!, id: Number(m[2]), moment: m[3] === undefined ? null : Number(m[3]) };\n}\n\n/** An OID token without its moment: \"Story:1234:5678\" -> \"Story:1234\". Anything that is not a token is returned as is. */\nexport function momentless(token: string): Oid {\n const m = OID_TOKEN.exec(token);\n return m ? `${m[1]}:${m[2]}` : token;\n}\n\n/** The asset type of an OID token: \"Story:1234\" -> \"Story\". */\nexport function typeOfOid(token: string): string {\n return parseOid(token).type;\n}\n\n/** An OID token from its parts. */\nexport function toOid(type: string, id: number, moment?: number | null): Oid {\n return moment == null ? `${type}:${id}` : `${type}:${id}:${moment}`;\n}\n","/**\n * The api/asset (Bulk API) wire module: exactly what the endpoint takes and\n * returns, and the translation between that and the model.\n *\n * The model is endpoint-agnostic: a relation is a Ref ({ _oid }), whatever\n * endpoint it came from or is going to. This module is where api/asset's\n * spellings live — a relation value written as an OID string (or an array\n * of them), one aliased command per array element, `previewOnly` on the\n * query string, YAML as a text body — so callers never learn them.\n *\n * Verified shapes (https://docs.digital.ai/agility-api/apis/asset-bulk, and\n * its errors page for commandFailures):\n * - response: requestId, createdDate, completedDate, duration,\n * durationSeconds, complete, processing, assetsCreated/assetsModified/\n * assetsOperatedOn { oidTokens, count }, commandFailures { commands,\n * count } with each entry the echoed command (its alias replaced by a\n * generated one) plus error { message, sourceCommandIndex, stackTrace? }\n * — sourceCommandIndex is the only reliable key back to the request —\n * and queryResult { results, resultMetaData, count } with results\n * POSITIONAL, one array per query command in request order.\n * - a batch commits per command: a later failure does not undo an\n * earlier success, and the HTTP status is 200 either way.\n * - preview (?previewOnly=true) returns the projection: creates echoed,\n * bare query-scoped updates and executes expanded to one command per\n * matched asset, aliased ones echoed unexpanded.\n */\nimport { ApiError, UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Asset, Oid, Ref } from \"../types/asset\";\nimport type { AssetTypeToken, AttributeLookup, AttributeTokenRef, AttributeType } from \"../types/metamodel\";\nimport type { CreateType, From, SelectPath, TypeOf } from \"../types/query\";\nimport { momentless } from \"../types/oid\";\nimport { fromTypeOf, resolvePath, type PathResolution } from \"./select\";\n\nexport { momentless };\n\n// ---- what the endpoint takes ------------------------------------------------\n\n/** A value in a command as the MODEL writes it: scalars, Refs, lists of either, or a nested command. */\nexport type CommandValue = string | number | boolean | null | Ref | CommandValue[] | { [key: string]: CommandValue };\n\nexport interface CreateBody { AssetType: CreateType; [attribute: string]: CommandValue }\n/**\n * A query. Written with a literal `from`, `select` completes from that\n * type's attributes and the rows come back typed by what was selected\n * (src/types/query.ts); written from variables, it is what it always was.\n */\nexport interface QueryBody<F extends string = string> {\n from: F | From;\n select?: (SelectPath<TypeOf<F>> | QueryBody)[];\n filter?: string[];\n where?: Record<string, string>;\n with?: Record<string, CommandValue>;\n sort?: string[];\n page?: { size: number; start: number };\n find?: string;\n findin?: string[];\n asof?: string;\n /** Ask api/asset for the total number of matches (query.v1 ignores it); read it with queryPage. */\n needTotal?: boolean;\n /** Group the rows by a relation: each result row is then a group, its rows under `_children` (translated like any row of `from`). */\n group?: (string | { from: string; [key: string]: unknown })[];\n}\n/**\n * An update. Each key of `update` is an attribute; its value replaces a\n * scalar or a single relation (null clears it). A multi-value relation is\n * changed with `{ add: [...], remove: [...] }`. A plain list does NOT\n * replace a multi-value relation: the server ADDS its members, like rest-1's\n * `act: \"add\"` (seen live on the API-testing instance, 2026-11-07). To set one exactly,\n * remove what should go and add what should come. A change comment goes in\n * the update node as `ChangeComment`.\n */\nexport interface UpdateBody { from: From; filter?: string[]; where?: Record<string, string>; with?: Record<string, CommandValue>; update: Record<string, CommandValue> }\n/**\n * An operation (QuickClose, Inactivate, Reactivate, Delete, …), optionally\n * with arguments. It cannot carry a change comment. Agility refuses to\n * Delete a closed asset (Violation'AssetCannotDeleteClosed): Reactivate it\n * first, as batch.reversible does.\n */\nexport interface ExecuteBody { from: From; filter?: string[]; where?: Record<string, string>; with?: Record<string, CommandValue>; execute: string | { op: string; args?: Record<string, CommandValue>; list?: Record<string, CommandValue>[] } }\nexport type CommandBody = CreateBody | QueryBody | UpdateBody | ExecuteBody;\n\n/** An alias key: \"@story\". */\nexport type Alias = `@${string}`;\n/** A command as sent: aliased ({ \"@x\": body }) or bare (the body itself). */\nexport type Command = { [alias: Alias]: CommandBody } | CommandBody;\n\n// ---- what the endpoint returns ----------------------------------------------\n\nexport interface OidTokens { oidTokens: Oid[]; count: number }\nexport interface CommandError { message: string; sourceCommandIndex?: number; stackTrace?: string }\n/** The echoed command (under a generated alias) plus the error. */\nexport type CommandFailure = { error: CommandError | string } & Record<string, unknown>;\nexport interface AssetApiResponse<Row extends Asset = Asset> {\n requestId: string;\n createdDate: string;\n completedDate: string;\n duration: string;\n durationSeconds: number;\n complete: boolean;\n processing: boolean;\n assetsCreated: OidTokens;\n assetsModified: OidTokens;\n assetsOperatedOn: OidTokens;\n commandFailures: { commands: CommandFailure[]; count: number };\n /**\n * One slot per query command, in request order; [] where a query matched\n * nothing. The server DROPS the slot of a query that failed, shifting the\n * later ones up (live, 2026-11-04); send puts the slot back as null, so a\n * caller's positions hold and a failure never reads as an empty result.\n */\n queryResult: { results: (Row[] | null)[]; resultMetaData: unknown[]; count: number };\n}\n\n// ---- translation ------------------------------------------------------------\n\nconst isRef = (v: unknown): v is Ref => !!v && typeof v === \"object\" && !Array.isArray(v) && \"_oid\" in v && typeof (v as Ref)._oid === \"string\";\n\n/**\n * A model value as api/asset wants it written: a Ref becomes its OID token,\n * a list of Refs a list of tokens, and everything else is left as is —\n * strings (OID tokens, monikers, alias references like \"@story\") pass\n * through untouched, and nested command bodies are translated recursively.\n */\nexport function toWireValue(value: CommandValue): unknown {\n if (isRef(value)) return momentless(value._oid);\n if (Array.isArray(value)) return value.map(toWireValue);\n if (value && typeof value === \"object\") return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, toWireValue(v)]));\n return value;\n}\n\n/** A batch as api/asset wants it. */\nexport const toWire = (commands: Command[]): unknown[] => commands.map((c) => toWireValue(c as CommandValue));\n\n/**\n * What a row is translated against: the schema, and the type of the rows.\n * Without it a row is passed through with only its OIDs normalised, which\n * is the endpoint's own spelling: every scalar a string, a sub-selected\n * single relation a one-element list.\n */\nexport interface RowContext { lookup: AttributeLookup; type: AssetTypeToken }\n\n/**\n * A query row as the model carries it. The endpoint spells every scalar as a\n * string (\"5\", \"False\") and a single relation selected with a sub-select as\n * a one-element list ([{ _oid }], or [] when unset); with a schema each key\n * is resolved to its attribute and translated — Numeric, LongInt and Rank\n * to number, Boolean to boolean, [x] to x and [] to null on a single\n * relation, { _oid: \"NULL\" } (an unset single relation) to null,\n * an @Count to number, and a sub-select's rows recursively by their own\n * type. Everywhere, OIDs lose their moment. A key the schema cannot resolve\n * is left as sent.\n */\nexport function fromWireRow<Row extends Asset = Asset>(row: Record<string, unknown>, context?: RowContext): Row {\n const out: Record<string, unknown> = {};\n // A `group` query answers with group rows: the group's key as `_oid` and\n // the grouped rows under `_children`. The children are rows of the query's\n // own type (or group rows again, for nested groups), so they translate\n // with the same context. No attribute is called _children, so its presence\n // is what marks a group row; a \"NULL\" key is the group of rows with the\n // relation unset, and reads as null like any unset relation.\n const grouped = Array.isArray(row._children);\n for (const [k, v] of Object.entries(row)) {\n if (grouped && k === \"_children\") out[k] = (v as unknown[]).map((child) => (child && typeof child === \"object\" ? fromWireRow(child as Record<string, unknown>, context) : child));\n else if (grouped && k === \"_oid\" && v === \"NULL\") out[k] = null;\n else if (k === \"_oid\" && typeof v === \"string\") out[k] = momentless(v);\n else out[k] = context ? translate(v, resolvePath(context.lookup, context.type, k), context.lookup) : fromWireValue(v);\n }\n return out as Row;\n}\n/**\n * An unset single relation selected without a sub-select: the endpoint\n * sends { _oid: \"NULL\" } (seen live on TeamRoom.Team, 2026-11-06). The\n * model reads it as null, never as a Ref to an asset called NULL.\n */\nconst isNullRef = (value: unknown): boolean => isRef(value) && value._oid === \"NULL\";\n\nfunction fromWireValue(value: unknown): unknown {\n if (isNullRef(value)) return null;\n if (isRef(value)) return { ...value, _oid: momentless(value._oid) };\n if (Array.isArray(value)) return value.map(fromWireValue);\n return value;\n}\n\nfunction translate(value: unknown, resolution: PathResolution, lookup: AttributeLookup): unknown {\n if (resolution.kind !== \"resolved\") return fromWireValue(value);\n if (resolution.aggregate) return toNumber(value);\n const definition = resolution.definition!;\n if (definition.AttributeType === \"Relation\") {\n const context = resolution.valueType ? { lookup, type: resolution.valueType } : undefined;\n const one = (x: unknown): unknown => (isNullRef(x) ? null : isRef(x) ? fromWireRow(x as Record<string, unknown>, context) : fromWireValue(x));\n if (resolution.multi) return (Array.isArray(value) ? value : value == null ? [] : [value]).filter((x) => !isNullRef(x)).map(one);\n if (Array.isArray(value)) return value.length ? one(value[0]) : null;\n return value == null ? null : one(value);\n }\n const one = (x: unknown): unknown => scalar(x, definition.AttributeType);\n return resolution.multi && Array.isArray(value) ? value.map(one) : one(value);\n}\n\n/** A scalar as the model carries it, from the string the endpoint sent. A value that does not parse is left as sent. */\nfunction scalar(value: unknown, type: AttributeType): unknown {\n if (value == null) return null;\n switch (type) {\n case \"Numeric\":\n case \"LongInt\":\n case \"Rank\": // a 32-bit integer sent as a string (\"-2000000000\"); sorts as a number\n return toNumber(value);\n case \"Boolean\":\n return value === true || value === \"True\" || value === \"true\" ? true : value === false || value === \"False\" || value === \"false\" ? false : value;\n default:\n return value;\n }\n}\nfunction toNumber(value: unknown): unknown {\n if (value == null) return null;\n if (typeof value === \"number\") return value;\n const n = typeof value === \"string\" && value.trim() !== \"\" ? Number(value) : NaN;\n return Number.isNaN(n) ? value : n;\n}\n\n/**\n * One failed command, normalised. `index` is the zero-based position, in\n * the batch as sent, of the command that produced the failure (the server's\n * sourceCommandIndex — the echoed alias is replaced by a generated one, so\n * the index is the only key back to the request); null when the server gave\n * none. Several failures can share one index: a failed create fails every\n * descendant it would have parented, and the first entry is the root cause.\n * `message` is the server's text, often an apostrophe-delimited token\n * (\"Violation'Invalid'Epic.Scope\") a caller can branch on or run through\n * loc-2 — but an unknown attribute reads differently in `select` and in\n * `where`, so match on text with care. stackTrace is never kept: only\n * internal development builds send it.\n */\nexport interface CommandFailureDetail {\n index: number | null;\n message: string;\n /**\n * The command as the server echoed it, under a generated alias: what a\n * caller resends after correcting it. Readable on every failure but not\n * enumerable, so a serialised failure (a receipt, a log line) carries\n * index, message and violation and not the whole command.\n */\n readonly echoed: Record<string, unknown>;\n /** The message read as a validation violation, when it is one. */\n violation: Violation | null;\n}\n\n/** A failure detail with `echoed` readable but not enumerable. */\nfunction failureDetail(index: number | null, message: string, echoed: Record<string, unknown>): CommandFailureDetail {\n const detail = { index, message, violation: parseViolation(message) } as CommandFailureDetail;\n Object.defineProperty(detail, \"echoed\", { value: echoed, enumerable: false, writable: false });\n return detail;\n}\n\n/**\n * A validation failure as api/asset words it: `Violation'<Rule>'<tag>`,\n * where the rule is Required, Invalid, AssetCannotDeleteClosed, … and the\n * rest, when present, names what was violated. The attribute form is a\n * loc-2 tag (`AttributeDefinition'Scope'Story`, live 2026-11-12), which\n * `client.localize` turns into the attribute's label; an older spelling is\n * the token itself (`Epic.Scope`). Both read as `attribute: \"Story.Scope\"`.\n */\nexport interface Violation {\n rule: string;\n /** \"Story.Scope\" when the violation names an attribute; null otherwise. */\n attribute: AttributeTokenRef | null;\n /** The loc-2 tag naming what was violated (`AttributeDefinition'Scope'Story`), when the message carries one; null for the token spelling. */\n tag: string | null;\n}\n\n/** The violation a failure message describes, or null when it is not one. */\nexport function parseViolation(message: string): Violation | null {\n const parts = message.trim().split(\"'\");\n if (parts[0] !== \"Violation\" || !parts[1]) return null;\n const rule = parts[1], rest = parts.slice(2).filter((p) => p !== \"\");\n if (rest[0] === \"AttributeDefinition\" && rest[1] && rest[2]) return { rule, attribute: `${rest[2]}.${rest[1]}`, tag: rest.join(\"'\") };\n // The older spelling names the attribute by its token (\"Epic.Scope\"): not a loc-2 tag, so `tag` is null there.\n const token = rest.length === 1 && /^[A-Za-z][A-Za-z0-9_]*\\.[A-Za-z][A-Za-z0-9_]*$/.test(rest[0]!) ? (rest[0] as AttributeTokenRef) : null;\n return { rule, attribute: token, tag: !token && rest.length > 1 ? rest.join(\"'\") : null };\n}\n\n/** The failures of a response, normalised: index and message, always both. */\nexport function failuresOf<Row extends Asset = Asset>(response: AssetApiResponse<Row>): CommandFailureDetail[] {\n return (response.commandFailures?.commands ?? []).map(({ error, ...echoed }) => failureDetail(\n typeof error === \"object\" && error && typeof error.sourceCommandIndex === \"number\" ? error.sourceCommandIndex : null,\n typeof error === \"string\" ? error : error?.message || \"command failed\",\n echoed\n ));\n}\n\n/** What a batch did, in the model's terms: the services read this, never the envelope. */\nexport interface Outcome<Row extends Asset = Asset> {\n /** The server's id for the request: what to quote when asking about a batch. Null for an outcome merged from several sends. */\n requestId: string | null;\n created: Oid[];\n modified: Oid[];\n operated: Oid[];\n failures: CommandFailureDetail[];\n /** One slot per query, in request order; null where the query failed. */\n queryResults: (Row[] | null)[];\n durationSeconds: number | null;\n}\n\n/**\n * The outcome of a (translated) response: OIDs momentless, failures\n * normalised. Every field has a default, so a partial envelope (a test fake\n * that sends only queryResult) still yields a complete Outcome; consumers'\n * fakes rely on that, and the unit tests keep it so.\n */\nexport function outcomeOf<Row extends Asset = Asset>(response: AssetApiResponse<Row>): Outcome<Row> {\n return {\n requestId: typeof response.requestId === \"string\" && response.requestId ? response.requestId : null,\n created: (response.assetsCreated?.oidTokens ?? []).map(momentless),\n modified: (response.assetsModified?.oidTokens ?? []).map(momentless),\n operated: (response.assetsOperatedOn?.oidTokens ?? []).map(momentless),\n failures: failuresOf(response),\n queryResults: response.queryResult?.results ?? [],\n durationSeconds: typeof response.durationSeconds === \"number\" ? response.durationSeconds : null\n };\n}\n\n/** An outcome with nothing in it, to merge several sends into. */\nexport const emptyOutcome = <Row extends Asset = Asset>(): Outcome<Row> => ({ requestId: null, created: [], modified: [], operated: [], failures: [], queryResults: [], durationSeconds: null });\n\n/**\n * Add one send's outcome to another's, for a batch sent in several\n * requests. `offset` is how many commands were sent before this one, so a\n * failure's index stays a position in everything sent.\n */\nexport function mergeOutcome<Row extends Asset = Asset>(into: Outcome<Row>, done: Outcome<Row>, offset: number): Outcome<Row> {\n into.created.push(...done.created);\n into.modified.push(...done.modified);\n into.operated.push(...done.operated);\n into.failures.push(...done.failures.map((f) => failureDetail(f.index === null ? null : f.index + offset, f.message, f.echoed)));\n into.queryResults.push(...done.queryResults);\n into.requestId = null; // several sends, several ids: none is \"the\" request\n if (done.durationSeconds !== null) into.durationSeconds = (into.durationSeconds ?? 0) + done.durationSeconds;\n return into;\n}\n\n/**\n * A batch in which at least one command failed. api/asset answers 200 and\n * commits per command, so this is not an HTTP failure and not all-or-\n * nothing: `response` is the whole (translated) envelope, with whatever did\n * succeed — created OIDs, modified OIDs, query rows — and `failures` says\n * which commands did not, by index. The message joins the failures'\n * messages, root cause first, so a log line reads like the server's own\n * words. To retry, correct and resend `response.commandFailures.commands`\n * verbatim: each entry is a complete command under its alias wrapper, the\n * succeeded commands are absent, so nothing is applied twice. Resending the\n * original batch is not safe. (Echoed execute failures do not resend\n * cleanly; rewrite them as from-addressed executes.)\n */\nexport class CommandFailureError<Row extends Asset = Asset> extends ApiError {\n readonly failures: CommandFailureDetail[];\n readonly response: AssetApiResponse<Row>;\n /** What the batch did, in the model's terms: the commands that succeeded are committed. */\n readonly outcome: Outcome<Row>;\n\n constructor(response: AssetApiResponse<Row>, failures: CommandFailureDetail[] = failuresOf(response)) {\n super(failures.map((f) => f.message).join(\"; \") || \"command failed\", 200, \"CommandFailure\", failures);\n this.name = \"CommandFailureError\";\n this.failures = failures;\n this.response = response;\n this.outcome = outcomeOf(response);\n }\n}\n\n// ---- the calls --------------------------------------------------------------\n\nexport interface ReadOptions {\n /** The schema to translate rows with; the types the queries touch must already be loaded (Schema.ensureFor). Without it, rows keep the endpoint's spelling. */\n lookup?: AttributeLookup;\n}\n\nexport interface SendOptions extends ReadOptions {\n /** Return the projection instead of executing (?previewOnly=true). */\n previewOnly?: boolean;\n /**\n * Throw a CommandFailureError when any command failed, instead of\n * returning the envelope with failures inside it. The commands that\n * succeeded are committed either way; the error carries the response.\n */\n throwOnFailure?: boolean;\n /**\n * The caller has made this batch safe to send twice (a guarded batch with\n * no creates: services/guard) and says so; the transport may then retry it\n * after a network failure or a 5xx. Never set it for a plain batch: a\n * retried write after a timeout is a double write.\n */\n idempotent?: boolean;\n}\n\n/** A command's body, aliased or bare. */\nconst bodyOf = (c: Command): unknown => { const keys = Object.keys(c); return keys.length === 1 && keys[0]!.startsWith(\"@\") ? (c as Record<string, unknown>)[keys[0]!] : c; };\nconst isQuery = (body: unknown): body is QueryBody => !!body && typeof body === \"object\" && typeof (body as QueryBody).from === \"string\" && !(\"update\" in body) && !(\"execute\" in body) && !(\"AssetType\" in body);\n/** The query commands of a batch, in order, each with its index in the batch. */\nfunction queriesIn(commands: Command[]): { body: QueryBody; index: number }[] {\n return commands.flatMap((c, index) => { const body = bodyOf(c); return isQuery(body) ? [{ body, index }] : []; });\n}\n\n/**\n * The server's results, one slot per query again. It sends a slot for every\n * query that ran (an empty match included) and none for a query that\n * failed; a failure names its command by sourceCommandIndex, so the failed\n * queries are known and the rest fill in order. Null when the counts\n * disagree: the positions cannot be trusted, and the caller decides what\n * that means rather than this guessing.\n */\nfunction realign<T>(sent: { index: number }[], results: T[], failed: Set<number>): (T | null)[] | null {\n const expected = sent.filter((q) => !failed.has(q.index)).length;\n if (results.length !== expected) return null;\n let next = 0;\n return sent.map((q) => (failed.has(q.index) ? null : results[next++]!));\n}\n\n/**\n * Send a batch. The response is the envelope; per-command failures are\n * inside it (failuresOf reads them), or thrown as a CommandFailureError with\n * throwOnFailure. Query rows are translated, each by its query's type when a\n * schema is given.\n */\nexport async function send<Row extends Asset = Asset>(transport: Transport, commands: Command[], options: SendOptions = {}): Promise<AssetApiResponse<Row>> {\n const response = await transport.request<AssetApiResponse<Row>>({\n method: \"POST\",\n path: \"/api/asset\",\n query: options.previewOnly ? { previewOnly: \"true\" } : undefined,\n body: toWire(commands),\n responseType: \"json\",\n idempotent: options.idempotent === true\n });\n // A preview answers with the projection, not an envelope.\n if (options.previewOnly) return response;\n const queries = queriesIn(commands);\n const failures = failuresOf(response);\n const failed = new Set(failures.flatMap((f) => (f.index === null ? [] : [f.index])));\n const results = response.queryResult?.results ?? [];\n let aligned = realign(queries, results, failed);\n if (!aligned) {\n // A failure without a sourceCommandIndex may be one of the queries, so\n // no row can be placed with confidence: every slot is null, never a\n // misplaced row, and the failures themselves are the answer (thrown\n // with throwOnFailure, as every read asks). With no such failure, the\n // server's answer is inconsistent, and that is an error of its own.\n if (!failures.some((f) => f.index === null)) throw new ApiError(`api/asset returned ${results.length} query results for ${queries.filter((q) => !failed.has(q.index)).length} queries that did not fail; cannot tell which result belongs to which query`, 200, \"BAD_RESPONSE\", response);\n aligned = queries.map(() => null);\n }\n const contextOf = (i: number): RowContext | undefined => {\n const type = options.lookup ? fromTypeOf(queries[i]!.body.from, commands) : null;\n return type ? { lookup: options.lookup!, type } : undefined;\n };\n const translated: AssetApiResponse<Row> = { ...response, queryResult: { ...response.queryResult, results: aligned!.map((rows, i) => rows && rows.map((r) => fromWireRow<Row>(r as Record<string, unknown>, contextOf(i)))) } };\n if (options.throwOnFailure && translated.commandFailures?.count) throw new CommandFailureError(translated);\n return translated;\n}\n\n/** Preview a batch: the projection, one command per asset the server would touch. */\nexport async function preview(transport: Transport, commands: Command[]): Promise<Command[]> {\n return transport.request<Command[]>({ method: \"POST\", path: \"/api/asset\", query: { previewOnly: \"true\" }, body: toWire(commands), responseType: \"json\" });\n}\n\n/**\n * Send YAML as written. api/asset parses it server-side (a single document\n * or several separated by ---); with previewOnly the parsed commands come\n * back as JSON, which is how a caller gets YAML parsed without a parser.\n */\nexport async function sendYaml<Row extends Asset = Asset>(transport: Transport, yaml: string, options: SendOptions = {}): Promise<AssetApiResponse<Row> | Command[]> {\n return transport.request({ method: \"POST\", path: \"/api/asset\", query: options.previewOnly ? { previewOnly: \"true\" } : undefined, body: yaml, contentType: \"text/yaml\", responseType: \"json\" });\n}\n\n/** One query, its rows. A page is required: no read of api/asset is unbounded. */\nexport async function query<Row extends Asset = Asset>(transport: Transport, q: QueryBody, options: ReadOptions = {}): Promise<Row[]> {\n const [rows] = await queries<Row>(transport, [q], options);\n return rows ?? [];\n}\n\n/**\n * One page of a query, with the total number of matches (api/asset reports\n * it when asked with needTotal; `total` is null when it does not) and\n * whether more pages follow.\n */\nexport async function queryPage<Row extends Asset = Asset>(transport: Transport, q: QueryBody, options: ReadOptions = {}): Promise<{ rows: Row[]; total: number | null; more: boolean }> {\n if (!q.page) throw new UsageError(`query of ${q.from} without a page: every api/asset read must be bounded`);\n const response = await send<Row>(transport, [{ ...q, needTotal: true }], { ...options, throwOnFailure: true });\n const rows = response.queryResult.results[0] ?? [];\n const reported = (response.queryResult as { resultMetaData?: { total?: unknown }[] }).resultMetaData?.[0]?.total;\n const total = typeof reported === \"number\" ? reported : null;\n return { rows, total, more: total === null ? rows.length === q.page.size : q.page.start + rows.length < total };\n}\n\n/**\n * Several queries in one request; one array of rows per query, in order, []\n * where a query matched nothing. A query the server rejected (a bad select\n * token, a malformed filter) throws a CommandFailureError rather than\n * reading as [] — a failure must never look like an empty result.\n */\nexport async function queries<Row extends Asset = Asset>(transport: Transport, qs: QueryBody[], options: ReadOptions = {}): Promise<Row[][]> {\n for (const q of qs) if (!q.page) throw new UsageError(`query of ${q.from} without a page: every api/asset read must be bounded`);\n const response = await send<Row>(transport, qs, { ...options, throwOnFailure: true });\n return qs.map((_, i) => response.queryResult.results[i] ?? []);\n}\n","/**\n * Select paths, resolved against the schema: what type of value a key in a\n * query row carries. api/asset and query.v1 spell every scalar as a string\n * and a sub-selected single relation as a one-element list, so translating\n * a row into the model needs the attribute behind each key. The grammar of\n * a select path (V1Query.g, as the docs publish it):\n *\n * Attribute Estimate\n * Relation.Attribute Status.Name one hop, or many\n * Relation:Downcast Children:Task the relation narrowed to a subtype\n * Relation[filter] BlockingIssues[AssetState!='Closed']\n * Relation.@Aggregate Owners.@Count a number, always\n *\n * and a sub-select `{ from: <path>, select: [...] }` whose key in the row is\n * its `from`. A path is resolved hop by hop; a hop through a multi-value\n * relation makes the value a list.\n */\nimport type { AssetTypeToken, AttributeDefinition, AttributeLookup } from \"../types/metamodel\";\nimport { isOidToken, typeOfOid } from \"../types/oid\";\n\nexport type Aggregate = \"Count\" | \"DistinctCount\" | \"Sum\" | \"Avg\" | \"Min\" | \"Max\";\n\nexport type PathResolution =\n | {\n kind: \"resolved\";\n /** The attribute the path ends on; null for an aggregate. */\n definition: AttributeDefinition | null;\n /** For a relation, the type of the value (after any downcast); for a scalar, the type that defines it. */\n valueType: AssetTypeToken | null;\n /** True when any hop fans out: the value is a list. */\n multi: boolean;\n aggregate: Aggregate | null;\n }\n /** The lookup has not loaded this type; load it and resolve again. */\n | { kind: \"needs\"; type: AssetTypeToken }\n /** Not a path the schema knows (a missing attribute, a scalar mid-path): leave the value as sent. */\n | { kind: \"unknown\"; at: string };\n\ninterface Segment { name: string; downcast: string | null; aggregate: Aggregate | null }\n\n/** Split a path on \".\" outside brackets and quotes, then read each segment. */\nexport function segmentsOf(path: string): Segment[] {\n const parts: string[] = [];\n let depth = 0, quote: string | null = null, current = \"\";\n for (const ch of path) {\n if (quote) { current += ch; if (ch === quote) quote = null; continue; }\n if (ch === \"'\" || ch === '\"') { quote = ch; current += ch; continue; }\n if (ch === \"[\") depth += 1;\n if (ch === \"]\") depth -= 1;\n if (ch === \".\" && depth === 0) { parts.push(current); current = \"\"; continue; }\n current += ch;\n }\n parts.push(current);\n return parts.map((raw) => {\n if (raw.startsWith(\"@\")) return { name: raw, downcast: null, aggregate: raw.slice(1) as Aggregate };\n const bare = raw.replace(/\\[[\\s\\S]*\\]$/, \"\"); // a trailing [filter] narrows rows, not the type\n const colon = bare.indexOf(\":\");\n return colon < 0 ? { name: bare, downcast: null, aggregate: null } : { name: bare.slice(0, colon), downcast: bare.slice(colon + 1) || null, aggregate: null };\n });\n}\n\n/** An attribute of a type, by its bare name; undefined when the type is not loaded, null when the type has no such attribute. */\nexport function attributeOf(lookup: AttributeLookup, type: AssetTypeToken, name: string): AttributeDefinition | null | undefined {\n const t = lookup.assetType(type);\n if (t === undefined) return undefined;\n if (t === null) return null;\n return t.Attributes[`${type}.${name}`] ?? Object.values(t.Attributes).find((a) => a.Name === name) ?? null;\n}\n\n/** What a select path yields on rows of `type`. */\nexport function resolvePath(lookup: AttributeLookup, type: AssetTypeToken, path: string): PathResolution {\n const segments = segmentsOf(path);\n let current = type, multi = false, last: AttributeDefinition | null = null;\n for (const [i, seg] of segments.entries()) {\n if (seg.aggregate) {\n return i === segments.length - 1 ? { kind: \"resolved\", definition: null, valueType: null, multi: false, aggregate: seg.aggregate } : { kind: \"unknown\", at: path };\n }\n const def = attributeOf(lookup, current, seg.name);\n if (def === undefined) return { kind: \"needs\", type: current };\n if (def === null) return { kind: \"unknown\", at: `${current}.${seg.name}` };\n if (def.AttributeType !== \"Relation\") {\n return i === segments.length - 1 ? { kind: \"resolved\", definition: def, valueType: current, multi, aggregate: null } : { kind: \"unknown\", at: path };\n }\n multi ||= def.IsMultivalue;\n const next = seg.downcast ?? def.RelatedAsset;\n if (!next) return { kind: \"unknown\", at: `${current}.${seg.name}` };\n current = next;\n last = def;\n }\n return { kind: \"resolved\", definition: last, valueType: current, multi, aggregate: null };\n}\n\n/** The minimum of a query this module needs to see: where it reads from and what it selects. */\nexport interface SelectShape { from: string; select?: (string | SelectShape)[] }\n\n/**\n * The asset type a query's `from` reads: a type token as is, the type of an\n * OID token, or the AssetType of the aliased create earlier in the batch.\n * Null when it cannot be told (an alias to a query, say).\n */\nexport function fromTypeOf(from: string, batch: readonly unknown[] = []): AssetTypeToken | null {\n const fromOid = isOidToken(from) ? typeOfOid(from) : null;\n if (fromOid) return fromOid;\n if (from.startsWith(\"@\")) {\n for (const command of batch) {\n const body = (command as Record<string, unknown>)?.[from];\n const assetType = body && typeof body === \"object\" ? (body as Record<string, unknown>).AssetType : undefined;\n if (typeof assetType === \"string\") return assetType;\n }\n return null;\n }\n return from;\n}\n\n/**\n * The types the lookup must load before every key of this query's rows can\n * be resolved — empty when it can resolve them all now. A lazy schema loads\n * these and asks again; a path that still does not resolve is unknown, not\n * missing, and is left alone.\n */\nexport function typesNeeded(lookup: AttributeLookup, query: SelectShape, type: AssetTypeToken): Set<AssetTypeToken> {\n const needed = new Set<AssetTypeToken>();\n if (lookup.assetType(type) === undefined) { needed.add(type); return needed; }\n for (const entry of query.select ?? []) {\n const path = typeof entry === \"string\" ? entry : entry.from;\n const r = resolvePath(lookup, type, path);\n if (r.kind === \"needs\") needed.add(r.type);\n else if (r.kind === \"resolved\" && typeof entry !== \"string\" && r.valueType) for (const t of typesNeeded(lookup, entry, r.valueType)) needed.add(t);\n }\n return needed;\n}\n","/**\n * The attachment wire module: the files an asset carries. Two endpoints and\n * one MVC route, none of them the data API:\n *\n * attachment.img/<id> GET the bytes; POST bytes to replace them\n * embedded.img/<id> GET an image embedded in rich text\n * EmbeddedImage.mvc/Upload POST multipart { image, oidToken } → an EmbeddedImage\n *\n * Addressed by the numeric id, not the OID token — the one place in the API\n * that does. Bytes travel as Uint8Array, ArrayBuffer or Blob, so this works\n * in Node and the browser alike (no Buffer).\n *\n * Verified against the API-testing instance (2026-11-07):\n * - GET attachment.img/<id> answers the bytes with the Attachment's\n * ContentType and `Content-Disposition: inline; filename=\"…\"`; 404 for\n * an id that does not exist. POST raw bytes (any content type) answers\n * 200 with an empty body and replaces them.\n * - An Attachment create requires Content (empty is allowed, absent is\n * Violation'Required'…'Content'); Base64 Content in the create stores\n * the bytes in one request, and selecting Content reads them back as\n * Base64.\n * - EmbeddedImage.mvc/Upload takes token auth and answers text/html:\n * `<textarea>{\"Url\":\"<base>/embedded.img/<id>\",\"Key\":\"EmbeddedImage:<id>\"}</textarea>`.\n * An EmbeddedImage cannot be deleted (no Delete operation).\n */\nimport { ApiError, UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Oid } from \"../types/asset\";\n\n/** Bytes as a caller has them: a Uint8Array, an ArrayBuffer, or a Blob (a browser File). */\nexport type Bytes = Uint8Array | ArrayBuffer | Blob;\n\n/** Bytes as a Uint8Array, whatever they came as. */\nexport async function toUint8Array(data: Bytes): Promise<Uint8Array> {\n if (data instanceof Uint8Array) return data;\n if (data instanceof ArrayBuffer) return new Uint8Array(data);\n return new Uint8Array(await data.arrayBuffer());\n}\n\n/** Base64 without Buffer, in chunks so a large file does not overflow the call stack. */\nexport function toBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i += 0x8000) binary += String.fromCharCode(...bytes.subarray(i, i + 0x8000));\n return btoa(binary);\n}\n\nexport function fromBase64(text: string): Uint8Array {\n const binary = atob(text);\n const out = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);\n return out;\n}\n\n/** The numeric id from \"Attachment:5678\", \"Attachment:5678:999\" (a moment) or \"5678\". */\nexport function numericId(spec: Oid | string | number): string {\n const m = /^(?:[A-Za-z]+:)?(\\d+)(?::\\d+)?$/.exec(String(spec).trim());\n if (!m) throw new UsageError(`\"${spec}\" is not an asset id (5678, or an OID token such as Attachment:5678)`);\n return m[1]!;\n}\n\nconst join = (baseUrl: string, path: string): string => `${baseUrl.replace(/\\/+$/, \"\")}/${path}`;\n\n/** Where a browser opens or downloads an attachment's bytes. */\nexport const attachmentUrl = (baseUrl: string, id: Oid | string | number): string => join(baseUrl, `attachment.img/${numericId(id)}`);\n/** Where an embedded image is served from. */\nexport const embeddedImageUrl = (baseUrl: string, id: Oid | string | number): string => join(baseUrl, `embedded.img/${numericId(id)}`);\n\n/**\n * Rich text with every `embedded.img/<id>` image reference rewritten to the\n * instance's absolute URL — what Agility's own editor stores — whatever\n * host, path or quoting the reference had before.\n */\nexport function normalizeEmbeddedImageUrls(html: string, baseUrl: string): string {\n return html.replace(/(\\bsrc\\s*=\\s*)([\"'])([^\"']*?embedded\\.img\\/(\\d+)[^\"']*)\\2/gi, (_m, attr: string, quote: string, _url: string, id: string) => `${attr}${quote}${embeddedImageUrl(baseUrl, id)}${quote}`);\n}\n\n/** The endpoint's statuses, named: 404 missing, 413 larger than the server's maximum request length. */\nfunction named(error: unknown, what: string): unknown {\n if (!(error instanceof ApiError)) return error;\n if (error.status === 404) return new ApiError(`${what}: not found`, 404, \"NOT_FOUND\", error.details);\n if (error.status === 413) return new ApiError(`${what}: larger than the server's maximum request length`, 413, \"TOO_LARGE\", error.details);\n return error;\n}\n\n/** An attachment's bytes. */\nexport async function getBytes(transport: Transport, id: Oid | string | number): Promise<Uint8Array> {\n const n = numericId(id);\n try {\n return await transport.request<Uint8Array>({ method: \"GET\", path: `/attachment.img/${n}`, responseType: \"bytes\" });\n } catch (error) {\n throw named(error, `attachment ${n}`);\n }\n}\n\n/** An attachment's bytes with the type and filename the server sent them with (Content-Type, Content-Disposition), when it did. */\nexport async function getFile(transport: Transport, id: Oid | string | number): Promise<{ bytes: Uint8Array; contentType: string | null; filename: string | null }> {\n const n = numericId(id);\n let contentType: string | null = null, filename: string | null = null;\n const onResponse = ({ headers }: { headers: { get(name: string): string | null } }) => {\n contentType = headers.get(\"content-type\");\n const disposition = headers.get(\"content-disposition\") ?? \"\";\n const encoded = /filename\\*=UTF-8''([^;]+)/i.exec(disposition)?.[1];\n filename = encoded ? decodeURIComponent(encoded) : /filename=\"?([^\";]+)\"?/i.exec(disposition)?.[1] ?? null;\n };\n try {\n const bytes = await transport.request<Uint8Array>({ method: \"GET\", path: `/attachment.img/${n}`, responseType: \"bytes\", onResponse });\n return { bytes, contentType, filename };\n } catch (error) {\n throw named(error, `attachment ${n}`);\n }\n}\n\n/** Replace an attachment's bytes. The Attachment asset (name, filename, content type) is unchanged. */\nexport async function putBytes(transport: Transport, id: Oid | string | number, data: Bytes, contentType = \"application/octet-stream\"): Promise<void> {\n const n = numericId(id);\n const body = data instanceof Blob ? data : await toUint8Array(data);\n try {\n await transport.request({ method: \"POST\", path: `/attachment.img/${n}`, body, contentType: data instanceof Blob && data.type ? data.type : contentType, responseType: \"text\" });\n } catch (error) {\n throw named(error, `attachment ${n}`);\n }\n}\n\nexport interface EmbeddedImage { oid: Oid; id: string; url: string }\n\n/**\n * Upload an image to embed in an asset's rich text. The answer is the\n * image's URL — put it in an `<img src>` — and its EmbeddedImage OID.\n */\nexport async function uploadEmbeddedImage(transport: Transport, asset: Oid, data: Bytes, options: { filename?: string; contentType?: string } = {}): Promise<EmbeddedImage> {\n const blob = data instanceof Blob ? data : new Blob([(await toUint8Array(data)) as Uint8Array<ArrayBuffer>], { type: options.contentType ?? \"application/octet-stream\" });\n const form = new FormData();\n form.append(\"image\", blob, options.filename ?? \"image\");\n form.append(\"oidToken\", asset);\n let html: string;\n try {\n html = await transport.request<string>({ method: \"POST\", path: \"/EmbeddedImage.mvc/Upload\", body: form, responseType: \"text\" });\n } catch (error) {\n throw named(error, `embedded image for ${asset}`);\n }\n const inner = /<textarea[^>]*>([\\s\\S]*?)<\\/textarea>/i.exec(html)?.[1];\n let payload: { Url?: unknown; Key?: unknown } | undefined;\n try {\n payload = inner ? JSON.parse(inner.replace(/"/g, '\"').replace(/</g, \"<\").replace(/>/g, \">\").replace(/&/g, \"&\")) : undefined;\n } catch { /* reported below */ }\n if (!payload || typeof payload.Url !== \"string\") throw new ApiError(\"EmbeddedImage.mvc/Upload did not answer with an image URL\", 200, \"BAD_RESPONSE\", html.slice(0, 500));\n const id = /embedded\\.img\\/(\\d+)/.exec(payload.Url)?.[1] ?? (typeof payload.Key === \"string\" ? numericId(payload.Key) : undefined);\n if (!id) throw new ApiError(\"EmbeddedImage.mvc/Upload answered a URL without an image id\", 200, \"BAD_RESPONSE\", payload);\n return { oid: typeof payload.Key === \"string\" ? payload.Key : `EmbeddedImage:${id}`, id, url: payload.Url };\n}\n","/**\n * The attachments service: the files attached to an asset, as part of\n * changing that asset like any other attribute. The metadata lives on an\n * Attachment asset (api/asset); the bytes live behind attachment.img\n * (wire/attachment). Consumers never call either directly.\n *\n * Two ways in for the bytes, chosen by size:\n * - inline: one api/asset create with Content as Base64. One request,\n * what a browser app consumer does; the JSON is a third larger than the file.\n * - two-step, as the docs prescribe for anything not tiny: create the\n * Attachment with empty Content, then POST the raw bytes. A failed\n * upload leaves an empty Attachment, which is reported, not hidden.\n *\n * Listing never selects Content: across many attachments that would Base64\n * every file into one response. Reading one file's bytes goes through\n * attachment.img.\n */\nimport { ApiError, WrappedError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Oid } from \"../types/asset\";\nimport { momentless } from \"../types/oid\";\nimport * as assetApi from \"../wire/assetApi\";\nimport { getFile, numericId, putBytes, toBase64, toUint8Array, type Bytes } from \"../wire/attachment\";\n\n/** Files up to this size go inline by default; larger ones in two steps. */\nexport const INLINE_LIMIT = 1_000_000;\n\nexport interface AttachmentInfo {\n oid: Oid;\n /** The numeric id attachment.img addresses it by. */\n id: string;\n name: string | null;\n filename: string | null;\n contentType: string | null;\n description: string | null;\n createDate: string | null;\n createdBy: string | null;\n}\n\ntype Row = { _oid: string; Name?: string | null; Filename?: string | null; ContentType?: string | null; Description?: string | null; CreateDate?: string | null; \"CreatedBy.Name\"?: string | null };\nconst SELECT = [\"Name\", \"Filename\", \"ContentType\", \"Description\", \"CreateDate\", \"CreatedBy.Name\"];\nconst infoOf = (r: Row): AttachmentInfo => {\n const oid = momentless(r._oid);\n return { oid, id: numericId(oid), name: r.Name ?? null, filename: r.Filename ?? null, contentType: r.ContentType ?? null, description: r.Description ?? null, createDate: r.CreateDate ?? null, createdBy: r[\"CreatedBy.Name\"] ?? null };\n};\n\n/** One page of the files attached to an asset, newest first, metadata only, with the total and whether more pages follow. */\nexport async function page(transport: Transport, asset: Oid, options: { page?: { size: number; start: number } } = {}): Promise<{ attachments: AttachmentInfo[]; total: number | null; more: boolean }> {\n const { rows, total, more } = await assetApi.queryPage(transport, { from: \"Attachment\", select: SELECT, filter: [\"Asset=$asset\"], with: { $asset: momentless(asset) }, sort: [\"-CreateDate\"], page: options.page ?? { size: 50, start: 0 } });\n return { attachments: rows.map((r) => infoOf(r as unknown as Row)), total, more };\n}\n\n/** The files attached to an asset, newest first, metadata only (one page; `page` also gives the total). */\nexport async function list(transport: Transport, asset: Oid, options: { page?: { size: number; start: number } } = {}): Promise<AttachmentInfo[]> {\n const rows = await assetApi.query(transport, { from: \"Attachment\", select: SELECT, filter: [\"Asset=$asset\"], with: { $asset: momentless(asset) }, sort: [\"-CreateDate\"], page: options.page ?? { size: 50, start: 0 } });\n return rows.map((r) => infoOf(r as unknown as Row));\n}\n\n/** One attachment's metadata, or null when there is none with that id. */\nexport async function info(transport: Transport, id: Oid | string | number): Promise<AttachmentInfo | null> {\n const [row] = await assetApi.query(transport, { from: \"Attachment\", select: SELECT, filter: [\"ID=$id\"], with: { $id: `Attachment:${numericId(id)}` }, page: { size: 1, start: 0 } });\n return row ? infoOf(row as unknown as Row) : null;\n}\n\n/**\n * One attachment: its metadata and its bytes. `contentType` is the type the\n * server sent the bytes with, falling back to the Attachment's recorded\n * one; `recordedContentType` is always the latter.\n */\nexport async function get(transport: Transport, id: Oid | string | number): Promise<AttachmentInfo & { bytes: Uint8Array; recordedContentType: string | null }> {\n const meta = await info(transport, id);\n if (!meta) throw new ApiError(`attachment ${numericId(id)}: not found`, 404, \"NOT_FOUND\");\n const file = await getFile(transport, meta.id);\n return { ...meta, bytes: file.bytes, contentType: file.contentType ?? meta.contentType, recordedContentType: meta.contentType };\n}\n\nexport interface AddOptions {\n filename: string;\n /** Defaults to the Blob's type, then application/octet-stream. */\n contentType?: string;\n /** Defaults to the filename. */\n name?: string;\n description?: string;\n /** Inline (one request) up to this many bytes, two-step above. Default INLINE_LIMIT. */\n inlineLimit?: number;\n}\n\n/** An Attachment was created but its bytes could not be uploaded: it exists, empty. Remove it or upload again with `put`. */\nexport class AttachmentUploadError extends WrappedError {\n constructor(readonly attachment: AttachmentInfo, cause: unknown) {\n super(`${attachment.oid} was created on its asset with no content, and uploading the file failed: ${cause instanceof Error ? cause.message : String(cause)}`, \"ATTACHMENT_UPLOAD\", cause);\n this.name = \"AttachmentUploadError\";\n }\n}\n\n/** Attach a file to an asset. Inline up to `inlineLimit` bytes, two-step above it. */\nexport async function add(transport: Transport, asset: Oid, data: Bytes, options: AddOptions): Promise<AttachmentInfo> {\n const bytes = await toUint8Array(data);\n const contentType = options.contentType ?? (typeof Blob !== \"undefined\" && data instanceof Blob && data.type ? data.type : \"application/octet-stream\");\n const inline = bytes.length <= (options.inlineLimit ?? INLINE_LIMIT);\n const create: assetApi.CreateBody = { AssetType: \"Attachment\", Asset: momentless(asset), Name: options.name ?? options.filename, Filename: options.filename, ContentType: contentType, Content: inline ? toBase64(bytes) : \"\" };\n if (options.description) create.Description = options.description;\n const oid = assetApi.outcomeOf(await assetApi.send(transport, [create], { throwOnFailure: true })).created[0]!;\n const created: AttachmentInfo = { oid, id: numericId(oid), name: String(create.Name), filename: options.filename, contentType, description: options.description ?? null, createDate: null, createdBy: null };\n if (!inline) {\n try {\n await putBytes(transport, created.id, bytes, contentType);\n } catch (error) {\n throw new AttachmentUploadError(created, error);\n }\n }\n return created;\n}\n\n/** Replace an attachment's bytes. */\nexport async function put(transport: Transport, id: Oid | string | number, data: Bytes, contentType?: string): Promise<void> {\n await putBytes(transport, id, data, contentType);\n}\n\n/** Delete an attachment. */\nexport async function remove(transport: Transport, id: Oid | string | number): Promise<void> {\n await assetApi.send(transport, [{ from: `Attachment:${numericId(id)}`, execute: \"Delete\" }], { throwOnFailure: true });\n}\n","/**\n * The guard: an api/asset batch sent as a compare-and-set, so a change only\n * lands on an asset nobody else has changed since it was read. Ported from\n * the CLI consumer's batch `guarded()`, with a different stamp.\n *\n * How: preview the batch (the server's projection expands every query-\n * scoped update and execute into one command per asset), read each touched\n * asset's ChangeDate, and send each per-asset command as a query-scoped one\n * filtered on its ID and that ChangeDate. An asset changed in between has a\n * newer ChangeDate, matches nothing, and is left alone; the response's\n * modified/operated lists say which assets the batch actually touched, so\n * the rest are `skipped`.\n *\n * The stamp, settled live on 2026-11-04 (test/integration/guard.test.ts):\n * - ChangeDate as a filter LITERAL is a true compare-and-set: the value\n * just read matches, a stale one matches nothing, and resending the same\n * guarded batch writes nothing the second time.\n * - ChangeDate as a `with` VARIABLE never matches, not even the value just\n * read back — so this is the one place a value is spliced into filter\n * text. It is the server's own timestamp, checked against a strict date\n * pattern first, so it cannot carry grammar. The ID stays a variable.\n * - Moment is NOT a stamp: `Moment=<an earlier moment of this asset>`\n * selects the asset as it was then (as-of), and an update scoped by it\n * lands on the current asset. A Moment guard guards nothing. Proven for\n * writes on 2026-11-11: an update filtered on a stale Moment previews as\n * one command and applies, overwriting the change made in between\n * (\"why not Moment, on a write\"; versionone/VersionOne.SDK.JavaScript#51).\n * Every type has ChangeDate except the Ideas product's (Idea*), which keeps\n * no history and cannot be guarded.\n *\n * A guarded batch without creates is safe to send twice — an applied\n * command has advanced the ChangeDate, so a resend matches nothing — and is\n * sent marked idempotent (spec 000 §6).\n */\nimport { ApiError, UsageError, WrappedError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Asset, Oid } from \"../types/asset\";\nimport type { AssetTypeToken } from \"../types/metamodel\";\nimport { momentless, typeOfOid } from \"../types/oid\";\nimport * as assetApi from \"../wire/assetApi\";\nimport type { Command, CommandValue, ExecuteBody } from \"../wire/assetApi\";\n\n/** OIDs per ChangeDate read: bounded, never one giant filter. */\nexport const CHUNK = 100;\n\n/** Types with no ChangeDate (the Ideas product keeps no history): nothing of theirs can be guarded. */\nexport const UNGUARDABLE_TYPES: readonly AssetTypeToken[] = [\"Idea\", \"IdeaChangeSet\", \"IdeaStatus\", \"IdeaComment\", \"IdeaCategory\", \"IdeaForum\", \"IdeaUser\"];\n\n/** Why a command cannot be sent guarded, by its index in the batch. */\nexport interface Unguardable { index: number; reason: string }\n\n/** A batch the guard will not send, rather than send unguarded without saying so. */\nexport class UnguardableError extends UsageError {\n readonly reasons: Unguardable[];\n constructor(reasons: Unguardable[]) {\n super(`cannot guard this batch: ${reasons.map((r) => `command ${r.index}: ${r.reason}`).join(\"; \")}`);\n this.name = \"UnguardableError\";\n this.reasons = reasons;\n }\n}\n\n// ---- reading commands ----------------------------------------------------------\n\n/** The alias and body of an aliased command, or null for a bare one. */\nexport function aliased(command: Command): { alias: string; body: Record<string, unknown> } | null {\n const keys = Object.keys(command);\n return keys.length === 1 && keys[0]!.startsWith(\"@\") ? { alias: keys[0]!, body: (command as Record<string, Record<string, unknown>>)[keys[0]!]! } : null;\n}\nconst bodyOf = (c: Command): Record<string, unknown> => aliased(c)?.body ?? (c as Record<string, unknown>);\nconst isObject = (v: unknown): v is Record<string, unknown> => !!v && typeof v === \"object\" && !Array.isArray(v);\n/** A relation value that is itself a create: the projection normalises these away, so they cannot be guarded. */\nconst isCreateValue = (v: unknown): boolean =>\n (isObject(v) && \"AssetType\" in v) || (Array.isArray(v) && v.some(isCreateValue)) || (isObject(v) && ([] as unknown[]).concat(v.add ?? []).some(isCreateValue));\n\n/** The commands of a batch the guard cannot cover, and why. Empty means it can. */\nexport function unguardable(commands: Command[]): Unguardable[] {\n const out: Unguardable[] = [];\n commands.forEach((c, index) => {\n const a = aliased(c);\n const body = bodyOf(c);\n const writes = \"update\" in body || \"execute\" in body;\n if (a && writes) out.push({ index, reason: `${a.alias} is an aliased ${\"update\" in body ? \"update\" : \"execute\"}: preview does not expand it, so it cannot be read or guarded per asset` });\n else if (!a && writes && typeof body.from === \"string\" && body.from.startsWith(\"@\")) out.push({ index, reason: `a bare update or execute from an alias (${body.from}) is rejected by the server; alias the command itself` });\n if (isObject(body.update) && Object.values(body.update).some(isCreateValue)) out.push({ index, reason: \"an update that creates assets inline: the projection normalises the creates away\" });\n });\n return out;\n}\n\n/** A projected per-asset command: the asset and what is done to it. */\ninterface PerAsset { oid: Oid; update?: Record<string, CommandValue>; execute?: CommandValue }\nfunction perAsset(projected: Command): PerAsset | null {\n const body = bodyOf(projected);\n return typeof body.oid === \"string\" && (\"update\" in body || \"execute\" in body)\n ? { oid: momentless(body.oid), update: body.update as Record<string, CommandValue> | undefined, execute: body.execute as CommandValue | undefined }\n : null;\n}\n\n/** The assets a projection updates or operates on, once each, in order. */\nexport const touchedBy = (projected: Command[]): Oid[] => [...new Set(projected.flatMap((p) => { const x = perAsset(p); return x ? [x.oid] : []; }))];\n\n// ---- the stamp -----------------------------------------------------------------\n\n/** A ChangeDate as the server writes it: 2026-11-04T16:49:40.12 (trailing zeros trimmed, no zone). */\nconst STAMP = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?$/;\n\n/** Each asset's current ChangeDate, one bounded query per type and chunk. An asset that no longer exists is absent. */\nexport async function stampsOf(transport: Transport, oids: readonly Oid[]): Promise<Record<Oid, string>> {\n const byType = new Map<string, Oid[]>();\n for (const oid of new Set(oids.map(momentless))) { const t = typeOfOid(oid); byType.set(t, [...(byType.get(t) ?? []), oid]); }\n const out: Record<Oid, string> = {};\n for (const [type, list] of byType) {\n if (UNGUARDABLE_TYPES.includes(type)) continue;\n for (let i = 0; i < list.length; i += CHUNK) {\n const part = list.slice(i, i + CHUNK);\n const rows = await assetApi.query<Asset & { ChangeDate?: string }>(transport, { from: type, select: [\"ChangeDate\"], filter: [\"ID=$oids\"], with: { $oids: part }, page: { size: part.length, start: 0 } });\n for (const r of rows) if (r.ChangeDate != null) out[momentless(r._oid)] = String(r.ChangeDate);\n }\n }\n return out;\n}\n\n/**\n * The batch to send: the projection, each per-asset update or execute\n * rewritten as a query-scoped command on its ID and ChangeDate. Creates and\n * queries pass through as the projection echoed them. An asset with no\n * stamp (gone since the preview) is left out and reported as skipped.\n */\nexport function guard(projected: Command[], stamps: Readonly<Record<Oid, string>>): { commands: Command[]; unstamped: Oid[] } {\n const commands: Command[] = [], unstamped: Oid[] = [];\n for (const p of projected) {\n const x = perAsset(p);\n if (!x) { commands.push(p); continue; }\n const stamp = stamps[x.oid];\n if (stamp === undefined) { unstamped.push(x.oid); continue; }\n if (!STAMP.test(stamp)) throw new ApiError(`${x.oid}: ChangeDate ${JSON.stringify(stamp)} is not a timestamp; refusing to put it in a filter`, 200, \"BAD_RESPONSE\", { oid: x.oid, stamp });\n // The literal is deliberate: as a `with` variable a ChangeDate never compares equal (see above).\n const scope = { from: typeOfOid(x.oid), filter: [\"ID=$oid\", `ChangeDate='${stamp}'`], with: { $oid: x.oid } };\n commands.push(x.update ? { ...scope, update: x.update } : { ...scope, execute: x.execute as ExecuteBody[\"execute\"] });\n }\n return { commands, unstamped };\n}\n\n// ---- passes --------------------------------------------------------------------\n\n/**\n * A projection split into passes: the k-th per-asset command for each asset\n * goes in pass k; creates and queries ride in pass 0. One pass is the usual\n * case. Two commands on one asset (a reverse batch's Reactivate then Delete,\n * say) cannot share a pass: both would be stamped with the ChangeDate read\n * before the batch, the first would advance it, and the second would match\n * nothing — silently skipped.\n */\nexport function passesOf(projected: Command[]): Command[][] {\n const seen = new Map<Oid, number>();\n const passes: Command[][] = [[]];\n for (const p of projected) {\n const x = perAsset(p);\n const k = x ? seen.get(x.oid) ?? 0 : 0;\n if (x) seen.set(x.oid, k + 1);\n (passes[k] ??= []).push(p);\n }\n return passes;\n}\n\n/** A guarded send that failed after some passes applied: `outcome` and `sent` say what did. */\nexport class GuardedPassError extends WrappedError {\n constructor(cause: unknown, readonly outcome: assetApi.Outcome, readonly sent: Command[], readonly pass: number) {\n super(`guarded send failed in pass ${pass + 1}${pass ? \" (earlier passes applied)\" : \"\"}: ${cause instanceof Error ? cause.message : String(cause)}`, \"GUARDED_PASS\", cause);\n this.name = \"GuardedPassError\";\n }\n}\n\n/**\n * Send a projection guarded, pass by pass. Pass 0 is guarded on `stamps`\n * (read before the batch). A later pass sends an asset's next command only\n * if its previous one applied, guarded on the ChangeDate read again just\n * after it — so the chain stays a compare-and-set, with one narrow window\n * between our write and that read. An asset whose earlier command was\n * skipped is skipped for the rest of the batch. Failure indexes are\n * positions in `sent` (all passes, in order). A send that fails in the\n * first pass throws as it would alone; in a later pass it throws a\n * GuardedPassError carrying what the earlier passes did.\n */\nexport async function sendPasses<Row extends Asset = Asset>(transport: Transport, projected: Command[], stamps: Readonly<Record<Oid, string>>, options: Pick<assetApi.SendOptions, \"lookup\" | \"throwOnFailure\"> = {}): Promise<{ outcome: assetApi.Outcome<Row>; sent: Command[]; unstamped: Oid[] }> {\n const passes = passesOf(projected);\n const outcome = assetApi.emptyOutcome<Row>();\n const sent: Command[] = [], unstamped: Oid[] = [];\n let applied = new Set<Oid>();\n for (const [k, pass] of passes.entries()) {\n let current: { commands: Command[]; unstamped: Oid[] };\n if (k === 0) current = guard(pass, stamps);\n else {\n // Only assets whose previous command applied go on, stamped afresh.\n const eligible = pass.filter((p) => applied.has(perAsset(p)!.oid));\n current = guard(eligible, await stampsOf(transport, eligible.map((p) => perAsset(p)!.oid)));\n }\n const commands = current.commands;\n unstamped.push(...current.unstamped);\n if (!commands.length) break;\n const offset = sent.length;\n let done: assetApi.Outcome<Row>;\n try {\n const creates = commands.some((c) => \"AssetType\" in bodyOf(c));\n done = assetApi.outcomeOf(await assetApi.send<Row>(transport, commands, { ...options, idempotent: !creates }));\n } catch (error) {\n // Nothing applied yet: the error is the whole story, as for a single send.\n if (k === 0) throw error;\n throw new GuardedPassError(error, outcome, sent, k);\n }\n sent.push(...commands);\n assetApi.mergeOutcome(outcome, done, offset);\n applied = new Set([...done.modified, ...done.operated].map(momentless));\n }\n return { outcome, sent, unstamped: [...new Set(unstamped)] };\n}\n\n// ---- the whole move --------------------------------------------------------------\n\nexport interface GuardedResult<Row extends Asset = Asset> {\n /** What the batch did: created, modified, operated, failures, query rows. */\n outcome: assetApi.Outcome<Row>;\n /** The server's projection the guard was built from. */\n projected: Command[];\n /** The batch as sent. */\n sent: Command[];\n /** Every asset the projection would update or operate on. */\n touched: Oid[];\n /** Each touched asset's ChangeDate when read: the stamp it was guarded on. */\n stamps: Record<Oid, string>;\n /**\n * Touched assets the batch left alone: changed or gone since they were\n * read — or their command failed, which `outcome.failures` says.\n */\n skipped: Oid[];\n}\n\n/**\n * Preview, stamp, send guarded. Throws UnguardableError, before any request,\n * for a batch the guard cannot cover; send such a batch with assetApi.send,\n * knowingly.\n */\nexport async function sendGuarded<Row extends Asset = Asset>(transport: Transport, commands: Command[], options: Pick<assetApi.SendOptions, \"lookup\" | \"throwOnFailure\"> = {}): Promise<GuardedResult<Row>> {\n const refused = unguardable(commands);\n if (refused.length) throw new UnguardableError(refused);\n const projected = await assetApi.preview(transport, commands);\n const touched = touchedBy(projected);\n const ideas = touched.filter((oid) => UNGUARDABLE_TYPES.includes(typeOfOid(oid)));\n if (ideas.length) throw new UnguardableError(ideas.map((oid) => ({ index: -1, reason: `${oid}: ${typeOfOid(oid)} has no ChangeDate` })));\n const stamps = await stampsOf(transport, touched);\n const { outcome, sent, unstamped } = await sendPasses<Row>(transport, projected, stamps, options);\n const done = new Set([...outcome.modified, ...outcome.operated]);\n return { outcome, projected, sent, touched, stamps, skipped: [...new Set([...unstamped, ...touched.filter((oid) => !done.has(oid))])] };\n}\n","/**\n * The batch service: an api/asset batch sent with a record of what it did.\n * Ported from the CLI consumer's batch module — preview, describe, snapshot, send\n * (guarded by default), receipt, reverse — minus what is the CLI's: file\n * I/O, console output, permalinks and the confirm prompt (a callback here).\n *\n * A receipt is what the response alone is not: the request as sent, the\n * server's projection (one command per asset it would touch), a BEFORE\n * snapshot of exactly the attributes each projected update names (and the\n * AssetState of each execute, and every touched asset's ChangeDate) taken\n * just before sending, and from those, what a person needs afterwards: the\n * created assets with their aliases, numbers and names; the touched assets;\n * which were skipped by the guard; and a reverse batch that undoes what\n * succeeded, best effort, with a note for anything it cannot.\n *\n * Closing a workitem cascades: the server's Inactivate and QuickClose also close\n * its open descendants, and Reactivate reopens only the asset it names. So\n * before a batch that closes, the receipt records each closing target's\n * open descendants; after it, the ones the close actually closed; and the\n * reverse reopens the parent, then those, top down.\n *\n * The snapshot keeps the endpoint's spelling (strings, relations as OID\n * tokens) on purpose: it is what a reverse batch writes back.\n */\nimport { UsageError, WrappedError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Asset, Oid } from \"../types/asset\";\nimport type { AssetTypeToken } from \"../types/metamodel\";\nimport { momentless, typeOfOid } from \"../types/oid\";\nimport * as assetApi from \"../wire/assetApi\";\nimport type { Command, CommandValue } from \"../wire/assetApi\";\nimport { aliased, guard, GuardedPassError, passesOf, sendPasses, stampsOf, touchedBy, unguardable, UnguardableError } from \"./guard\";\nimport type { Schema } from \"./schema\";\n\n/** OIDs per lookup query: bounded, never one giant filter. */\nexport const CHUNK = 100;\n\n// ---- describing a batch ----------------------------------------------------------\n\nexport interface Described {\n creates: { index: number; alias: string | null; type: string; name: string | null }[];\n queries: { index: number; from: string }[];\n updates: { oid: Oid; attributes: Record<string, CommandValue> }[];\n executes: { oid: Oid; op: string; args: Record<string, CommandValue> }[];\n /**\n * Aliased updates and executes: preview does not expand them, so they\n * have no per-asset entry above, no snapshot and no reverse. They are\n * work all the same, sent as written (only with guard: false).\n */\n deferred: { index: number; alias: string; from: string; kind: \"update\" | \"execute\" }[];\n}\n\nconst bodyOf = (c: Command): Record<string, unknown> => aliased(c)?.body ?? (c as Record<string, unknown>);\n\n/** What a batch does: creates and queries read off the request; updates and executes, per asset, off the projection. */\nexport function describe(commands: Command[], projected: Command[]): Described {\n const out: Described = { creates: [], queries: [], updates: [], executes: [], deferred: [] };\n commands.forEach((c, index) => {\n const a = aliased(c), body = bodyOf(c);\n if (a && typeof body.from === \"string\" && (\"update\" in body || \"execute\" in body)) out.deferred.push({ index, alias: a.alias, from: body.from, kind: \"update\" in body ? \"update\" : \"execute\" });\n else if (typeof body.AssetType === \"string\") out.creates.push({ index, alias: a?.alias ?? null, type: body.AssetType, name: typeof body.Name === \"string\" ? body.Name : null });\n else if (typeof body.from === \"string\" && !(\"update\" in body) && !(\"execute\" in body)) out.queries.push({ index, from: body.from });\n });\n for (const p of projected) {\n const body = bodyOf(p);\n if (typeof body.oid !== \"string\") continue;\n const oid = momentless(body.oid);\n if (body.update && typeof body.update === \"object\") out.updates.push({ oid, attributes: body.update as Record<string, CommandValue> });\n else if (body.execute !== undefined) {\n const e = body.execute as string | { op: string; args?: Record<string, CommandValue> };\n out.executes.push({ oid, op: typeof e === \"string\" ? e : e.op, args: typeof e === \"string\" ? {} : e.args ?? {} });\n }\n }\n return out;\n}\n\n// ---- reading assets --------------------------------------------------------------\n\nconst byType = (oids: Iterable<Oid>): Map<AssetTypeToken, Oid[]> => {\n const out = new Map<AssetTypeToken, Oid[]>();\n for (const oid of new Set([...oids].map(momentless))) out.set(typeOfOid(oid), [...(out.get(typeOfOid(oid)) ?? []), oid]);\n return out;\n};\nconst chunks = <T>(list: T[]): T[][] => Array.from({ length: Math.ceil(list.length / CHUNK) }, (_, i) => list.slice(i * CHUNK, (i + 1) * CHUNK));\n/** A relation as a reverse batch writes it: OID tokens. */\nconst plain = (v: unknown): unknown =>\n Array.isArray(v) ? v.map(plain) : v && typeof v === \"object\" && \"_oid\" in v ? momentless(String((v as { _oid: unknown })._oid)) : v ?? null;\n\nexport interface Named { number: string | null; name: string | null }\n\n/** Told about a name lookup that failed: the type, the assets left unnamed, and why. */\nexport type NameLookupFailure = (failure: { type: AssetTypeToken; oids: Oid[]; error: unknown }) => void;\n\n/**\n * Numbers and names, one bounded query per type and chunk, asking each type\n * only for what the schema says it has (a Conversation has neither, and\n * asking fails the query). Cosmetic: a lookup that fails leaves those assets\n * unnamed rather than failing a batch that may already be sent, and is\n * reported to `onFailure` so a caller can say so.\n */\nexport async function namesOf(transport: Transport, schema: Schema, oids: Iterable<Oid>, onFailure?: NameLookupFailure): Promise<Map<Oid, Named>> {\n const out = new Map<Oid, Named>();\n for (const [type, list] of byType(oids)) {\n let select: string[];\n try {\n await schema.load(type);\n select = [\"Name\", \"Number\"].filter((a) => schema.attribute(type, a));\n } catch (error) {\n onFailure?.({ type, oids: list, error });\n continue;\n }\n if (!select.length) continue;\n for (const part of chunks(list)) {\n try {\n const rows = await assetApi.query<Asset & { Name?: string; Number?: string }>(transport, { from: type, select, filter: [\"ID=$oids\"], with: { $oids: part }, page: { size: part.length, start: 0 } });\n for (const r of rows) out.set(momentless(r._oid), { number: r.Number ?? null, name: r.Name ?? null });\n } catch (error) {\n onFailure?.({ type, oids: part, error });\n }\n }\n }\n return out;\n}\n\n/** The values about to be overwritten: each update's named attributes, each execute's AssetState, and every touched asset's ChangeDate. */\nexport async function snapshot(transport: Transport, described: Described): Promise<Record<Oid, Record<string, unknown>>> {\n const wanted = new Map<Oid, Set<string>>();\n const want = (oid: Oid, attrs: string[]) => { const s = wanted.get(oid) ?? new Set<string>(); attrs.forEach((a) => s.add(a)); wanted.set(oid, s); };\n for (const u of described.updates) want(u.oid, [...Object.keys(u.attributes), \"ChangeDate\"]);\n for (const e of described.executes) want(e.oid, [\"AssetState\", \"ChangeDate\"]);\n const before: Record<Oid, Record<string, unknown>> = {};\n for (const [type, oids] of byType(wanted.keys())) {\n const select = [...new Set(oids.flatMap((o) => [...wanted.get(o)!]))];\n for (const part of chunks(oids)) {\n const rows = await assetApi.query<Asset>(transport, { from: type, select, filter: [\"ID=$oids\"], with: { $oids: part }, page: { size: part.length, start: 0 } });\n for (const r of rows) {\n const oid = momentless(r._oid), row = r as unknown as Record<string, unknown>;\n before[oid] = Object.fromEntries([...wanted.get(oid)!].map((a) => [a, plain(row[a])]));\n }\n }\n }\n return before;\n}\n\n// ---- undoing it --------------------------------------------------------------------\n\n/** The known inverse operations. Anything else is reported, not guessed. */\nexport const INVERSE: Readonly<Record<string, string>> = { Inactivate: \"Reactivate\", QuickClose: \"Reactivate\", Reactivate: \"Inactivate\", Delete: \"Undelete\", Undelete: \"Delete\" };\n\n/** Operations that close an asset's open descendants along with it (the server's close cascade). */\nexport const CASCADING: ReadonlySet<string> = new Set([\"Inactivate\", \"QuickClose\"]);\n\n/** How deep a cascade is followed: Epic → sub-Epic → Story → Task is four. */\nconst CASCADE_DEPTH = 8;\n\n/**\n * Each root's open descendants, top down (children, then grandchildren, …),\n * through the Children relation of the types that have one. One bounded\n * query per type and chunk for each level's children, and one for their\n * states. A root whose type has no Children has none.\n */\nexport async function openDescendantsOf(transport: Transport, schema: Schema, roots: Oid[]): Promise<Record<Oid, Oid[]>> {\n const out: Record<Oid, Oid[]> = {};\n const rootOf = new Map<Oid, Oid>(roots.map((r) => [momentless(r), momentless(r)]));\n const seen = new Set(rootOf.keys());\n let frontier = [...rootOf.keys()];\n for (let depth = 0; depth < CASCADE_DEPTH && frontier.length; depth += 1) {\n const children = new Map<Oid, Oid>(); // child → its root\n for (const [type, list] of byType(frontier)) {\n await schema.load(type);\n if (!schema.attribute(type, \"Children\")) continue;\n for (const part of chunks(list)) {\n const rows = await assetApi.query<Asset & { Children?: unknown }>(transport, { from: type, select: [\"Children\"], filter: [\"ID=$oids\"], with: { $oids: part }, page: { size: part.length, start: 0 } });\n for (const r of rows) {\n const parent = momentless(r._oid);\n for (const c of ([] as unknown[]).concat(plain(r.Children) ?? [])) {\n const child = momentless(String(c));\n if (seen.has(child)) continue;\n seen.add(child);\n children.set(child, rootOf.get(parent)!);\n }\n }\n }\n }\n const states = children.size ? await statesOf(transport, [...children.keys()]) : {};\n frontier = [];\n for (const [child, root] of children) {\n if (states[child] === undefined || isClosed(states[child])) continue; // gone, or closed already: not the cascade's\n rootOf.set(child, root);\n (out[root] ??= []).push(child);\n frontier.push(child);\n }\n }\n return out;\n}\n\nexport interface Reverse { commands: Command[]; notes: string[] }\n\n/** What reverseOf can know beyond the response, each optional. */\nexport interface ReverseContext {\n /** Per closing target, its open descendants before the batch (Receipt.openDescendants). */\n openDescendants?: Record<Oid, Oid[]>;\n /** Per closing target, the descendants the close closed (Receipt.cascaded); undefined when they could not be read back. */\n cascaded?: Record<Oid, Oid[]>;\n /** Can this type do this operation? Undefined is \"don't know\", and the command is kept. */\n canOperate?: (type: AssetTypeToken, op: string) => boolean | undefined;\n}\n\n/**\n * A batch that undoes what the response says succeeded — best effort. Only\n * what the response confirms is reversed (membership in it, not command\n * index, decides): updated attributes put back from the snapshot, the\n * inverse operation where one is known (and, for a close, the descendants\n * it closed reopened after it, top down), created assets deleted (newest\n * first). An operation a type does not have, by `context.canOperate`, is\n * a note rather than a command the server would refuse.\n */\nexport function reverseOf(described: Described, before: Record<Oid, Record<string, unknown>>, done: { created: Oid[]; modified: Oid[]; operated: Oid[] }, context: ReverseContext = {}): Reverse {\n const commands: Command[] = [], notes: string[] = [];\n const cannot = (oid: Oid, op: string) => context.canOperate?.(typeOfOid(oid), op) === false;\n const modified = new Set(done.modified.map(momentless)), operated = new Set(done.operated.map(momentless));\n for (const u of described.updates) {\n if (!modified.has(u.oid)) continue;\n const was = before[u.oid];\n if (!was) { notes.push(`${u.oid}: no snapshot, cannot restore`); continue; }\n const update: Record<string, CommandValue> = {};\n for (const [attr, change] of Object.entries(u.attributes)) {\n const prior = was[attr];\n const c = change && typeof change === \"object\" && !Array.isArray(change) ? change as { add?: CommandValue; remove?: CommandValue } : {};\n const add = ([] as CommandValue[]).concat(c.add ?? []), remove = ([] as CommandValue[]).concat(c.remove ?? []);\n if (Array.isArray(prior)) {\n const added = add.filter((v) => !prior.includes(v)), removed = remove.filter((v) => prior.includes(v));\n if (added.length || removed.length) update[attr] = { add: removed, remove: added };\n } else if (prior === undefined) notes.push(`${u.oid}.${attr}: not in snapshot, cannot restore`);\n else update[attr] = prior as CommandValue; // a scalar or single relation: put the old value back (null clears)\n }\n if (Object.keys(update).length) commands.push({ from: u.oid, update });\n }\n for (const e of described.executes) {\n if (!operated.has(e.oid)) continue;\n const inverse = INVERSE[e.op];\n if (!inverse) { notes.push(`${e.oid}: ${e.op} has no known inverse (was ${String(before[e.oid]?.AssetState ?? \"?\")})`); continue; }\n if (cannot(e.oid, inverse)) { notes.push(`${e.oid}: ${typeOfOid(e.oid)} has no ${inverse} operation, so its ${e.op} is not reversed`); continue; }\n commands.push({ from: e.oid, execute: inverse });\n if (!CASCADING.has(e.op)) continue;\n const open = context.openDescendants?.[e.oid] ?? [];\n const closed = context.cascaded ? context.cascaded[e.oid] ?? [] : undefined;\n if (closed === undefined) {\n if (open.length) notes.push(`${e.oid}: ${e.op} may also have closed ${open.length} open descendant${open.length === 1 ? \"\" : \"s\"} (${open.join(\", \")}); they could not be read back, so they are not reopened`);\n continue;\n }\n for (const d of closed) {\n if (cannot(d, \"Reactivate\")) notes.push(`${d}: closed with ${e.oid}, but ${typeOfOid(d)} has no Reactivate operation`);\n else commands.push({ from: d, execute: \"Reactivate\" });\n }\n if (closed.length) notes.push(`${e.oid}: ${e.op} also closed ${closed.join(\", \")}; reopened after it`);\n }\n for (const oid of [...done.created].reverse().map(momentless)) {\n if (cannot(oid, \"Delete\")) notes.push(`${oid}: ${typeOfOid(oid)} has no Delete operation, so it is not deleted${typeOfOid(oid) === \"Conversation\" ? \" (the server removes a Conversation once its last Expression is deleted)\" : \"\"}`);\n else commands.push({ from: oid, execute: \"Delete\" });\n }\n for (const d of described.deferred ?? []) notes.push(`command ${d.index} (${d.alias}): an aliased ${d.kind} of ${d.from}, sent as written with no snapshot; not reversed`);\n if (commands.length) notes.unshift(\"restores the state recorded at snapshotAt; anything that changed between then and sentAt is not reflected, and a scalar restored to null is cleared, not unset\");\n return { commands, notes };\n}\n\n// ---- the receipt -----------------------------------------------------------------------\n\nexport interface Receipt {\n receipt: 1;\n request: Command[];\n previewedAt: string;\n preview: Command[];\n described: Described;\n /** Numbers and names of the assets the preview touches, looked up before confirm. */\n names: Record<Oid, Named>;\n snapshotAt?: string;\n /** Before values per touched asset, ChangeDate included: what the guard compared and the reverse restores. */\n before: Record<Oid, Record<string, unknown>>;\n /** Was the batch sent? False for a preview, a declined confirm, or nothing to do. */\n sent: boolean;\n guarded: boolean;\n /** The batch as sent (the guarded projection, or the request as written). */\n sentCommands?: Command[];\n sentAt?: string;\n /** What the server says the batch did. */\n outcome?: assetApi.Outcome;\n created: ({ alias: string | null; type: string; oid: Oid } & Named)[];\n touched: ({ oid: Oid } & Named)[];\n /** ChangeDate of everything the batch touched, just after it: the stamp a later reverse checks for drift. */\n after: Record<Oid, string>;\n /** Touched assets the guard left alone: changed or gone since the snapshot. Not the ones whose command failed: those are in `failed`. */\n skipped: Oid[];\n /** Touched assets whose command the server reports as failed (outcome.failures says why). */\n failed: Oid[];\n /** Per asset the batch closes (Inactivate, QuickClose): its open descendants at the snapshot, top down. */\n openDescendants: Record<Oid, Oid[]>;\n /** Per asset the batch closed: the descendants the close closed with it, read back after the send. */\n cascaded: Record<Oid, Oid[]>;\n reverse: Reverse;\n /** What the record could not do and why: a name lookup that failed, deferred commands sent unsnapshotted. */\n notes: string[];\n}\n\n/**\n * The batch was sent and the server's outcome is on the receipt\n * (`receipt.sent`, `receipt.outcome`, `receipt.reverse`), but reading the\n * assets back afterwards failed, so `receipt.after` is incomplete: keep the\n * receipt, and know that a reverse built from it cannot check every asset\n * for changes made since.\n */\nexport class BatchRecordError extends WrappedError {\n readonly receipt: Receipt;\n constructor(cause: unknown, receipt: Receipt) {\n super(`the batch was sent and its outcome recorded, but reading the assets back afterwards failed, so receipt.after is incomplete: ${cause instanceof Error ? cause.message : String(cause)}`, \"BATCH_RECORD\", cause);\n this.name = \"BatchRecordError\";\n this.receipt = receipt;\n }\n}\n\n/** The send itself failed (a timeout, a 5xx): whether the server applied it is unknown. The receipt holds everything up to the attempt. */\nexport class BatchSendError extends WrappedError {\n readonly receipt: Receipt;\n constructor(cause: unknown, receipt: Receipt) {\n super(`the batch send failed; whether the server applied it is unknown: ${cause instanceof Error ? cause.message : String(cause)}`, \"BATCH_SEND\", cause);\n this.name = \"BatchSendError\";\n this.receipt = receipt;\n }\n}\n\nexport interface BatchOptions {\n /** Send as a compare-and-set (default). An unguardable batch then throws UnguardableError before any request; pass false to send it as written. */\n guard?: boolean;\n /** Stop after the snapshot and send nothing: the receipt says what would happen. */\n dryRun?: boolean;\n /** Asked after the snapshot, before the send, with the touched assets' names on the receipt; false sends nothing. */\n confirm?: (receipt: Receipt) => boolean | Promise<boolean>;\n}\n\nconst now = (): string => new Date().toISOString();\n\n/** Preview, describe, name, snapshot, (confirm,) send, receipt. */\nexport async function runBatch(transport: Transport, schema: Schema, commands: Command[], options: BatchOptions = {}): Promise<Receipt> {\n const useGuard = options.guard ?? true;\n if (!commands.length) throw new UsageError(\"the batch is empty\");\n const refused = unguardable(commands);\n const fatal = refused.filter((r) => r.reason.includes(\"rejected by the server\"));\n if (fatal.length || (useGuard && refused.length)) throw new UnguardableError(useGuard ? refused : fatal);\n\n const notes: string[] = [];\n const noteFailure: NameLookupFailure = ({ type, oids, error }) =>\n notes.push(`could not look up Name for ${oids.length} ${type} asset${oids.length === 1 ? \"\" : \"s\"}: ${error instanceof Error ? error.message : String(error)}`);\n const previewedAt = now();\n const projected = await assetApi.preview(transport, commands);\n const described = describe(commands, projected);\n const touched = touchedBy(projected);\n const names = await namesOf(transport, schema, touched, noteFailure);\n const receipt: Receipt = { receipt: 1, request: commands, previewedAt, preview: projected, described, names: Object.fromEntries(names), before: {}, sent: false, guarded: false, created: [], touched: [], after: {}, skipped: [], failed: [], openDescendants: {}, cascaded: {}, reverse: { commands: [], notes: [] }, notes };\n const nothing = !described.creates.length && !described.updates.length && !described.executes.length && !described.queries.length && !described.deferred.length;\n if (nothing) return receipt;\n for (const d of described.deferred) notes.push(`command ${d.index} (${d.alias}): an aliased ${d.kind}, which preview does not expand; sent as written, not snapshotted, not reversible`);\n receipt.snapshotAt = now();\n receipt.before = await snapshot(transport, described);\n const closing = described.executes.filter((e) => CASCADING.has(e.op)).map((e) => e.oid);\n if (closing.length) receipt.openDescendants = await openDescendantsOf(transport, schema, closing);\n if (options.dryRun) return receipt;\n if (options.confirm && !(await options.confirm(receipt))) return receipt;\n\n let unstamped: Oid[] = [];\n receipt.guarded = useGuard;\n receipt.sentAt = now();\n let done: assetApi.Outcome;\n try {\n if (useGuard) {\n // Guarded pass by pass: a second command on the same asset (Reactivate\n // then Delete in a reverse) goes only if the first applied (guard.ts).\n const stamps = Object.fromEntries(Object.entries(receipt.before).flatMap(([oid, v]) => (typeof v.ChangeDate === \"string\" ? [[oid, v.ChangeDate]] : [])));\n receipt.sentCommands = guard(passesOf(projected)[0]!, stamps).commands; // what the first pass sends; replaced below by everything sent\n const result = await sendPasses(transport, projected, stamps);\n ({ outcome: done, unstamped } = result);\n receipt.sentCommands = result.sent;\n } else {\n receipt.sentCommands = commands;\n done = assetApi.outcomeOf(await assetApi.send(transport, commands));\n }\n } catch (error) {\n if (error instanceof GuardedPassError) {\n // Earlier passes applied: the receipt says so, and what failed after.\n receipt.sent = true;\n receipt.outcome = error.outcome;\n receipt.sentCommands = error.sent;\n }\n throw new BatchSendError(error, receipt);\n }\n receipt.sent = true;\n receipt.outcome = done;\n\n // The record, from the response alone: nothing below this block can lose it.\n const hit = [...new Set([...done.modified, ...done.operated])];\n const unnamed = { number: null, name: null };\n receipt.created = done.created.map((oid, i) => ({ alias: described.creates[i]?.alias ?? null, type: described.creates[i]?.type ?? typeOfOid(oid), oid, ...unnamed }));\n receipt.touched = hit.map((oid) => ({ oid, ...(names.get(oid) ?? unnamed) }));\n // A failed command names its asset in what was sent: the guard's\n // with.$oid, or the from of a per-asset command sent as written.\n const sentAs = receipt.sentCommands ?? [];\n const oidOfSent = (i: number | null): Oid | null => {\n const body = i === null ? undefined : (sentAs[i] ? bodyOf(sentAs[i]!) : undefined);\n const id = (body?.with as { $oid?: unknown } | undefined)?.$oid ?? body?.from;\n return typeof id === \"string\" && id.includes(\":\") ? momentless(id) : null;\n };\n receipt.failed = [...new Set(done.failures.map((f) => oidOfSent(f.index)).filter((oid): oid is Oid => !!oid && touched.includes(oid) && !hit.includes(oid)))];\n receipt.skipped = useGuard ? [...new Set([...unstamped, ...touched.filter((oid) => !hit.includes(oid) && !receipt.failed.includes(oid))])] : [];\n // What each type can do, from the definitions already loaded (or loadable):\n // an unknown answer keeps the command, as before.\n for (const type of new Set([...done.created, ...hit].map((oid) => typeOfOid(momentless(oid))))) await schema.load(type).catch(() => null);\n const canOperate = (type: AssetTypeToken, op: string) => schema.canOperate(type, op);\n const operatedNow = new Set(done.operated.map(momentless));\n const closed = Object.keys(receipt.openDescendants).filter((oid) => operatedNow.has(oid) && receipt.openDescendants[oid]!.length);\n // Until the cascade is read back, the reverse says what it could not reopen.\n receipt.reverse = reverseOf(described, receipt.before, done, { openDescendants: receipt.openDescendants, cascaded: closed.length ? undefined : {}, canOperate });\n\n // Decoration, read back from the server. Names are cosmetic (a failure is\n // a note); the after stamps are not, so a failure there throws with the\n // receipt, outcome and all.\n try {\n if (closed.length) {\n // The descendants the close closed: open at the snapshot, closed now.\n const states = await statesOf(transport, closed.flatMap((oid) => receipt.openDescendants[oid]!));\n receipt.cascaded = Object.fromEntries(closed.map((oid) => [oid, receipt.openDescendants[oid]!.filter((d) => isClosed(states[d]))]));\n receipt.reverse = reverseOf(described, receipt.before, done, { openDescendants: receipt.openDescendants, cascaded: receipt.cascaded, canOperate });\n }\n const more = await namesOf(transport, schema, [...done.created, ...hit.filter((oid) => !names.has(oid))], noteFailure);\n receipt.created = receipt.created.map((c) => ({ ...c, ...(more.get(c.oid) ?? unnamed) }));\n receipt.touched = receipt.touched.map((t) => (names.has(t.oid) ? t : { ...t, ...(more.get(t.oid) ?? unnamed) }));\n // The cascade's descendants too: a later reverse reopens them, and checks them for changes first.\n const all = [...new Set([...done.created, ...hit, ...Object.values(receipt.cascaded).flat()])];\n receipt.after = all.length ? await stampsOf(transport, all) : {};\n } catch (error) {\n throw new BatchRecordError(error, receipt);\n }\n return receipt;\n}\n\n/** Each asset's AssetState by name (\"Active\", \"Closed\"), one bounded query per type and chunk. An asset that no longer exists is absent. */\nasync function statesOf(transport: Transport, oids: Oid[]): Promise<Record<Oid, string>> {\n const out: Record<Oid, string> = {};\n for (const [type, list] of byType(oids)) {\n for (const part of chunks(list)) {\n const rows = await assetApi.query<Asset & { AssetState?: unknown }>(transport, { from: type, select: [\"AssetState\"], filter: [\"ID=$oids\"], with: { $oids: part }, page: { size: part.length, start: 0 } });\n for (const r of rows) if (r.AssetState != null) out[momentless(r._oid)] = String(r.AssetState);\n }\n }\n return out;\n}\n\n/** AssetState as the endpoint spells a closed asset: by name, or by the server's code (128). */\nconst isClosed = (state: string | undefined): boolean => state === \"Closed\" || state === \"128\";\n\n/**\n * A receipt's reverse batch, minus the assets someone changed since the\n * batch (their ChangeDate is no longer the one recorded just after it),\n * unless `force`. Send what it returns with runBatch like any batch.\n *\n * Agility refuses to Delete a closed asset (Violation'AssetCannotDeleteClosed),\n * so a Delete of an asset that is closed now gets a Reactivate just before\n * it: two commands on one asset, which runBatch sends in two guarded passes\n * (the Delete only if the Reactivate applied). `reactivated` lists them.\n */\nexport async function reversible(transport: Transport, receipt: Pick<Receipt, \"reverse\" | \"after\">, options: { force?: boolean } = {}): Promise<{ commands: Command[]; drifted: { oid: Oid; was: string; now: string | null }[]; reactivated: Oid[] }> {\n const targets = receipt.reverse.commands.map((c) => momentless(String(bodyOf(c).from)));\n const now = await stampsOf(transport, targets.filter((oid) => receipt.after[oid] !== undefined));\n const drifted = targets.flatMap((oid) => (receipt.after[oid] !== undefined && now[oid] !== receipt.after[oid] ? [{ oid, was: receipt.after[oid]!, now: now[oid] ?? null }] : []));\n const skip = new Set(options.force ? [] : drifted.map((d) => d.oid));\n const kept = receipt.reverse.commands.filter((c) => !skip.has(momentless(String(bodyOf(c).from))));\n const deletes = kept.flatMap((c) => (bodyOf(c).execute === \"Delete\" ? [momentless(String(bodyOf(c).from))] : []));\n const states = deletes.length ? await statesOf(transport, deletes) : {};\n const reactivated = deletes.filter((oid) => isClosed(states[oid]));\n const commands = kept.flatMap((c) => {\n const body = bodyOf(c), oid = momentless(String(body.from));\n return body.execute === \"Delete\" && reactivated.includes(oid) ? [{ from: oid, execute: \"Reactivate\" } as Command, c] : [c];\n });\n return { commands, drifted, reactivated };\n}\n","/**\n * The field-visibility wire module: which attributes the product shows for\n * an asset type in a scope. Two GET endpoints, both answering attribute\n * NAMES, narrower than everything meta.v1 reports — the workspace's\n * configuration (which custom fields are displayed, say) is applied only\n * here. Verified against the API-testing instance and the server's\n * source (2026-11-14):\n *\n * api/visibleFields?scopeOid=Scope:0&assetTypeToken=Story&assetTypeToken=Defect\n * Both parameters REPEAT (not comma lists). Answers one entry per\n * type, { assetType, fields }, fields sorted and de-duplicated, custom\n * fields included once configured for display. A global asset type\n * (no scope context) ignores scopeOid; mixing global and non-global\n * types is 400 \"Cannot mix global and non-global asset types\"; an\n * unknown type is 400.\n * api/visibleFieldsByAsset?oidToken=Story:1234\n * The same for one asset, its own Scope as the context; a flat list.\n * An asset of a global type (a Member) answers 500 on the instance.\n */\nimport { ApiError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Oid } from \"../types/asset\";\nimport type { AssetTypeToken } from \"../types/metamodel\";\nimport { momentless } from \"../types/oid\";\n\ninterface VisibleFieldsEntry { assetType: string; fields: string[] }\n\n/** The attributes shown for each type in the scopes given: a map from type token to sorted attribute names. */\nexport async function visibleFields(transport: Transport, types: readonly AssetTypeToken[], scopes: readonly Oid[]): Promise<Record<AssetTypeToken, string[]>> {\n if (!types.length) return {};\n // The endpoint wants repeated keys; the transport's query map cannot spell that, so the string is built here.\n const params = [...scopes.map((s) => `scopeOid=${encodeURIComponent(momentless(s))}`), ...types.map((t) => `assetTypeToken=${encodeURIComponent(t)}`)].join(\"&\");\n const answer = await transport.request<unknown>({ method: \"GET\", path: `/api/visibleFields?${params}`, responseType: \"json\" });\n if (!Array.isArray(answer)) throw new ApiError(\"api/visibleFields did not answer a list\", 200, \"BAD_RESPONSE\", answer);\n const out: Record<AssetTypeToken, string[]> = {};\n for (const entry of answer as VisibleFieldsEntry[]) if (entry && typeof entry.assetType === \"string\") out[entry.assetType] = Array.isArray(entry.fields) ? entry.fields.filter((f): f is string => typeof f === \"string\") : [];\n return out;\n}\n\n/** The attributes shown for one asset, in its own Scope. */\nexport async function visibleFieldsByAsset(transport: Transport, oid: Oid): Promise<string[]> {\n const answer = await transport.request<unknown>({ method: \"GET\", path: \"/api/visibleFieldsByAsset\", query: { oidToken: momentless(oid) }, responseType: \"json\" });\n if (!Array.isArray(answer)) throw new ApiError(\"api/visibleFieldsByAsset did not answer a list\", 200, \"BAD_RESPONSE\", answer);\n return answer.filter((f): f is string => typeof f === \"string\");\n}\n","/**\n * The fields service: what a form for an asset type in a scope needs to\n * know, from three sources the API keeps apart —\n * - meta.v1 (through the schema): which attributes are REQUIRED to\n * create one (IsRequired and writable: Name and Scope on a Story);\n * - api/visibleFields: which attributes the product SHOWS for the type\n * in that scope, custom fields included once configured;\n * - the scope's Scheme: its IMPORTANT fields (Scheme.ImportantFields, a\n * list of attribute tokens) and whether they are enforced at close\n * (Scheme.IsRequiredAtClose).\n * One call, one answer, every list spelled as bare attribute names.\n */\nimport type { Transport } from \"../core/transport\";\nimport type { Asset, Oid, Ref } from \"../types/asset\";\nimport type { AssetTypeToken } from \"../types/metamodel\";\nimport { momentless } from \"../types/oid\";\nimport * as assetApi from \"../wire/assetApi\";\nimport * as fields from \"../wire/fields\";\nimport type { Schema } from \"./schema\";\n\nexport interface FieldsOf {\n type: AssetTypeToken;\n scope: Oid;\n /** The scope's Scheme; null when the scope has none. */\n scheme: Oid | null;\n /** Attributes the server requires on a create (meta: IsRequired, writable). */\n required: string[];\n /** Attributes the product shows for the type in this scope (api/visibleFields). */\n visible: string[];\n /** The scheme's important fields that belong to this type (or an ancestor); [] when the scheme names none. */\n important: string[];\n /** Whether the scheme enforces its important fields when an asset is closed. */\n requiredAtClose: boolean;\n}\n\ntype SchemeRow = Asset & { Scheme?: (Ref & { ImportantFields?: unknown; IsRequiredAtClose?: unknown }) | null };\n\n/** The ancestors of a type, itself first, from the loaded schema. */\nasync function lineage(schema: Schema, type: AssetTypeToken): Promise<AssetTypeToken[]> {\n const out: AssetTypeToken[] = [];\n for (let t: AssetTypeToken | undefined = type; t && !out.includes(t); ) {\n out.push(t);\n const def = await schema.load(t);\n t = def?.Base;\n }\n return out;\n}\n\n/**\n * An important-field token as the scheme spells it (\"Story.Owners\", or a\n * bare \"Owners\") reduced to the attribute name when it belongs to one of\n * the types given; null otherwise.\n */\nexport function importantName(token: string, types: readonly AssetTypeToken[]): string | null {\n const dot = token.indexOf(\".\");\n if (dot < 0) return token;\n return types.includes(token.slice(0, dot)) ? token.slice(dot + 1) : null;\n}\n\n/** Required, visible and important attributes for creating or editing an asset of `type` in `scope`. */\nexport async function describe(transport: Transport, schema: Schema, type: AssetTypeToken, scope: Oid): Promise<FieldsOf> {\n const scopeOid = momentless(scope);\n const types = await lineage(schema, type);\n const definition = await schema.load(type);\n const required = definition ? Object.values(definition.Attributes).filter((a) => a.IsRequired && !a.IsReadOnly).map((a) => a.Name).sort() : [];\n const [visible, [row]] = await Promise.all([\n fields.visibleFields(transport, [type], [scopeOid]),\n assetApi.query<SchemeRow>(transport, { from: \"Scope\", select: [{ from: \"Scheme\", select: [\"ImportantFields\", \"IsRequiredAtClose\"] }], filter: [\"ID=$scope\"], with: { $scope: scopeOid }, page: { size: 1, start: 0 } }, { lookup: schema })\n ]);\n const scheme = row?.Scheme ?? null;\n const tokens = Array.isArray(scheme?.ImportantFields) ? scheme.ImportantFields.filter((t): t is string => typeof t === \"string\") : [];\n const important = [...new Set(tokens.map((t) => importantName(t, types)).filter((n): n is string => !!n))].sort();\n return {\n type,\n scope: scopeOid,\n scheme: scheme ? momentless(scheme._oid) : null,\n required,\n visible: visible[type] ?? [],\n important,\n requiredAtClose: scheme?.IsRequiredAtClose === true\n };\n}\n","/**\n * The hand-written roots the generated asset types build on. Everything\n * else under src/types/assets is generated from the metamodel.\n *\n * These are MODEL types: one shape, wherever an asset came from or is going.\n * A relation is a Ref here whether api/asset will write it as an OID string\n * or query.v1 read it back as { _oid }; the wire layer translates.\n */\n\n/** An OID token, momentless: \"Story:1234\". */\nexport type Oid = string;\n\n/** An ISO-8601 date-time as the API renders it, e.g. \"2026-09-06T13:52:51.903\". */\nexport type DateString = string;\n\n/**\n * An AssetState as the model carries it: the names of the server's AssetState\n * enum (Future 0, Active 64, Closed 128, Dead 192,\n * OldBrokenDownStory 208, Deprecated 254, Deleted 255). rest-1 renders the\n * number and query.v1 the name; the wire layer normalises to the name.\n */\nexport type AssetStateValue = \"Future\" | \"Active\" | \"Closed\" | \"Dead\" | \"Template\" | \"OldBrokenDownStory\" | \"Deprecated\" | \"Deleted\";\n\n/** The server's AssetState codes, by name — the rest-1 rendering. */\nexport const ASSET_STATE_CODES: Record<AssetStateValue, number> = { Future: 0, Active: 64, Closed: 128, Dead: 192, Template: 200, OldBrokenDownStory: 208, Deprecated: 254, Deleted: 255 };\n\nconst STATE_OF_CODE: Record<number, AssetStateValue> = Object.fromEntries(Object.entries(ASSET_STATE_CODES).map(([name, code]) => [code, name as AssetStateValue]));\n\n/**\n * An AssetState by name, whichever way the endpoint spelled it: api/asset\n * and query.v1 send the name (\"Closed\") for most states but the code for a\n * few (\"200\", a template), and rest-1 always sends the number. An unknown\n * code is left as sent.\n */\nexport function assetStateOf(value: unknown): AssetStateValue | string | null {\n if (value == null) return null;\n const code = typeof value === \"number\" ? value : typeof value === \"string\" && /^\\d+$/.test(value) ? Number(value) : NaN;\n return Number.isNaN(code) ? String(value) : STATE_OF_CODE[code] ?? String(value);\n}\n\n/**\n * A reference to another asset: always at least its OID, plus whatever a\n * select pulled through (Owners.Name lands on the Ref as Name).\n */\nexport type Ref<T extends Asset = Asset> = { _oid: Oid } & Partial<Omit<T, \"_oid\">>;\n\n/** The value types an attribute can carry in the model. */\nexport type AttributeValue = string | number | boolean | null | Ref | Ref[];\n\n/**\n * Custom attributes are not generated: they differ per instance. One is\n * named with the Custom_ prefix; the reciprocal side of a custom relation,\n * which the server adds on the related type, with ReciprocalOf_ (live\n * 2026-11-12: `Custom_Demo_List.ReciprocalOf_Story_Custom_Demo_Single_List`).\n * The root carries both.\n */\nexport interface CustomAttributes {\n [custom: `Custom_${string}`]: AttributeValue | undefined;\n [reciprocal: `ReciprocalOf_${string}`]: AttributeValue | undefined;\n}\n\n/** The root every generated asset type extends. */\nexport interface Asset extends CustomAttributes {\n _oid: Oid;\n}\n","/**\n * The resolve service: what a person types (an asset number, an OID token)\n * turned into the asset it names. Ported from the CLI consumer's resolve module,\n * minus the prompting, which stays in the\n * CLI.\n *\n * Which type a number's prefix belongs to is the instance's business (the\n * prefixes are configurable), so there is no client-side prefix map: every\n * type whose Number attribute is its own definition is a \"number root\", and\n * one api/asset request asks each root for all the numbers at once. Workitem\n * is one root and covers every workitem type, custom ones included; the rest\n * come from the metamodel (test/unit/resolve.test.ts recomputes the list\n * from metamodel.json, so it cannot drift).\n *\n * Numbers travel as a `with` list, never spliced into the filter text: a\n * value is then data, not grammar (an em dash in a filter literal fails to\n * parse; the same value as a variable does not — live, 2026-11-04). Number\n * matching on the server is case-insensitive.\n */\nimport { UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport { assetStateOf, type Asset, type AssetStateValue, type Oid } from \"../types/asset\";\nimport type { TypeCache } from \"./schema\";\nimport type { AssetTypeToken } from \"../types/metamodel\";\nimport { isOidToken, momentless, typeOfOid } from \"../types/oid\";\nimport * as assetApi from \"../wire/assetApi\";\n\n/**\n * Types whose Number attribute is their own definition (no Base), from the\n * canned metamodel, each with what it can be asked for: Number always, Name\n * and AssetState where the type has them (ExternalActionInvocation has\n * neither, Grant no Name — an unknown select token fails the query).\n */\nexport const NUMBER_ROOTS: Readonly<Record<AssetTypeToken, readonly string[]>> = {\n Environment: [\"Number\", \"Name\", \"AssetState\"],\n ExternalActionInvocation: [\"Number\"],\n Goal: [\"Number\", \"Name\", \"AssetState\"],\n Grant: [\"Number\", \"AssetState\"],\n Issue: [\"Number\", \"Name\", \"AssetState\"],\n Milestone: [\"Number\", \"Name\", \"AssetState\"],\n Okr: [\"Number\", \"Name\", \"AssetState\"],\n OkrSession: [\"Number\", \"Name\", \"AssetState\"],\n RegressionPlan: [\"Number\", \"Name\", \"AssetState\"],\n RegressionSuite: [\"Number\", \"Name\", \"AssetState\"],\n RegressionTest: [\"Number\", \"Name\", \"AssetState\"],\n Request: [\"Number\", \"Name\", \"AssetState\"],\n Roadmap: [\"Number\", \"Name\", \"AssetState\"],\n StrategicTheme: [\"Number\", \"Name\", \"AssetState\"],\n Topic: [\"Number\", \"Name\", \"AssetState\"],\n Workitem: [\"Number\", \"Name\", \"AssetState\"]\n};\n\n/**\n * An asset number as a person types one: a prefix and digits (S-1234,\n * TK-12). Prefixes are instance configuration, so any length is accepted;\n * a false positive (\"UTF-8\") costs nothing but a `missing`. Scanning prose\n * for numbers (commit messages) wants a stricter pattern, and is the\n * caller's.\n */\nexport const isAssetNumber = (text: string): boolean => /^[A-Za-z]+-\\d+$/.test(text.trim());\n\n/** How many numbers one request asks about: bounded, never one giant filter. */\nexport const CHUNK = 100;\n\nexport interface ResolvedAsset {\n /** The number as the server spells it; null for a ref given as an OID token. */\n number: string | null;\n oid: Oid;\n type: AssetTypeToken;\n name: string | null;\n assetState: AssetStateValue | null;\n}\n\nexport interface Resolution {\n /** In the order the numbers were asked for, one per distinct number found. */\n found: ResolvedAsset[];\n /** Numbers no root knows, as they were asked for. */\n missing: string[];\n}\n\n// Roots an instance turned out not to have, asked once, then left out. With a\n// TypeCache (the client passes its schema's) that is the cache's own record of\n// types the instance lacks (null), so clients that share a cache share it;\n// without one, it is remembered per transport.\nconst absentRoots = new WeakMap<Transport, Set<string>>();\n\ninterface Absent { has(root: string): boolean; add(root: string): void }\nconst absentFor = (transport: Transport, types?: TypeCache): Absent => {\n if (types) return { has: (root) => types.types.get(root) === null, add: (root) => { types.types.set(root, null); } };\n const set = absentRoots.get(transport) ?? new Set<string>();\n absentRoots.set(transport, set);\n return set;\n};\nconst UNKNOWN_TYPE = /^Unknown AssetType: (\\S+)/;\n\ntype Row = Asset & { Name?: string | null; Number?: string; AssetState?: unknown };\n\nasync function askRoots(transport: Transport, numbers: string[], types?: TypeCache): Promise<Row[]> {\n const absent = absentFor(transport, types);\n for (let attempt = 0; ; attempt += 1) {\n const roots = Object.keys(NUMBER_ROOTS).filter((r) => !absent.has(r));\n try {\n const results = await assetApi.queries<Row>(transport, roots.map((from) => ({\n from,\n select: [...NUMBER_ROOTS[from]!],\n filter: [\"Number=$numbers\"],\n with: { $numbers: numbers },\n page: { size: numbers.length, start: 0 }\n })));\n return results.flat();\n } catch (error) {\n // An instance without one of the roots answers \"Unknown AssetType\" for\n // that query alone. Remember it and ask again without it — once; any\n // other failure is the caller's to see.\n const unknown = error instanceof assetApi.CommandFailureError ? error.failures.map((f) => UNKNOWN_TYPE.exec(f.message)?.[1]) : [];\n if (attempt > 0 || !unknown.length || unknown.some((t) => !t || !roots.includes(t))) throw error;\n for (const t of unknown) absent.add(t!);\n }\n }\n}\n\n/** Resolve asset numbers in one request per hundred numbers. Not found is not an error: it is `missing`. */\nexport async function resolveNumbers(transport: Transport, numbers: readonly string[], options: { types?: TypeCache } = {}): Promise<Resolution> {\n const firsts = new Map<string, string>();\n for (const n of numbers) if (!firsts.has(n.trim().toUpperCase())) firsts.set(n.trim().toUpperCase(), n.trim());\n const asked = [...firsts.values()];\n const invalid = asked.filter((n) => !isAssetNumber(n));\n if (invalid.length) throw new UsageError(`not asset numbers (expected a prefix and digits, S-1234): ${invalid.join(\", \")}`);\n const byNumber = new Map<string, ResolvedAsset>();\n for (let i = 0; i < asked.length; i += CHUNK) {\n for (const r of await askRoots(transport, asked.slice(i, i + CHUNK), options.types)) {\n if (!r.Number || byNumber.has(r.Number.toUpperCase())) continue;\n const oid = momentless(r._oid);\n byNumber.set(r.Number.toUpperCase(), { number: r.Number, oid, type: typeOfOid(oid), name: r.Name ?? null, assetState: assetStateOf(r.AssetState) as AssetStateValue | null });\n }\n }\n return {\n found: asked.flatMap((n) => byNumber.get(n.toUpperCase()) ?? []),\n missing: asked.filter((n) => !byNumber.has(n.toUpperCase()))\n };\n}\n\n/**\n * One asset by whichever shape the person has: an OID token (Story:1234 —\n * used as is, no request, so `number` and `name` are null) or a number\n * (resolved; null when no root knows it). Anything else is a TypeError.\n */\nexport async function resolveRef(transport: Transport, spec: string, options: { types?: TypeCache } = {}): Promise<ResolvedAsset | null> {\n const text = spec.trim();\n if (isOidToken(text)) { const oid = momentless(text); return { number: null, oid, type: typeOfOid(oid), name: null, assetState: null }; }\n if (isAssetNumber(text)) return (await resolveNumbers(transport, [text], options)).found[0] ?? null;\n throw new UsageError(`\"${spec}\" is neither an asset number (S-1234) nor an OID token (Story:1234)`);\n}\n","/**\n * The meta.v1 wire module: what the endpoint delivers, and the translation\n * into the metamodel types (src/types/metamodel.ts).\n *\n * meta.v1 describes the instance's schema. Three reads:\n * GET /meta.v1 the whole metamodel (large: ~7 MB, 165 types)\n * GET /meta.v1/<Type> one asset type with its attributes\n * GET /meta.v1/<Type>/<Attribute> one attribute definition\n *\n * Every meta.v1 answer carries one strong ETag for the whole schema\n * (\"26.3.1.13.636764259167912911\": the release and a change stamp), the\n * same on the document, a type and an attribute, and If-None-Match with\n * that exact tag answers 304 with no body (live 2026-11-14; a weak form\n * is not matched). So \"has the schema changed?\" is one conditional read\n * of the smallest resource, and a cached metamodel needs re-parsing only\n * when the tag moves. Cache-Control is public with a max-age under an\n * hour.\n *\n * The delivered document is its own vocabulary — Token, DisplayName,\n * IsMultivalue, RelatedAsset, Base — and NOT the attribute set of the\n * metamodel's own AttributeDefinition asset type (NativeValue, IsBasic, …).\n * The hand-written types model the delivered document. References inside\n * it arrive as { href, tokenref } or { href, nameref }; the model keeps the\n * token. An attribute the type defines itself has no Base; an inherited one\n * names the defining ancestor's attribute.\n */\nimport { UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { AssetType, AssetTypeToken, AttributeDefinition, AttributeTokenRef, AttributeType, Metamodel } from \"../types/metamodel\";\n\n// ---- what the endpoint delivers ------------------------------------------------\n\nexport interface TokenRef { href: string; tokenref: AttributeTokenRef }\nexport interface NameRef { href: string; nameref: AssetTypeToken }\n\nexport interface AttributeDefinitionDocument {\n HREF?: string;\n _type: \"AttributeDefinition\";\n Name: string;\n Token: AttributeTokenRef;\n DisplayName: string;\n AttributeType: AttributeType;\n IsReadOnly: boolean;\n IsRequired: boolean;\n IsMultivalue: boolean;\n IsCanned: boolean;\n IsCustom: boolean;\n /** Present on an inherited attribute: the defining ancestor's attribute. */\n Base?: TokenRef;\n ReciprocalRelation?: TokenRef;\n OrderByAttribute?: TokenRef;\n DisplayByAttribute?: TokenRef;\n /** Present on a Relation. */\n RelatedAsset?: NameRef;\n}\n\nexport interface AssetTypeDocument {\n HREF?: string;\n Version?: string;\n _type: \"AssetType\";\n Token: AssetTypeToken;\n /** The delivered Name is a reference to the type's Name attribute; the token is the name. */\n Name: TokenRef | string;\n DisplayName: string;\n Abstract: boolean;\n /** Absent on a root type. */\n Base?: NameRef;\n DefaultOrderBy?: TokenRef;\n DefaultDisplayBy?: TokenRef;\n ShortName?: TokenRef;\n Description?: TokenRef;\n Attributes: Record<string, AttributeDefinitionDocument>;\n Operations?: Record<string, unknown>;\n Rules?: Record<string, unknown>;\n}\n\nexport interface MetamodelDocument {\n HREF?: string;\n Version: string;\n AssetTypes: Record<string, AssetTypeDocument>;\n}\n\n// ---- translation ----------------------------------------------------------------\n\nexport function toAttributeDefinition(doc: AttributeDefinitionDocument): AttributeDefinition {\n return {\n _type: \"AttributeDefinition\",\n Name: doc.Name,\n Token: doc.Token,\n DisplayName: doc.DisplayName,\n AttributeType: doc.AttributeType,\n IsReadOnly: doc.IsReadOnly,\n IsRequired: doc.IsRequired,\n IsMultivalue: doc.IsMultivalue,\n IsCanned: doc.IsCanned,\n IsCustom: doc.IsCustom,\n ...(doc.Base ? { Base: doc.Base.tokenref } : {}),\n ...(doc.ReciprocalRelation ? { ReciprocalRelation: doc.ReciprocalRelation.tokenref } : {}),\n ...(doc.OrderByAttribute ? { OrderByAttribute: doc.OrderByAttribute.tokenref } : {}),\n ...(doc.DisplayByAttribute ? { DisplayByAttribute: doc.DisplayByAttribute.tokenref } : {}),\n ...(doc.RelatedAsset ? { RelatedAsset: doc.RelatedAsset.nameref } : {})\n };\n}\n\nexport function toAssetType(doc: AssetTypeDocument): AssetType {\n return {\n _type: \"AssetType\",\n Name: doc.Token,\n Token: doc.Token,\n DisplayName: doc.DisplayName,\n Abstract: doc.Abstract,\n ...(doc.Base ? { Base: doc.Base.nameref } : {}),\n ...(doc.DefaultOrderBy ? { DefaultOrderBy: doc.DefaultOrderBy.tokenref } : {}),\n ...(doc.DefaultDisplayBy ? { DefaultDisplayBy: doc.DefaultDisplayBy.tokenref } : {}),\n ...(doc.ShortName ? { ShortName: doc.ShortName.tokenref } : {}),\n Attributes: Object.fromEntries(Object.entries(doc.Attributes ?? {}).map(([key, value]) => [key, toAttributeDefinition(value)])),\n ...(doc.Operations ? { Operations: Object.keys(doc.Operations).map((token) => token.slice(token.indexOf(\".\") + 1)) } : {})\n };\n}\n\nexport function toMetamodel(doc: MetamodelDocument): Metamodel {\n return { Version: doc.Version, AssetTypes: Object.fromEntries(Object.entries(doc.AssetTypes).map(([key, value]) => [key, toAssetType(value)])) };\n}\n\n/** Is this a metamodel document as meta.v1 delivers it? (A downloaded metamodel.json, say.) */\nexport function isMetamodelDocument(value: unknown): value is MetamodelDocument {\n return !!value && typeof value === \"object\" && typeof (value as MetamodelDocument).Version === \"string\" && !!(value as MetamodelDocument).AssetTypes && typeof (value as MetamodelDocument).AssetTypes === \"object\";\n}\n\n// ---- the calls ------------------------------------------------------------------\n\n/** A conditional read: the tag a previous answer carried. With it, an unchanged resource is null. */\nexport interface ConditionalOptions { ifNoneMatch?: string | null }\n\n/** What a read answered, with the schema's tag as the server sent it (null when it sent none). */\nexport interface Tagged<T> { value: T; etag: string | null }\n\n/** The smallest meta.v1 resource: what the schema's tag is read from. */\nconst PROBE_PATH = \"/meta.v1/BaseAsset/Name\";\n\nasync function conditional<Doc>(transport: Transport, path: string, options: ConditionalOptions): Promise<Tagged<Doc> | null> {\n let etag: string | null = null, status = 200;\n const onResponse = (r: { status: number; headers: { get(name: string): string | null } }) => { status = r.status; etag = r.headers.get(\"etag\"); };\n const headers = options.ifNoneMatch ? { \"if-none-match\": options.ifNoneMatch } : undefined;\n const doc = await transport.request<Doc | undefined>({ method: \"GET\", path, headers, responseType: \"json\", onResponse, acceptNotModified: !!options.ifNoneMatch });\n if (status === 304 || doc === undefined) return null;\n return { value: doc, etag };\n}\n\nexport async function getMetamodel(transport: Transport): Promise<Metamodel> {\n return toMetamodel(await transport.request<MetamodelDocument>({ method: \"GET\", path: \"/meta.v1\", responseType: \"json\" }));\n}\n\n/** The metamodel with its tag; null when `ifNoneMatch` still matches (nothing was downloaded). */\nexport async function readMetamodel(transport: Transport, options: ConditionalOptions = {}): Promise<Tagged<Metamodel> | null> {\n const read = await conditional<MetamodelDocument>(transport, \"/meta.v1\", options);\n return read && { value: toMetamodel(read.value), etag: read.etag };\n}\n\nexport async function getAssetType(transport: Transport, token: AssetTypeToken): Promise<AssetType> {\n return toAssetType(await transport.request<AssetTypeDocument>({ method: \"GET\", path: `/meta.v1/${encodeURIComponent(token)}`, responseType: \"json\" }));\n}\n\n/** One type with the schema's tag; null when `ifNoneMatch` still matches. */\nexport async function readAssetType(transport: Transport, token: AssetTypeToken, options: ConditionalOptions = {}): Promise<Tagged<AssetType> | null> {\n const read = await conditional<AssetTypeDocument>(transport, `/meta.v1/${encodeURIComponent(token)}`, options);\n return read && { value: toAssetType(read.value), etag: read.etag };\n}\n\n/**\n * The schema's current tag, from one small read, or null when the server\n * sends none. With `ifNoneMatch`, \"unchanged\" is answered as that same tag\n * without a body — the cheapest way to ask whether anything in meta moved.\n */\nexport async function etag(transport: Transport, options: ConditionalOptions = {}): Promise<string | null> {\n const read = await conditional<unknown>(transport, PROBE_PATH, options);\n return read ? read.etag : options.ifNoneMatch ?? null;\n}\n\nexport async function getAttributeDefinition(transport: Transport, tokenref: AttributeTokenRef): Promise<AttributeDefinition> {\n const [type, attribute] = tokenref.split(\".\");\n if (!type || !attribute) throw new UsageError(`\"${tokenref}\" is not an attribute token (\"Story.Name\")`);\n return toAttributeDefinition(await transport.request<AttributeDefinitionDocument>({ method: \"GET\", path: `/meta.v1/${encodeURIComponent(type)}/${encodeURIComponent(attribute)}`, responseType: \"json\" }));\n}\n","/**\n * The schema service: the instance's asset types, loaded from meta.v1 one\n * type at a time as queries need them, and handed to the wire layer as the\n * AttributeLookup it translates rows with.\n *\n * Why lazy: the whole metamodel is ~7 MB and 165 types, and a consumer\n * touches a dozen. Why a service and not the wire module: loading is\n * asynchronous and cross-cutting (one cache per client, in-flight requests\n * deduplicated — the pattern a browser app consumer's metamodel store proves),\n * while translation is synchronous and per row. A schema can also be seeded\n * from a metamodel document (a committed metamodel.json, or one read with\n * meta.getMetamodel) and then needs no transport at all.\n */\nimport { ApiError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { AssetType, AssetTypeToken, AttributeDefinition, AttributeLookup, Metamodel } from \"../types/metamodel\";\nimport * as meta from \"../wire/meta\";\nimport { attributeOf, fromTypeOf, typesNeeded, type SelectShape } from \"../wire/select\";\n\n/**\n * The type definitions loaded from one instance, shareable by any number of\n * schemas. A definition does not depend on who read it, so a server that\n * builds a client per user (each with that user's token) can give them all\n * one cache per instance: each type is fetched once, through whichever\n * client needed it first, and concurrent loads of a type share one request.\n */\nexport class TypeCache {\n /** Loaded types; null records that the instance has no such type, so it is not asked for again. */\n readonly types = new Map<AssetTypeToken, AssetType | null>();\n readonly loading = new Map<AssetTypeToken, Promise<AssetType | null>>();\n /** The schema's tag the loaded types came with (meta.v1's ETag, one for the whole schema); null until a load, or for a seeded cache. */\n etag: string | null = null;\n\n /** Forget every loaded type (and the tag): the next query loads afresh. In-flight loads finish into the cache as before. */\n clear(): void {\n this.types.clear();\n this.etag = null;\n }\n\n /** A cache seeded from a metamodel document. */\n static fromMetamodel(metamodel: Metamodel): TypeCache {\n const cache = new TypeCache();\n for (const [token, type] of Object.entries(metamodel.AssetTypes)) cache.types.set(token, type);\n return cache;\n }\n}\n\nexport class Schema implements AttributeLookup {\n private readonly types: Map<AssetTypeToken, AssetType | null>;\n private readonly loading: Map<AssetTypeToken, Promise<AssetType | null>>;\n /** Where this schema keeps what it loads; pass it to another schema to share it. */\n readonly cache: TypeCache;\n\n constructor(private readonly transport?: Transport, seed?: Metamodel, cache: TypeCache = new TypeCache()) {\n this.cache = cache;\n this.types = cache.types;\n this.loading = cache.loading;\n if (seed) for (const [token, type] of Object.entries(seed.AssetTypes)) if (!this.types.has(token)) this.types.set(token, type);\n }\n\n /** The same cache, loading anything missing through another transport (another user's credentials). */\n withTransport(transport: Transport): Schema {\n return new Schema(transport, undefined, this.cache);\n }\n\n /** A complete schema from a metamodel document; nothing is ever fetched. */\n static fromMetamodel(metamodel: Metamodel): Schema {\n return new Schema(undefined, metamodel);\n }\n\n /** The type, null when the instance has none, undefined when not loaded yet. */\n assetType(token: AssetTypeToken): AssetType | null | undefined {\n return this.types.has(token) ? this.types.get(token)! : undefined;\n }\n\n /** An attribute by bare name; undefined when the type is not loaded, null when it has no such attribute. */\n attribute(type: AssetTypeToken, name: string): AttributeDefinition | null | undefined {\n return attributeOf(this, type, name);\n }\n\n /**\n * Can the type do this operation (Delete, Reactivate, …)? Undefined when\n * the type is not loaded or its definition carries no operations, so a\n * caller can tell \"no\" from \"don't know\".\n */\n canOperate(type: AssetTypeToken, op: string): boolean | undefined {\n const t = this.assetType(type);\n return t?.Operations ? t.Operations.includes(op) : undefined;\n }\n\n /** The tokens loaded so far. */\n get loaded(): AssetTypeToken[] {\n return [...this.types.entries()].filter(([, t]) => t !== null).map(([token]) => token);\n }\n\n /**\n * Load one type from meta.v1 (once; concurrent callers share the request).\n * A type the instance does not have resolves to null and is remembered;\n * any other failure (auth, network) is thrown, not swallowed.\n */\n async load(token: AssetTypeToken): Promise<AssetType | null> {\n if (this.types.has(token)) return this.types.get(token)!;\n const inFlight = this.loading.get(token);\n if (inFlight) return inFlight;\n if (!this.transport) { this.types.set(token, null); return null; }\n const request = meta.readAssetType(this.transport, token)\n .then((read) => { if (read?.etag) this.cache.etag = read.etag; return read ? read.value : null; })\n .catch((error: unknown) => { if (error instanceof ApiError && error.status === 404) return null; throw error; })\n .then((type) => { this.types.set(token, type); return type; })\n .finally(() => this.loading.delete(token));\n this.loading.set(token, request);\n return request;\n }\n\n /**\n * Has the instance's schema changed since these types were loaded? One\n * small conditional read of meta.v1. Unchanged: nothing happens.\n * Changed (or never tagged, or the transport cannot see headers): the\n * loaded types are dropped, so the next query loads them again, and the\n * new tag is kept. Answers whether it changed and the current tag. A\n * schema without a transport (seeded) never changes.\n */\n async revalidate(): Promise<{ changed: boolean; etag: string | null }> {\n if (!this.transport) return { changed: false, etag: this.cache.etag };\n const was = this.cache.etag;\n const now = await meta.etag(this.transport, { ifNoneMatch: was });\n if (was && now === was) return { changed: false, etag: was };\n this.cache.clear();\n this.cache.etag = now;\n return { changed: true, etag: now };\n }\n\n /**\n * Load whatever the queries in a batch need to have their rows translated:\n * the `from` types, then the types behind every relation hop and sub-select,\n * until nothing more is needed. Non-query commands are ignored.\n */\n async ensureFor(commands: readonly unknown[]): Promise<void> {\n for (const command of commands) {\n const query = queryOf(command);\n if (!query) continue;\n const type = fromTypeOf(query.from, commands);\n if (!type) continue;\n for (let round = 0; round < 32; round += 1) {\n const needed = [...typesNeeded(this, query, type)].filter((t) => !this.types.has(t));\n if (!needed.length) break;\n await Promise.all(needed.map((t) => this.load(t)));\n }\n }\n }\n}\n\n/** The query body of a command (bare or aliased), or null when it is not a query. */\nexport function queryOf(command: unknown): SelectShape | null {\n if (!command || typeof command !== \"object\") return null;\n const keys = Object.keys(command);\n const body = (keys.length === 1 && keys[0]!.startsWith(\"@\") ? (command as Record<string, unknown>)[keys[0]!] : command) as Record<string, unknown>;\n if (!body || typeof body !== \"object\" || typeof body.from !== \"string\") return null;\n if (\"update\" in body || \"execute\" in body || \"AssetType\" in body) return null;\n return body as unknown as SelectShape;\n}\n","/**\n * The loc-2.v1 wire module: localized labels for Agility's tags.\n *\n * Verified shapes (https://docs.digital.ai/agility-api/apis/loc-2-v1, and a\n * live instance 2026-11-04):\n * - The whole raw query string is the payload, parsed as LSON (lenient\n * JSON) — no name=value. An array in gives an object out, keyed by the\n * tags exactly as sent, duplicates collapsed; a scalar in gives a bare\n * string. This module only ever sends the array form.\n * - Tags hold tics (AttributeDefinition'Name'Story) and may hold spaces,\n * commas or `]`, which split a bare LSON token; a tag starting with a\n * tic reads as a quote. Every tag is therefore sent double-quoted —\n * JSON.stringify of the list is valid LSON, escapes and non-ASCII\n * included (round-tripped live).\n * - GET for a list that fits a URL; POST of the same payload, URL-encoded\n * as the body, for a long one. Identical results.\n * - Accept-Language picks the culture (only its first entry is read; a\n * neutral culture expands to its default specific one; absent or\n * unparseable means the invariant culture).\n * - No authentication: an Authorization header is ignored.\n * - A tag that matches nothing resolves to itself. There is no \"missing\"\n * and no error for it, so a typo is indistinguishable from an\n * untranslated tag; this module does not pretend otherwise.\n * - Errors are text/plain, not JSON (a 500 \"Server Error\" for an element\n * that is not a string, which the string[] signature rules out).\n */\nimport { ApiError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\n\n/** A tag-to-label map, keyed by each tag exactly as sent. */\nexport type Localizations = Record<string, string>;\n\nexport interface LocalizeOptions {\n /** Accept-Language for the request: \"fr-CA\", \"de\". Omitted: the server's invariant culture. */\n culture?: string;\n /**\n * The longest encoded payload sent as a GET; longer lists are POSTed.\n * Conservative by default: IIS rejects a query string past 2048\n * characters unless an instance raises the limit.\n */\n maxGetLength?: number;\n}\n\nexport const DEFAULT_MAX_GET_LENGTH = 2000;\n\n/** The payload as loc-2.v1 parses it: a JSON array of the tags, which is valid LSON. */\nexport const toLson = (tags: readonly string[]): string => JSON.stringify(tags);\n\n/**\n * Labels for a list of tags, in one request: a map keyed by each tag as\n * sent. An empty list asks nothing of the server and answers {}.\n */\nexport async function localize(transport: Transport, tags: readonly string[], options: LocalizeOptions = {}): Promise<Localizations> {\n const unique = [...new Set(tags)];\n if (!unique.length) return {};\n const encoded = encodeURIComponent(toLson(unique));\n const headers = options.culture ? { \"Accept-Language\": options.culture } : undefined;\n const result = encoded.length <= (options.maxGetLength ?? DEFAULT_MAX_GET_LENGTH)\n ? await transport.request<unknown>({ method: \"GET\", path: `/loc-2.v1?${encoded}`, headers, responseType: \"json\" })\n // A POST here is a read: safe to send again after a network failure or a 5xx.\n : await transport.request<unknown>({ method: \"POST\", path: \"/loc-2.v1\", headers, body: encoded, contentType: \"application/x-www-form-urlencoded\", responseType: \"json\", idempotent: true });\n if (!result || typeof result !== \"object\" || Array.isArray(result)) throw new ApiError(`loc-2.v1 answered an array of tags with ${JSON.stringify(result)?.slice(0, 100)}, not an object`, 200, \"BAD_RESPONSE\", result);\n return result as Localizations;\n}\n\n/** One tag's label. Sent in the array form like every other call, so parsing stays uniform. */\nexport async function localizeOne(transport: Transport, tag: string, options: LocalizeOptions = {}): Promise<string> {\n const map = await localize(transport, [tag], options);\n return map[tag] ?? tag;\n}\n","/**\n * The query.v1 wire module: reads only. The endpoint takes the same query\n * bodies as api/asset's query commands and answers with nothing but the\n * rows — an array with one array of rows per query, in request order — so\n * it is the simplest place to explore what a query does. api/asset can do\n * everything query.v1 does (and write); query.v1 can never write.\n *\n * Verified against the API-testing instance (2026-11-06):\n * - POST a query body, or an array of them (or YAML documents separated by\n * ---); the answer is [[row, …], …], [] for a query that matched nothing.\n * - rows are spelled exactly as api/asset spells them: every scalar a\n * string (\"2\", \"True\"), a relation { _oid }, a multi-value relation a\n * list, a sub-selected single relation a list. So they translate through\n * the same schema the same way.\n * - one bad query fails the whole request: 400 with rest-1's error shape,\n * { error: \"Bad Request\", exceptions: [{ type, message }, …] }, and no\n * rows at all. The useful text is in exceptions, not error.\n * - a filter literal with an em dash fails here too; a `with` variable\n * carrying the same value works.\n *\n * Because the endpoint cannot change anything, a request is sent idempotent:\n * the transport may retry it after a network failure or a 5xx like a GET.\n */\nimport { ApiError, UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport type { Asset } from \"../types/asset\";\nimport { fromWireRow, type QueryBody, type ReadOptions, type RowContext } from \"./assetApi\";\nimport { fromTypeOf } from \"./select\";\n\n/** What query.v1 said about each refused query: its exception type and message. */\nexport interface QueryRejection { type: string | null; message: string }\n\n/**\n * The error query.v1 sends for a query it refused: the exceptions'\n * messages joined as the message, and `details` the exceptions alone\n * ({ type, message }[]) — not the whole error document, so a caller that\n * prints details prints what matters.\n */\nfunction rejected(error: ApiError): ApiError {\n const details = error.details as { exceptions?: { type?: unknown; message?: unknown }[] } | undefined;\n const rejections: QueryRejection[] = (details?.exceptions ?? []).filter((e) => e && typeof e.message === \"string\" && e.message).map((e) => ({ type: typeof e.type === \"string\" ? e.type : null, message: e.message as string }));\n return rejections.length ? new ApiError(rejections.map((r) => r.message).join(\"; \"), error.status, \"QUERY_REJECTED\", rejections) : error;\n}\n\n/**\n * Several queries in one request; one array of rows per query, in order, []\n * where a query matched nothing. A page is required on every query. A\n * query the server refuses throws (an ApiError coded QUERY_REJECTED, with\n * the server's messages) — never an empty result.\n */\nexport async function queries<Row extends Asset = Asset>(transport: Transport, qs: QueryBody[], options: ReadOptions = {}): Promise<Row[][]> {\n for (const q of qs) if (!q.page) throw new UsageError(`query of ${q.from} without a page: every query.v1 read must be bounded`);\n if (!qs.length) return [];\n let response: unknown;\n try {\n response = await transport.request<unknown>({ method: \"POST\", path: \"/query.v1\", body: qs, responseType: \"json\", idempotent: true });\n } catch (error) {\n throw error instanceof ApiError && error.status === 400 ? rejected(error) : error;\n }\n if (!Array.isArray(response) || response.length !== qs.length || !response.every(Array.isArray)) {\n throw new ApiError(`query.v1 answered with ${Array.isArray(response) ? `${response.length} results` : \"no result list\"} for ${qs.length} queries`, 200, \"BAD_RESPONSE\", response);\n }\n return qs.map((q, i) => {\n const type = options.lookup ? fromTypeOf(q.from, qs) : null;\n const context: RowContext | undefined = type ? { lookup: options.lookup!, type } : undefined;\n return (response as Record<string, unknown>[][])[i]!.map((row) => fromWireRow<Row>(row, context));\n });\n}\n\n/** One query, its rows. */\nexport async function query<Row extends Asset = Asset>(transport: Transport, q: QueryBody, options: ReadOptions = {}): Promise<Row[]> {\n const [rows] = await queries<Row>(transport, [q], options);\n return rows ?? [];\n}\n","/**\n * The rest-1.v1 wire module: what the endpoint takes and returns, and the\n * translation into the model. rest-1 is the endpoint with the most\n * translation, which is exactly why none of it may leak past this file.\n *\n * Reads (all GET, JSON asked for by Accept):\n * /rest-1.v1/Data/<Type> a list; where, sel, find, findin, sort, page (size,start), deleted, needTotal, with, asof\n * (taken as a query's `filter`/`select`; `where`/`sel` are rest-1's spellings, translated here)\n * /rest-1.v1/Data/<Type>/<id> one asset\n * /rest-1.v1/Hist/<Type>[/<id>] history: the same shape, one row per moment, ids carrying the moment\n * /rest-1.v1/New/<Type>?ctx=<oid> a template: the asset the type's initializer would create in that\n * context (the server runs the type's initializer with ctx as the\n * context OID — a Timebox gets the next sprint name, dates after the\n * schedule's last timebox, the schedule, a state and the owner; live\n * 2026-11-14). Same document shape, id \"\", every attribute with act \"set\".\n *\n * Two writes, kept narrow: rest-1 carries nothing api/asset does, except\n * POST /rest-1.v1/Data/<Type>/<id>?op=<Operation> the operation's RESULT, which api/asset drops:\n * Copy answers the new asset's id (Story:146979:194422), any other\n * operation the source at its new moment; an unknown operation is 400\n * \"Unknown Operation 'Story.NoSuchOp'\" (live 2026-11-14).\n *\n * What it returns, verified against a dev instance (2026-09-07):\n * { _type: \"Assets\"|\"History\", total?, pageSize, pageStart, Assets: [\n * { _type: \"Asset\", href, id: \"Story:2104\"|\"Story:2104:2797\", Attributes: {\n * Name: { _type: \"Attribute\", name, value }, scalar; multi-value as an array\n * Owners: { _type: \"Relation\", name, value: [{ _type: \"Asset\", href, idref }] } multi-value relation\n * Super: { _type: \"Relation\", name, value: { _type: \"Asset\", href, idref } | null } single relation\n * } } ] }\n * - `total` only with needTotal=true (else absent; -1 in some renderings).\n * - AssetState is the NUMBER (the server's AssetState enum); the model wants the name.\n * - a type-qualified sel (Story.Number on BaseAsset) arrives keyed by its plain name (Number).\n * - selecting a relation also brings its display columns (Owners.Name,\n * Owners.Nickname, Status.Name) uninvited; they are folded onto the Refs.\n * - a page is required by this module: no Data read is unbounded.\n */\nimport { ApiError, UsageError } from \"../core/errors\";\nimport type { Transport } from \"../core/transport\";\nimport { assetStateOf, type Asset, type Oid, type Ref } from \"../types/asset\";\nimport { momentless } from \"../types/oid\";\n\nexport { momentless };\n\n// ---- what the endpoint returns -------------------------------------------\n\nexport interface AssetRefDocument { _type: \"Asset\"; href: string; idref: Oid }\nexport interface AttributeDocument { _type: \"Attribute\"; name: string; value: unknown }\nexport interface RelationDocument { _type: \"Relation\"; name: string; value: AssetRefDocument | AssetRefDocument[] | null }\nexport interface AssetDocument { _type: \"Asset\"; href: string; id: string; Attributes?: Record<string, AttributeDocument | RelationDocument> }\nexport interface AssetsDocument { _type: \"Assets\" | \"History\"; total?: number; pageSize: number; pageStart: number; Assets: AssetDocument[] }\n\n// ---- what the endpoint takes ---------------------------------------------\n\nexport interface ReadParams {\n /** Attributes to select, as a query's `select`; a type-qualified name (Story.Number) reaches a subtype's attribute from a base type. */\n select?: string[];\n /** @deprecated rest-1's own spelling of `select`; kept for one alpha. */\n sel?: string[];\n /** Filter terms, as a query's `filter`, joined with ';' (AND). */\n filter?: string[];\n /** @deprecated rest-1's own spelling of `filter`; kept for one alpha. */\n where?: string[];\n /** The filter context: { $oids: [...] } — sent in rest-1's spelling, $name=a,b|$other=c. */\n with?: Record<string, string | string[]>;\n find?: string;\n findin?: string[];\n sort?: string[];\n /** Required. size first, then start. */\n page: { size: number; start: number };\n deleted?: boolean;\n needTotal?: boolean;\n asof?: string;\n}\n\n// ---- translation -----------------------------------------------------------\n\n\nconst toRef = (doc: AssetRefDocument): Ref => ({ _oid: momentless(doc.idref) });\n\n/**\n * One rest-1 asset as the model carries it. Relations become Refs; the\n * display columns rest-1 adds beside a selected relation (Owners.Name) are\n * folded onto those Refs by position, and kept under their dotted key too\n * for a caller that asked for them by name; AssetState becomes its name;\n * everything else is the value as sent. The row's own _oid keeps its\n * moment only on a history read (it is the moment that identifies the row).\n */\nexport function fromAssetDocument<Row extends Asset = Asset>(doc: AssetDocument, { history = false } = {}): Row {\n const out: Record<string, unknown> = { _oid: history ? doc.id : momentless(doc.id) };\n const attrs = doc.Attributes ?? {};\n for (const [key, a] of Object.entries(attrs)) {\n if (a._type === \"Relation\") {\n out[key] = Array.isArray(a.value) ? a.value.map(toRef) : a.value ? toRef(a.value) : null;\n } else if (key === \"AssetState\" && typeof a.value === \"number\") {\n out[key] = assetStateOf(a.value);\n } else {\n out[key] = a.value;\n }\n }\n // Fold \"Rel.Attr\" columns onto the Ref(s) of a selected relation.\n for (const [key, a] of Object.entries(attrs)) {\n const dot = key.indexOf(\".\");\n if (dot < 0 || a._type !== \"Attribute\") continue;\n const rel = key.slice(0, dot), attr = key.slice(dot + 1);\n if (attr.includes(\".\")) continue; // deeper paths stay as columns only\n const target = out[rel];\n const values = a.value;\n if (Array.isArray(target) && Array.isArray(values)) target.forEach((ref, i) => { if (ref && typeof ref === \"object\") (ref as Record<string, unknown>)[attr] = values[i]; });\n else if (target && typeof target === \"object\" && !Array.isArray(target) && !Array.isArray(a.value)) (target as Record<string, unknown>)[attr] = a.value;\n }\n return out as Row;\n}\n\n/** The query string rest-1 wants, from the model's parameters. */\nexport function toQuery(params: ReadParams): Record<string, string | undefined> {\n return {\n sel: (params.select ?? params.sel)?.join(\",\"),\n where: (params.filter ?? params.where)?.length ? (params.filter ?? params.where)!.join(\";\") : undefined,\n with: params.with ? Object.entries(params.with).map(([k, v]) => `${k}=${[].concat(v as never).join(\",\")}`).join(\"|\") : undefined,\n find: params.find,\n findin: params.findin?.join(\",\"),\n sort: params.sort?.join(\",\"),\n page: `${params.page.size},${params.page.start}`,\n deleted: params.deleted === undefined ? undefined : String(params.deleted),\n needTotal: params.needTotal === undefined ? undefined : String(params.needTotal),\n asof: params.asof\n };\n}\n\n// ---- the calls -------------------------------------------------------------\n\nexport interface ReadResult<Row extends Asset = Asset> { rows: Row[]; total: number | null; pageSize: number; pageStart: number }\n\nasync function read<Row extends Asset>(transport: Transport, path: string, params: ReadParams, history: boolean): Promise<ReadResult<Row>> {\n if (!params.page) throw new UsageError(`rest-1 read of ${path} without a page: every read must be bounded`);\n const doc = await transport.request<AssetsDocument>({ method: \"GET\", path, query: toQuery(params), responseType: \"json\" });\n return { rows: (doc.Assets ?? []).map((a) => fromAssetDocument<Row>(a, { history })), total: typeof doc.total === \"number\" && doc.total >= 0 ? doc.total : null, pageSize: doc.pageSize, pageStart: doc.pageStart };\n}\n\n/** A bounded list read of a type. */\nexport const list = <Row extends Asset = Asset>(transport: Transport, type: string, params: ReadParams): Promise<ReadResult<Row>> =>\n read<Row>(transport, `/rest-1.v1/Data/${encodeURIComponent(type)}`, params, false);\n\n/** One asset by OID. */\nexport async function get<Row extends Asset = Asset>(transport: Transport, oid: Oid, select?: string[]): Promise<Row> {\n const [type, id] = momentless(oid).split(\":\");\n const doc = await transport.request<AssetDocument>({ method: \"GET\", path: `/rest-1.v1/Data/${encodeURIComponent(type!)}/${encodeURIComponent(id!)}`, query: { sel: select?.join(\",\") }, responseType: \"json\" });\n return fromAssetDocument<Row>(doc);\n}\n\n/**\n * What an operation answered with: the asset the server returned, as an\n * OID token — for Copy the copy, for anything else the operated asset —\n * and the moment the server stamped on it.\n */\nexport interface OperationResult { oid: Oid; moment: string | null }\n\n/**\n * Run an operation (Copy, Inactivate, …) through rest-1, for its result.\n * api/asset's `execute` performs the same operations but reports only the\n * operated asset, so a Copy's new OID is unobservable there; rest-1 answers\n * it. Not idempotent: never retried.\n */\nexport async function operate(transport: Transport, oid: Oid, op: string): Promise<OperationResult> {\n const [type, id] = momentless(oid).split(\":\");\n if (!type || !id) throw new UsageError(`\"${oid}\" is not an OID token (Story:1234)`);\n const doc = await transport.request<AssetDocument>({ method: \"POST\", path: `/rest-1.v1/Data/${encodeURIComponent(type)}/${encodeURIComponent(id)}`, query: { op }, responseType: \"json\" });\n if (!doc || typeof doc.id !== \"string\" || !doc.id) throw new ApiError(`rest-1 ${op} on ${oid} did not answer with an asset`, 200, \"BAD_RESPONSE\", doc);\n const moment = doc.id.split(\":\")[2] ?? null;\n return { oid: momentless(doc.id), moment };\n}\n\n/** A new asset's template as the model carries it: the attributes the initializer set, no `_oid`. */\nexport type Template<Row extends Asset = Asset> = Partial<Omit<Row, \"_oid\">>;\n\n/**\n * The template for a new asset of `type` in a context (a Scope, a parent\n * asset): what the server's initializer would fill in — defaults nothing\n * else exposes. Idempotent, like any GET. Without a context the template\n * is empty, and an unknown context is echoed back, not refused.\n */\nexport async function template<Row extends Asset = Asset>(transport: Transport, type: string, options: { ctx?: Oid } = {}): Promise<Template<Row>> {\n const doc = await transport.request<AssetDocument>({ method: \"GET\", path: `/rest-1.v1/New/${encodeURIComponent(type)}`, query: { ctx: options.ctx ? momentless(options.ctx) : undefined }, responseType: \"json\" });\n const { _oid: _ignored, ...values } = fromAssetDocument<Row>({ ...doc, id: doc.id || `${type}:0` });\n return values as Template<Row>;\n}\n\n/** A bounded history read: one row per moment, _oid carrying the moment. */\nexport const history = <Row extends Asset = Asset>(transport: Transport, target: string, params: ReadParams): Promise<ReadResult<Row>> => {\n const [type, id] = target.split(\":\");\n const path = id ? `/rest-1.v1/Hist/${encodeURIComponent(type!)}/${encodeURIComponent(id)}` : `/rest-1.v1/Hist/${encodeURIComponent(type!)}`;\n return read<Row>(transport, path, params, true);\n};\n","import type { ClientConfig } from \"./core/clientConfig\";\nimport { ApiError, UsageError } from \"./core/errors\";\nimport { createFetchTransport } from \"./core/fetchTransport\";\nimport type { Transport } from \"./core/transport\";\nimport * as attachments from \"./services/attachments\";\nimport * as batch from \"./services/batch\";\nimport * as fieldsService from \"./services/fields\";\nimport * as guard from \"./services/guard\";\nimport * as resolve from \"./services/resolve\";\nimport { Schema, type TypeCache } from \"./services/schema\";\nimport type { Asset, Oid } from \"./types/asset\";\nimport type { Member } from \"./types/assets/Member\";\nimport type { Metamodel } from \"./types/metamodel\";\nimport type { From, RowOf, RowsOf, Selected, SelectPath, TypeOf } from \"./types/query\";\nimport { isOidToken, momentless } from \"./types/oid\";\nimport { isAssetNumber } from \"./services/resolve\";\nimport * as assetApi from \"./wire/assetApi\";\nimport * as attachment from \"./wire/attachment\";\nimport * as fields from \"./wire/fields\";\nimport * as loc2 from \"./wire/loc2\";\nimport * as meta from \"./wire/meta\";\nimport * as queryV1 from \"./wire/queryV1\";\nimport * as rest1 from \"./wire/rest1\";\n\nexport interface ClientOptions {\n /** Bring your own transport (a fake in tests, an instrumented one in an app). */\n transport?: Transport;\n /**\n * Seed the schema so no type is fetched: a metamodel document as\n * meta.getMetamodel returns it, or the committed metamodel.json run\n * through meta.toMetamodel. Without it, types are loaded from meta.v1 as\n * queries first touch them.\n */\n metamodel?: Metamodel;\n /** Share an existing schema (and its cache) instead of starting a new one. */\n schema?: Schema;\n /**\n * Share loaded type definitions with other clients of the same instance,\n * whatever their credentials: this client's schema keeps its types in\n * `types` and loads anything missing through this client's transport.\n * A server that builds a client per user keeps one TypeCache per instance.\n */\n types?: TypeCache;\n}\n\n/** One page of rows, with the total number of matches when the server reports it, and whether more pages follow. */\nexport interface Page<Row extends Asset = Asset> { rows: Row[]; total: number | null; more: boolean }\n\nexport interface PagesOptions {\n /**\n * The most rows to read across all pages: the iteration stops there, and\n * the last page is cut to fit. Default 1000. Every read is bounded; a\n * caller that truly wants everything says how many that is.\n */\n limit?: number;\n}\n\n/** What `me` answers: the member the credentials belong to. */\nexport type Me = Pick<Member, \"_oid\" | \"Name\" | \"Username\" | \"Nickname\" | \"Email\">;\n\nconst DEFAULT_LIMIT = 1000;\nconst ME_SELECT = [\"Name\", \"Username\", \"Nickname\", \"Email\"];\n\n/**\n * The client: one transport, one schema, and the wire modules bound to\n * them. Every read goes through the schema so its rows arrive in the\n * model's shape (numbers as numbers, a single relation as one Ref), and\n * every write answers in the model's terms (an Outcome, never an envelope).\n *\n * Reads: `query`, `queries`, `get`, `queryPage`, `pages`, `all`, `me`. A\n * query body is the same everywhere; the client picks the endpoint.\n * query.v1 answers rows alone — the lightest response, and read-only by\n * construction, so a request can be resent like a GET — but its shape has\n * nowhere to put a total; api/asset reports one (`needTotal`) beside the\n * rows, which is why `queryPage` goes there and `query` does not. rest-1\n * sits behind `data` for what neither does: deleted assets, history, a\n * new asset's template, an operation's result. Writes: `assets.send`,\n * `assets.sendGuarded`, `batch.run`, `copy`. Services: `resolve`,\n * `fields`, `attachments`, `embeddedImages`, `schema`, `localize`, `urls`.\n */\nexport class AgilityApiClient {\n readonly transport: Transport;\n readonly schema: Schema;\n\n constructor(config: ClientConfig, options: ClientOptions | Transport = {}) {\n // A bare Transport as the second argument is the older spelling; keep it working.\n const opts: ClientOptions = \"request\" in options ? { transport: options } : options;\n this.transport = opts.transport ?? createFetchTransport({\n baseUrl: config.baseUrl,\n authorization: config.authorization,\n accessToken: config.accessToken,\n timeoutMs: config.timeoutMs,\n retries: config.retries,\n defaultHeaders: config.defaultHeaders,\n credentials: config.credentials,\n onUnauthorized: config.onUnauthorized,\n unauthorizedStatuses: config.unauthorizedStatuses\n });\n this.config = config;\n this.schema = opts.schema ?? new Schema(this.transport, opts.metamodel, opts.types);\n }\n\n private readonly config: ClientConfig;\n\n /**\n * The same client, with every request it sends tied to `signal`: abort it\n * (on navigation, say) and in-flight requests end with an ApiError coded\n * ABORTED. The schema and its cache are shared; a type load that other\n * callers are waiting on is not cancelled.\n */\n withSignal(signal: AbortSignal): AgilityApiClient {\n const base = this.transport;\n const transport: Transport = { request: (options) => base.request({ ...options, signal: options.signal ?? signal }) };\n return new AgilityApiClient(this.config, { transport, schema: this.schema });\n }\n\n // ---- reads ------------------------------------------------------------------\n\n /**\n * One query, its rows, translated. Sent to query.v1: it cannot write, so\n * the request is marked idempotent and the transport may resend it after\n * a network failure or a 5xx — when `retries` is set above its default\n * of 0. A page is required; a query the server refuses throws an\n * ApiError (kind \"invalid\", code QUERY_REJECTED; `message` holds the\n * server's sentences, `details` its whole error document), never an\n * empty result.\n */\n query<const F extends From, const Q extends assetApi.QueryBody<F>>(q: Q & assetApi.QueryBody<F>): Promise<RowOf<Q>[]>;\n query<Row extends Asset = Asset>(q: assetApi.QueryBody): Promise<Row[]>;\n async query(q: assetApi.QueryBody): Promise<Asset[]> {\n await this.schema.ensureFor([q]);\n return queryV1.query(this.transport, q, { lookup: this.schema });\n }\n\n /** Several queries in one request; one array of rows per query, in order. */\n queries<const Qs extends readonly assetApi.QueryBody[]>(qs: Qs): Promise<RowsOf<Qs>>;\n queries<Row extends Asset = Asset>(qs: assetApi.QueryBody[]): Promise<Row[][]>;\n async queries(qs: readonly assetApi.QueryBody[]): Promise<Asset[][]> {\n await this.schema.ensureFor(qs);\n return queryV1.queries(this.transport, [...qs], { lookup: this.schema });\n }\n\n /**\n * One asset by OID token, with the attributes selected, or null when no\n * asset has that OID. (`select` omitted: just the OID, which tells you it\n * exists.)\n */\n get<const O extends string, const S extends readonly (SelectPath<TypeOf<O>> | assetApi.QueryBody)[]>(oid: O, select: S): Promise<Selected<TypeOf<O>, S> | null>;\n get<Row extends Asset = Asset>(oid: Oid, select?: assetApi.QueryBody[\"select\"]): Promise<Row | null>;\n async get(oid: Oid, select?: assetApi.QueryBody[\"select\"]): Promise<Asset | null> {\n const rows = await this.query({ from: momentless(oid), ...(select ? { select } : {}), page: { size: 1, start: 0 } });\n return rows[0] ?? null;\n }\n\n /**\n * One page with its total: api/asset reports the number of matches when\n * asked (query.v1 does not), so this read goes there. `total` is null\n * when the server did not say; `more` is then whether the page was full.\n */\n queryPage<const F extends From, const Q extends assetApi.QueryBody<F>>(q: Q & assetApi.QueryBody<F>): Promise<Page<RowOf<Q>>>;\n queryPage<Row extends Asset = Asset>(q: assetApi.QueryBody): Promise<Page<Row>>;\n async queryPage(q: assetApi.QueryBody): Promise<Page> {\n await this.schema.ensureFor([q]);\n return assetApi.queryPage(this.transport, q, { lookup: this.schema });\n }\n\n /**\n * The query page by page, as an async iterator, up to `limit` rows in\n * all (default 1000): `page.start` advances by `page.size` from where the\n * query starts, and the iteration ends at a short page or at the limit.\n * Each page is a plain read on query.v1, so a long walk survives a\n * transient failure like any GET.\n */\n pages<const F extends From, const Q extends assetApi.QueryBody<F>>(q: Q & assetApi.QueryBody<F>, options?: PagesOptions): AsyncGenerator<RowOf<Q>[], void, undefined>;\n pages<Row extends Asset = Asset>(q: assetApi.QueryBody, options?: PagesOptions): AsyncGenerator<Row[], void, undefined>;\n async *pages(q: assetApi.QueryBody, options: PagesOptions = {}): AsyncGenerator<Asset[], void, undefined> {\n if (!q.page) throw new UsageError(`query of ${q.from} without a page: every read must be bounded`);\n const limit = options.limit ?? DEFAULT_LIMIT;\n const size = q.page.size;\n let start = q.page.start, read = 0;\n while (read < limit) {\n const want = Math.min(size, limit - read);\n const rows = await this.query({ ...q, page: { size: want, start } });\n if (rows.length) yield rows;\n read += rows.length;\n start += rows.length;\n if (rows.length < want) return;\n }\n }\n\n /** Every row of the query up to `limit` (default 1000), read page by page. */\n all<const F extends From, const Q extends assetApi.QueryBody<F>>(q: Q & assetApi.QueryBody<F>, options?: PagesOptions): Promise<RowOf<Q>[]>;\n all<Row extends Asset = Asset>(q: assetApi.QueryBody, options?: PagesOptions): Promise<Row[]>;\n async all(q: assetApi.QueryBody, options: PagesOptions = {}): Promise<Asset[]> {\n const out: Asset[] = [];\n for await (const page of this.pages(q, options)) out.push(...page);\n return out;\n }\n\n /** The member these credentials belong to (Member.IsSelf, live 2026-11-12): what a comment's Author is. */\n async me(): Promise<Me> {\n const [row] = await this.query<Me>({ from: \"Member\", select: ME_SELECT, filter: [\"IsSelf='true'\"], page: { size: 1, start: 0 } });\n if (!row) throw new ApiError(\"the server knows no member for these credentials\", 0, \"NOT_FOUND\");\n return row;\n }\n\n // ---- the endpoints behind the reads -----------------------------------------------\n\n /**\n * meta.v1: the instance's schema, raw. (The translated, cached view is\n * `schema`; `schema.revalidate()` drops it when the schema's tag moves.)\n * `read` and `readType` are conditional: pass the tag a previous answer\n * carried and an unchanged schema answers null without a download —\n * meta.v1 sends one strong ETag for the whole schema. `etag()` reads that\n * tag alone, from the smallest resource.\n */\n readonly meta = {\n metamodel: () => meta.getMetamodel(this.transport),\n read: (options?: meta.ConditionalOptions) => meta.readMetamodel(this.transport, options),\n assetType: (token: string) => meta.getAssetType(this.transport, token),\n readType: (token: string, options?: meta.ConditionalOptions) => meta.readAssetType(this.transport, token, options),\n attributeDefinition: (tokenref: `${string}.${string}`) => meta.getAttributeDefinition(this.transport, tokenref),\n etag: (options?: meta.ConditionalOptions) => meta.etag(this.transport, options)\n };\n\n /**\n * loc-2.v1: labels for tags, in one request (meta's DisplayName values are\n * tags, and so is a violation's `tag`). An unmatched tag comes back as\n * itself; the server never says \"missing\", so neither does this.\n */\n localize(tags: readonly string[], options?: loc2.LocalizeOptions): Promise<loc2.Localizations> {\n return loc2.localize(this.transport, tags, options);\n }\n\n /**\n * rest-1.v1, for what the other endpoints cannot do: deleted assets\n * (`deleted: true`), one asset by OID without a page, history (one row\n * per moment), a new asset's template (`template`: what the type's\n * initializer fills in for a context — a Timebox's next name and dates,\n * a Story's carry-over from a Request), and an operation's result\n * (`operate`: api/asset performs a Copy but never says what it made;\n * rest-1 answers the new OID). Parameters are spelled as a query's\n * (`select`, `filter`).\n */\n readonly data = {\n list: <Row extends Asset = Asset>(type: string, params: rest1.ReadParams) => rest1.list<Row>(this.transport, type, params),\n get: <Row extends Asset = Asset>(oid: string, select?: string[]) => rest1.get<Row>(this.transport, oid, select),\n history: <Row extends Asset = Asset>(target: string, params: rest1.ReadParams) => rest1.history<Row>(this.transport, target, params),\n template: <F extends From>(type: F, options?: { ctx?: Oid }) => rest1.template<TypeOf<F>>(this.transport, type, options),\n operate: (oid: Oid, op: string) => rest1.operate(this.transport, oid, op)\n };\n\n /** Copy an asset (the server's Copy operation) and answer the copy's OID: the one thing api/asset's `execute: \"Copy\"` does not say. */\n async copy(oid: Oid): Promise<Oid> {\n return (await rest1.operate(this.transport, oid, \"Copy\")).oid;\n }\n\n /**\n * What a form needs for an asset type in a scope: the attributes the\n * server requires to create one (meta), the ones the product shows there\n * (api/visibleFields, custom fields included once configured), and the\n * scope's scheme's important fields and whether they are enforced at\n * close. `visible` alone answers for several types and scopes at once.\n */\n readonly fields = {\n describe: (type: From, scope: Oid) => fieldsService.describe(this.transport, this.schema, type, scope),\n visible: (types: readonly From[], scopes: readonly Oid[]) => fields.visibleFields(this.transport, types, scopes),\n visibleByAsset: (oid: Oid) => fields.visibleFieldsByAsset(this.transport, oid)\n };\n\n /** @deprecated since 1.0.0-alpha.3: use `client.query` / `client.queries` (the same endpoint, query.v1; only the name moved). Removed in 1.0.0. */\n readonly queryV1 = {\n query: <Row extends Asset = Asset>(q: assetApi.QueryBody) => this.query<Row>(q),\n queries: <Row extends Asset = Asset>(qs: assetApi.QueryBody[]) => this.queries<Row>(qs)\n };\n\n // ---- writes -----------------------------------------------------------------------\n\n /** api/asset: batches, answered in the model's terms. */\n readonly assets = {\n /**\n * Send a batch. The Outcome says what it did — created, modified and\n * operated OIDs, failures by index (each with its parsed violation),\n * query rows per query command — and never the envelope. api/asset\n * commits per command and answers 200 either way, so a failed command\n * is in `failures`, or thrown as a CommandFailureError with\n * `throwOnFailure` (the error carries the same Outcome).\n */\n send: async <Row extends Asset = Asset>(commands: assetApi.Command[], options?: Omit<assetApi.SendOptions, \"lookup\" | \"previewOnly\">): Promise<assetApi.Outcome<Row>> => {\n await this.schema.ensureFor(commands);\n return assetApi.outcomeOf(await assetApi.send<Row>(this.transport, commands, { ...options, lookup: this.schema }));\n },\n /** The server's projection of a batch: one command per asset it would touch, nothing applied. */\n preview: (commands: assetApi.Command[]) => assetApi.preview(this.transport, commands),\n /**\n * Send as a compare-and-set: each asset is changed only if nobody has\n * changed it since the preview read it; the rest come back `skipped`.\n * Throws UnguardableError, before any request, for shapes it cannot\n * cover.\n */\n sendGuarded: async <Row extends Asset = Asset>(commands: assetApi.Command[], options?: Pick<assetApi.SendOptions, \"throwOnFailure\">) => {\n await this.schema.ensureFor(commands);\n return guard.sendGuarded<Row>(this.transport, commands, { ...options, lookup: this.schema });\n },\n /** @deprecated since 1.0.0-alpha.3: use `client.query` (rows, through query.v1) or `client.queryPage` (rows and a total, through api/asset as this does). Removed in 1.0.0. */\n query: async <Row extends Asset = Asset>(q: assetApi.QueryBody) => {\n await this.schema.ensureFor([q]);\n return assetApi.query<Row>(this.transport, q, { lookup: this.schema });\n },\n /** @deprecated since 1.0.0-alpha.3: use `client.queries`. Removed in 1.0.0. */\n queries: async <Row extends Asset = Asset>(qs: assetApi.QueryBody[]) => {\n await this.schema.ensureFor(qs);\n return assetApi.queries<Row>(this.transport, qs, { lookup: this.schema });\n }\n };\n\n /**\n * Services: what a person types, turned into assets. Numbers resolve in\n * one api/asset request across every number root; an OID token is taken\n * as is.\n */\n readonly resolve = {\n numbers: (numbers: readonly string[]) => resolve.resolveNumbers(this.transport, numbers, { types: this.schema.cache }),\n ref: (spec: string) => resolve.resolveRef(this.transport, spec, { types: this.schema.cache })\n };\n\n /**\n * A batch with a record: preview, snapshot what it overwrites, (confirm,)\n * send guarded, and a receipt with created/touched/skipped assets and a\n * reverse batch. `reversible` drops from a receipt's reverse the assets\n * changed since, unless forced.\n */\n readonly batch = {\n run: (commands: assetApi.Command[], options?: batch.BatchOptions) => batch.runBatch(this.transport, this.schema, commands, options),\n reversible: (receipt: Pick<batch.Receipt, \"reverse\" | \"after\">, options?: { force?: boolean }) => batch.reversible(this.transport, receipt, options)\n };\n\n /**\n * The files attached to assets: metadata on Attachment assets, bytes\n * through attachment.img. `add` sends a small file inline (one request)\n * and a large one in two steps.\n */\n readonly attachments = {\n list: (asset: string, options?: { page?: { size: number; start: number } }) => attachments.list(this.transport, asset, options),\n page: (asset: string, options?: { page?: { size: number; start: number } }) => attachments.page(this.transport, asset, options),\n info: (id: string | number) => attachments.info(this.transport, id),\n get: (id: string | number) => attachments.get(this.transport, id),\n add: (asset: string, data: attachment.Bytes, options: attachments.AddOptions) => attachments.add(this.transport, asset, data, options),\n put: (id: string | number, data: attachment.Bytes, contentType?: string) => attachments.put(this.transport, id, data, contentType),\n remove: (id: string | number) => attachments.remove(this.transport, id),\n /** @deprecated since 1.0.0-alpha.3: `client.urls.attachment`. Removed in 1.0.0. */\n url: (id: string | number) => this.urls.attachment(id)\n };\n\n /**\n * Images embedded in an asset's rich text (Description and other long\n * text). `upload` returns the URL to put in an <img src>; `normalize`\n * rewrites every embedded.img reference in some HTML to this instance's\n * absolute URL, as Agility's own editor stores it. They cannot be deleted.\n */\n readonly embeddedImages = {\n upload: (asset: string, data: attachment.Bytes, options?: { filename?: string; contentType?: string }) => attachment.uploadEmbeddedImage(this.transport, asset, data, options),\n /** @deprecated since 1.0.0-alpha.3: `client.urls.embeddedImage`. Removed in 1.0.0. */\n url: (id: string | number) => this.urls.embeddedImage(id),\n normalize: (html: string) => attachment.normalizeEmbeddedImageUrls(html, this.config.baseUrl)\n };\n\n /** Where a browser opens things on this instance: an asset's page, an attachment's bytes, an embedded image. */\n readonly urls = {\n /**\n * The asset's page, from an OID token or an asset Number (S-01001,\n * what a person typed and what a message shows): assetdetail.v1\n * resolves either and redirects to the type's own detail page; a signed-\n * out reader lands there after logging in. Anything else is a UsageError.\n */\n asset: (ref: Oid | string) => {\n const base = this.config.baseUrl.replace(/\\/+$/, \"\");\n const text = ref.trim();\n if (isOidToken(text)) return `${base}/assetdetail.v1?oid=${momentless(text)}`;\n if (isAssetNumber(text)) return `${base}/assetdetail.v1?Number=${encodeURIComponent(text)}`;\n throw new UsageError(`\"${ref}\" is neither an OID token (Story:1234) nor an asset number (S-1234)`);\n },\n attachment: (id: string | number) => attachment.attachmentUrl(this.config.baseUrl, id),\n embeddedImage: (id: string | number) => attachment.embeddedImageUrl(this.config.baseUrl, id)\n };\n}\n"],"mappings":"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","names":["CHUNK","query","query","one","queries","bodyOf","byType","list","CHUNK","bodyOf","list","add","remove","now","describe","CHUNK","etag","read","read","now","query","queries","query","queries","query","get","list","history","list","get","query","queries","read","page","list","get","describe"]}
|