@tanstack/db
Version:
A reactive client store for building super fast apps on sync
1 lines • 23.2 kB
Source Map (JSON)
{"version":3,"file":"ir-stable-identity.cjs","sources":["../../../src/query/ir-stable-identity.ts"],"sourcesContent":["import { isRefProxy, toExpression } from './builder/ref-proxy.js'\nimport { getQueryIR } from './builder/index.js'\nimport type {\n Aggregate,\n BasicExpression,\n ConditionalSelect,\n From,\n Having,\n IncludesSubquery,\n JoinClause,\n OrderByClause,\n QueryIR,\n Select,\n Where,\n} from './ir.js'\nimport type { InitialQueryBuilder, QueryBuilder } from './builder/index.js'\n\ntype StableIdentityValue =\n | null\n | boolean\n | number\n | string\n | Array<StableIdentityValue>\n | { [key: string]: StableIdentityValue }\n\nexport class UnhashableQueryIRError extends Error {\n constructor(\n public readonly path: string,\n public readonly reason: string,\n ) {\n super(`Query IR is not stably hashable at ${path}: ${reason}`)\n this.name = `UnhashableQueryIRError`\n }\n}\n\nexport function getStableQueryIRHash(query: QueryIR): string {\n return JSON.stringify(canonicalizeQueryIR(query))\n}\n\nexport function getStableQueryBuilderHash(\n query: InitialQueryBuilder | QueryBuilder<any>,\n): string {\n return getStableQueryIRHash(getQueryIR(query))\n}\n\nexport function getStableValueHash(value: unknown, path = `value`): string {\n return JSON.stringify(canonicalizeRuntimeValue(value, path, new WeakSet()))\n}\n\nexport function canonicalizeQueryIR(query: QueryIR): StableIdentityValue {\n return canonicalizeQuery(query, `query`, new WeakSet<object>())\n}\n\nfunction canonicalizeQuery(\n query: QueryIR,\n path: string,\n seen: WeakSet<object>,\n): StableIdentityValue {\n if (query.fnSelect) {\n throw new UnhashableQueryIRError(`${path}.fnSelect`, `function select`)\n }\n\n if (query.fnWhere?.length) {\n throw new UnhashableQueryIRError(`${path}.fnWhere`, `function where`)\n }\n\n if (query.fnHaving?.length) {\n throw new UnhashableQueryIRError(`${path}.fnHaving`, `function having`)\n }\n\n const result: Record<string, StableIdentityValue> = {\n type: `query`,\n from: canonicalizeSource(query.from, `${path}.from`, seen),\n }\n\n if (query.select) {\n result.select = canonicalizeSelect(query.select, `${path}.select`, seen)\n }\n\n if (query.join) {\n result.join = query.join.map((join, index) =>\n canonicalizeJoin(join, `${path}.join[${index}]`, seen),\n )\n }\n\n if (query.where) {\n result.where = query.where.map((where, index) =>\n canonicalizeWhere(where, `${path}.where[${index}]`, seen),\n )\n }\n\n if (query.groupBy) {\n result.groupBy = query.groupBy.map((expression, index) =>\n canonicalizeExpression(expression, `${path}.groupBy[${index}]`, seen),\n )\n }\n\n if (query.having) {\n result.having = query.having.map((having, index) =>\n canonicalizeWhere(having, `${path}.having[${index}]`, seen),\n )\n }\n\n if (query.orderBy) {\n result.orderBy = query.orderBy.map((orderBy, index) =>\n canonicalizeOrderBy(orderBy, `${path}.orderBy[${index}]`, seen),\n )\n }\n\n if (query.limit !== undefined) {\n result.limit = canonicalizeRuntimeValue(query.limit, `${path}.limit`, seen)\n }\n\n if (query.offset !== undefined) {\n result.offset = canonicalizeRuntimeValue(\n query.offset,\n `${path}.offset`,\n seen,\n )\n }\n\n if (query.distinct) {\n result.distinct = true\n }\n\n if (query.singleResult) {\n result.singleResult = true\n }\n\n return result\n}\n\nfunction canonicalizeJoin(\n join: JoinClause,\n path: string,\n seen: WeakSet<object>,\n): StableIdentityValue {\n return {\n type: join.type,\n from: canonicalizeSource(join.from, `${path}.from`, seen),\n left: canonicalizeExpression(join.left, `${path}.left`, seen),\n right: canonicalizeExpression(join.right, `${path}.right`, seen),\n }\n}\n\nfunction canonicalizeSource(\n source: From,\n path: string,\n seen: WeakSet<object>,\n): StableIdentityValue {\n if (source.type === `collectionRef`) {\n return {\n type: `collectionRef`,\n alias: source.alias,\n collectionId: canonicalizeRuntimeValue(\n source.collection.id,\n `${path}.collection.id`,\n seen,\n ),\n }\n }\n\n if (source.type === `unionFrom`) {\n return {\n type: `unionFrom`,\n sources: source.sources.map((unionSource, index) =>\n canonicalizeSource(unionSource, `${path}.sources[${index}]`, seen),\n ),\n }\n }\n\n if (source.type === `unionAll`) {\n return {\n type: `unionAll`,\n queries: source.queries.map((query, index) =>\n canonicalizeQuery(query, `${path}.queries[${index}]`, seen),\n ),\n }\n }\n\n return {\n type: `queryRef`,\n alias: source.alias,\n query: canonicalizeQuery(source.query, `${path}.query`, seen),\n }\n}\n\nfunction canonicalizeSelect(\n select: Select,\n path: string,\n seen: WeakSet<object>,\n): StableIdentityValue {\n return {\n type: `select`,\n fields: Object.keys(select)\n .sort()\n .map((key) => [\n key,\n canonicalizeSelectValue(select[key]!, `${path}.${key}`, seen),\n ]),\n }\n}\n\nfunction canonicalizeSelectValue(\n value: unknown,\n path: string,\n seen: WeakSet<object>,\n): StableIdentityValue {\n if (isRefProxy(value)) {\n return canonicalizeExpression(toExpression(value), path, seen)\n }\n\n if (isExpression(value)) {\n return canonicalizeExpression(value, path, seen)\n }\n\n if (isPlainObject(value)) {\n return canonicalizeSelect(value as Select, path, seen)\n }\n\n return canonicalizeRuntimeValue(value, path, seen)\n}\n\nfunction canonicalizeWhere(\n where: Where | Having,\n path: string,\n seen: WeakSet<object>,\n): StableIdentityValue {\n if (isWhereObject(where)) {\n const result: Record<string, StableIdentityValue> = {\n type: `where`,\n expression: canonicalizeExpression(\n where.expression,\n `${path}.expression`,\n seen,\n ),\n }\n\n if (where.residual === true) {\n result.residual = true\n }\n\n return result\n }\n\n return canonicalizeExpression(where, path, seen)\n}\n\nfunction canonicalizeOrderBy(\n orderBy: OrderByClause,\n path: string,\n seen: WeakSet<object>,\n): StableIdentityValue {\n return {\n expression: canonicalizeExpression(\n orderBy.expression,\n `${path}.expression`,\n seen,\n ),\n compareOptions: canonicalizeRuntimeValue(\n orderBy.compareOptions,\n `${path}.compareOptions`,\n seen,\n ),\n }\n}\n\nfunction canonicalizeExpression(\n expression:\n | BasicExpression\n | Aggregate\n | IncludesSubquery\n | ConditionalSelect,\n path: string,\n seen: WeakSet<object>,\n): StableIdentityValue {\n if (expression.type === `ref`) {\n return {\n type: `ref`,\n path: expression.path.map((segment, index) =>\n canonicalizeRuntimeValue(segment, `${path}.path[${index}]`, seen),\n ),\n }\n }\n\n if (expression.type === `val`) {\n return {\n type: `val`,\n value: canonicalizeRuntimeValue(expression.value, `${path}.value`, seen),\n }\n }\n\n if (expression.type === `func`) {\n return {\n type: `func`,\n name: expression.name,\n args: expression.args.map((arg, index) =>\n canonicalizeExpression(arg, `${path}.args[${index}]`, seen),\n ),\n }\n }\n\n if (expression.type === `agg`) {\n return {\n type: `agg`,\n name: expression.name,\n args: expression.args.map((arg, index) =>\n canonicalizeExpression(arg, `${path}.args[${index}]`, seen),\n ),\n }\n }\n\n if (expression.type === `conditionalSelect`) {\n const result: Record<string, StableIdentityValue> = {\n type: `conditionalSelect`,\n branches: expression.branches.map((branch, index) => ({\n condition: canonicalizeExpression(\n branch.condition,\n `${path}.branches[${index}].condition`,\n seen,\n ),\n value: canonicalizeSelectValue(\n branch.value,\n `${path}.branches[${index}].value`,\n seen,\n ),\n })),\n }\n\n if (expression.defaultValue !== undefined) {\n result.defaultValue = canonicalizeSelectValue(\n expression.defaultValue,\n `${path}.defaultValue`,\n seen,\n )\n }\n\n return result\n }\n\n const result: Record<string, StableIdentityValue> = {\n type: `includesSubquery`,\n query: canonicalizeQuery(expression.query, `${path}.query`, seen),\n correlationField: canonicalizeExpression(\n expression.correlationField,\n `${path}.correlationField`,\n seen,\n ),\n childCorrelationField: canonicalizeExpression(\n expression.childCorrelationField,\n `${path}.childCorrelationField`,\n seen,\n ),\n fieldName: expression.fieldName,\n materialization: expression.materialization,\n }\n\n if (expression.parentFilters) {\n result.parentFilters = expression.parentFilters.map((where, index) =>\n canonicalizeWhere(where, `${path}.parentFilters[${index}]`, seen),\n )\n }\n\n if (expression.parentProjection) {\n result.parentProjection = expression.parentProjection.map(\n (projection, index) =>\n canonicalizeExpression(\n projection,\n `${path}.parentProjection[${index}]`,\n seen,\n ),\n )\n }\n\n if (expression.scalarField !== undefined) {\n result.scalarField = expression.scalarField\n }\n\n return result\n}\n\nfunction canonicalizeRuntimeValue(\n value: unknown,\n path: string,\n seen: WeakSet<object>,\n): StableIdentityValue {\n if (value === null) return [`null`]\n\n if (typeof value === `string`) {\n return [`string`, value]\n }\n\n if (typeof value === `boolean`) {\n return [`boolean`, value]\n }\n\n if (typeof value === `number`) {\n if (Number.isNaN(value)) {\n return [`number`, `NaN`]\n }\n\n if (value === Infinity) {\n return [`number`, `Infinity`]\n }\n\n if (value === -Infinity) {\n return [`number`, `-Infinity`]\n }\n\n if (Object.is(value, -0)) {\n return [`number`, `-0`]\n }\n\n return [`number`, value]\n }\n\n if (typeof value === `undefined`) {\n return [`undefined`]\n }\n\n if (typeof value === `bigint`) {\n return [`bigint`, value.toString()]\n }\n\n if (typeof value === `function`) {\n throw new UnhashableQueryIRError(path, `function value`)\n }\n\n if (typeof value === `symbol`) {\n throw new UnhashableQueryIRError(path, `symbol value`)\n }\n\n if (isRefProxy(value)) {\n return canonicalizeExpression(toExpression(value), path, seen)\n }\n\n if (Array.isArray(value)) {\n return withCircularGuard(value, path, seen, () => [\n `array`,\n value.map((item, index) =>\n canonicalizeRuntimeValue(item, `${path}[${index}]`, seen),\n ),\n ])\n }\n\n if (value instanceof Date) {\n const timestamp = value.getTime()\n if (Number.isNaN(timestamp)) {\n throw new UnhashableQueryIRError(path, `invalid Date`)\n }\n\n return [`Date`, value.toISOString()]\n }\n\n if (value instanceof ArrayBuffer) {\n return [`binary`, `ArrayBuffer`, Array.from(new Uint8Array(value))]\n }\n\n if (ArrayBuffer.isView(value)) {\n return [\n `binary`,\n value.constructor.name,\n Array.from(\n new Uint8Array(value.buffer, value.byteOffset, value.byteLength),\n ),\n ]\n }\n\n if (value instanceof Map) {\n return withCircularGuard(value, path, seen, () => {\n const entries = Array.from(\n value.entries(),\n ([key, entryValue], index) => [\n canonicalizeRuntimeValue(key, `${path}.key[${index}]`, seen),\n canonicalizeRuntimeValue(entryValue, `${path}.value[${index}]`, seen),\n ],\n )\n entries.sort(compareStableIdentityValues)\n return [`Map`, entries]\n })\n }\n\n if (value instanceof Set) {\n return withCircularGuard(value, path, seen, () => {\n const entries = Array.from(value, (entry, index) =>\n canonicalizeRuntimeValue(entry, `${path}[${index}]`, seen),\n )\n entries.sort(compareStableIdentityValues)\n return [`Set`, entries]\n })\n }\n\n if (isPlainObject(value)) {\n return canonicalizeObject(value, path, seen)\n }\n\n throw new UnhashableQueryIRError(path, `non-plain object value`)\n}\n\nfunction compareStableIdentityValues(\n left: StableIdentityValue,\n right: StableIdentityValue,\n): number {\n const serializedLeft = JSON.stringify(left)\n const serializedRight = JSON.stringify(right)\n return serializedLeft < serializedRight\n ? -1\n : serializedLeft > serializedRight\n ? 1\n : 0\n}\n\nfunction canonicalizeObject(\n value: Record<string, unknown>,\n path: string,\n seen: WeakSet<object>,\n): StableIdentityValue {\n return withCircularGuard(value, path, seen, () => [\n `object`,\n Object.keys(value)\n .sort()\n .map((key) => [\n key,\n canonicalizeRuntimeValue(value[key], `${path}.${key}`, seen),\n ]),\n ])\n}\n\nfunction withCircularGuard<T>(\n value: object,\n path: string,\n seen: WeakSet<object>,\n callback: () => T,\n): T {\n if (seen.has(value)) {\n throw new UnhashableQueryIRError(path, `circular value`)\n }\n\n seen.add(value)\n try {\n return callback()\n } finally {\n seen.delete(value)\n }\n}\n\nfunction isWhereObject(\n where: Where | Having,\n): where is { expression: BasicExpression<boolean>; residual?: boolean } {\n return `expression` in where\n}\n\nfunction isExpression(\n value: unknown,\n): value is BasicExpression | Aggregate | IncludesSubquery {\n if (value === null || typeof value !== `object`) {\n return false\n }\n\n const expressionType = (value as { type?: unknown }).type\n return (\n expressionType === `agg` ||\n expressionType === `conditionalSelect` ||\n expressionType === `func` ||\n expressionType === `ref` ||\n expressionType === `val` ||\n expressionType === `includesSubquery`\n )\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== `object`) return false\n\n const prototype = Object.getPrototypeOf(value)\n return prototype === Object.prototype || prototype === null\n}\n"],"names":["getQueryIR","index","isRefProxy","toExpression","result"],"mappings":";;;;AAyBO,MAAM,+BAA+B,MAAM;AAAA,EAChD,YACkB,MACA,QAChB;AACA,UAAM,sCAAsC,IAAI,KAAK,MAAM,EAAE;AAH7C,SAAA,OAAA;AACA,SAAA,SAAA;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,qBAAqB,OAAwB;AAC3D,SAAO,KAAK,UAAU,oBAAoB,KAAK,CAAC;AAClD;AAEO,SAAS,0BACd,OACQ;AACR,SAAO,qBAAqBA,iBAAW,KAAK,CAAC;AAC/C;AAEO,SAAS,mBAAmB,OAAgB,OAAO,SAAiB;AACzE,SAAO,KAAK,UAAU,yBAAyB,OAAO,MAAM,oBAAI,QAAA,CAAS,CAAC;AAC5E;AAEO,SAAS,oBAAoB,OAAqC;AACvE,SAAO,kBAAkB,OAAO,SAAS,oBAAI,SAAiB;AAChE;AAEA,SAAS,kBACP,OACA,MACA,MACqB;AACrB,MAAI,MAAM,UAAU;AAClB,UAAM,IAAI,uBAAuB,GAAG,IAAI,aAAa,iBAAiB;AAAA,EACxE;AAEA,MAAI,MAAM,SAAS,QAAQ;AACzB,UAAM,IAAI,uBAAuB,GAAG,IAAI,YAAY,gBAAgB;AAAA,EACtE;AAEA,MAAI,MAAM,UAAU,QAAQ;AAC1B,UAAM,IAAI,uBAAuB,GAAG,IAAI,aAAa,iBAAiB;AAAA,EACxE;AAEA,QAAM,SAA8C;AAAA,IAClD,MAAM;AAAA,IACN,MAAM,mBAAmB,MAAM,MAAM,GAAG,IAAI,SAAS,IAAI;AAAA,EAAA;AAG3D,MAAI,MAAM,QAAQ;AAChB,WAAO,SAAS,mBAAmB,MAAM,QAAQ,GAAG,IAAI,WAAW,IAAI;AAAA,EACzE;AAEA,MAAI,MAAM,MAAM;AACd,WAAO,OAAO,MAAM,KAAK;AAAA,MAAI,CAAC,MAAMC,WAClC,iBAAiB,MAAM,GAAG,IAAI,SAASA,MAAK,KAAK,IAAI;AAAA,IAAA;AAAA,EAEzD;AAEA,MAAI,MAAM,OAAO;AACf,WAAO,QAAQ,MAAM,MAAM;AAAA,MAAI,CAAC,OAAOA,WACrC,kBAAkB,OAAO,GAAG,IAAI,UAAUA,MAAK,KAAK,IAAI;AAAA,IAAA;AAAA,EAE5D;AAEA,MAAI,MAAM,SAAS;AACjB,WAAO,UAAU,MAAM,QAAQ;AAAA,MAAI,CAAC,YAAYA,WAC9C,uBAAuB,YAAY,GAAG,IAAI,YAAYA,MAAK,KAAK,IAAI;AAAA,IAAA;AAAA,EAExE;AAEA,MAAI,MAAM,QAAQ;AAChB,WAAO,SAAS,MAAM,OAAO;AAAA,MAAI,CAAC,QAAQA,WACxC,kBAAkB,QAAQ,GAAG,IAAI,WAAWA,MAAK,KAAK,IAAI;AAAA,IAAA;AAAA,EAE9D;AAEA,MAAI,MAAM,SAAS;AACjB,WAAO,UAAU,MAAM,QAAQ;AAAA,MAAI,CAAC,SAASA,WAC3C,oBAAoB,SAAS,GAAG,IAAI,YAAYA,MAAK,KAAK,IAAI;AAAA,IAAA;AAAA,EAElE;AAEA,MAAI,MAAM,UAAU,QAAW;AAC7B,WAAO,QAAQ,yBAAyB,MAAM,OAAO,GAAG,IAAI,UAAU,IAAI;AAAA,EAC5E;AAEA,MAAI,MAAM,WAAW,QAAW;AAC9B,WAAO,SAAS;AAAA,MACd,MAAM;AAAA,MACN,GAAG,IAAI;AAAA,MACP;AAAA,IAAA;AAAA,EAEJ;AAEA,MAAI,MAAM,UAAU;AAClB,WAAO,WAAW;AAAA,EACpB;AAEA,MAAI,MAAM,cAAc;AACtB,WAAO,eAAe;AAAA,EACxB;AAEA,SAAO;AACT;AAEA,SAAS,iBACP,MACA,MACA,MACqB;AACrB,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,MAAM,mBAAmB,KAAK,MAAM,GAAG,IAAI,SAAS,IAAI;AAAA,IACxD,MAAM,uBAAuB,KAAK,MAAM,GAAG,IAAI,SAAS,IAAI;AAAA,IAC5D,OAAO,uBAAuB,KAAK,OAAO,GAAG,IAAI,UAAU,IAAI;AAAA,EAAA;AAEnE;AAEA,SAAS,mBACP,QACA,MACA,MACqB;AACrB,MAAI,OAAO,SAAS,iBAAiB;AACnC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,OAAO;AAAA,MACd,cAAc;AAAA,QACZ,OAAO,WAAW;AAAA,QAClB,GAAG,IAAI;AAAA,QACP;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,OAAO,SAAS,aAAa;AAC/B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,OAAO,QAAQ;AAAA,QAAI,CAAC,aAAaA,WACxC,mBAAmB,aAAa,GAAG,IAAI,YAAYA,MAAK,KAAK,IAAI;AAAA,MAAA;AAAA,IACnE;AAAA,EAEJ;AAEA,MAAI,OAAO,SAAS,YAAY;AAC9B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,OAAO,QAAQ;AAAA,QAAI,CAAC,OAAOA,WAClC,kBAAkB,OAAO,GAAG,IAAI,YAAYA,MAAK,KAAK,IAAI;AAAA,MAAA;AAAA,IAC5D;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,OAAO;AAAA,IACd,OAAO,kBAAkB,OAAO,OAAO,GAAG,IAAI,UAAU,IAAI;AAAA,EAAA;AAEhE;AAEA,SAAS,mBACP,QACA,MACA,MACqB;AACrB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,OAAO,KAAK,MAAM,EACvB,OACA,IAAI,CAAC,QAAQ;AAAA,MACZ;AAAA,MACA,wBAAwB,OAAO,GAAG,GAAI,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI;AAAA,IAAA,CAC7D;AAAA,EAAA;AAEP;AAEA,SAAS,wBACP,OACA,MACA,MACqB;AACrB,MAAIC,SAAAA,WAAW,KAAK,GAAG;AACrB,WAAO,uBAAuBC,SAAAA,aAAa,KAAK,GAAG,MAAM,IAAI;AAAA,EAC/D;AAEA,MAAI,aAAa,KAAK,GAAG;AACvB,WAAO,uBAAuB,OAAO,MAAM,IAAI;AAAA,EACjD;AAEA,MAAI,cAAc,KAAK,GAAG;AACxB,WAAO,mBAAmB,OAAiB,MAAM,IAAI;AAAA,EACvD;AAEA,SAAO,yBAAyB,OAAO,MAAM,IAAI;AACnD;AAEA,SAAS,kBACP,OACA,MACA,MACqB;AACrB,MAAI,cAAc,KAAK,GAAG;AACxB,UAAM,SAA8C;AAAA,MAClD,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM;AAAA,QACN,GAAG,IAAI;AAAA,QACP;AAAA,MAAA;AAAA,IACF;AAGF,QAAI,MAAM,aAAa,MAAM;AAC3B,aAAO,WAAW;AAAA,IACpB;AAEA,WAAO;AAAA,EACT;AAEA,SAAO,uBAAuB,OAAO,MAAM,IAAI;AACjD;AAEA,SAAS,oBACP,SACA,MACA,MACqB;AACrB,SAAO;AAAA,IACL,YAAY;AAAA,MACV,QAAQ;AAAA,MACR,GAAG,IAAI;AAAA,MACP;AAAA,IAAA;AAAA,IAEF,gBAAgB;AAAA,MACd,QAAQ;AAAA,MACR,GAAG,IAAI;AAAA,MACP;AAAA,IAAA;AAAA,EACF;AAEJ;AAEA,SAAS,uBACP,YAKA,MACA,MACqB;AACrB,MAAI,WAAW,SAAS,OAAO;AAC7B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,WAAW,KAAK;AAAA,QAAI,CAAC,SAASF,WAClC,yBAAyB,SAAS,GAAG,IAAI,SAASA,MAAK,KAAK,IAAI;AAAA,MAAA;AAAA,IAClE;AAAA,EAEJ;AAEA,MAAI,WAAW,SAAS,OAAO;AAC7B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,yBAAyB,WAAW,OAAO,GAAG,IAAI,UAAU,IAAI;AAAA,IAAA;AAAA,EAE3E;AAEA,MAAI,WAAW,SAAS,QAAQ;AAC9B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,WAAW;AAAA,MACjB,MAAM,WAAW,KAAK;AAAA,QAAI,CAAC,KAAKA,WAC9B,uBAAuB,KAAK,GAAG,IAAI,SAASA,MAAK,KAAK,IAAI;AAAA,MAAA;AAAA,IAC5D;AAAA,EAEJ;AAEA,MAAI,WAAW,SAAS,OAAO;AAC7B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,WAAW;AAAA,MACjB,MAAM,WAAW,KAAK;AAAA,QAAI,CAAC,KAAKA,WAC9B,uBAAuB,KAAK,GAAG,IAAI,SAASA,MAAK,KAAK,IAAI;AAAA,MAAA;AAAA,IAC5D;AAAA,EAEJ;AAEA,MAAI,WAAW,SAAS,qBAAqB;AAC3C,UAAMG,UAA8C;AAAA,MAClD,MAAM;AAAA,MACN,UAAU,WAAW,SAAS,IAAI,CAAC,QAAQH,YAAW;AAAA,QACpD,WAAW;AAAA,UACT,OAAO;AAAA,UACP,GAAG,IAAI,aAAaA,MAAK;AAAA,UACzB;AAAA,QAAA;AAAA,QAEF,OAAO;AAAA,UACL,OAAO;AAAA,UACP,GAAG,IAAI,aAAaA,MAAK;AAAA,UACzB;AAAA,QAAA;AAAA,MACF,EACA;AAAA,IAAA;AAGJ,QAAI,WAAW,iBAAiB,QAAW;AACzCG,cAAO,eAAe;AAAA,QACpB,WAAW;AAAA,QACX,GAAG,IAAI;AAAA,QACP;AAAA,MAAA;AAAA,IAEJ;AAEA,WAAOA;AAAAA,EACT;AAEA,QAAM,SAA8C;AAAA,IAClD,MAAM;AAAA,IACN,OAAO,kBAAkB,WAAW,OAAO,GAAG,IAAI,UAAU,IAAI;AAAA,IAChE,kBAAkB;AAAA,MAChB,WAAW;AAAA,MACX,GAAG,IAAI;AAAA,MACP;AAAA,IAAA;AAAA,IAEF,uBAAuB;AAAA,MACrB,WAAW;AAAA,MACX,GAAG,IAAI;AAAA,MACP;AAAA,IAAA;AAAA,IAEF,WAAW,WAAW;AAAA,IACtB,iBAAiB,WAAW;AAAA,EAAA;AAG9B,MAAI,WAAW,eAAe;AAC5B,WAAO,gBAAgB,WAAW,cAAc;AAAA,MAAI,CAAC,OAAOH,WAC1D,kBAAkB,OAAO,GAAG,IAAI,kBAAkBA,MAAK,KAAK,IAAI;AAAA,IAAA;AAAA,EAEpE;AAEA,MAAI,WAAW,kBAAkB;AAC/B,WAAO,mBAAmB,WAAW,iBAAiB;AAAA,MACpD,CAAC,YAAYA,WACX;AAAA,QACE;AAAA,QACA,GAAG,IAAI,qBAAqBA,MAAK;AAAA,QACjC;AAAA,MAAA;AAAA,IACF;AAAA,EAEN;AAEA,MAAI,WAAW,gBAAgB,QAAW;AACxC,WAAO,cAAc,WAAW;AAAA,EAClC;AAEA,SAAO;AACT;AAEA,SAAS,yBACP,OACA,MACA,MACqB;AACrB,MAAI,UAAU,KAAM,QAAO,CAAC,MAAM;AAElC,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,CAAC,UAAU,KAAK;AAAA,EACzB;AAEA,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO,CAAC,WAAW,KAAK;AAAA,EAC1B;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,OAAO,MAAM,KAAK,GAAG;AACvB,aAAO,CAAC,UAAU,KAAK;AAAA,IACzB;AAEA,QAAI,UAAU,UAAU;AACtB,aAAO,CAAC,UAAU,UAAU;AAAA,IAC9B;AAEA,QAAI,UAAU,WAAW;AACvB,aAAO,CAAC,UAAU,WAAW;AAAA,IAC/B;AAEA,QAAI,OAAO,GAAG,OAAO,EAAE,GAAG;AACxB,aAAO,CAAC,UAAU,IAAI;AAAA,IACxB;AAEA,WAAO,CAAC,UAAU,KAAK;AAAA,EACzB;AAEA,MAAI,OAAO,UAAU,aAAa;AAChC,WAAO,CAAC,WAAW;AAAA,EACrB;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,CAAC,UAAU,MAAM,SAAA,CAAU;AAAA,EACpC;AAEA,MAAI,OAAO,UAAU,YAAY;AAC/B,UAAM,IAAI,uBAAuB,MAAM,gBAAgB;AAAA,EACzD;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,uBAAuB,MAAM,cAAc;AAAA,EACvD;AAEA,MAAIC,SAAAA,WAAW,KAAK,GAAG;AACrB,WAAO,uBAAuBC,SAAAA,aAAa,KAAK,GAAG,MAAM,IAAI;AAAA,EAC/D;AAEA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,kBAAkB,OAAO,MAAM,MAAM,MAAM;AAAA,MAChD;AAAA,MACA,MAAM;AAAA,QAAI,CAAC,MAAMF,WACf,yBAAyB,MAAM,GAAG,IAAI,IAAIA,MAAK,KAAK,IAAI;AAAA,MAAA;AAAA,IAC1D,CACD;AAAA,EACH;AAEA,MAAI,iBAAiB,MAAM;AACzB,UAAM,YAAY,MAAM,QAAA;AACxB,QAAI,OAAO,MAAM,SAAS,GAAG;AAC3B,YAAM,IAAI,uBAAuB,MAAM,cAAc;AAAA,IACvD;AAEA,WAAO,CAAC,QAAQ,MAAM,YAAA,CAAa;AAAA,EACrC;AAEA,MAAI,iBAAiB,aAAa;AAChC,WAAO,CAAC,UAAU,eAAe,MAAM,KAAK,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA,EACpE;AAEA,MAAI,YAAY,OAAO,KAAK,GAAG;AAC7B,WAAO;AAAA,MACL;AAAA,MACA,MAAM,YAAY;AAAA,MAClB,MAAM;AAAA,QACJ,IAAI,WAAW,MAAM,QAAQ,MAAM,YAAY,MAAM,UAAU;AAAA,MAAA;AAAA,IACjE;AAAA,EAEJ;AAEA,MAAI,iBAAiB,KAAK;AACxB,WAAO,kBAAkB,OAAO,MAAM,MAAM,MAAM;AAChD,YAAM,UAAU,MAAM;AAAA,QACpB,MAAM,QAAA;AAAA,QACN,CAAC,CAAC,KAAK,UAAU,GAAGA,WAAU;AAAA,UAC5B,yBAAyB,KAAK,GAAG,IAAI,QAAQA,MAAK,KAAK,IAAI;AAAA,UAC3D,yBAAyB,YAAY,GAAG,IAAI,UAAUA,MAAK,KAAK,IAAI;AAAA,QAAA;AAAA,MACtE;AAEF,cAAQ,KAAK,2BAA2B;AACxC,aAAO,CAAC,OAAO,OAAO;AAAA,IACxB,CAAC;AAAA,EACH;AAEA,MAAI,iBAAiB,KAAK;AACxB,WAAO,kBAAkB,OAAO,MAAM,MAAM,MAAM;AAChD,YAAM,UAAU,MAAM;AAAA,QAAK;AAAA,QAAO,CAAC,OAAOA,WACxC,yBAAyB,OAAO,GAAG,IAAI,IAAIA,MAAK,KAAK,IAAI;AAAA,MAAA;AAE3D,cAAQ,KAAK,2BAA2B;AACxC,aAAO,CAAC,OAAO,OAAO;AAAA,IACxB,CAAC;AAAA,EACH;AAEA,MAAI,cAAc,KAAK,GAAG;AACxB,WAAO,mBAAmB,OAAO,MAAM,IAAI;AAAA,EAC7C;AAEA,QAAM,IAAI,uBAAuB,MAAM,wBAAwB;AACjE;AAEA,SAAS,4BACP,MACA,OACQ;AACR,QAAM,iBAAiB,KAAK,UAAU,IAAI;AAC1C,QAAM,kBAAkB,KAAK,UAAU,KAAK;AAC5C,SAAO,iBAAiB,kBACpB,KACA,iBAAiB,kBACf,IACA;AACR;AAEA,SAAS,mBACP,OACA,MACA,MACqB;AACrB,SAAO,kBAAkB,OAAO,MAAM,MAAM,MAAM;AAAA,IAChD;AAAA,IACA,OAAO,KAAK,KAAK,EACd,OACA,IAAI,CAAC,QAAQ;AAAA,MACZ;AAAA,MACA,yBAAyB,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI;AAAA,IAAA,CAC5D;AAAA,EAAA,CACJ;AACH;AAEA,SAAS,kBACP,OACA,MACA,MACA,UACG;AACH,MAAI,KAAK,IAAI,KAAK,GAAG;AACnB,UAAM,IAAI,uBAAuB,MAAM,gBAAgB;AAAA,EACzD;AAEA,OAAK,IAAI,KAAK;AACd,MAAI;AACF,WAAO,SAAA;AAAA,EACT,UAAA;AACE,SAAK,OAAO,KAAK;AAAA,EACnB;AACF;AAEA,SAAS,cACP,OACuE;AACvE,SAAO,gBAAgB;AACzB;AAEA,SAAS,aACP,OACyD;AACzD,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,WAAO;AAAA,EACT;AAEA,QAAM,iBAAkB,MAA6B;AACrD,SACE,mBAAmB,SACnB,mBAAmB,uBACnB,mBAAmB,UACnB,mBAAmB,SACnB,mBAAmB,SACnB,mBAAmB;AAEvB;AAEA,SAAS,cAAc,OAAkD;AACvE,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AAExD,QAAM,YAAY,OAAO,eAAe,KAAK;AAC7C,SAAO,cAAc,OAAO,aAAa,cAAc;AACzD;;;;;;"}