@hyperscale0/hsx 1.0.330 → 1.0.334

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.
@@ -0,0 +1,7 @@
1
+ /**
2
+ * One program that attaches every standard template with bindings the
3
+ * compiler admits. Each template guide takes its example from here, and
4
+ * std-headers.spec proves the whole program compiles.
5
+ */
6
+ export declare const catalogProgramSource = "program catalog \"Template catalog\"\nuse money\nuse escrow\nuse purchase\nuse booking\nuse marketplace\nuse financing\nuse insurance\nuse lending\nuse wallet\nuse cards\nuse collections\nuse savings\nuse reporting\nparty supplier: business\nparty inspector: staff role claim_inspector\nparty investor: business\nobject item \"Item\" {\n attach transfer = money.transfer { payer: actor, payee: owner, amount: 750 SAR }\n attach hold = money.hold { payer: actor, payee: owner, amount: 750 SAR }\n attach split = money.split { payer: actor, amount: 750 SAR }\n attach schedule = money.schedule { payer: actor, payee: owner, amount: 750 SAR, count: 3 }\n attach pool = money.pool { payer: actor, payee: owner, target: 1000 SAR, closes: 2027-01-01 }\n attach swap = money.swap { first: actor, second: owner, first_amount: 100 SAR, second_amount: 200 SAR, expires: 2027-01-01 }\n attach payout = money.payout { payer: actor, payee: owner, adapter: \"conformance_boundary\" }\n attach mandate = money.mandate { payer: actor, payee: owner }\n attach metered = money.metered { payer: actor, payee: owner, unit_price: 10 SAR }\n attach policy = insurance.cover { holder: actor, adapter: \"conformance_boundary\" }\n attach claim = insurance.claim { cover: policy, inspector: inspector }\n attach cov = insurance.cover { holder: actor, broker: supplier, adapter: \"conformance_boundary\", covers: sale }\n attach deposit = escrow.hold { payer: actor, payee: owner }\n attach sale = escrow.hold { funding: { controllers: [checkout], reference: \"funds\", blocking_states: [active] }, payer: actor, payee: owner }\n attach trip = booking.reservation { customer: actor, operator: owner }\n attach limits = financing.limits { borrower: actor, per_borrower: 60000 SAR }\n attach ceiling = financing.portfolio_limit { limit: 1500000 SAR }\n attach checkout = purchase.checkout { plans: plan, funds: sale, borrower: actor, capital: operator }\n attach plan = financing.installments { borrower: actor, capital: operator, months: 3, pricing: flat_total, profit_rate: 2.5%, down_payment: 20%, funds: checkout, limits: limits, portfolio: ceiling }\n attach late = financing.late_charge { on: plan, borrower: actor }\n attach line = financing.credit_line { borrower: operator, adapter: \"conformance_boundary\", limit: 100000 SAR, expires: 2027-01-01 }\n attach advance = financing.advance { line: line }\n attach case = collections.case { on: plan, agency: supplier }\n attach contact = collections.contact { case: case, agency: supplier }\n attach reminder = collections.reminder { on: plan }\n attach wallet = wallet.balance { holder: investor }\n attach spend = wallet.spend { wallet: wallet, payee: supplier, holder: investor }\n attach round = lending.round { borrower: actor, plan: plan, minimum_ticket: 100 SAR, investor_cap: 100% }\n attach commitment = lending.commitment { round: round, wallet: wallet, investor: investor }\n attach distribution = lending.distribution { round: round, receipt: plan.settlement }\n attach cardholder = cards.cardholder { holder: actor }\n attach card = cards.card { holder: cardholder, person: actor, spend_limit: 5000 SAR }\n attach authorization = cards.authorization { card: card, merchant: supplier }\n attach transaction = cards.transaction { authorization: authorization }\n attach dispute = cards.dispute { transaction: transaction }\n attach listing = marketplace.listing { seller: owner }\n attach order = marketplace.order { listing: listing, buyer: actor }\n attach reservation = marketplace.reservation { listing: listing, funds: sale, converters: checkout, buyer: actor, seller: owner }\n attach circle = savings.circle { contribution: 300 SAR, members: 8, starts: 2027-01-01 }\n attach membership = savings.membership { circle: circle, member: actor }\n attach reports = reporting.portfolio { on: plan }\n}";
7
+ //# sourceMappingURL=catalog-program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-program.d.ts","sourceRoot":"","sources":["../../src/catalog-program.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,swHA2D/B,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * One program that attaches every standard template with bindings the
3
+ * compiler admits. Each template guide takes its example from here, and
4
+ * std-headers.spec proves the whole program compiles.
5
+ */
6
+ export const catalogProgramSource = `program catalog "Template catalog"
7
+ use money
8
+ use escrow
9
+ use purchase
10
+ use booking
11
+ use marketplace
12
+ use financing
13
+ use insurance
14
+ use lending
15
+ use wallet
16
+ use cards
17
+ use collections
18
+ use savings
19
+ use reporting
20
+ party supplier: business
21
+ party inspector: staff role claim_inspector
22
+ party investor: business
23
+ object item "Item" {
24
+ attach transfer = money.transfer { payer: actor, payee: owner, amount: 750 SAR }
25
+ attach hold = money.hold { payer: actor, payee: owner, amount: 750 SAR }
26
+ attach split = money.split { payer: actor, amount: 750 SAR }
27
+ attach schedule = money.schedule { payer: actor, payee: owner, amount: 750 SAR, count: 3 }
28
+ attach pool = money.pool { payer: actor, payee: owner, target: 1000 SAR, closes: 2027-01-01 }
29
+ attach swap = money.swap { first: actor, second: owner, first_amount: 100 SAR, second_amount: 200 SAR, expires: 2027-01-01 }
30
+ attach payout = money.payout { payer: actor, payee: owner, adapter: "conformance_boundary" }
31
+ attach mandate = money.mandate { payer: actor, payee: owner }
32
+ attach metered = money.metered { payer: actor, payee: owner, unit_price: 10 SAR }
33
+ attach policy = insurance.cover { holder: actor, adapter: "conformance_boundary" }
34
+ attach claim = insurance.claim { cover: policy, inspector: inspector }
35
+ attach cov = insurance.cover { holder: actor, broker: supplier, adapter: "conformance_boundary", covers: sale }
36
+ attach deposit = escrow.hold { payer: actor, payee: owner }
37
+ attach sale = escrow.hold { funding: { controllers: [checkout], reference: "funds", blocking_states: [active] }, payer: actor, payee: owner }
38
+ attach trip = booking.reservation { customer: actor, operator: owner }
39
+ attach limits = financing.limits { borrower: actor, per_borrower: 60000 SAR }
40
+ attach ceiling = financing.portfolio_limit { limit: 1500000 SAR }
41
+ attach checkout = purchase.checkout { plans: plan, funds: sale, borrower: actor, capital: operator }
42
+ attach plan = financing.installments { borrower: actor, capital: operator, months: 3, pricing: flat_total, profit_rate: 2.5%, down_payment: 20%, funds: checkout, limits: limits, portfolio: ceiling }
43
+ attach late = financing.late_charge { on: plan, borrower: actor }
44
+ attach line = financing.credit_line { borrower: operator, adapter: "conformance_boundary", limit: 100000 SAR, expires: 2027-01-01 }
45
+ attach advance = financing.advance { line: line }
46
+ attach case = collections.case { on: plan, agency: supplier }
47
+ attach contact = collections.contact { case: case, agency: supplier }
48
+ attach reminder = collections.reminder { on: plan }
49
+ attach wallet = wallet.balance { holder: investor }
50
+ attach spend = wallet.spend { wallet: wallet, payee: supplier, holder: investor }
51
+ attach round = lending.round { borrower: actor, plan: plan, minimum_ticket: 100 SAR, investor_cap: 100% }
52
+ attach commitment = lending.commitment { round: round, wallet: wallet, investor: investor }
53
+ attach distribution = lending.distribution { round: round, receipt: plan.settlement }
54
+ attach cardholder = cards.cardholder { holder: actor }
55
+ attach card = cards.card { holder: cardholder, person: actor, spend_limit: 5000 SAR }
56
+ attach authorization = cards.authorization { card: card, merchant: supplier }
57
+ attach transaction = cards.transaction { authorization: authorization }
58
+ attach dispute = cards.dispute { transaction: transaction }
59
+ attach listing = marketplace.listing { seller: owner }
60
+ attach order = marketplace.order { listing: listing, buyer: actor }
61
+ attach reservation = marketplace.reservation { listing: listing, funds: sale, converters: checkout, buyer: actor, seller: owner }
62
+ attach circle = savings.circle { contribution: 300 SAR, members: 8, starts: 2027-01-01 }
63
+ attach membership = savings.membership { circle: circle, member: actor }
64
+ attach reports = reporting.portfolio { on: plan }
65
+ }`;
66
+ //# sourceMappingURL=catalog-program.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-program.js","sourceRoot":"","sources":["../../src/catalog-program.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2DlC,CAAC"}
@@ -7,4 +7,5 @@ export { bundledStandardLibrary, type StandardLibrary } from "./std-library.ts";
7
7
  export { buildUdlCostManifest, type UdlCostManifest } from "./cost.ts";
8
8
  export type { Program, Decl, AssignmentDecl, ObjectDecl, InstrumentDecl, Expr, Span, Diagnostic, } from "./ast.ts";
