@telorun/cel 0.0.0-stage → 0.108.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +281 -2
  3. package/dist/activation.d.ts +27 -0
  4. package/dist/activation.d.ts.map +1 -0
  5. package/dist/activation.js +24 -0
  6. package/dist/backend-runtime.d.ts +184 -0
  7. package/dist/backend-runtime.d.ts.map +1 -0
  8. package/dist/backend-runtime.js +425 -0
  9. package/dist/bounded-cache.d.ts +21 -0
  10. package/dist/bounded-cache.d.ts.map +1 -0
  11. package/dist/bounded-cache.js +42 -0
  12. package/dist/catalog-runtime.d.ts +59 -0
  13. package/dist/catalog-runtime.d.ts.map +1 -0
  14. package/dist/catalog-runtime.js +786 -0
  15. package/dist/cel-expression.d.ts +32 -0
  16. package/dist/cel-expression.d.ts.map +1 -0
  17. package/dist/cel-expression.js +29 -0
  18. package/dist/cel-map-value.d.ts +47 -0
  19. package/dist/cel-map-value.d.ts.map +1 -0
  20. package/dist/cel-map-value.js +85 -0
  21. package/dist/cel-program.d.ts +44 -0
  22. package/dist/cel-program.d.ts.map +1 -0
  23. package/dist/cel-program.js +72 -0
  24. package/dist/cel-type.d.ts +131 -0
  25. package/dist/cel-type.d.ts.map +1 -0
  26. package/dist/cel-type.js +293 -0
  27. package/dist/cel-value.d.ts +166 -0
  28. package/dist/cel-value.d.ts.map +1 -0
  29. package/dist/cel-value.js +225 -0
  30. package/dist/check-diagnostic.d.ts +54 -0
  31. package/dist/check-diagnostic.d.ts.map +1 -0
  32. package/dist/check-diagnostic.js +66 -0
  33. package/dist/checker.d.ts +86 -0
  34. package/dist/checker.d.ts.map +1 -0
  35. package/dist/checker.js +806 -0
  36. package/dist/closure-backend.d.ts +21 -0
  37. package/dist/closure-backend.d.ts.map +1 -0
  38. package/dist/closure-backend.js +487 -0
  39. package/dist/comprehension-bindings.d.ts +33 -0
  40. package/dist/comprehension-bindings.d.ts.map +1 -0
  41. package/dist/comprehension-bindings.js +50 -0
  42. package/dist/comprehension-runtime.d.ts +44 -0
  43. package/dist/comprehension-runtime.d.ts.map +1 -0
  44. package/dist/comprehension-runtime.js +137 -0
  45. package/dist/declared-chain.d.ts +35 -0
  46. package/dist/declared-chain.d.ts.map +1 -0
  47. package/dist/declared-chain.js +36 -0
  48. package/dist/duration-value.d.ts +70 -0
  49. package/dist/duration-value.d.ts.map +1 -0
  50. package/dist/duration-value.js +149 -0
  51. package/dist/emitted-module.d.ts +207 -0
  52. package/dist/emitted-module.d.ts.map +1 -0
  53. package/dist/emitted-module.js +359 -0
  54. package/dist/engine-version.d.ts +3 -0
  55. package/dist/engine-version.d.ts.map +1 -0
  56. package/dist/engine-version.js +8 -0
  57. package/dist/environment-digest.d.ts +44 -0
  58. package/dist/environment-digest.d.ts.map +1 -0
  59. package/dist/environment-digest.js +98 -0
  60. package/dist/environment.d.ts +291 -0
  61. package/dist/environment.d.ts.map +1 -0
  62. package/dist/environment.js +474 -0
  63. package/dist/function-catalog.d.ts +66 -0
  64. package/dist/function-catalog.d.ts.map +1 -0
  65. package/dist/function-catalog.js +77 -0
  66. package/dist/function-registry.d.ts +118 -0
  67. package/dist/function-registry.d.ts.map +1 -0
  68. package/dist/function-registry.js +292 -0
  69. package/dist/index.d.ts +93 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +65 -0
  72. package/dist/integer-arithmetic.d.ts +27 -0
  73. package/dist/integer-arithmetic.d.ts.map +1 -0
  74. package/dist/integer-arithmetic.js +58 -0
  75. package/dist/js-emitter.d.ts +133 -0
  76. package/dist/js-emitter.d.ts.map +1 -0
  77. package/dist/js-emitter.js +568 -0
  78. package/dist/json-schema-type.d.ts +182 -0
  79. package/dist/json-schema-type.d.ts.map +1 -0
  80. package/dist/json-schema-type.js +487 -0
  81. package/dist/json-text-scan.d.ts +28 -0
  82. package/dist/json-text-scan.d.ts.map +1 -0
  83. package/dist/json-text-scan.js +159 -0
  84. package/dist/lexer.d.ts +103 -0
  85. package/dist/lexer.d.ts.map +1 -0
  86. package/dist/lexer.js +458 -0
  87. package/dist/macro-check.d.ts +41 -0
  88. package/dist/macro-check.d.ts.map +1 -0
  89. package/dist/macro-check.js +162 -0
  90. package/dist/macro-shape.d.ts +24 -0
  91. package/dist/macro-shape.d.ts.map +1 -0
  92. package/dist/macro-shape.js +55 -0
  93. package/dist/member-read.d.ts +89 -0
  94. package/dist/member-read.d.ts.map +1 -0
  95. package/dist/member-read.js +166 -0
  96. package/dist/namespace-resolution.d.ts +35 -0
  97. package/dist/namespace-resolution.d.ts.map +1 -0
  98. package/dist/namespace-resolution.js +160 -0
  99. package/dist/nominal-type.d.ts +63 -0
  100. package/dist/nominal-type.d.ts.map +1 -0
  101. package/dist/nominal-type.js +98 -0
  102. package/dist/nullable-access.d.ts +38 -0
  103. package/dist/nullable-access.d.ts.map +1 -0
  104. package/dist/nullable-access.js +93 -0
  105. package/dist/parse-limits.d.ts +26 -0
  106. package/dist/parse-limits.d.ts.map +1 -0
  107. package/dist/parse-limits.js +21 -0
  108. package/dist/parser.d.ts +48 -0
  109. package/dist/parser.d.ts.map +1 -0
  110. package/dist/parser.js +503 -0
  111. package/dist/qualified-calls.d.ts +22 -0
  112. package/dist/qualified-calls.d.ts.map +1 -0
  113. package/dist/qualified-calls.js +27 -0
  114. package/dist/regular-expression.d.ts +48 -0
  115. package/dist/regular-expression.d.ts.map +1 -0
  116. package/dist/regular-expression.js +77 -0
  117. package/dist/reserved-words.d.ts +52 -0
  118. package/dist/reserved-words.d.ts.map +1 -0
  119. package/dist/reserved-words.js +77 -0
  120. package/dist/resolved-call.d.ts +46 -0
  121. package/dist/resolved-call.d.ts.map +1 -0
  122. package/dist/resolved-call.js +15 -0
  123. package/dist/root-references.d.ts +23 -0
  124. package/dist/root-references.d.ts.map +1 -0
  125. package/dist/root-references.js +120 -0
  126. package/dist/runtime-library.d.ts +67 -0
  127. package/dist/runtime-library.d.ts.map +1 -0
  128. package/dist/runtime-library.js +554 -0
  129. package/dist/serializer.d.ts +24 -0
  130. package/dist/serializer.d.ts.map +1 -0
  131. package/dist/serializer.js +256 -0
  132. package/dist/sha256.d.ts +20 -0
  133. package/dist/sha256.d.ts.map +1 -0
  134. package/dist/sha256.js +103 -0
  135. package/dist/signature.d.ts +72 -0
  136. package/dist/signature.d.ts.map +1 -0
  137. package/dist/signature.js +61 -0
  138. package/dist/signatures/function-catalog.json +788 -0
  139. package/dist/signatures/standard-library.json +229 -0
  140. package/dist/standard-library.d.ts +41 -0
  141. package/dist/standard-library.d.ts.map +1 -0
  142. package/dist/standard-library.js +85 -0
  143. package/dist/syntax-diagnostic.d.ts +61 -0
  144. package/dist/syntax-diagnostic.d.ts.map +1 -0
  145. package/dist/syntax-diagnostic.js +28 -0
  146. package/dist/syntax-tree.d.ts +160 -0
  147. package/dist/syntax-tree.d.ts.map +1 -0
  148. package/dist/syntax-tree.js +58 -0
  149. package/dist/timestamp-value.d.ts +62 -0
  150. package/dist/timestamp-value.d.ts.map +1 -0
  151. package/dist/timestamp-value.js +238 -0
  152. package/dist/tree-equality.d.ts +15 -0
  153. package/dist/tree-equality.d.ts.map +1 -0
  154. package/dist/tree-equality.js +105 -0
  155. package/dist/type-expression.d.ts +42 -0
  156. package/dist/type-expression.d.ts.map +1 -0
  157. package/dist/type-expression.js +154 -0
  158. package/dist/value-equality.d.ts +38 -0
  159. package/dist/value-equality.d.ts.map +1 -0
  160. package/dist/value-equality.js +196 -0
  161. package/dist/value-text.d.ts +25 -0
  162. package/dist/value-text.d.ts.map +1 -0
  163. package/dist/value-text.js +44 -0
  164. package/dist/zoned-calendar.d.ts +61 -0
  165. package/dist/zoned-calendar.d.ts.map +1 -0
  166. package/dist/zoned-calendar.js +143 -0
  167. package/package.json +56 -3
  168. package/src/activation.ts +32 -0
  169. package/src/backend-runtime.ts +604 -0
  170. package/src/bounded-cache.ts +45 -0
  171. package/src/catalog-runtime.ts +921 -0
  172. package/src/cel-expression.ts +53 -0
  173. package/src/cel-map-value.ts +97 -0
  174. package/src/cel-program.ts +103 -0
  175. package/src/cel-type.ts +359 -0
  176. package/src/cel-value.ts +361 -0
  177. package/src/check-diagnostic.ts +104 -0
  178. package/src/checker.ts +1045 -0
  179. package/src/closure-backend.ts +547 -0
  180. package/src/comprehension-bindings.ts +66 -0
  181. package/src/comprehension-runtime.ts +157 -0
  182. package/src/declared-chain.ts +45 -0
  183. package/src/duration-value.ts +160 -0
  184. package/src/emitted-module.ts +494 -0
  185. package/src/engine-version.ts +9 -0
  186. package/src/environment-digest.ts +111 -0
  187. package/src/environment.ts +761 -0
  188. package/src/function-catalog.ts +140 -0
  189. package/src/function-registry.ts +341 -0
  190. package/src/index.ts +407 -0
  191. package/src/integer-arithmetic.ts +64 -0
  192. package/src/js-emitter.ts +721 -0
  193. package/src/json-schema-type.ts +664 -0
  194. package/src/json-text-scan.ts +163 -0
  195. package/src/lexer.ts +562 -0
  196. package/src/macro-check.ts +197 -0
  197. package/src/macro-shape.ts +66 -0
  198. package/src/member-read.ts +167 -0
  199. package/src/namespace-resolution.ts +167 -0
  200. package/src/nominal-type.ts +149 -0
  201. package/src/nullable-access.ts +95 -0
  202. package/src/parse-limits.ts +36 -0
  203. package/src/parser.ts +554 -0
  204. package/src/qualified-calls.ts +39 -0
  205. package/src/regular-expression.ts +101 -0
  206. package/src/reserved-words.ts +94 -0
  207. package/src/resolved-call.ts +47 -0
  208. package/src/root-references.ts +126 -0
  209. package/src/runtime-library.ts +639 -0
  210. package/src/serializer.ts +262 -0
  211. package/src/sha256.ts +112 -0
  212. package/src/signature.ts +127 -0
  213. package/src/signatures/function-catalog.json +788 -0
  214. package/src/signatures/standard-library.json +235 -0
  215. package/src/standard-library.ts +149 -0
  216. package/src/syntax-diagnostic.ts +72 -0
  217. package/src/syntax-tree.ts +229 -0
  218. package/src/timestamp-value.ts +310 -0
  219. package/src/tree-equality.ts +130 -0
  220. package/src/type-expression.ts +182 -0
  221. package/src/value-equality.ts +201 -0
  222. package/src/value-text.ts +45 -0
  223. package/src/zoned-calendar.ts +178 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Whether each macro call is shaped like one at all, judged before any type is read.
3
+ *
4
+ * A macro's own arguments are not values: `xs.map(i, …)` declares the name `i`, and
5
+ * `has(a.b)` asks about the member `b` of a chain of names. Neither is something a type
6
+ * can be wrong about — they are either written in the shape the macro takes, or the call
7
+ * is not that macro. So this is a **structural** pass over the whole tree, and it runs
8
+ * first: a macro written wrongly is reported before anything inside it is typed, because
9
+ * the typing of its body depends on a name the call failed to declare.
10
+ *
11
+ * The walk is **post-order**, so the innermost mistake is the one reported first. Nesting
12
+ * macros is how a generated expression goes wrong, and the inner call is the one a reader
13
+ * has to fix.
14
+ */
15
+ import type { CelCheckCode } from "./check-diagnostic.js";
16
+ import type { CelNode, SourceRange } from "./syntax-tree.js";
17
+ export interface MacroShapeFinding {
18
+ readonly code: CelCheckCode;
19
+ readonly message: string;
20
+ readonly range: SourceRange;
21
+ }
22
+ /** Every macro call whose own arguments are not the shape it takes, innermost first. */
23
+ export declare function macroShapeFindings(root: CelNode): readonly MacroShapeFinding[];
24
+ //# sourceMappingURL=macro-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macro-shape.d.ts","sourceRoot":"","sources":["../src/macro-shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG7D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,iBAAiB,EAAE,CAI9E"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Whether each macro call is shaped like one at all, judged before any type is read.
3
+ *
4
+ * A macro's own arguments are not values: `xs.map(i, …)` declares the name `i`, and
5
+ * `has(a.b)` asks about the member `b` of a chain of names. Neither is something a type
6
+ * can be wrong about — they are either written in the shape the macro takes, or the call
7
+ * is not that macro. So this is a **structural** pass over the whole tree, and it runs
8
+ * first: a macro written wrongly is reported before anything inside it is typed, because
9
+ * the typing of its body depends on a name the call failed to declare.
10
+ *
11
+ * The walk is **post-order**, so the innermost mistake is the one reported first. Nesting
12
+ * macros is how a generated expression goes wrong, and the inner call is the one a reader
13
+ * has to fix.
14
+ */
15
+ import { namespaceMacroBinding, receiverMacroBinding } from "./comprehension-bindings.js";
16
+ import { childNodes } from "./syntax-tree.js";
17
+ /** Every macro call whose own arguments are not the shape it takes, innermost first. */
18
+ export function macroShapeFindings(root) {
19
+ const findings = [];
20
+ collect(root, findings);
21
+ return findings;
22
+ }
23
+ function collect(node, findings) {
24
+ for (const child of childNodes(node))
25
+ collect(child, findings);
26
+ const finding = shapeOf(node);
27
+ if (finding)
28
+ findings.push(finding);
29
+ }
30
+ function shapeOf(node) {
31
+ if (node.kind === "call" && node.name === "has" && node.args.length === 1) {
32
+ const argument = node.args[0];
33
+ if (argument.kind === "select" && argument.field !== "")
34
+ return undefined;
35
+ return {
36
+ code: "CEL_INVALID_ARGUMENT",
37
+ message: "has() asks whether a member is there, so it takes a member read: write has(a.b)",
38
+ range: argument.range,
39
+ };
40
+ }
41
+ if (node.kind !== "receiverCall")
42
+ return undefined;
43
+ const binding = receiverMacroBinding(node.name, node.args.length) ??
44
+ namespaceMacroBinding(node.receiver.kind === "ident" ? node.receiver.name : "", node.name, node.args.length);
45
+ if (!binding)
46
+ return undefined;
47
+ const variable = node.args[binding.variableArgument];
48
+ if (variable.kind === "ident")
49
+ return undefined;
50
+ return {
51
+ code: "CEL_INVALID_ARGUMENT",
52
+ message: `${node.name} binds a name here, and this is not a name`,
53
+ range: variable.range,
54
+ };
55
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * The member-read seam: **one** lookup, for every form a read is written in.
3
+ *
4
+ * `a.b`, `a['b']`, `a[expr]`, `a.?b`, `a[?expr]`, a macro's field read and the presence
5
+ * question `has()` all resolve here, through a single lookup over the value's **own**
6
+ * entries. Neither backend ever performs a host property read, so no key — however it
7
+ * was computed — can reach a prototype, a method or a function property: `a['length']`
8
+ * on a map is a missing key, not `0`, and `a[request.query.k]` cannot reach
9
+ * `constructor`.
10
+ *
11
+ * That is why the reserved-word set holds CEL's own words and nothing else. A word list
12
+ * is the wrong instrument: a member *name* is written by the author, while a member
13
+ * *key* can come from a request, so no list at any position touches the form an
14
+ * attacker can actually reach — and refusing `__proto__` as a name would make a
15
+ * resource that may legally be called that unreadable through CEL.
16
+ *
17
+ * A key the value does not hold is the `no_such_key` **error value**, which
18
+ * participates in short-circuit. Never `undefined` passed along.
19
+ *
20
+ * **What each of the four verdicts answers is written once here**, in `lookupAbsence`,
21
+ * and read by both presence callers — so the closure backend, the emitter and the
22
+ * `has()` macro cannot differ by construction.
23
+ */
24
+ import type { CelValue } from "./cel-value.js";
25
+ import { type CelError } from "./cel-value.js";
26
+ import type { SourceRange } from "./syntax-tree.js";
27
+ /**
28
+ * What one lookup found. The four refusals are **symbols**, not objects: a lookup happens
29
+ * on nearly every evaluation, and a wrapper object per read is an allocation per read.
30
+ * `MISSING` is a key the container does not hold — which `has()` answers `false` for and a
31
+ * read turns into `no_such_key`; the other three are mistakes in the read itself.
32
+ */
33
+ export declare const MISSING: unique symbol;
34
+ export declare const OUT_OF_RANGE: unique symbol;
35
+ export declare const UNSUPPORTED_CONTAINER: unique symbol;
36
+ export declare const UNSUPPORTED_KEY: unique symbol;
37
+ export type Lookup = CelValue | typeof MISSING | typeof OUT_OF_RANGE | typeof UNSUPPORTED_CONTAINER | typeof UNSUPPORTED_KEY;
38
+ /**
39
+ * The single lookup. It is total over the value domain: a container that holds no members
40
+ * at all answers `UNSUPPORTED_CONTAINER` rather than falling back to a property read that
41
+ * might find `length`, `name`, `call` or `apply`.
42
+ */
43
+ export declare function celLookup(container: CelValue, key: CelValue): Lookup;
44
+ /** The value at a key, or the error a failed lookup is. */
45
+ export declare function celRead(container: CelValue, key: CelValue, range?: SourceRange): CelValue | CelError;
46
+ /**
47
+ * Whether a lookup that found nothing answers **absence** rather than an error. This is
48
+ * the seam's contract, in the one place both backends and the emitter read it: they all
49
+ * reach a member read through `backend-runtime.ts`, which reaches the four verdicts
50
+ * through here.
51
+ *
52
+ * - A **presence-shaped** read — `a.?b`, `a[?k]` and `has(a.b)` — answers absence for
53
+ * *missing*, *out of range* and *holds no members* alike, and the error only for an
54
+ * **unusable key**. It asks whether a member is THERE, and a value that cannot hold one
55
+ * has none to find. The authority is the optional library's own: it enters this engine
56
+ * from cel-go whole, and cel-go's attribute qualification answers "not found" for a
57
+ * receiver that is neither a mapper, a lister nor an indexer **whenever the read is a
58
+ * presence test**, erroring only otherwise — the error reading being an explicitly named
59
+ * opt-in (`EnableErrorOnBadPresenceTest`), which Telo does not carry, because a
60
+ * per-environment switch over what an expression MEANS would let the analyzer and a
61
+ * kernel disagree about one manifest.
62
+ * - A read **through a present optional, written in the ordinary form** — the `.c` of
63
+ * `a.?b.c` — is not a presence question about `c`. It answers absence for a key the held
64
+ * value does not hold (`optional.of({'c': {}}).c.missing` is absent, cel-spec's
65
+ * `optional_chaining_5`) and the error for a held value that holds no members at all
66
+ * (`{true: dyn(0)}[?true].absent` is cel-spec's error).
67
+ * - A **plain** read never asks: each of the four is the error `lookupError` words.
68
+ *
69
+ * An unusable key is the one refusal no form forgives: `[?3.1]` names an entry no
70
+ * container of that shape could hold, so it is a mistake in the READ rather than a member
71
+ * that happens to be absent.
72
+ */
73
+ export declare function lookupAbsence(found: symbol, presence: boolean): boolean;
74
+ /** The error a refused lookup is. */
75
+ export declare function lookupError(found: symbol, key: CelValue, range?: SourceRange): CelError;
76
+ /**
77
+ * Whether a key is there — `has(a.b)`. The question is presence-shaped, so a value that
78
+ * holds no members answers `false` exactly as a missing key does: it has no member to
79
+ * find. Only an unusable key is a mistake in the question itself.
80
+ */
81
+ export declare function celHas(container: CelValue, key: CelValue, range?: SourceRange): boolean | CelError;
82
+ /**
83
+ * The elements a comprehension ranges over: a list's items, a map's keys. A list is handed
84
+ * over as it is — nothing in CEL mutates a value, and every comprehension reads its range —
85
+ * so copying it would cost the length of the list per comprehension to defend against a
86
+ * write no expression can perform.
87
+ */
88
+ export declare function celIterable(container: CelValue, range?: SourceRange): readonly CelValue[] | CelError;
89
+ //# sourceMappingURL=member-read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member-read.d.ts","sourceRoot":"","sources":["../src/member-read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAA8C,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,OAAO,eAA+B,CAAC;AACpD,eAAO,MAAM,YAAY,eAAkC,CAAC;AAC5D,eAAO,MAAM,qBAAqB,eAA4C,CAAC;AAC/E,eAAO,MAAM,eAAe,eAAsC,CAAC;AAEnE,MAAM,MAAM,MAAM,GACd,QAAQ,GACR,OAAO,OAAO,GACd,OAAO,YAAY,GACnB,OAAO,qBAAqB,GAC5B,OAAO,eAAe,CAAC;AAY3B;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,GAAG,MAAM,CAqBpE;AAED,2DAA2D;AAC3D,wBAAgB,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAIpG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAGvE;AAED,qCAAqC;AACrC,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,QAAQ,CASvF;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,QAAQ,CAKlG;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,QAAQ,EAAE,GAAG,QAAQ,CAKpG"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * The member-read seam: **one** lookup, for every form a read is written in.
3
+ *
4
+ * `a.b`, `a['b']`, `a[expr]`, `a.?b`, `a[?expr]`, a macro's field read and the presence
5
+ * question `has()` all resolve here, through a single lookup over the value's **own**
6
+ * entries. Neither backend ever performs a host property read, so no key — however it
7
+ * was computed — can reach a prototype, a method or a function property: `a['length']`
8
+ * on a map is a missing key, not `0`, and `a[request.query.k]` cannot reach
9
+ * `constructor`.
10
+ *
11
+ * That is why the reserved-word set holds CEL's own words and nothing else. A word list
12
+ * is the wrong instrument: a member *name* is written by the author, while a member
13
+ * *key* can come from a request, so no list at any position touches the form an
14
+ * attacker can actually reach — and refusing `__proto__` as a name would make a
15
+ * resource that may legally be called that unreadable through CEL.
16
+ *
17
+ * A key the value does not hold is the `no_such_key` **error value**, which
18
+ * participates in short-circuit. Never `undefined` passed along.
19
+ *
20
+ * **What each of the four verdicts answers is written once here**, in `lookupAbsence`,
21
+ * and read by both presence callers — so the closure backend, the emitter and the
22
+ * `has()` macro cannot differ by construction.
23
+ */
24
+ import { celMapKeys, mapKeyIdentity } from "./cel-map-value.js";
25
+ import { celError, isCelMap, isCelRecord, isCelUint } from "./cel-value.js";
26
+ /**
27
+ * What one lookup found. The four refusals are **symbols**, not objects: a lookup happens
28
+ * on nearly every evaluation, and a wrapper object per read is an allocation per read.
29
+ * `MISSING` is a key the container does not hold — which `has()` answers `false` for and a
30
+ * read turns into `no_such_key`; the other three are mistakes in the read itself.
31
+ */
32
+ export const MISSING = Symbol("cel.lookup.missing");
33
+ export const OUT_OF_RANGE = Symbol("cel.lookup.outOfRange");
34
+ export const UNSUPPORTED_CONTAINER = Symbol("cel.lookup.unsupportedContainer");
35
+ export const UNSUPPORTED_KEY = Symbol("cel.lookup.unsupportedKey");
36
+ /** An int-valued index, or nothing when the value is of no index type. */
37
+ function indexOf(key) {
38
+ if (typeof key === "bigint")
39
+ return key;
40
+ if (isCelUint(key))
41
+ return key.value;
42
+ // A double that holds a whole number indexes a list: a `dyn` arithmetic result is a
43
+ // double, and cel-spec indexes with it where it is integral.
44
+ if (typeof key === "number" && Number.isInteger(key))
45
+ return BigInt(key);
46
+ return undefined;
47
+ }
48
+ /**
49
+ * The single lookup. It is total over the value domain: a container that holds no members
50
+ * at all answers `UNSUPPORTED_CONTAINER` rather than falling back to a property read that
51
+ * might find `length`, `name`, `call` or `apply`.
52
+ */
53
+ export function celLookup(container, key) {
54
+ if (typeof key === "string" && isCelRecord(container)) {
55
+ // An OWN entry, never an inherited one: a host's object is data here.
56
+ return Object.prototype.hasOwnProperty.call(container, key)
57
+ ? container[key]
58
+ : MISSING;
59
+ }
60
+ if (isCelMap(container)) {
61
+ const identity = mapKeyIdentity(key);
62
+ if (identity === undefined)
63
+ return UNSUPPORTED_KEY;
64
+ const entry = container.entries.get(identity);
65
+ return entry ? entry.value : MISSING;
66
+ }
67
+ if (Array.isArray(container)) {
68
+ const at = indexOf(key);
69
+ if (at === undefined)
70
+ return UNSUPPORTED_KEY;
71
+ if (at < 0n || at >= BigInt(container.length))
72
+ return OUT_OF_RANGE;
73
+ return container[Number(at)];
74
+ }
75
+ if (isCelRecord(container))
76
+ return UNSUPPORTED_KEY;
77
+ return UNSUPPORTED_CONTAINER;
78
+ }
79
+ /** The value at a key, or the error a failed lookup is. */
80
+ export function celRead(container, key, range) {
81
+ const found = celLookup(container, key);
82
+ if (typeof found !== "symbol")
83
+ return found;
84
+ return lookupError(found, key, range);
85
+ }
86
+ /**
87
+ * Whether a lookup that found nothing answers **absence** rather than an error. This is
88
+ * the seam's contract, in the one place both backends and the emitter read it: they all
89
+ * reach a member read through `backend-runtime.ts`, which reaches the four verdicts
90
+ * through here.
91
+ *
92
+ * - A **presence-shaped** read — `a.?b`, `a[?k]` and `has(a.b)` — answers absence for
93
+ * *missing*, *out of range* and *holds no members* alike, and the error only for an
94
+ * **unusable key**. It asks whether a member is THERE, and a value that cannot hold one
95
+ * has none to find. The authority is the optional library's own: it enters this engine
96
+ * from cel-go whole, and cel-go's attribute qualification answers "not found" for a
97
+ * receiver that is neither a mapper, a lister nor an indexer **whenever the read is a
98
+ * presence test**, erroring only otherwise — the error reading being an explicitly named
99
+ * opt-in (`EnableErrorOnBadPresenceTest`), which Telo does not carry, because a
100
+ * per-environment switch over what an expression MEANS would let the analyzer and a
101
+ * kernel disagree about one manifest.
102
+ * - A read **through a present optional, written in the ordinary form** — the `.c` of
103
+ * `a.?b.c` — is not a presence question about `c`. It answers absence for a key the held
104
+ * value does not hold (`optional.of({'c': {}}).c.missing` is absent, cel-spec's
105
+ * `optional_chaining_5`) and the error for a held value that holds no members at all
106
+ * (`{true: dyn(0)}[?true].absent` is cel-spec's error).
107
+ * - A **plain** read never asks: each of the four is the error `lookupError` words.
108
+ *
109
+ * An unusable key is the one refusal no form forgives: `[?3.1]` names an entry no
110
+ * container of that shape could hold, so it is a mistake in the READ rather than a member
111
+ * that happens to be absent.
112
+ */
113
+ export function lookupAbsence(found, presence) {
114
+ if (found === MISSING || found === OUT_OF_RANGE)
115
+ return true;
116
+ return presence && found === UNSUPPORTED_CONTAINER;
117
+ }
118
+ /** The error a refused lookup is. */
119
+ export function lookupError(found, key, range) {
120
+ if (found === MISSING)
121
+ return celError("no_such_key", `no such key: ${describe(key)}`, range);
122
+ if (found === OUT_OF_RANGE) {
123
+ return celError("index_out_of_range", `index out of range: ${describe(key)}`, range);
124
+ }
125
+ if (found === UNSUPPORTED_KEY) {
126
+ return celError("unsupported_key_type", `${describe(key)} cannot name an entry of this value`, range);
127
+ }
128
+ return celError("unsupported_container", "this value holds no members", range);
129
+ }
130
+ /**
131
+ * Whether a key is there — `has(a.b)`. The question is presence-shaped, so a value that
132
+ * holds no members answers `false` exactly as a missing key does: it has no member to
133
+ * find. Only an unusable key is a mistake in the question itself.
134
+ */
135
+ export function celHas(container, key, range) {
136
+ const found = celLookup(container, key);
137
+ if (typeof found !== "symbol")
138
+ return true;
139
+ if (lookupAbsence(found, true))
140
+ return false;
141
+ return lookupError(found, key, range);
142
+ }
143
+ /**
144
+ * The elements a comprehension ranges over: a list's items, a map's keys. A list is handed
145
+ * over as it is — nothing in CEL mutates a value, and every comprehension reads its range —
146
+ * so copying it would cost the length of the list per comprehension to defend against a
147
+ * write no expression can perform.
148
+ */
149
+ export function celIterable(container, range) {
150
+ if (Array.isArray(container))
151
+ return container;
152
+ if (isCelMap(container))
153
+ return celMapKeys(container);
154
+ if (isCelRecord(container))
155
+ return Object.keys(container);
156
+ return celError("unsupported_container", "a comprehension reads a list or a map", range);
157
+ }
158
+ function describe(key) {
159
+ if (typeof key === "string")
160
+ return JSON.stringify(key);
161
+ if (isCelUint(key))
162
+ return `${key.value}`;
163
+ if (typeof key === "bigint")
164
+ return `${key}`;
165
+ return String(key);
166
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Turning `Alias.fn(x)` into a qualified call.
3
+ *
4
+ * `Alias.fn(x)` and `obj.method(x)` are **the same syntax** — a call written on a
5
+ * receiver — so no parser can tell them apart, and only a set of names that denote
6
+ * namespaces rather than values can. That set comes from the host, which is why
7
+ * this is a separate total tree-to-tree pass rather than a parser rule: the parser
8
+ * has one input and this has two.
9
+ *
10
+ * The pass is total — it visits every node and rewrites every receiver call whose
11
+ * receiver is a bare identifier in the set, wherever it sits. It is also the only
12
+ * producer of `qcall`, and `cel` and `optional` can never be in the set, because
13
+ * the standard macros are written on them (`cel.bind(…)`, `optional.of(…)`) and a
14
+ * namespace would capture those calls instead.
15
+ *
16
+ * A resolved tree records the set it was resolved under, so a consumer given a tree
17
+ * can tell whether it was resolved under the set it is about to check it against —
18
+ * the alternative is a tree that looks resolved and silently is not.
19
+ */
20
+ import type { CelNode } from "./syntax-tree.js";
21
+ /** Names that can never be registered as a namespace. */
22
+ export declare const RESERVED_NAMESPACES: readonly string[];
23
+ /** A namespace set a host cannot have: the name is not a name, or is reserved. */
24
+ export declare class CelNamespaceError extends Error {
25
+ constructor(message: string);
26
+ }
27
+ /**
28
+ * Validates a namespace set and puts it in a canonical order, so that two sets with
29
+ * the same names compare equal however the host listed them.
30
+ */
31
+ export declare function normalizeNamespaces(names: Iterable<string>): readonly string[];
32
+ export declare function namespaceSetsEqual(left: readonly string[], right: readonly string[]): boolean;
33
+ /** Rewrites every call on a name of the set into a `qcall`. Total; shares what it does not change. */
34
+ export declare function resolveNamespaces(root: CelNode, namespaces: readonly string[]): CelNode;
35
+ //# sourceMappingURL=namespace-resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"namespace-resolution.d.ts","sourceRoot":"","sources":["../src/namespace-resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAe,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE7D,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAAwB,CAAC;AAE1E,kFAAkF;AAClF,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,SAAS,MAAM,EAAE,CAiB9E;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAE7F;AAED,sGAAsG;AACtG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAsBvF"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Turning `Alias.fn(x)` into a qualified call.
3
+ *
4
+ * `Alias.fn(x)` and `obj.method(x)` are **the same syntax** — a call written on a
5
+ * receiver — so no parser can tell them apart, and only a set of names that denote
6
+ * namespaces rather than values can. That set comes from the host, which is why
7
+ * this is a separate total tree-to-tree pass rather than a parser rule: the parser
8
+ * has one input and this has two.
9
+ *
10
+ * The pass is total — it visits every node and rewrites every receiver call whose
11
+ * receiver is a bare identifier in the set, wherever it sits. It is also the only
12
+ * producer of `qcall`, and `cel` and `optional` can never be in the set, because
13
+ * the standard macros are written on them (`cel.bind(…)`, `optional.of(…)`) and a
14
+ * namespace would capture those calls instead.
15
+ *
16
+ * A resolved tree records the set it was resolved under, so a consumer given a tree
17
+ * can tell whether it was resolved under the set it is about to check it against —
18
+ * the alternative is a tree that looks resolved and silently is not.
19
+ */
20
+ import { isIdentifierSpelling, isReservedWord } from "./reserved-words.js";
21
+ /** Names that can never be registered as a namespace. */
22
+ export const RESERVED_NAMESPACES = ["cel", "optional"];
23
+ /** A namespace set a host cannot have: the name is not a name, or is reserved. */
24
+ export class CelNamespaceError extends Error {
25
+ constructor(message) {
26
+ super(message);
27
+ this.name = "CelNamespaceError";
28
+ }
29
+ }
30
+ /**
31
+ * Validates a namespace set and puts it in a canonical order, so that two sets with
32
+ * the same names compare equal however the host listed them.
33
+ */
34
+ export function normalizeNamespaces(names) {
35
+ const normalized = [];
36
+ for (const name of names) {
37
+ if (!isIdentifierSpelling(name)) {
38
+ throw new CelNamespaceError(`${JSON.stringify(name)} is not spelled as a name, so it names no namespace`);
39
+ }
40
+ if (isReservedWord(name)) {
41
+ throw new CelNamespaceError(`${JSON.stringify(name)} is a reserved word, so it names no namespace`);
42
+ }
43
+ if (RESERVED_NAMESPACES.includes(name)) {
44
+ throw new CelNamespaceError(`${JSON.stringify(name)} is reserved: the standard macros are written on it, and a namespace would capture them`);
45
+ }
46
+ if (!normalized.includes(name))
47
+ normalized.push(name);
48
+ }
49
+ return normalized.sort();
50
+ }
51
+ export function namespaceSetsEqual(left, right) {
52
+ return left.length === right.length && left.every((name, at) => name === right[at]);
53
+ }
54
+ /** Rewrites every call on a name of the set into a `qcall`. Total; shares what it does not change. */
55
+ export function resolveNamespaces(root, namespaces) {
56
+ // With no namespaces the pass is the identity — nothing can match an empty set — so it
57
+ // answers without walking. Every site with no module names takes this path, which is why
58
+ // it is worth stating rather than leaving to the structural sharing below.
59
+ if (namespaces.length === 0)
60
+ return root;
61
+ const resolved = mapChildren(root, (child) => resolveNamespaces(child, namespaces));
62
+ if (resolved.kind !== "receiverCall")
63
+ return resolved;
64
+ const receiver = resolved.receiver;
65
+ // An absolute name denotes a value the environment declares, never a namespace: a
66
+ // namespaced call has exactly one spelling, and `.Alias.fn(x)` is not it.
67
+ if (receiver.kind !== "ident" || receiver.absolute || !namespaces.includes(receiver.name)) {
68
+ return resolved;
69
+ }
70
+ return {
71
+ kind: "qcall",
72
+ namespace: receiver.name,
73
+ namespaceRange: receiver.range,
74
+ name: resolved.name,
75
+ nameRange: resolved.nameRange,
76
+ args: resolved.args,
77
+ range: resolved.range,
78
+ };
79
+ }
80
+ /** Rebuilds a node from its mapped children, returning the original when none moved. */
81
+ function mapChildren(node, map) {
82
+ switch (node.kind) {
83
+ case "literal":
84
+ case "ident":
85
+ case "unparsed":
86
+ return node;
87
+ case "list": {
88
+ let moved = false;
89
+ const elements = node.elements.map((element) => {
90
+ const value = map(element.value);
91
+ if (value === element.value)
92
+ return element;
93
+ moved = true;
94
+ return { ...element, value };
95
+ });
96
+ return moved ? { ...node, elements } : node;
97
+ }
98
+ case "map": {
99
+ let moved = false;
100
+ const entries = node.entries.map((entry) => {
101
+ const key = map(entry.key);
102
+ const value = map(entry.value);
103
+ if (key === entry.key && value === entry.value)
104
+ return entry;
105
+ moved = true;
106
+ return { ...entry, key, value };
107
+ });
108
+ return moved ? { ...node, entries } : node;
109
+ }
110
+ case "select": {
111
+ const operand = map(node.operand);
112
+ return operand === node.operand ? node : { ...node, operand };
113
+ }
114
+ case "index": {
115
+ const operand = map(node.operand);
116
+ const index = map(node.index);
117
+ return operand === node.operand && index === node.index ? node : { ...node, operand, index };
118
+ }
119
+ case "call":
120
+ case "qcall": {
121
+ const args = mapList(node.args, map);
122
+ return args ? { ...node, args } : node;
123
+ }
124
+ case "receiverCall": {
125
+ const receiver = map(node.receiver);
126
+ const args = mapList(node.args, map);
127
+ if (receiver === node.receiver && !args)
128
+ return node;
129
+ return { ...node, receiver, args: args ?? node.args };
130
+ }
131
+ case "unary": {
132
+ const operand = map(node.operand);
133
+ return operand === node.operand ? node : { ...node, operand };
134
+ }
135
+ case "binary": {
136
+ const left = map(node.left);
137
+ const right = map(node.right);
138
+ return left === node.left && right === node.right ? node : { ...node, left, right };
139
+ }
140
+ case "conditional": {
141
+ const condition = map(node.condition);
142
+ const whenTrue = map(node.whenTrue);
143
+ const whenFalse = map(node.whenFalse);
144
+ return condition === node.condition && whenTrue === node.whenTrue && whenFalse === node.whenFalse
145
+ ? node
146
+ : { ...node, condition, whenTrue, whenFalse };
147
+ }
148
+ }
149
+ }
150
+ /** The mapped list, or nothing when every element is the one it started as. */
151
+ function mapList(nodes, map) {
152
+ let moved = false;
153
+ const mapped = nodes.map((node) => {
154
+ const next = map(node);
155
+ if (next !== node)
156
+ moved = true;
157
+ return next;
158
+ });
159
+ return moved ? mapped : undefined;
160
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Named types a host registers — the one mechanism, with none of the vocabulary.
3
+ *
4
+ * A nominal type is a name over a base type, with its own operators, comparisons,
5
+ * conversions and member functions, and with named **invariant** type parameters. It
6
+ * is not its base: a value of the base does not stand where the named type is wanted,
7
+ * and only what the definition declares applies to it. That is what makes a named type
8
+ * worth having — a slot that wants one refuses a plain value of the base, which is
9
+ * exactly what an engine typing by wrapper class cannot express.
10
+ *
11
+ * Invariance is deliberate: `Holder<string>` and `Holder<int>` are unrelated, so a
12
+ * type argument that differs is a mistake with its own diagnostic rather than a silent
13
+ * widening to the base.
14
+ *
15
+ * `Self` inside a definition names the type being defined, with its own parameters
16
+ * applied, so a member can answer its own type without repeating it.
17
+ */
18
+ import type { CelType, NominalType } from "./cel-type.js";
19
+ import type { NominalResolver } from "./type-expression.js";
20
+ export interface NominalOperatorDeclaration {
21
+ readonly operator: string;
22
+ /** Type expressions; `Self` names the type being defined. */
23
+ readonly parameters: readonly string[];
24
+ readonly returns: string;
25
+ }
26
+ export interface NominalTypeDefinition {
27
+ readonly name: string;
28
+ /** The type expression a value of this type is, underneath. */
29
+ readonly base: string;
30
+ /** Invariant type parameter names, each a single capital letter. */
31
+ readonly parameters?: readonly string[];
32
+ /** Operators over the type, written with `Self`. */
33
+ readonly operators?: readonly NominalOperatorDeclaration[];
34
+ /** Operator symbols to register as `(Self, Self): bool`. */
35
+ readonly comparisons?: readonly string[];
36
+ /** Conversion signatures, e.g. `string(Self): string`. */
37
+ readonly conversions?: readonly string[];
38
+ /** Member signatures, e.g. `Self.scaled(int): Self`. */
39
+ readonly members?: readonly string[];
40
+ readonly description?: string;
41
+ }
42
+ export declare class CelTypeRegistrationError extends Error {
43
+ constructor(message: string);
44
+ }
45
+ /** A registered nominal type: its definition, its base, and the type `Self` names. */
46
+ export interface RegisteredType {
47
+ readonly definition: NominalTypeDefinition;
48
+ readonly base: CelType;
49
+ readonly parameters: readonly string[];
50
+ /** The type with its own parameters applied — what `Self` resolves to. */
51
+ readonly self: NominalType;
52
+ }
53
+ export declare function validateTypeName(name: string): void;
54
+ /**
55
+ * Builds the registered form of a definition. `resolveNominal` resolves names the
56
+ * definition's own base or members mention, including itself through `Self`.
57
+ */
58
+ export declare function buildRegisteredType(definition: NominalTypeDefinition, resolveNominal: NominalResolver): RegisteredType;
59
+ /** The signatures a definition declares, as text, in registration order. */
60
+ export declare function nominalSignatures(definition: NominalTypeDefinition): readonly string[];
61
+ /** The operator declarations a definition implies, its comparisons expanded. */
62
+ export declare function nominalOperators(definition: NominalTypeDefinition): readonly NominalOperatorDeclaration[];
63
+ //# sourceMappingURL=nominal-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nominal-type.d.ts","sourceRoot":"","sources":["../src/nominal-type.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,oDAAoD;IACpD,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;IAC3D,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,wDAAwD;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAsBD,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAI5B;AAED,sFAAsF;AACtF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAYnD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,qBAAqB,EACjC,cAAc,EAAE,eAAe,GAC9B,cAAc,CA6BhB;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,qBAAqB,GAAG,SAAS,MAAM,EAAE,CAEtF;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,qBAAqB,GAAG,SAAS,0BAA0B,EAAE,CAOzG"}