9
9
  export { headerManifest, HEADER_NAMES } from "./headers.ts";
10
+ export { templateGuide, templateIndex, type TemplateGuide, type TemplateIndexEntry, } from "./template-guide.ts";
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACvE,YAAY,EACV,OAAO,EACP,IAAI,EACJ,cAAc,EACd,UAAU,EACV,cAAc,EACd,IAAI,EACJ,IAAI,EACJ,UAAU,GACX,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACvE,YAAY,EACV,OAAO,EACP,IAAI,EACJ,cAAc,EACd,UAAU,EACV,cAAc,EACd,IAAI,EACJ,IAAI,EACJ,UAAU,GACX,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EACL,aAAa,EACb,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC"}
package/dist/src/index.js CHANGED
@@ -5,4 +5,5 @@ export { format } from "./format.js";
5
5
  export { bundledStandardLibrary } from "./std-library.js";
6
6
  export { buildUdlCostManifest } from "./cost.js";
7
7
  export { headerManifest, HEADER_NAMES } from "./headers.js";
8
+ export { templateGuide, templateIndex, } from "./template-guide.js";
8
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,GAMR,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAwB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAwB,MAAM,WAAW,CAAC;AAYvE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,GAMR,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAwB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAwB,MAAM,WAAW,CAAC;AAYvE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EACL,aAAa,EACb,aAAa,GAGd,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { type CompileOptions } from "./compile.ts";
2
+ import { type StandardLibrary } from "./std-library.ts";
3
+ export interface TemplateIndexEntry {
4
+ qualifiedName: string;
5
+ summary: string;
6
+ parties: string[];
7
+ }
8
+ export interface TemplateGuideAction {
9
+ name: string;
10
+ runBy: string;
11
+ from?: string;
12
+ to?: string;
13
+ due?: string;
14
+ deadline?: string;
15
+ requires?: string[];
16
+ moves?: string[];
17
+ invokes?: string[];
18
+ when?: string;
19
+ }
20
+ export interface TemplateGuide {
21
+ qualifiedName: string;
22
+ summary: string;
23
+ signature: string;
24
+ use: string;
25
+ states: string[];
26
+ tunables: Array<{
27
+ name: string;
28
+ type: string;
29
+ required: boolean;
30
+ default?: string;
31
+ meaning: string;
32
+ }>;
33
+ createInput: Array<{
34
+ name: string;
35
+ type: string;
36
+ }>;
37
+ subject: Array<{
38
+ name: string;
39
+ type: string;
40
+ }>;
41
+ actions: TemplateGuideAction[];
42
+ example: string;
43
+ notes: string[];
44
+ }
45
+ /** One line per template, small enough to read whole. */
46
+ export declare function templateIndex(library?: StandardLibrary): TemplateIndexEntry[];
47
+ /**
48
+ * Everything an author needs for one template, spelled from its std
49
+ * declaration and proved by compiling its example. Undefined when the
50
+ * catalog has no such template.
51
+ */
52
+ export declare function templateGuide(qualifiedName: string, options?: GuideOptions): TemplateGuide | undefined;
53
+ type GuideOptions = Pick<CompileOptions, "adapterRegistry"> & {
54
+ library?: StandardLibrary;
55
+ };
56
+ export {};
57
+ //# sourceMappingURL=template-guide.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-guide.d.ts","sourceRoot":"","sources":["../../src/template-guide.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAI5D,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AASD,yDAAyD;AACzD,wBAAgB,aAAa,CAC3B,OAAO,GAAE,eAAwC,GAChD,kBAAkB,EAAE,CAQtB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,YAAiB,GACzB,aAAa,GAAG,SAAS,CAgE3B;AAoYD,KAAK,YAAY,GAAG,IAAI,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG;IAC5D,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B,CAAC"}
@@ -0,0 +1,421 @@
1
+ import { catalogProgramSource } from "./catalog-program.js";
2
+ import { compile } from "./compile.js";
3
+ import { parseHeader } from "./header-source.js";
4
+ import { headerManifest, HEADER_NAMES } from "./headers.js";
5
+ import { parseProgram } from "./parse.js";
6
+ import { bundledStandardLibrary } from "./std-library.js";
7
+ // How to read runBy, the same for every template.
8
+ const RUN_BY_NOTE = "runBy names who runs each action: a party is whoever the attach binds to it (owner, actor, operator or a declared business), clock is the platform when the action falls due, parent runs only inside its parent record's action, and caller is anyone the exposed action admits.";
9
+ const SUBJECT_NOTE = "subject names fields the attached object must carry, or rename to with rename { field: yourField }, before the actions that read them can run.";
10
+ /** One line per template, small enough to read whole. */
11
+ export function templateIndex(library = bundledStandardLibrary) {
12
+ return headerManifest(library).headers.flatMap((header) => header.objects.map((object) => ({
13
+ qualifiedName: object.qualifiedName,
14
+ summary: object.summary,
15
+ parties: object.parties,
16
+ })));
17
+ }
18
+ /**
19
+ * Everything an author needs for one template, spelled from its std
20
+ * declaration and proved by compiling its example. Undefined when the
21
+ * catalog has no such template.
22
+ */
23
+ export function templateGuide(qualifiedName, options = {}) {
24
+ const library = options.library ?? bundledStandardLibrary;
25
+ const [header, name, extra] = qualifiedName.split(".");
26
+ if (!header || !name || extra !== undefined)
27
+ return undefined;
28
+ if (!HEADER_NAMES.includes(header))
29
+ return undefined;
30
+ const source = library.source(header);
31
+ if (!source)
32
+ return undefined;
33
+ const manifest = headerManifest(library, [header]).headers[0].objects.find((object) => object.name === name);
34
+ const decl = parseHeader(source, header).decls.find((d) => d.kind === "instrument" && d.name === name);
35
+ if (!manifest || !decl)
36
+ return undefined;
37
+ const spell = (expression) => source
38
+ .slice(expression.span.start, expression.span.end)
39
+ .trim()
40
+ .replace(/\s+/g, " ");
41
+ const actions = guideActions(decl.body, spell);
42
+ // Compile once bare, then expose each root action a party or caller runs
43
+ // that these bindings keep, and compile again to prove the example.
44
+ const example = exampleProgram(qualifiedName, library);
45
+ const bare = compiledAttachment(example.render([]), example.attachment, options);
46
+ const exposes = actions
47
+ .filter((action) => !action.name.includes(".") &&
48
+ !["clock", "parent"].includes(action.runBy) &&
49
+ bare.actions[action.name])
50
+ .map((action) => `expose ${action.name}`);
51
+ const program = example.render(exposes);
52
+ const create = compiledAttachment(program, example.attachment, options)
53
+ .actions.create;
54
+ return {
55
+ qualifiedName,
56
+ summary: manifest.summary,
57
+ signature: manifest.signature,
58
+ use: `use ${header}`,
59
+ states: manifest.states,
60
+ tunables: manifest.tunables.map((tunable) => ({
61
+ name: tunable.name,
62
+ type: tunable.type,
63
+ required: tunable.required,
64
+ ...(tunable.default ? { default: tunable.default } : {}),
65
+ meaning: tunable.type === "party" || tunable.type === "party?"
66
+ ? partyMeaning(tunable.name, actions)
67
+ : valueMeaning(tunable.name, tunable.default, decl, spell),
68
+ })),
69
+ createInput: (create?.input ?? []).map((field) => ({
70
+ name: field.name,
71
+ type: inputType(field),
72
+ })),
73
+ subject: manifest.subject,
74
+ actions,
75
+ example: program,
76
+ notes: [RUN_BY_NOTE, ...(manifest.subject.length ? [SUBJECT_NOTE] : [])],
77
+ };
78
+ }
79
+ function slot(block, key) {
80
+ return block.entries.find((entry) => entry.key === key)?.value;
81
+ }
82
+ /**
83
+ * The parser desugars `requires` and `moves` into blocks without source
84
+ * spans, so each clause is spelled from the slot's own source text.
85
+ */
86
+ function clauses(action, key, spell) {
87
+ return action.entries
88
+ .filter((entry) => entry.key === key)
89
+ .flatMap((entry) => spell(entry.value)
90
+ .split(new RegExp(`(?:^|[;,]?\\s+)${key}\\s+`))
91
+ .map((clause) => clause.trim().replace(/[;,]$/, ""))
92
+ .filter(Boolean));
93
+ }
94
+ function items(expression) {
95
+ if (!expression)
96
+ return [];
97
+ return expression.kind === "list" ? expression.items : [expression];
98
+ }
99
+ /** Root actions first, then each record's, prefixed with the record name. */
100
+ function guideActions(body, spell, prefix = "", parentActions = []) {
101
+ const result = [];
102
+ for (const entry of body.entries) {
103
+ if (!entry.key.startsWith("action ") || entry.value.kind !== "block")
104
+ continue;
105
+ const action = entry.value;
106
+ const actor = slot(action, "actor");
107
+ const party = actor?.kind === "block" ? slot(actor, "party") : undefined;
108
+ const parent = actor?.kind === "block" ? slot(actor, "parent") : undefined;
109
+ const runBy = !actor
110
+ ? "caller"
111
+ : party
112
+ ? spell(party)
113
+ : parent
114
+ ? "parent"
115
+ : spell(actor);
116
+ const at = (key) => {
117
+ const value = slot(action, key);
118
+ if (value?.kind !== "block")
119
+ return value ? spell(value) : undefined;
120
+ const instant = slot(value, "at");
121
+ const offset = slot(value, "offset");
122
+ if (!instant)
123
+ return spell(value);
124
+ return offset ? `${spell(instant)} + ${spell(offset)}` : spell(instant);
125
+ };
126
+ const due = at("due");
127
+ const deadline = at("deadline");
128
+ const requires = clauses(action, "requires", spell);
129
+ const moves = clauses(action, "moves", spell);
130
+ const invokes = items(slot(action, "invoke")).flatMap((item) => item.kind === "block" ? [invocation(item, spell, prefix)] : []);
131
+ const from = slot(action, "from");
132
+ const to = slot(action, "to");
133
+ const guide = {
134
+ name: prefix + entry.key.slice(7),
135
+ runBy,
136
+ ...(from ? { from: spell(from) } : {}),
137
+ ...(to ? { to: spell(to) } : {}),
138
+ ...(due ? { due } : {}),
139
+ ...(deadline ? { deadline } : {}),
140
+ ...(requires.length ? { requires } : {}),
141
+ ...(moves.length ? { moves } : {}),
142
+ ...(invokes.length ? { invokes } : {}),
143
+ };
144
+ const when = timing(guide, parentActions);
145
+ result.push(when ? { ...guide, when } : guide);
146
+ }
147
+ const records = slot(body, "records");
148
+ if (records?.kind === "block")
149
+ for (const record of records.entries)
150
+ if (record.value.kind === "block")
151
+ result.push(...guideActions(record.value, spell, `${prefix}${record.key}.`, prefix ? parentActions : result));
152
+ return result;
153
+ }
154
+ function invocation(block, spell, prefix) {
155
+ const instrument = slot(block, "instrument");
156
+ const action = slot(block, "action");
157
+ const target = `${instrument ? `${prefix}${spell(instrument)}.` : ""}${action ? spell(action) : "?"}`;
158
+ const range = slot(block, "range");
159
+ const count = range?.kind === "block" ? slot(range, "count") : undefined;
160
+ const literal = count?.kind === "block" ? (slot(count, "literal") ?? count) : count;
161
+ const selection = slot(block, "selection");
162
+ const selected = selection?.kind === "block" ? slot(selection, "instrument") : undefined;
163
+ return literal
164
+ ? `${target}, ${spell(literal)} times`
165
+ : selected
166
+ ? `${target} on each matching ${spell(selected)}`
167
+ : target;
168
+ }
169
+ /**
170
+ * The runtime's timing rules, applied to one action: a clock action that
171
+ * needs a record in another state waits, and the action that moves the
172
+ * record there collects it in the same request (docs/public/runtime.md).
173
+ */
174
+ function timing(action, parentActions) {
175
+ if (action.runBy === "clock" && action.due) {
176
+ const waits = (action.requires ?? []).flatMap((requirement) => {
177
+ const match = requirement.match(/^self\.\w+ in \[([^\]]+)\]$/);
178
+ return match ? [{ requirement, states: match[1].split(/,\s*/) }] : [];
179
+ });
180
+ const openers = parentActions
181
+ .filter((parent) => waits.some((wait) => wait.states.includes(parent.to ?? "")))
182
+ .map((parent) => parent.name);
183
+ return [
184
+ `The clock runs it at ${action.due}.`,
185
+ ...waits.map((wait) => `While ${wait.requirement} does not hold, it waits.`),
186
+ ...(openers.length
187
+ ? [
188
+ `${openers.join(" or ")} collects every one already due in the same request.`,
189
+ ]
190
+ : []),
191
+ ].join(" ");
192
+ }
193
+ const parts = [
194
+ ...(action.due
195
+ ? [`Runnable from ${action.due}; ${action.runBy} still runs it.`]
196
+ : []),
197
+ ...(action.deadline ? [`Refused after ${action.deadline}.`] : []),
198
+ ];
199
+ return parts.length ? parts.join(" ") : undefined;
200
+ }
201
+ function partyMeaning(name, actions) {
202
+ const runs = actions.filter((action) => action.runBy === name);
203
+ const pays = actions.filter((action) => action.moves?.some((move) => new RegExp(`\\bfrom ${name}\\b`).test(move)));
204
+ const receives = actions.filter((action) => action.moves?.some((move) => new RegExp(`\\bto ${name}\\b`).test(move)));
205
+ const names = (list) => list.map((action) => action.name).join(", ");
206
+ const parts = [
207
+ ...(runs.length ? [`Runs ${names(runs)}.`] : []),
208
+ ...(pays.length ? [`Pays in ${names(pays)}.`] : []),
209
+ ...(receives.length ? [`Receives in ${names(receives)}.`] : []),
210
+ ];
211
+ return parts.length
212
+ ? parts.join(" ")
213
+ : "Named by the template; runs no action and moves no money itself.";
214
+ }
215
+ /**
216
+ * A value tunable's meaning is where it lands: the fields it sets and every
217
+ * field or action that reads those fields, spelled as the std writes them.
218
+ */
219
+ function valueMeaning(name, fallback, decl, spell) {
220
+ const bare = new RegExp(`(?<![\\w.])${name}(?!\\w)`);
221
+ const fields = slot(decl.body, "fields");
222
+ const set = fields?.kind === "block"
223
+ ? fields.entries.filter((entry) => bare.test(fieldValue(entry, spell)))
224
+ : [];
225
+ const read = new Set(set.map((entry) => entry.key));
226
+ const uses = [];
227
+ const visit = (body, prefix, parentRefs) => {
228
+ const own = slot(body, "fields");
229
+ const reads = (text) => bare.test(text) ||
230
+ [...read].some((field) => prefix
231
+ ? parentRefs.some((ref) => new RegExp(`\\bself\\.${ref}\\.${field}\\b`).test(text))
232
+ : new RegExp(`\\bself\\.${field}\\b`).test(text));
233
+ if (own?.kind === "block" && prefix)
234
+ for (const entry of own.entries) {
235
+ const value = fieldValue(entry, spell);
236
+ if (reads(value))
237
+ uses.push(`${prefix}${entry.key}: ${value}`);
238
+ }
239
+ for (const entry of body.entries) {
240
+ if (!entry.key.startsWith("action ") || entry.value.kind !== "block")
241
+ continue;
242
+ for (const part of entry.value.entries) {
243
+ if (["actor", "from", "to", "summary"].includes(part.key))
244
+ continue;
245
+ const text = spell(part.value);
246
+ // A long slot, such as an invoke list, is named rather than spelled.
247
+ if (reads(text))
248
+ uses.push(`${prefix}${entry.key.slice(7)} ${part.key}${text.length > 100 ? "" : `: ${text}`}`);
249
+ }
250
+ }
251
+ const records = slot(body, "records");
252
+ if (records?.kind === "block")
253
+ for (const record of records.entries) {
254
+ if (record.value.kind !== "block")
255
+ continue;
256
+ const recordFields = slot(record.value, "fields");
257
+ const refs = recordFields?.kind === "block"
258
+ ? recordFields.entries
259
+ .filter((entry) => /^ref<parent>/.test(fieldValue(entry, spell)))
260
+ .map((entry) => entry.key)
261
+ : [];
262
+ visit(record.value, `${prefix}${record.key}.`, refs);
263
+ }
264
+ };
265
+ visit(decl.body, "", []);
266
+ const parts = [
267
+ ...(fallback === "runtime"
268
+ ? [
269
+ `Leave it out of the attach and create takes ${name} for each record, or bind one fixed value.`,
270
+ ]
271
+ : []),
272
+ ...(set.length
273
+ ? [
274
+ `Sets ${set.map((entry) => `${entry.key}: ${fieldValue(entry, spell)}`).join(", ")}.`,
275
+ ]
276
+ : []),
277
+ ...(uses.length ? [`Read by ${uses.slice(0, 6).join("; ")}.`] : []),
278
+ ];
279
+ return parts.length ? parts.join(" ") : "Configures the template.";
280
+ }
281
+ function fieldValue(entry, spell) {
282
+ return entry.value.kind === "default"
283
+ ? `${spell(entry.value.type)} = ${spell(entry.value.value)}`
284
+ : spell(entry.value);
285
+ }
286
+ /**
287
+ * The template's attach from the catalog program, with every attach it names
288
+ * and the parties and headers those need.
289
+ */
290
+ function exampleProgram(qualifiedName, library) {
291
+ const program = parseProgram(catalogProgramSource).program;
292
+ const object = program.decls.find((decl) => decl.kind === "object");
293
+ if (object?.kind !== "object")
294
+ throw new Error("catalog program has no object");
295
+ const attaches = object.body.entries.flatMap((entry) => {
296
+ const match = entry.key.match(/^attach (\w+) = (\w+)\.(\w+)$/);
297
+ return match
298
+ ? [
299
+ {
300
+ entry,
301
+ name: match[1],
302
+ header: match[2],
303
+ template: `${match[2]}.${match[3]}`,
304
+ },
305
+ ]
306
+ : [];
307
+ });
308
+ const target = attaches.find((attach) => attach.template === qualifiedName);
309
+ if (!target)
310
+ throw new Error(`catalog program does not attach ${qualifiedName}`);
311
+ const referenced = (expression) => {
312
+ if (expression.kind === "name")
313
+ return [expression.value.split(".")[0]];
314
+ if (expression.kind === "list")
315
+ return expression.items.flatMap(referenced);
316
+ if (expression.kind === "block")
317
+ return expression.entries.flatMap((entry) => referenced(entry.value));
318
+ return [];
319
+ };
320
+ // A parameter that defaults to object(header.template) binds the sibling
321
+ // attach of that template, so the example carries that attach too.
322
+ const templates = new Map(headerManifest(library).headers.flatMap((header) => header.objects.map((object) => [object.qualifiedName, object])));
323
+ const siblings = (template) => (templates.get(template)?.tunables ?? []).flatMap((tunable) => {
324
+ const match = tunable.default?.match(/^object\((\w+\.\w+)\)$/);
325
+ const sibling = match
326
+ ? attaches.find((attach) => attach.template === match[1])
327
+ : undefined;
328
+ return sibling ? [sibling.name] : [];
329
+ });
330
+ const names = new Set();
331
+ const include = (name) => {
332
+ if (names.has(name))
333
+ return;
334
+ const attach = attaches.find((candidate) => candidate.name === name);
335
+ if (!attach)
336
+ return;
337
+ names.add(name);
338
+ [...referenced(attach.entry.value), ...siblings(attach.template)].forEach(include);
339
+ };
340
+ include(target.name);
341
+ const included = attaches.filter((attach) => names.has(attach.name));
342
+ const used = new Set(included.flatMap((attach) => referenced(attach.entry.value)));
343
+ const text = (span) => catalogProgramSource.slice(span.start, span.end).trim();
344
+ return {
345
+ attachment: target.name,
346
+ render: (exposes) => [
347
+ `program example "${qualifiedName} example"`,
348
+ ...new Set(included.map((attach) => `use ${attach.header}`)),
349
+ ...program.decls.flatMap((decl) => decl.kind === "party" && used.has(decl.name) ? [text(decl.span)] : []),
350
+ `object item "Item" {`,
351
+ ...included.map((attach) => {
352
+ const line = text(attach.entry.span);
353
+ return wrapAttach(attach === target && exposes.length
354
+ ? line.replace(/\s*\}$/, `, ${exposes.join(", ")} }`)
355
+ : line);
356
+ }),
357
+ "}",
358
+ ].join("\n"),
359
+ };
360
+ }
361
+ /** An attach line within 76 columns, else one binding per line. */
362
+ function wrapAttach(line) {
363
+ if (line.length <= 74)
364
+ return ` ${line}`;
365
+ const open = line.indexOf("{");
366
+ const items = [];
367
+ let depth = 0;
368
+ let quoted = false;
369
+ let start = open + 1;
370
+ for (let index = start; index < line.length - 1; index++) {
371
+ const char = line[index];
372
+ if (char === '"')
373
+ quoted = !quoted;
374
+ if (quoted)
375
+ continue;
376
+ if ("{[(".includes(char))
377
+ depth++;
378
+ if ("}])".includes(char))
379
+ depth--;
380
+ if (char === "," && depth === 0) {
381
+ items.push(line.slice(start, index).trim());
382
+ start = index + 1;
383
+ }
384
+ }
385
+ items.push(line.slice(start, line.lastIndexOf("}")).trim());
386
+ return [
387
+ ` ${line.slice(0, open + 1)}`,
388
+ ...items.map((item) => ` ${item},`),
389
+ " }",
390
+ ].join("\n");
391
+ }
392
+ /** The example's compiled root instrument, or the compiler's refusal. */
393
+ function compiledAttachment(source, attachment, options) {
394
+ const result = compile(source, {
395
+ ...(options.library ? { standardLibrary: options.library } : {}),
396
+ ...(options.adapterRegistry
397
+ ? { adapterRegistry: options.adapterRegistry }
398
+ : {}),
399
+ });
400
+ const document = result.artifacts?.document;
401
+ if (!document)
402
+ throw new Error(`${attachment} example does not compile: ${result.diagnostics.map((d) => d.message).join("; ")}`);
403
+ const instrumentId = document.objects
404
+ .flatMap((object) => object.attachments)
405
+ .find((candidate) => candidate.name === attachment)?.instrument;
406
+ const instrument = document.instruments.find((candidate) => candidate.id === instrumentId);
407
+ if (!instrument)
408
+ throw new Error(`${attachment} example has no instrument`);
409
+ return instrument;
410
+ }
411
+ function inputType(field) {
412
+ const type = String(field.type);
413
+ if (type === "list")
414
+ return `list of ${String(field.item)}${field.maxItems === undefined ? "" : `, at most ${String(field.maxItems)}`}`;
415
+ if (type === "ref" && field.target)
416
+ return `ref to ${String(field.target)}`;
417
+ if (type === "enum" && Array.isArray(field.values))
418
+ return `one of ${field.values.join(", ")}`;
419
+ return type;
420
+ }
421
+ //# sourceMappingURL=template-guide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-guide.js","sourceRoot":"","sources":["../../src/template-guide.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAwB,MAAM,kBAAkB,CAAC;AAyChF,kDAAkD;AAClD,MAAM,WAAW,GACf,mRAAmR,CAAC;AAEtR,MAAM,YAAY,GAChB,gJAAgJ,CAAC;AAEnJ,yDAAyD;AACzD,MAAM,UAAU,aAAa,CAC3B,OAAO,GAAoB,sBAAsB;IAEjD,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACxD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAC,CACJ,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,aAAqB,EACrB,OAAO,GAAiB,EAAE;IAE1B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,sBAAsB,CAAC;IAC1D,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC9D,IAAI,CAAE,YAAkC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,IAAI,CACzE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CACjC,CAAC;IACF,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CACjD,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CACvE,CAAC;IACF,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,UAAgB,EAAE,EAAE,CACjC,MAAM;SACH,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;SACjD,IAAI,EAAE;SACN,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/C,yEAAyE;IACzE,oEAAoE;IACpE,MAAM,OAAO,GAAG,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,kBAAkB,CAC7B,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAClB,OAAO,CAAC,UAAU,EAClB,OAAO,CACR,CAAC;IACF,MAAM,OAAO,GAAG,OAAO;SACpB,MAAM,CACL,CAAC,MAAM,EAAE,EAAE,CACT,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC1B,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAC5B;SACA,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC;SACpE,OAAO,CAAC,MAAM,CAAC;IAClB,OAAO;QACL,aAAa;QACb,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,GAAG,EAAE,OAAO,MAAM,EAAE;QACpB,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC5C,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,OAAO,EACL,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ;gBACnD,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;gBACrC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC;SAC/D,CAAC,CAAC;QACH,WAAW,EAAE,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACjD,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,SAAS,CAAC,KAA2C,CAAC;SAC7D,CAAC,CAAC;QACH,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,OAAO;QACP,OAAO,EAAE,OAAO;QAChB,KAAK,EAAE,CAAC,WAAW,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KACzE,CAAC;AACJ,CAAC;AAED,SAAS,IAAI,CAAC,KAAgB,EAAE,GAAW;IACzC,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,KAAK,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CACd,MAAiB,EACjB,GAAyB,EACzB,KAAmC;IAEnC,OAAO,MAAM,CAAC,OAAO;SAClB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC;SACpC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CACjB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;SACf,KAAK,CAAC,IAAI,MAAM,CAAC,kBAAkB,GAAG,MAAM,CAAC,CAAC;SAC9C,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;SACnD,MAAM,CAAC,OAAO,CAAC,CACnB,CAAC;AACN,CAAC;AAED,SAAS,KAAK,CAAC,UAA4B;IACzC,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,CAAC;IAC3B,OAAO,UAAU,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;AACtE,CAAC;AAED,6EAA6E;AAC7E,SAAS,YAAY,CACnB,IAAe,EACf,KAAmC,EACnC,MAAM,GAAG,EAAE,EACX,aAAa,GAA0B,EAAE;IAEzC,MAAM,MAAM,GAA0B,EAAE,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO;YAClE,SAAS;QACX,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,KAAK,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACzE,MAAM,MAAM,GAAG,KAAK,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3E,MAAM,KAAK,GAAG,CAAC,KAAK;YAClB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,KAAK;gBACL,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;gBACd,CAAC,CAAC,MAAM;oBACN,CAAC,CAAC,QAAQ;oBACV,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,MAAM,EAAE,GAAG,CAAC,GAAW,EAAE,EAAE;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAChC,IAAI,KAAK,EAAE,IAAI,KAAK,OAAO;gBAAE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACrE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YACrC,IAAI,CAAC,OAAO;gBAAE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC;YAClC,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1E,CAAC,CAAC;QACF,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;QACtB,MAAM,QAAQ,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC7D,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAC/D,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAClC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAwB;YACjC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;YACjC,KAAK;YACL,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvB,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvC,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACtC,IAAI,OAAO,EAAE,IAAI,KAAK,OAAO;QAC3B,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO;YAClC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO;gBAC/B,MAAM,CAAC,IAAI,CACT,GAAG,YAAY,CACb,MAAM,CAAC,KAAK,EACZ,KAAK,EACL,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,EACzB,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAChC,CACF,CAAC;IACR,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CACjB,KAAgB,EAChB,KAAmC,EACnC,MAAc;IAEd,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IACtG,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,KAAK,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzE,MAAM,OAAO,GACX,KAAK,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACtE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC3C,MAAM,QAAQ,GACZ,SAAS,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,OAAO,OAAO;QACZ,CAAC,CAAC,GAAG,MAAM,KAAK,KAAK,CAAC,OAAO,CAAC,QAAQ;QACtC,CAAC,CAAC,QAAQ;YACR,CAAC,CAAC,GAAG,MAAM,qBAAqB,KAAK,CAAC,QAAQ,CAAC,EAAE;YACjD,CAAC,CAAC,MAAM,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,MAAM,CACb,MAA2B,EAC3B,aAAoC;IAEpC,IAAI,MAAM,CAAC,KAAK,KAAK,OAAO,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;YAC5D,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC/D,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,CAAC,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,aAAa;aAC1B,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CACjB,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAC5D;aACA,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO;YACL,wBAAwB,MAAM,CAAC,GAAG,GAAG;YACrC,GAAG,KAAK,CAAC,GAAG,CACV,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,IAAI,CAAC,WAAW,2BAA2B,CAC/D;YACD,GAAG,CAAC,OAAO,CAAC,MAAM;gBAChB,CAAC,CAAC;oBACE,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,sDAAsD;iBAC9E;gBACH,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG;QACZ,GAAG,CAAC,MAAM,CAAC,GAAG;YACZ,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,KAAK,iBAAiB,CAAC;YACjE,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC;IACF,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,OAA8B;IAChE,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CACrC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,WAAW,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAC1E,CAAC;IACF,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CACzC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CACxE,CAAC;IACF,MAAM,KAAK,GAAG,CAAC,IAA2B,EAAE,EAAE,CAC5C,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG;QACZ,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAChE,CAAC;IACF,OAAO,KAAK,CAAC,MAAM;QACjB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QACjB,CAAC,CAAC,kEAAkE,CAAC;AACzE,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CACnB,IAAY,EACZ,QAA4B,EAC5B,IAAoB,EACpB,KAAmC;IAEnC,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC,cAAc,IAAI,SAAS,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACzC,MAAM,GAAG,GACP,MAAM,EAAE,IAAI,KAAK,OAAO;QACtB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QACvE,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,KAAK,GAAG,CAAC,IAAe,EAAE,MAAc,EAAE,UAAoB,EAAE,EAAE;QACtE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAC7B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACf,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACvB,MAAM;gBACJ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CACtB,IAAI,MAAM,CAAC,aAAa,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACxD;gBACH,CAAC,CAAC,IAAI,MAAM,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACnD,CAAC;QACJ,IAAI,GAAG,EAAE,IAAI,KAAK,OAAO,IAAI,MAAM;YACjC,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAChC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBACvC,IAAI,KAAK,CAAC,KAAK,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO;gBAClE,SAAS;YACX,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBACvC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;oBAAE,SAAS;gBACpE,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/B,qEAAqE;gBACrE,IAAI,KAAK,CAAC,IAAI,CAAC;oBACb,IAAI,CAAC,IAAI,CACP,GAAG,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CACpF,CAAC;YACN,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACtC,IAAI,OAAO,EAAE,IAAI,KAAK,OAAO;YAC3B,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACrC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO;oBAAE,SAAS;gBAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAClD,MAAM,IAAI,GACR,YAAY,EAAE,IAAI,KAAK,OAAO;oBAC5B,CAAC,CAAC,YAAY,CAAC,OAAO;yBACjB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAChB,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAC9C;yBACA,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC;oBAC9B,CAAC,CAAC,EAAE,CAAC;gBACT,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC;YACvD,CAAC;IACL,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACzB,MAAM,KAAK,GAAG;QACZ,GAAG,CAAC,QAAQ,KAAK,SAAS;YACxB,CAAC,CAAC;gBACE,+CAA+C,IAAI,4CAA4C;aAChG;YACH,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,GAAG,CAAC,MAAM;YACZ,CAAC,CAAC;gBACE,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;aACtF;YACH,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACpE,CAAC;IACF,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC;AACrE,CAAC;AAED,SAAS,UAAU,CAAC,KAAY,EAAE,KAAmC;IACnE,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;QACnC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;QAC5D,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAOD;;;GAGG;AACH,SAAS,cAAc,CACrB,aAAqB,EACrB,OAAwB;IAExB,MAAM,OAAO,GAAG,YAAY,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACpE,IAAI,MAAM,EAAE,IAAI,KAAK,QAAQ;QAC3B,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACrD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC/D,OAAO,KAAK;YACV,CAAC,CAAC;gBACE;oBACE,KAAK;oBACL,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE;oBACf,MAAM,EAAE,KAAK,CAAC,CAAC,CAAE;oBACjB,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE;iBACpC;aACF;YACH,CAAC,CAAC,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC;IAC5E,IAAI,CAAC,MAAM;QACT,MAAM,IAAI,KAAK,CAAC,mCAAmC,aAAa,EAAE,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,CAAC,UAAgB,EAAY,EAAE;QAChD,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;QACzE,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC5E,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO;YAC7B,OAAO,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IACF,yEAAyE;IACzE,mEAAmE;IACnE,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,cAAc,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACjD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAU,CAAC,CACxE,CACF,CAAC;IACF,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAE,EAAE,CACpC,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,KAAK;YACnB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC;YACzD,CAAC,CAAC,SAAS,CAAC;QACd,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IACL,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE;QAC/B,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO;QAC5B,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACrE,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CACvE,OAAO,CACR,CAAC;IACJ,CAAC,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrB,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACrE,MAAM,IAAI,GAAG,IAAI,GAAG,CAClB,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAC7D,CAAC;IACF,MAAM,IAAI,GAAG,CAAC,IAAoC,EAAE,EAAE,CACpD,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1D,OAAO;QACL,UAAU,EAAE,MAAM,CAAC,IAAI;QACvB,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAClB;YACE,oBAAoB,aAAa,WAAW;YAC5C,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5D,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAChC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CACtE;YACD,sBAAsB;YACtB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;gBACzB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACrC,OAAO,UAAU,CACf,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM;oBACjC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;oBACrD,CAAC,CAAC,IAAI,CACT,CAAC;YACJ,CAAC,CAAC;YACF,GAAG;SACJ,CAAC,IAAI,CAAC,IAAI,CAAC;KACf,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE;QAAE,OAAO,KAAK,IAAI,EAAE,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC;IACrB,KAAK,IAAI,KAAK,GAAG,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAE,CAAC;QAC1B,IAAI,IAAI,KAAK,GAAG;YAAE,MAAM,GAAG,CAAC,MAAM,CAAC;QACnC,IAAI,MAAM;YAAE,SAAS;QACrB,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,KAAK,EAAE,CAAC;QAClC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5C,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,OAAO;QACL,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,EAAE;QAC9B,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,GAAG,CAAC;QACtC,KAAK;KACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAMD,yEAAyE;AACzE,SAAS,kBAAkB,CACzB,MAAc,EACd,UAAkB,EAClB,OAAqB;IAErB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE;QAC7B,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,OAAO,CAAC,eAAe;YACzB,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE;YAC9C,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC;IAC5C,IAAI,CAAC,QAAQ;QACX,MAAM,IAAI,KAAK,CACb,GAAG,UAAU,8BAA8B,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACjG,CAAC;IACJ,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO;SAClC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;SACvC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,UAAU,CAAC;IAClE,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAC1C,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,YAAY,CAC7C,CAAC;IACF,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,4BAA4B,CAAC,CAAC;IAC5E,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,SAAS,CAAC,KAA8B;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,IAAI,KAAK,MAAM;QACjB,OAAO,WAAW,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;IACrH,IAAI,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,UAAU,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;IAC5E,IAAI,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QAChD,OAAO,UAAU,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC7C,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperscale0/hsx",
3
- "version": "1.0.330",
3
+ "version": "1.0.334",
4
4
  "description": "The strictly typed HSX language: compile total financial programs into canonical UDL.",
5
5
  "keywords": [
6
6
  "hsx",
@@ -90,8 +90,8 @@
90
90
  "bases:bundle": "bun scripts/bundle-bases.ts"
91
91
  },
92
92
  "dependencies": {
93
- "@hyperscale0/adl": "1.0.330",
94
- "@hyperscale0/udl": "1.0.330",
93
+ "@hyperscale0/adl": "1.0.334",
94
+ "@hyperscale0/udl": "1.0.334",
95
95
  "fast-sha256": "1.3.0"
96
96
  },
97
97
  "devDependencies": {
@@ -103,5 +103,5 @@
103
103
  "Amir Ayub",
104
104
  "Sara AlBakaawi"
105
105
  ],
106
- "gitHead": "a54f755dfc24c90c4c44953e73bbe4653593dea5"
106
+ "gitHead": "63ce2f153ec13ff17f2ea8a910cc134bfecdab16"
107
107
  }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * One program that attaches every standard template with bindings the
3
+ * compiler admits. Each template guide takes its example from here, and
4
+ * std-headers.spec proves the whole program compiles.
5
+ */
6
+ export const catalogProgramSource = `program catalog "Template catalog"
7
+ use money
8
+ use escrow
9
+ use purchase
10
+ use booking
11
+ use marketplace
12
+ use financing
13
+ use insurance
14
+ use lending
15
+ use wallet
16
+ use cards
17
+ use collections
18
+ use savings
19
+ use reporting
20
+ party supplier: business
21
+ party inspector: staff role claim_inspector
22
+ party investor: business
23
+ object item "Item" {
24
+ attach transfer = money.transfer { payer: actor, payee: owner, amount: 750 SAR }
25
+ attach hold = money.hold { payer: actor, payee: owner, amount: 750 SAR }
26
+ attach split = money.split { payer: actor, amount: 750 SAR }
27
+ attach schedule = money.schedule { payer: actor, payee: owner, amount: 750 SAR, count: 3 }
28
+ attach pool = money.pool { payer: actor, payee: owner, target: 1000 SAR, closes: 2027-01-01 }
29
+ attach swap = money.swap { first: actor, second: owner, first_amount: 100 SAR, second_amount: 200 SAR, expires: 2027-01-01 }
30
+ attach payout = money.payout { payer: actor, payee: owner, adapter: "conformance_boundary" }
31
+ attach mandate = money.mandate { payer: actor, payee: owner }
32
+ attach metered = money.metered { payer: actor, payee: owner, unit_price: 10 SAR }
33
+ attach policy = insurance.cover { holder: actor, adapter: "conformance_boundary" }
34
+ attach claim = insurance.claim { cover: policy, inspector: inspector }
35
+ attach cov = insurance.cover { holder: actor, broker: supplier, adapter: "conformance_boundary", covers: sale }
36
+ attach deposit = escrow.hold { payer: actor, payee: owner }
37
+ attach sale = escrow.hold { funding: { controllers: [checkout], reference: "funds", blocking_states: [active] }, payer: actor, payee: owner }
38
+ attach trip = booking.reservation { customer: actor, operator: owner }
39
+ attach limits = financing.limits { borrower: actor, per_borrower: 60000 SAR }
40
+ attach ceiling = financing.portfolio_limit { limit: 1500000 SAR }
41
+ attach checkout = purchase.checkout { plans: plan, funds: sale, borrower: actor, capital: operator }
42
+ attach plan = financing.installments { borrower: actor, capital: operator, months: 3, pricing: flat_total, profit_rate: 2.5%, down_payment: 20%, funds: checkout, limits: limits, portfolio: ceiling }
43
+ attach late = financing.late_charge { on: plan, borrower: actor }
44
+ attach line = financing.credit_line { borrower: operator, adapter: "conformance_boundary", limit: 100000 SAR, expires: 2027-01-01 }
45
+ attach advance = financing.advance { line: line }
46
+ attach case = collections.case { on: plan, agency: supplier }
47
+ attach contact = collections.contact { case: case, agency: supplier }
48
+ attach reminder = collections.reminder { on: plan }
49
+ attach wallet = wallet.balance { holder: investor }
50
+ attach spend = wallet.spend { wallet: wallet, payee: supplier, holder: investor }
51
+ attach round = lending.round { borrower: actor, plan: plan, minimum_ticket: 100 SAR, investor_cap: 100% }
52
+ attach commitment = lending.commitment { round: round, wallet: wallet, investor: investor }
53
+ attach distribution = lending.distribution { round: round, receipt: plan.settlement }
54
+ attach cardholder = cards.cardholder { holder: actor }
55
+ attach card = cards.card { holder: cardholder, person: actor, spend_limit: 5000 SAR }
56
+ attach authorization = cards.authorization { card: card, merchant: supplier }
57
+ attach transaction = cards.transaction { authorization: authorization }
58
+ attach dispute = cards.dispute { transaction: transaction }
59
+ attach listing = marketplace.listing { seller: owner }
60
+ attach order = marketplace.order { listing: listing, buyer: actor }
61
+ attach reservation = marketplace.reservation { listing: listing, funds: sale, converters: checkout, buyer: actor, seller: owner }
62
+ attach circle = savings.circle { contribution: 300 SAR, members: 8, starts: 2027-01-01 }
63
+ attach membership = savings.membership { circle: circle, member: actor }
64
+ attach reports = reporting.portfolio { on: plan }
65
+ }`;
package/src/index.ts CHANGED
@@ -24,3 +24,9 @@ export type {
24
24
  } from "./ast.ts";
25
25
 
26
26
  export { headerManifest, HEADER_NAMES } from "./headers.ts";
27
+ export {
28
+ templateGuide,
29
+ templateIndex,
30
+ type TemplateGuide,
31
+ type TemplateIndexEntry,
32
+ } from "./template-guide.ts";
@@ -0,0 +1,567 @@
1
+ import type { BlockExpr, Entry, Expr, InstrumentDecl } from "./ast.ts";
2
+ import { catalogProgramSource } from "./catalog-program.ts";
3
+ import { compile, type CompileOptions } from "./compile.ts";
4
+ import { parseHeader } from "./header-source.ts";
5
+ import { headerManifest, HEADER_NAMES } from "./headers.ts";
6
+ import { parseProgram } from "./parse.ts";
7
+ import { bundledStandardLibrary, type StandardLibrary } from "./std-library.ts";
8
+
9
+ export interface TemplateIndexEntry {
10
+ qualifiedName: string;
11
+ summary: string;
12
+ parties: string[];
13
+ }
14
+
15
+ export interface TemplateGuideAction {
16
+ name: string;
17
+ runBy: string;
18
+ from?: string;
19
+ to?: string;
20
+ due?: string;
21
+ deadline?: string;
22
+ requires?: string[];
23
+ moves?: string[];
24
+ invokes?: string[];
25
+ when?: string;
26
+ }
27
+
28
+ export interface TemplateGuide {
29
+ qualifiedName: string;
30
+ summary: string;
31
+ signature: string;
32
+ use: string;
33
+ states: string[];
34
+ tunables: Array<{
35
+ name: string;
36
+ type: string;
37
+ required: boolean;
38
+ default?: string;
39
+ meaning: string;
40
+ }>;
41
+ createInput: Array<{ name: string; type: string }>;
42
+ subject: Array<{ name: string; type: string }>;
43
+ actions: TemplateGuideAction[];
44
+ example: string;
45
+ notes: string[];
46
+ }
47
+
48
+ // How to read runBy, the same for every template.
49
+ const RUN_BY_NOTE =
50
+ "runBy names who runs each action: a party is whoever the attach binds to it (owner, actor, operator or a declared business), clock is the platform when the action falls due, parent runs only inside its parent record's action, and caller is anyone the exposed action admits.";
51
+
52
+ const SUBJECT_NOTE =
53
+ "subject names fields the attached object must carry, or rename to with rename { field: yourField }, before the actions that read them can run.";
54
+
55
+ /** One line per template, small enough to read whole. */
56
+ export function templateIndex(
57
+ library: StandardLibrary = bundledStandardLibrary,
58
+ ): TemplateIndexEntry[] {
59
+ return headerManifest(library).headers.flatMap((header) =>
60
+ header.objects.map((object) => ({
61
+ qualifiedName: object.qualifiedName,
62
+ summary: object.summary,
63
+ parties: object.parties,
64
+ })),
65
+ );
66
+ }
67
+
68
+ /**
69
+ * Everything an author needs for one template, spelled from its std
70
+ * declaration and proved by compiling its example. Undefined when the
71
+ * catalog has no such template.
72
+ */
73
+ export function templateGuide(
74
+ qualifiedName: string,
75
+ options: GuideOptions = {},
76
+ ): TemplateGuide | undefined {
77
+ const library = options.library ?? bundledStandardLibrary;
78
+ const [header, name, extra] = qualifiedName.split(".");
79
+ if (!header || !name || extra !== undefined) return undefined;
80
+ if (!(HEADER_NAMES as readonly string[]).includes(header)) return undefined;
81
+ const source = library.source(header);
82
+ if (!source) return undefined;
83
+ const manifest = headerManifest(library, [header]).headers[0]!.objects.find(
84
+ (object) => object.name === name,
85
+ );
86
+ const decl = parseHeader(source, header).decls.find(
87
+ (d): d is InstrumentDecl => d.kind === "instrument" && d.name === name,
88
+ );
89
+ if (!manifest || !decl) return undefined;
90
+ const spell = (expression: Expr) =>
91
+ source
92
+ .slice(expression.span.start, expression.span.end)
93
+ .trim()
94
+ .replace(/\s+/g, " ");
95
+ const actions = guideActions(decl.body, spell);
96
+ // Compile once bare, then expose each root action a party or caller runs
97
+ // that these bindings keep, and compile again to prove the example.
98
+ const example = exampleProgram(qualifiedName, library);
99
+ const bare = compiledAttachment(
100
+ example.render([]),
101
+ example.attachment,
102
+ options,
103
+ );
104
+ const exposes = actions
105
+ .filter(
106
+ (action) =>
107
+ !action.name.includes(".") &&
108
+ !["clock", "parent"].includes(action.runBy) &&
109
+ bare.actions[action.name],
110
+ )
111
+ .map((action) => `expose ${action.name}`);
112
+ const program = example.render(exposes);
113
+ const create = compiledAttachment(program, example.attachment, options)
114
+ .actions.create;
115
+ return {
116
+ qualifiedName,
117
+ summary: manifest.summary,
118
+ signature: manifest.signature,
119
+ use: `use ${header}`,
120
+ states: manifest.states,
121
+ tunables: manifest.tunables.map((tunable) => ({
122
+ name: tunable.name,
123
+ type: tunable.type,
124
+ required: tunable.required,
125
+ ...(tunable.default ? { default: tunable.default } : {}),
126
+ meaning:
127
+ tunable.type === "party" || tunable.type === "party?"
128
+ ? partyMeaning(tunable.name, actions)
129
+ : valueMeaning(tunable.name, tunable.default, decl, spell),
130
+ })),
131
+ createInput: (create?.input ?? []).map((field) => ({
132
+ name: field.name,
133
+ type: inputType(field as unknown as Record<string, unknown>),
134
+ })),
135
+ subject: manifest.subject,
136
+ actions,
137
+ example: program,
138
+ notes: [RUN_BY_NOTE, ...(manifest.subject.length ? [SUBJECT_NOTE] : [])],
139
+ };
140
+ }
141
+
142
+ function slot(block: BlockExpr, key: string) {
143
+ return block.entries.find((entry) => entry.key === key)?.value;
144
+ }
145
+
146
+ /**
147
+ * The parser desugars `requires` and `moves` into blocks without source
148
+ * spans, so each clause is spelled from the slot's own source text.
149
+ */
150
+ function clauses(
151
+ action: BlockExpr,
152
+ key: "requires" | "moves",
153
+ spell: (expression: Expr) => string,
154
+ ) {
155
+ return action.entries
156
+ .filter((entry) => entry.key === key)
157
+ .flatMap((entry) =>
158
+ spell(entry.value)
159
+ .split(new RegExp(`(?:^|[;,]?\\s+)${key}\\s+`))
160
+ .map((clause) => clause.trim().replace(/[;,]$/, ""))
161
+ .filter(Boolean),
162
+ );
163
+ }
164
+
165
+ function items(expression: Expr | undefined): Expr[] {
166
+ if (!expression) return [];
167
+ return expression.kind === "list" ? expression.items : [expression];
168
+ }
169
+
170
+ /** Root actions first, then each record's, prefixed with the record name. */
171
+ function guideActions(
172
+ body: BlockExpr,
173
+ spell: (expression: Expr) => string,
174
+ prefix = "",
175
+ parentActions: TemplateGuideAction[] = [],
176
+ ): TemplateGuideAction[] {
177
+ const result: TemplateGuideAction[] = [];
178
+ for (const entry of body.entries) {
179
+ if (!entry.key.startsWith("action ") || entry.value.kind !== "block")
180
+ continue;
181
+ const action = entry.value;
182
+ const actor = slot(action, "actor");
183
+ const party = actor?.kind === "block" ? slot(actor, "party") : undefined;
184
+ const parent = actor?.kind === "block" ? slot(actor, "parent") : undefined;
185
+ const runBy = !actor
186
+ ? "caller"
187
+ : party
188
+ ? spell(party)
189
+ : parent
190
+ ? "parent"
191
+ : spell(actor);
192
+ const at = (key: string) => {
193
+ const value = slot(action, key);
194
+ if (value?.kind !== "block") return value ? spell(value) : undefined;
195
+ const instant = slot(value, "at");
196
+ const offset = slot(value, "offset");
197
+ if (!instant) return spell(value);
198
+ return offset ? `${spell(instant)} + ${spell(offset)}` : spell(instant);
199
+ };
200
+ const due = at("due");
201
+ const deadline = at("deadline");
202
+ const requires = clauses(action, "requires", spell);
203
+ const moves = clauses(action, "moves", spell);
204
+ const invokes = items(slot(action, "invoke")).flatMap((item) =>
205
+ item.kind === "block" ? [invocation(item, spell, prefix)] : [],
206
+ );
207
+ const from = slot(action, "from");
208
+ const to = slot(action, "to");
209
+ const guide: TemplateGuideAction = {
210
+ name: prefix + entry.key.slice(7),
211
+ runBy,
212
+ ...(from ? { from: spell(from) } : {}),
213
+ ...(to ? { to: spell(to) } : {}),
214
+ ...(due ? { due } : {}),
215
+ ...(deadline ? { deadline } : {}),
216
+ ...(requires.length ? { requires } : {}),
217
+ ...(moves.length ? { moves } : {}),
218
+ ...(invokes.length ? { invokes } : {}),
219
+ };
220
+ const when = timing(guide, parentActions);
221
+ result.push(when ? { ...guide, when } : guide);
222
+ }
223
+ const records = slot(body, "records");
224
+ if (records?.kind === "block")
225
+ for (const record of records.entries)
226
+ if (record.value.kind === "block")
227
+ result.push(
228
+ ...guideActions(
229
+ record.value,
230
+ spell,
231
+ `${prefix}${record.key}.`,
232
+ prefix ? parentActions : result,
233
+ ),
234
+ );
235
+ return result;
236
+ }
237
+
238
+ function invocation(
239
+ block: BlockExpr,
240
+ spell: (expression: Expr) => string,
241
+ prefix: string,
242
+ ) {
243
+ const instrument = slot(block, "instrument");
244
+ const action = slot(block, "action");
245
+ const target = `${instrument ? `${prefix}${spell(instrument)}.` : ""}${action ? spell(action) : "?"}`;
246
+ const range = slot(block, "range");
247
+ const count = range?.kind === "block" ? slot(range, "count") : undefined;
248
+ const literal =
249
+ count?.kind === "block" ? (slot(count, "literal") ?? count) : count;
250
+ const selection = slot(block, "selection");
251
+ const selected =
252
+ selection?.kind === "block" ? slot(selection, "instrument") : undefined;
253
+ return literal
254
+ ? `${target}, ${spell(literal)} times`
255
+ : selected
256
+ ? `${target} on each matching ${spell(selected)}`
257
+ : target;
258
+ }
259
+
260
+ /**
261
+ * The runtime's timing rules, applied to one action: a clock action that
262
+ * needs a record in another state waits, and the action that moves the
263
+ * record there collects it in the same request (docs/public/runtime.md).
264
+ */
265
+ function timing(
266
+ action: TemplateGuideAction,
267
+ parentActions: TemplateGuideAction[],
268
+ ): string | undefined {
269
+ if (action.runBy === "clock" && action.due) {
270
+ const waits = (action.requires ?? []).flatMap((requirement) => {
271
+ const match = requirement.match(/^self\.\w+ in \[([^\]]+)\]$/);
272
+ return match ? [{ requirement, states: match[1]!.split(/,\s*/) }] : [];
273
+ });
274
+ const openers = parentActions
275
+ .filter((parent) =>
276
+ waits.some((wait) => wait.states.includes(parent.to ?? "")),
277
+ )
278
+ .map((parent) => parent.name);
279
+ return [
280
+ `The clock runs it at ${action.due}.`,
281
+ ...waits.map(
282
+ (wait) => `While ${wait.requirement} does not hold, it waits.`,
283
+ ),
284
+ ...(openers.length
285
+ ? [
286
+ `${openers.join(" or ")} collects every one already due in the same request.`,
287
+ ]
288
+ : []),
289
+ ].join(" ");
290
+ }
291
+ const parts = [
292
+ ...(action.due
293
+ ? [`Runnable from ${action.due}; ${action.runBy} still runs it.`]
294
+ : []),
295
+ ...(action.deadline ? [`Refused after ${action.deadline}.`] : []),
296
+ ];
297
+ return parts.length ? parts.join(" ") : undefined;
298
+ }
299
+
300
+ function partyMeaning(name: string, actions: TemplateGuideAction[]) {
301
+ const runs = actions.filter((action) => action.runBy === name);
302
+ const pays = actions.filter((action) =>
303
+ action.moves?.some((move) => new RegExp(`\\bfrom ${name}\\b`).test(move)),
304
+ );
305
+ const receives = actions.filter((action) =>
306
+ action.moves?.some((move) => new RegExp(`\\bto ${name}\\b`).test(move)),
307
+ );
308
+ const names = (list: TemplateGuideAction[]) =>
309
+ list.map((action) => action.name).join(", ");
310
+ const parts = [
311
+ ...(runs.length ? [`Runs ${names(runs)}.`] : []),
312
+ ...(pays.length ? [`Pays in ${names(pays)}.`] : []),
313
+ ...(receives.length ? [`Receives in ${names(receives)}.`] : []),
314
+ ];
315
+ return parts.length
316
+ ? parts.join(" ")
317
+ : "Named by the template; runs no action and moves no money itself.";
318
+ }
319
+
320
+ /**
321
+ * A value tunable's meaning is where it lands: the fields it sets and every
322
+ * field or action that reads those fields, spelled as the std writes them.
323
+ */
324
+ function valueMeaning(
325
+ name: string,
326
+ fallback: string | undefined,
327
+ decl: InstrumentDecl,
328
+ spell: (expression: Expr) => string,
329
+ ) {
330
+ const bare = new RegExp(`(?<![\\w.])${name}(?!\\w)`);
331
+ const fields = slot(decl.body, "fields");
332
+ const set =
333
+ fields?.kind === "block"
334
+ ? fields.entries.filter((entry) => bare.test(fieldValue(entry, spell)))
335
+ : [];
336
+ const read = new Set(set.map((entry) => entry.key));
337
+ const uses: string[] = [];
338
+ const visit = (body: BlockExpr, prefix: string, parentRefs: string[]) => {
339
+ const own = slot(body, "fields");
340
+ const reads = (text: string) =>
341
+ bare.test(text) ||
342
+ [...read].some((field) =>
343
+ prefix
344
+ ? parentRefs.some((ref) =>
345
+ new RegExp(`\\bself\\.${ref}\\.${field}\\b`).test(text),
346
+ )
347
+ : new RegExp(`\\bself\\.${field}\\b`).test(text),
348
+ );
349
+ if (own?.kind === "block" && prefix)
350
+ for (const entry of own.entries) {
351
+ const value = fieldValue(entry, spell);
352
+ if (reads(value)) uses.push(`${prefix}${entry.key}: ${value}`);
353
+ }
354
+ for (const entry of body.entries) {
355
+ if (!entry.key.startsWith("action ") || entry.value.kind !== "block")
356
+ continue;
357
+ for (const part of entry.value.entries) {
358
+ if (["actor", "from", "to", "summary"].includes(part.key)) continue;
359
+ const text = spell(part.value);
360
+ // A long slot, such as an invoke list, is named rather than spelled.
361
+ if (reads(text))
362
+ uses.push(
363
+ `${prefix}${entry.key.slice(7)} ${part.key}${text.length > 100 ? "" : `: ${text}`}`,
364
+ );
365
+ }
366
+ }
367
+ const records = slot(body, "records");
368
+ if (records?.kind === "block")
369
+ for (const record of records.entries) {
370
+ if (record.value.kind !== "block") continue;
371
+ const recordFields = slot(record.value, "fields");
372
+ const refs =
373
+ recordFields?.kind === "block"
374
+ ? recordFields.entries
375
+ .filter((entry) =>
376
+ /^ref<parent>/.test(fieldValue(entry, spell)),
377
+ )
378
+ .map((entry) => entry.key)
379
+ : [];
380
+ visit(record.value, `${prefix}${record.key}.`, refs);
381
+ }
382
+ };
383
+ visit(decl.body, "", []);
384
+ const parts = [
385
+ ...(fallback === "runtime"
386
+ ? [
387
+ `Leave it out of the attach and create takes ${name} for each record, or bind one fixed value.`,
388
+ ]
389
+ : []),
390
+ ...(set.length
391
+ ? [
392
+ `Sets ${set.map((entry) => `${entry.key}: ${fieldValue(entry, spell)}`).join(", ")}.`,
393
+ ]
394
+ : []),
395
+ ...(uses.length ? [`Read by ${uses.slice(0, 6).join("; ")}.`] : []),
396
+ ];
397
+ return parts.length ? parts.join(" ") : "Configures the template.";
398
+ }
399
+
400
+ function fieldValue(entry: Entry, spell: (expression: Expr) => string) {
401
+ return entry.value.kind === "default"
402
+ ? `${spell(entry.value.type)} = ${spell(entry.value.value)}`
403
+ : spell(entry.value);
404
+ }
405
+
406
+ interface Example {
407
+ attachment: string;
408
+ render(exposes: string[]): string;
409
+ }
410
+
411
+ /**
412
+ * The template's attach from the catalog program, with every attach it names
413
+ * and the parties and headers those need.
414
+ */
415
+ function exampleProgram(
416
+ qualifiedName: string,
417
+ library: StandardLibrary,
418
+ ): Example {
419
+ const program = parseProgram(catalogProgramSource).program;
420
+ const object = program.decls.find((decl) => decl.kind === "object");
421
+ if (object?.kind !== "object")
422
+ throw new Error("catalog program has no object");
423
+ const attaches = object.body.entries.flatMap((entry) => {
424
+ const match = entry.key.match(/^attach (\w+) = (\w+)\.(\w+)$/);
425
+ return match
426
+ ? [
427
+ {
428
+ entry,
429
+ name: match[1]!,
430
+ header: match[2]!,
431
+ template: `${match[2]}.${match[3]}`,
432
+ },
433
+ ]
434
+ : [];
435
+ });
436
+ const target = attaches.find((attach) => attach.template === qualifiedName);
437
+ if (!target)
438
+ throw new Error(`catalog program does not attach ${qualifiedName}`);
439
+ const referenced = (expression: Expr): string[] => {
440
+ if (expression.kind === "name") return [expression.value.split(".")[0]!];
441
+ if (expression.kind === "list") return expression.items.flatMap(referenced);
442
+ if (expression.kind === "block")
443
+ return expression.entries.flatMap((entry) => referenced(entry.value));
444
+ return [];
445
+ };
446
+ // A parameter that defaults to object(header.template) binds the sibling
447
+ // attach of that template, so the example carries that attach too.
448
+ const templates = new Map(
449
+ headerManifest(library).headers.flatMap((header) =>
450
+ header.objects.map((object) => [object.qualifiedName, object] as const),
451
+ ),
452
+ );
453
+ const siblings = (template: string) =>
454
+ (templates.get(template)?.tunables ?? []).flatMap((tunable) => {
455
+ const match = tunable.default?.match(/^object\((\w+\.\w+)\)$/);
456
+ const sibling = match
457
+ ? attaches.find((attach) => attach.template === match[1])
458
+ : undefined;
459
+ return sibling ? [sibling.name] : [];
460
+ });
461
+ const names = new Set<string>();
462
+ const include = (name: string) => {
463
+ if (names.has(name)) return;
464
+ const attach = attaches.find((candidate) => candidate.name === name);
465
+ if (!attach) return;
466
+ names.add(name);
467
+ [...referenced(attach.entry.value), ...siblings(attach.template)].forEach(
468
+ include,
469
+ );
470
+ };
471
+ include(target.name);
472
+ const included = attaches.filter((attach) => names.has(attach.name));
473
+ const used = new Set(
474
+ included.flatMap((attach) => referenced(attach.entry.value)),
475
+ );
476
+ const text = (span: { start: number; end: number }) =>
477
+ catalogProgramSource.slice(span.start, span.end).trim();
478
+ return {
479
+ attachment: target.name,
480
+ render: (exposes) =>
481
+ [
482
+ `program example "${qualifiedName} example"`,
483
+ ...new Set(included.map((attach) => `use ${attach.header}`)),
484
+ ...program.decls.flatMap((decl) =>
485
+ decl.kind === "party" && used.has(decl.name) ? [text(decl.span)] : [],
486
+ ),
487
+ `object item "Item" {`,
488
+ ...included.map((attach) => {
489
+ const line = text(attach.entry.span);
490
+ return wrapAttach(
491
+ attach === target && exposes.length
492
+ ? line.replace(/\s*\}$/, `, ${exposes.join(", ")} }`)
493
+ : line,
494
+ );
495
+ }),
496
+ "}",
497
+ ].join("\n"),
498
+ };
499
+ }
500
+
501
+ /** An attach line within 76 columns, else one binding per line. */
502
+ function wrapAttach(line: string): string {
503
+ if (line.length <= 74) return ` ${line}`;
504
+ const open = line.indexOf("{");
505
+ const items: string[] = [];
506
+ let depth = 0;
507
+ let quoted = false;
508
+ let start = open + 1;
509
+ for (let index = start; index < line.length - 1; index++) {
510
+ const char = line[index]!;
511
+ if (char === '"') quoted = !quoted;
512
+ if (quoted) continue;
513
+ if ("{[(".includes(char)) depth++;
514
+ if ("}])".includes(char)) depth--;
515
+ if (char === "," && depth === 0) {
516
+ items.push(line.slice(start, index).trim());
517
+ start = index + 1;
518
+ }
519
+ }
520
+ items.push(line.slice(start, line.lastIndexOf("}")).trim());
521
+ return [
522
+ ` ${line.slice(0, open + 1)}`,
523
+ ...items.map((item) => ` ${item},`),
524
+ " }",
525
+ ].join("\n");
526
+ }
527
+
528
+ type GuideOptions = Pick<CompileOptions, "adapterRegistry"> & {
529
+ library?: StandardLibrary;
530
+ };
531
+
532
+ /** The example's compiled root instrument, or the compiler's refusal. */
533
+ function compiledAttachment(
534
+ source: string,
535
+ attachment: string,
536
+ options: GuideOptions,
537
+ ) {
538
+ const result = compile(source, {
539
+ ...(options.library ? { standardLibrary: options.library } : {}),
540
+ ...(options.adapterRegistry
541
+ ? { adapterRegistry: options.adapterRegistry }
542
+ : {}),
543
+ });
544
+ const document = result.artifacts?.document;
545
+ if (!document)
546
+ throw new Error(
547
+ `${attachment} example does not compile: ${result.diagnostics.map((d) => d.message).join("; ")}`,
548
+ );
549
+ const instrumentId = document.objects
550
+ .flatMap((object) => object.attachments)
551
+ .find((candidate) => candidate.name === attachment)?.instrument;
552
+ const instrument = document.instruments.find(
553
+ (candidate) => candidate.id === instrumentId,
554
+ );
555
+ if (!instrument) throw new Error(`${attachment} example has no instrument`);
556
+ return instrument;
557
+ }
558
+
559
+ function inputType(field: Record<string, unknown>) {
560
+ const type = String(field.type);
561
+ if (type === "list")
562
+ return `list of ${String(field.item)}${field.maxItems === undefined ? "" : `, at most ${String(field.maxItems)}`}`;
563
+ if (type === "ref" && field.target) return `ref to ${String(field.target)}`;
564
+ if (type === "enum" && Array.isArray(field.values))
565
+ return `one of ${field.values.join(", ")}`;
566
+ return type;
567
+ }