From accd4b2240c89d4e2b483b4c96fc26d42fd1de06 Mon Sep 17 00:00:00 2001 From: Thundercracker Date: Wed, 24 Jun 2026 01:28:46 +0000 Subject: [PATCH 1/3] =?UTF-8?q?feat!:=20drop=20`self.`=20qualifier=20?= =?UTF-8?q?=E2=80=94=20same-node=20calls=20are=20bare=20`Name(args)`=20(re?= =?UTF-8?q?fs=20#71)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the `self.` qualifier (ADR-041, supersedes ADR-004): a same-node callable is invoked by a bare call `Name(args)`. The sequence renderer now follows a same-node call's body inline, ending the silent-drop trap where a cross-system call inside a `self.`-delegated helper never reached the diagram. Spec (LANG.md §3.3/§5.1/§8.1/§9.2/§10, ADR-041), conformance cases, the self-model, samples, the authoring skill, completion/inference/references, and the regenerated wasm + doc site are all migrated. Co-Authored-By: Claude Opus 4.8 --- .claude/skills/pseudocode/SKILL.md | 2 +- CONFORMANCE/generation/README.md | 2 +- CONFORMANCE/static/3-3-unresolved-type.pds | 2 +- CONFORMANCE/static/5-1-arg-type-mismatch.pds | 2 +- CONFORMANCE/static/5-1-call-arity.pds | 2 +- .../5-1-self-call-unresolved.diagnostics | 2 +- .../static/5-1-self-call-unresolved.pds | 4 +- CONFORMANCE/static/5-missing-return.pds | 2 +- CONFORMANCE/static/6-option-value-on-none.pds | 2 +- .../7-from-expr-conversion-mismatch.pds | 2 +- CONFORMANCE/static/7-from-expr-ok.pds | 2 +- CONFORMANCE/static/7-from-result-target.pds | 2 +- CONFORMANCE/static/7-rebind-rejected.pds | 4 +- CONFORMANCE/syntax/3-option.pds | 2 +- CONFORMANCE/syntax/5-self-call.pds | 4 +- CONFORMANCE/syntax/5-self-removed.reject | 11 ++ .../syntax/5-self-removed.reject.expected | 1 + CONFORMANCE/syntax/7-chaining.pds | 2 +- CONFORMANCE/syntax/7-from-expr.pds | 4 +- CONFORMANCE/syntax/7-statements.pds | 4 +- LANG.md | 15 +-- crates/pseudoscript-emit/src/project.rs | 60 +++++++-- .../tests/features/svg.feature | 25 ++++ crates/pseudoscript-format/src/printer.rs | 25 ++-- .../tests/features/golden.feature | 4 +- crates/pseudoscript-format/tests/format.rs | 2 +- .../tests/completion_adversarial.rs | 2 +- crates/pseudoscript-lsp-core/src/analysis.rs | 2 +- crates/pseudoscript-lsp-core/src/refs.rs | 4 +- .../tests/features/semantic_tokens.feature | 5 +- crates/pseudoscript-model/src/check.rs | 119 +++++++++++------- .../src/check/cross_module.rs | 8 +- .../src/check/result_flow.rs | 5 + crates/pseudoscript-model/src/complete.rs | 46 +++++-- crates/pseudoscript-model/src/graph.rs | 59 +++++---- crates/pseudoscript-model/src/infer.rs | 17 ++- crates/pseudoscript-model/src/resolve.rs | 31 ++++- crates/pseudoscript-model/src/semantic.rs | 11 +- .../pseudoscript-model/tests/conformance.rs | 5 +- .../tests/features/argument_types.feature | 6 +- .../tests/features/call_arity.feature | 6 +- .../tests/features/conditions.feature | 2 +- .../tests/features/cross_module.feature | 6 +- .../tests/features/graph.feature | 12 +- .../tests/features/member_calls.feature | 4 +- .../tests/features/rules.feature | 10 +- .../tests/features/self_calls.feature | 31 +++-- .../tests/features/suggestions.feature | 4 +- crates/pseudoscript-syntax/src/ast.rs | 12 +- crates/pseudoscript-syntax/src/parser.rs | 88 ++++++++++--- .../pseudoscript-syntax/tests/conformance.rs | 2 +- crates/pseudoscript/tests/eval.rs | 2 +- decisions/041-drop-self-qualifier.md | 32 +++++ decisions/README.md | 8 +- model/cli.pds | 78 ++++++------ model/doc.pds | 116 ++++++++--------- model/dot.pds | 6 +- model/emit.pds | 118 ++++++++--------- model/format.pds | 11 +- model/ide.pds | 50 ++++---- model/lsp.pds | 22 ++-- model/model.pds | 48 +++---- model/project.pds | 4 +- model/site/health.html | 2 +- model/site/index.html | 2 +- model/site/module/cli.html | 22 ++-- model/site/module/context.html | 4 +- model/site/module/doc.html | 36 +++--- model/site/module/dot.html | 8 +- model/site/module/emit.html | 21 ++-- model/site/module/format.html | 8 +- model/site/module/ide.html | 20 +-- model/site/module/landing.html | 2 +- model/site/module/layout.html | 4 +- model/site/module/lsp.html | 8 +- model/site/module/lsp_core.html | 6 +- model/site/module/model.html | 26 ++-- model/site/module/project.html | 4 +- model/site/module/syntax.html | 29 ++--- model/site/module/universe.html | 18 +-- model/site/search-index.js | 2 +- model/site/universe.html | 6 +- model/syntax.pds | 28 +++-- model/universe.pds | 22 ++-- web-ide/src/lib/bundled/LANG.md | 15 +-- .../src/lib/components/RenameDialog.test.ts | 2 +- web-ide/src/lib/fim-context.ts | 2 +- .../lib/pds-ide-wasm/pseudoscript_ide_bg.wasm | Bin 2400200 -> 2404898 bytes .../lib/samples/acme-payments/backoffice.pds | 6 +- .../src/lib/samples/acme-payments/charges.pds | 58 ++++----- .../lib/samples/acme-payments/disputes.pds | 30 ++--- .../src/lib/samples/acme-payments/gateway.pds | 22 ++-- .../lib/samples/acme-payments/identity.pds | 2 +- .../src/lib/samples/acme-payments/intents.pds | 70 +++++------ .../src/lib/samples/acme-payments/ledger.pds | 12 +- .../samples/acme-payments/notifications.pds | 6 +- .../src/lib/samples/acme-payments/payouts.pds | 28 ++--- .../src/lib/samples/acme-payments/refunds.pds | 8 +- .../src/lib/samples/acme-payments/vault.pds | 6 +- .../lib/samples/acme-payments/webhooks.pds | 24 ++-- .../lib/samples/acme-tickets/backoffice.pds | 6 +- .../src/lib/samples/acme-tickets/catalog.pds | 6 +- .../src/lib/samples/acme-tickets/identity.pds | 10 +- .../lib/samples/acme-tickets/inventory.pds | 32 ++--- .../samples/acme-tickets/notifications.pds | 6 +- .../src/lib/samples/acme-tickets/orders.pds | 40 +++--- .../src/lib/samples/acme-tickets/payments.pds | 46 +++---- .../src/lib/samples/acme-tickets/pricing.pds | 12 +- .../src/lib/samples/acme-tickets/tickets.pds | 12 +- .../lib/samples/acme-tickets/waitingroom.pds | 12 +- web-ide/static/pseudocode-skill.zip | Bin 20933 -> 21086 bytes 111 files changed, 1124 insertions(+), 808 deletions(-) create mode 100644 CONFORMANCE/syntax/5-self-removed.reject create mode 100644 CONFORMANCE/syntax/5-self-removed.reject.expected create mode 100644 decisions/041-drop-self-qualifier.md diff --git a/.claude/skills/pseudocode/SKILL.md b/.claude/skills/pseudocode/SKILL.md index a857b08d..fd713e2a 100644 --- a/.claude/skills/pseudocode/SKILL.md +++ b/.claude/skills/pseudocode/SKILL.md @@ -257,7 +257,7 @@ public container Checkout for shop::Shop { if (reserved.isErr) { return Err(reserved.error) } - quote = number from self.Quote(cmd.sku, cmd.qty) + quote = number from Quote(cmd.sku, cmd.qty) order = shop::Order from { cmd, quote } paid = Result from shop::Payments.charge(order) if (paid.isErr) { diff --git a/CONFORMANCE/generation/README.md b/CONFORMANCE/generation/README.md index d303f55d..c295990d 100644 --- a/CONFORMANCE/generation/README.md +++ b/CONFORMANCE/generation/README.md @@ -38,7 +38,7 @@ frame "" # opens a frame; nested lines indent t ``` - **Participants** in order of first appearance in the trace; the entry's owner is first. A real trigger actor (client/scheduler/event) leads as its own lifeline and receives the entry's returns. A callable with no trigger omits the generic `caller` participant — the owner leads, and the entry's returns to that absent caller are suppressed (they reappear once a real incoming trigger exists). -- **Messages** in body evaluation order (§7). A chained expression emits one `message` per call, left-to-right; a `self.` call is `self` kind (from owner to owner). A `return` is a `return` message back to the caller. Every call has a matching return: a call to a disclosed callable expands inline and returns through its body; a call to a bodyless callable emits a synthesised `return ""` from callee to caller (the out-and-back response), its label empty and detail the callee's return type. +- **Messages** in body evaluation order (§7). A chained expression emits one `message` per call, left-to-right; a same-node call `Name(args)` is `self` kind (from owner to owner) and expands its disclosed body inline, a method on a local value stays a leaf `self` message (LANG.md §9.2, ADR-041). A `return` is a `return` message back to the caller. Every call has a matching return: a call to a disclosed callable expands inline and returns through its body; a call to a bodyless callable emits a synthesised `return ""` from callee to caller (the out-and-back response), its label empty and detail the callee's return type. - **Frames**: `if`/`else` → `frame alt`; `for`/`while` → `frame loop`. The frame's body messages indent two spaces under it; a closing line is implicit at the dedent. An `else` arm emits a second `frame alt "else "`. An `if` whose then-arm ends in `return` and has no `else` is a guard clause: the steps following it in the same block run only when the guard is false, so they emit as that second `frame alt "else "`. A branch (then or else) whose traced body is empty — e.g. its only step is a return suppressed for a triggerless entry — emits no frame. ### Data entity view (`data`) diff --git a/CONFORMANCE/static/3-3-unresolved-type.pds b/CONFORMANCE/static/3-3-unresolved-type.pds index 5330268e..994916aa 100644 --- a/CONFORMANCE/static/3-3-unresolved-type.pds +++ b/CONFORMANCE/static/3-3-unresolved-type.pds @@ -7,6 +7,6 @@ public system S; public container C for S { - ping(): Ghost { return self.pong() } + ping(): Ghost { return pong() } pong(): number { return 1 } } diff --git a/CONFORMANCE/static/5-1-arg-type-mismatch.pds b/CONFORMANCE/static/5-1-arg-type-mismatch.pds index 9a82d5ff..0df505dc 100644 --- a/CONFORMANCE/static/5-1-arg-type-mismatch.pds +++ b/CONFORMANCE/static/5-1-arg-type-mismatch.pds @@ -6,6 +6,6 @@ public system S; public container C for S { - run(): void { self.take("x") } + run(): void { take("x") } take(n: number): void { } } diff --git a/CONFORMANCE/static/5-1-call-arity.pds b/CONFORMANCE/static/5-1-call-arity.pds index e4e4f9b0..57094f72 100644 --- a/CONFORMANCE/static/5-1-call-arity.pds +++ b/CONFORMANCE/static/5-1-call-arity.pds @@ -6,6 +6,6 @@ public system S; public container C for S { - run(): void { self.add(1, 2, 3) } + run(): void { add(1, 2, 3) } add(a: number, b: number): number { return a } } diff --git a/CONFORMANCE/static/5-1-self-call-unresolved.diagnostics b/CONFORMANCE/static/5-1-self-call-unresolved.diagnostics index fd02f2eb..10d3a5d4 100644 --- a/CONFORMANCE/static/5-1-self-call-unresolved.diagnostics +++ b/CONFORMANCE/static/5-1-self-call-unresolved.diagnostics @@ -1 +1 @@ -`self.missing` does not name a callable of `C` +`missing` does not name a callable of `C` diff --git a/CONFORMANCE/static/5-1-self-call-unresolved.pds b/CONFORMANCE/static/5-1-self-call-unresolved.pds index 5b71e06f..9b2925c9 100644 --- a/CONFORMANCE/static/5-1-self-call-unresolved.pds +++ b/CONFORMANCE/static/5-1-self-call-unresolved.pds @@ -1,4 +1,4 @@ -// LANG.md §5.1 (ADR-004): `self.Name(args)` must name a callable of the +// LANG.md §5.1 (ADR-041): `Name(args)` must name a callable of the // enclosing node. `missing` is not declared on `C`. //! example @@ -6,5 +6,5 @@ public system S; public container C for S { - run(): void { self.missing() } + run(): void { missing() } } diff --git a/CONFORMANCE/static/5-missing-return.pds b/CONFORMANCE/static/5-missing-return.pds index 94a952da..e5a3cca4 100644 --- a/CONFORMANCE/static/5-missing-return.pds +++ b/CONFORMANCE/static/5-missing-return.pds @@ -10,7 +10,7 @@ public system Banking; public container Mainframe for Banking { Get(): Result { - r = Result from self.Fetch() + r = Result from Fetch() if (r.isErr) { return Err(r.error) } diff --git a/CONFORMANCE/static/6-option-value-on-none.pds b/CONFORMANCE/static/6-option-value-on-none.pds index 7c76d7c4..cae0208d 100644 --- a/CONFORMANCE/static/6-option-value-on-none.pds +++ b/CONFORMANCE/static/6-option-value-on-none.pds @@ -10,7 +10,7 @@ public system Registry; public container Directory for Registry { public find(id: number): Option { - o = Option from self.lookup(id) + o = Option from lookup(id) if (o.isNone) { return Some(o.value) } diff --git a/CONFORMANCE/static/7-from-expr-conversion-mismatch.pds b/CONFORMANCE/static/7-from-expr-conversion-mismatch.pds index fee29176..5a430720 100644 --- a/CONFORMANCE/static/7-from-expr-conversion-mismatch.pds +++ b/CONFORMANCE/static/7-from-expr-conversion-mismatch.pds @@ -10,6 +10,6 @@ public data Dog; public system Zoo; public container Pen for Zoo { - AdoptCat(): Cat { return Cat from self.MakeDog() } + AdoptCat(): Cat { return Cat from MakeDog() } MakeDog(): Dog; } diff --git a/CONFORMANCE/static/7-from-expr-ok.pds b/CONFORMANCE/static/7-from-expr-ok.pds index c1b89aa1..c2b1433e 100644 --- a/CONFORMANCE/static/7-from-expr-ok.pds +++ b/CONFORMANCE/static/7-from-expr-ok.pds @@ -8,6 +8,6 @@ public data Cat; public system Zoo; public container Pen for Zoo { - AdoptCat(): Cat { return Cat from self.MakeCat() } + AdoptCat(): Cat { return Cat from MakeCat() } MakeCat(): Cat; } diff --git a/CONFORMANCE/static/7-from-result-target.pds b/CONFORMANCE/static/7-from-result-target.pds index 7c8e4654..2a6b38ca 100644 --- a/CONFORMANCE/static/7-from-result-target.pds +++ b/CONFORMANCE/static/7-from-result-target.pds @@ -10,7 +10,7 @@ public system Banking; public container Mainframe for Banking { Get(): Result { - r = Result from self.Fetch() + r = Result from Fetch() return r } Fetch(): Result; diff --git a/CONFORMANCE/static/7-rebind-rejected.pds b/CONFORMANCE/static/7-rebind-rejected.pds index 764860b1..4309bd56 100644 --- a/CONFORMANCE/static/7-rebind-rejected.pds +++ b/CONFORMANCE/static/7-rebind-rejected.pds @@ -9,8 +9,8 @@ public system Banking; public container Mainframe for Banking { Run(): void { - r = Info from self.Make() - r = Info from self.Make() + r = Info from Make() + r = Info from Make() } Make(): Info; } diff --git a/CONFORMANCE/syntax/3-option.pds b/CONFORMANCE/syntax/3-option.pds index 9ae7f496..ae15a327 100644 --- a/CONFORMANCE/syntax/3-option.pds +++ b/CONFORMANCE/syntax/3-option.pds @@ -10,7 +10,7 @@ public system Registry; public container Directory for Registry { /// The optional person on file for an id. public find(id: number): Option { - o = Option from self.lookup(id) + o = Option from lookup(id) if (o.isNone) { return None } diff --git a/CONFORMANCE/syntax/5-self-call.pds b/CONFORMANCE/syntax/5-self-call.pds index f868d685..f084b168 100644 --- a/CONFORMANCE/syntax/5-self-call.pds +++ b/CONFORMANCE/syntax/5-self-call.pds @@ -1,10 +1,10 @@ -// LANG.md §5 (ADR-004): a same-node callable is invoked via `self.Name(args)`. +// LANG.md §5 (ADR-041): a same-node callable is invoked via `Name(args)`. public system Banking; public container Mainframe for Banking { A(): void { - self.B() + B() } B(): void; } diff --git a/CONFORMANCE/syntax/5-self-removed.reject b/CONFORMANCE/syntax/5-self-removed.reject new file mode 100644 index 00000000..6ed00e70 --- /dev/null +++ b/CONFORMANCE/syntax/5-self-removed.reject @@ -0,0 +1,11 @@ +// LANG.md §5.1 (ADR-041): the `self.` qualifier was removed. A same-node call +// is bare `Name(args)`; `self.Name(args)` no longer parses. + +public system Banking; + +public container Mainframe for Banking { + A(): void { + self.B() + } + B(): void; +} diff --git a/CONFORMANCE/syntax/5-self-removed.reject.expected b/CONFORMANCE/syntax/5-self-removed.reject.expected new file mode 100644 index 00000000..a87c9f2f --- /dev/null +++ b/CONFORMANCE/syntax/5-self-removed.reject.expected @@ -0,0 +1 @@ +`self.` is removed; call `Name(args)` directly (ADR-041) diff --git a/CONFORMANCE/syntax/7-chaining.pds b/CONFORMANCE/syntax/7-chaining.pds index bab60bff..699dbcba 100644 --- a/CONFORMANCE/syntax/7-chaining.pds +++ b/CONFORMANCE/syntax/7-chaining.pds @@ -8,6 +8,6 @@ data Info { owner: string } public container Mainframe for Banking { Run(): void { a = string from Store::Repo.fetch(1).value.owner - b = string from self.Pick().first().tag + b = string from Pick().first().tag } } diff --git a/CONFORMANCE/syntax/7-from-expr.pds b/CONFORMANCE/syntax/7-from-expr.pds index c1e281d0..382bf91b 100644 --- a/CONFORMANCE/syntax/7-from-expr.pds +++ b/CONFORMANCE/syntax/7-from-expr.pds @@ -10,8 +10,8 @@ public system Zoo; public container Pen for Zoo { Make(): Cat { - c = Cat from self.fetch() - cats = Cat[] from self.fetchMany() + c = Cat from fetch() + cats = Cat[] from fetchMany() return c } fetch(): Cat; diff --git a/CONFORMANCE/syntax/7-statements.pds b/CONFORMANCE/syntax/7-statements.pds index 6210cce6..1dd8ae22 100644 --- a/CONFORMANCE/syntax/7-statements.pds +++ b/CONFORMANCE/syntax/7-statements.pds @@ -17,10 +17,10 @@ public container Mainframe for Banking { x = BankingInfo from a.value } while (cond) { - self.step() + step() } for (item in items) { - self.handle(item) + handle(item) } } } diff --git a/LANG.md b/LANG.md index 10f53ac8..71f84ee1 100644 --- a/LANG.md +++ b/LANG.md @@ -123,7 +123,7 @@ Option // optional value: Some(T) | None ### 3.3 Type expressions A named type (`BankingInfo`), generic (`Result`, `Option`), or array (`T[]`). `[]` is the only type suffix; an absent value is modeled with `Option` (§6). -Every named type — a field, parameter, or return type, and each generic argument — MUST resolve to a primitive (§3.1), `Result`/`Option` (§3.2), or a declared type or node (§3.4, §3.5, §4); an unresolved type MUST be rejected (ADR-022). A reference to a declared type or node MUST be its FQN (§8.1), including one in the same module; only primitives, `Result`/`Option`, and `self` are bare. +Every named type — a field, parameter, or return type, and each generic argument — MUST resolve to a primitive (§3.1), `Result`/`Option` (§3.2), or a declared type or node (§3.4, §3.5, §4); an unresolved type MUST be rejected (ADR-022). A reference to a declared type or node MUST be its FQN (§8.1), including one in the same module; only primitives and `Result`/`Option` are bare. ### 3.4 Data declarations A `data` type models any payload — DTOs, entities, messages alike. It MAY stay a **black box** with `;` (fields not yet disclosed). @@ -224,8 +224,8 @@ A function-shaped declaration is a callable. - All calls are request/response. A call to a resolvable callable MUST pass one argument per declared parameter, and each inferable argument MUST match its parameter's type; a wrong arity or argument type MUST be rejected (ADR-022, ADR-023). - Every callable MUST declare a return type; a callable without one MUST be rejected (ADR-040). `void` declares that no value is returned. A disclosed non-`void` callable MUST return a value on every path. - A `return` operand whose type is determinable — a literal, an `Ok`/`Err`/`Some`/`None` marker (§6), a `from` (§7.2), a typed binding, or a call to a resolvable callable — MUST match the declared return type; a mismatch MUST be rejected. A union variant satisfies its union type (§3.5). A bare reference resolving to a `data` record or a node is not a value and MUST be rejected (§7.2). -- A bare name in a body MUST resolve to a parameter, a binding, or a `for` binding; it MUST NOT resolve to a node or union variant (ADR-030) — those are referenced by FQN (§8.1). An unresolved bare name MUST be rejected (ADR-022). -- A same-node callable is invoked via `self.Name(args)` (`self` = the enclosing node); this also covers recursion. +- A bare name read as a value MUST resolve to a parameter, a binding, or a `for` binding; it MUST NOT resolve to a node or union variant (ADR-030) — those are referenced by FQN (§8.1). An unresolved bare name MUST be rejected (ADR-022). +- A same-node callable is invoked by a bare call `Name(args)` — a sibling, or the enclosing callable itself for recursion (ADR-041). A bare name in call position MUST resolve to a callable on the enclosing node; one matching no callable on the node MUST be rejected (ADR-022). - A callable's name and its parameter names MUST NOT be reserved words (§2.3) — `container`, `component`, `data`, and `for` are reserved. - A call statement MAY ignore its `Result` (the call still renders as a message). - A black-box callable shows in C4 as a capability; a call to it in a sequence diagram is a single message with no expansion. @@ -402,7 +402,7 @@ Each path segment becomes an FQN segment, which MUST be an identifier (§2.2). A A module has four distinct namespaces: **type names** (`data` declarations and hoisted record variants, §3.5), **node names** (`system`/`container`/`component`/`person`), **feature names** (§5.2), and **value names** (`constant`, §3.6). A name MUST be unique within its namespace; the four do not collide — a `data`, a `container`, a `feature`, and a `constant` MAY share a name. Callable and parameter names are scoped to their owner, not the module. -Every reference to a node, type, union variant, or constant MUST be its FQN, including a reference to one declared in the same module (ADR-030). A bare leaf name MUST NOT resolve to a node, type, variant, or constant; it resolves only to a parameter, a binding, or a `for` binding (§7). `self` and member access (§7.1) are unaffected, as are the primitives (§3.1) and `Result`/`Option` (§3.2). Within `banking/core.pds`, a sibling node is addressed `banking::core::Other`, never `Other`. An FQN names a node by its module path and name only; the system→container→component nesting (§4) is carried by `for`, not the name. A structural drill — a node addressed through its C4 ancestry, `Container::Component` or `module::System::Container::Component` — is not an FQN and MUST NOT resolve (ADR-036). +Every reference to a node, type, union variant, or constant MUST be its FQN, including a reference to one declared in the same module (ADR-030). A bare leaf name read as a value MUST NOT resolve to a node, type, variant, or constant; it resolves only to a parameter, a binding, or a `for` binding (§7). A bare name in call position resolves to a callable on the enclosing node (§5.1, ADR-041). Member access (§7.1) is unaffected, as are the primitives (§3.1) and `Result`/`Option` (§3.2). Within `banking/core.pds`, a sibling node is addressed `banking::core::Other`, never `Other`. An FQN names a node by its module path and name only; the system→container→component nesting (§4) is carried by `for`, not the name. A structural drill — a node addressed through its C4 ancestry, `Container::Component` or `module::System::Container::Component` — is not an FQN and MUST NOT resolve (ADR-036). An FQN's first segment is a **root**. The file-derived module paths above are the local roots; a `[dependencies]` entry (§8.3) adds one root per declared dependency. @@ -453,7 +453,7 @@ From disclosed callables per §7. A **triggered** callable (one bearing a trigge A call to a **disclosed** callee expands inline: the callee becomes the active lifeline, its body traces in place, and each of its `return`s is a return message to its caller's lifeline. A call to a **black-box** callable renders as a single message with no expansion (§5.1). A callee already in flight on the call path (direct or mutual recursion) MUST NOT re-expand; it renders as a single message. -In a chained expression, each call is its own message, emitted left-to-right; field accesses between calls are local. A `self.` call renders as a self-message. +In a chained expression, each call is its own message, emitted left-to-right; field accesses between calls are local. A same-node call (`Name(args)`, §5.1) renders as a self-message and expands its callee's body inline, exactly as a direct call to a disclosed callee does (ADR-041); recursion is stack-guarded as above. A method on a local value or chain intermediate renders as a leaf self-message — it names no node callable and has no body to follow. Each lifeline head card shows the participant's C4 kind and name. A `container` or `component` participant SHOULD also show its `for` ancestry (enclosing node names, outermost first) dimmed beneath the name. Every declared participant SHOULD show its `///` summary, as on a C4 card (§9.1). A synthesised initiator carries neither. @@ -572,11 +572,12 @@ AddExpr = MulExpr { ( "+" | "-" ) MulExpr } ; MulExpr = UnaryExpr { ( "*" | "/" | "%" ) UnaryExpr } ; UnaryExpr = ( "!" | "-" ) UnaryExpr | Postfix ; Postfix = Primary { "." Ident [ "(" [ Args ] ")" ] } ; // field access / call, chained -Primary = Ref | Literal | "(" Expr ")" ; +Primary = Call | Ref | Literal | "(" Expr ")" ; +Call = Ident "(" [ Args ] ")" ; // same-node callable (§5.1) Marker = ( "Ok" | "Err" | "Some" ) [ "(" Expr ")" ] | "None" ; // built-in generic constructors FromExpr = Type "from" ( "{" [ Expr { "," Expr } ] "}" | Expr ) ; // brace source set, or a single value; "[]" target composes an array Args = Expr { "," Expr } ; -Ref = "self" | Ident | Path ; // self or an FQN +Ref = Ident | Path ; // a local name or an FQN Path = Ident { "::" Ident } ; Literal = String | Number | Bool ; diff --git a/crates/pseudoscript-emit/src/project.rs b/crates/pseudoscript-emit/src/project.rs index 3d74546c..63974409 100644 --- a/crates/pseudoscript-emit/src/project.rs +++ b/crates/pseudoscript-emit/src/project.rs @@ -801,6 +801,53 @@ fn project_black_box(graph: &Graph, node: &GraphNode, entry: &str) -> SequenceSc } } +/// A self-message on `active`'s lifeline (from and to itself). +fn self_message(active: &str, method: &str, detail: String) -> SeqItem { + SeqItem::Message(Message { + from: active.to_owned(), + to: active.to_owned(), + kind: MessageKind::SelfMsg, + label: method.to_owned(), + detail, + }) +} + +/// A same-node call (`LANG.md` §9.2, ADR-041): the self-message, then the +/// callee's disclosed body expanded inline on the same lifeline (stack-guarded +/// against recursion), so its cross-boundary calls reach the diagram. A leaf +/// (black-box or in-flight) call needs no synthesised return — the self-message +/// is its own round trip. +fn trace_self_call( + graph: &Graph, + active: &str, + method: &str, + order: &mut Vec, + stack: &mut Vec, +) -> Vec { + let invoked = format!("{active}::{method}"); + let sig = graph.node(&invoked).and_then(|n| n.signature.as_ref()); + let mut items = vec![self_message( + active, + method, + sig.map(call_detail).unwrap_or_default(), + )]; + if let Some(invoked_body) = graph.body(&invoked) + && !stack.iter().any(|f| f == &invoked) + { + stack.push(invoked.clone()); + items.extend(trace_body( + graph, + active, + active, + invoked_body, + order, + stack, + )); + stack.pop(); + } + items +} + /// Traces the body of `active` (the executing node) into ordered items. `caller` /// is the lifeline `active`'s `return`s land on; `stack` is the callables in /// flight. Disclosed callees expand inline (the active lifeline switches to the @@ -857,13 +904,12 @@ fn trace_body( } } Step::SelfCall { method } => { - items.push(SeqItem::Message(Message { - from: active.to_owned(), - to: active.to_owned(), - kind: MessageKind::SelfMsg, - label: method.clone(), - detail: String::new(), - })); + items.extend(trace_self_call(graph, active, method, order, stack)); + } + Step::LocalCall { method } => { + // A method on a local value or chain intermediate: a leaf + // self-message — it names no node callable, no body to follow. + items.push(self_message(active, method, String::new())); } Step::Return { marker } => { // An empty `caller` is the suppressed generic caller (a triggerless diff --git a/crates/pseudoscript-emit/tests/features/svg.feature b/crates/pseudoscript-emit/tests/features/svg.feature index ac508100..6850df40 100644 --- a/crates/pseudoscript-emit/tests/features/svg.feature +++ b/crates/pseudoscript-emit/tests/features/svg.feature @@ -60,3 +60,28 @@ Feature: SVG rendering smoke And the rendered SVG contains "Place" And the rendered SVG contains "Inventory" And the rendered SVG contains "reserve" + + Scenario: a same-node call's downstream cross-node call reaches the sequence (issue #71, ADR-041) + Given the model: + """ + //! chat + public data Event { id: number } + public system Chat; + public container Topic for Chat { + produce(event: chat::Event): void; + } + public container Guest for Chat { + #[manual] + public postMessage(event: chat::Event): void { + sendEvent(event) + } + sendEvent(event: chat::Event): void { + Topic.produce(event) + } + } + """ + When I project the "sequence" view of "chat::Guest::postMessage" + Then the rendered SVG is well-formed + And the rendered SVG contains "sendEvent" + And the rendered SVG contains "Topic" + And the rendered SVG contains "produce" diff --git a/crates/pseudoscript-format/src/printer.rs b/crates/pseudoscript-format/src/printer.rs index 2935ce6a..fe6c96fe 100644 --- a/crates/pseudoscript-format/src/printer.rs +++ b/crates/pseudoscript-format/src/printer.rs @@ -480,6 +480,11 @@ impl Printer { self.write_postfix_seg(seg); } } + // §5.1, ADR-041: a bare same-node call `Name(args)`. + ExprKind::OwnCall { name, args } => { + self.push(&name.name); + self.write_args(args); + } ExprKind::Ref(r) => self.write_ref(r), ExprKind::Literal(lit) => self.write_literal(lit), ExprKind::Unary { op, expr, .. } => { @@ -510,20 +515,24 @@ impl Printer { self.push("."); self.push(&seg.name.name); if let Some(args) = &seg.call_args { - self.push("("); - for (i, arg) in args.iter().enumerate() { - if i > 0 { - self.push(", "); - } - self.write_expr(arg); + self.write_args(args); + } + } + + /// Writes a parenthesised, comma-separated argument list `(a, b)`. + fn write_args(&mut self, args: &[Expr]) { + self.push("("); + for (i, arg) in args.iter().enumerate() { + if i > 0 { + self.push(", "); } - self.push(")"); + self.write_expr(arg); } + self.push(")"); } fn write_ref(&mut self, r: &Ref) { match r { - Ref::SelfNode(_) => self.push("self"), Ref::Path(path) => self.write_path(path), } } diff --git a/crates/pseudoscript-format/tests/features/golden.feature b/crates/pseudoscript-format/tests/features/golden.feature index 05f238d9..fe3679d1 100644 --- a/crates/pseudoscript-format/tests/features/golden.feature +++ b/crates/pseudoscript-format/tests/features/golden.feature @@ -25,9 +25,9 @@ Feature: Golden canonical outputs Then the result equals "public component Repo for S {\n fetch(id: number): Result;\n}\n" Scenario: nested body, control flow, from-composition, and postfix chain - Given the source "public container M for B {\nrun(s:Source):Result{\ntree=Ast from {s.text,s.path}\nx=string from Repo.fetch(id).value.owner\nfor(item in xs){self.handle(item)}\nreturn Ok(tree)\n}\n}" + Given the source "public container M for B {\nrun(s:Source):Result{\ntree=Ast from {s.text,s.path}\nx=string from Repo.fetch(id).value.owner\nfor(item in xs){handle(item)}\nreturn Ok(tree)\n}\n}" When I format it - Then the result equals "public container M for B {\n run(s: Source): Result {\n tree = Ast from { s.text, s.path }\n x = string from Repo.fetch(id).value.owner\n for (item in xs) {\n self.handle(item)\n }\n return Ok(tree)\n }\n}\n" + Then the result equals "public container M for B {\n run(s: Source): Result {\n tree = Ast from { s.text, s.path }\n x = string from Repo.fetch(id).value.owner\n for (item in xs) {\n handle(item)\n }\n return Ok(tree)\n }\n}\n" Scenario: a feature reformats to one step per line Given the source "feature Open for Bank{given \"a\"\nwhen \"b\"\nthen \"c\"}" diff --git a/crates/pseudoscript-format/tests/format.rs b/crates/pseudoscript-format/tests/format.rs index 3ff8e792..e0c84fac 100644 --- a/crates/pseudoscript-format/tests/format.rs +++ b/crates/pseudoscript-format/tests/format.rs @@ -48,7 +48,7 @@ public container Web for Shop { return Err(line.error) } } - r = Result from self.finalize(cart) + r = Result from finalize(cart) return Ok(r.value) } diff --git a/crates/pseudoscript-ide/tests/completion_adversarial.rs b/crates/pseudoscript-ide/tests/completion_adversarial.rs index 56e81600..a0a631cd 100644 --- a/crates/pseudoscript-ide/tests/completion_adversarial.rs +++ b/crates/pseudoscript-ide/tests/completion_adversarial.rs @@ -103,7 +103,7 @@ fn type_position_offers_types_only() { #[test] fn generic_argument_position_offers_types_only() { let l = labels( - "//! m\npublic data Money { amount: number }\npublic system A {\n find(): Result<~ > { return self.find() }\n}\n", + "//! m\npublic data Money { amount: number }\npublic system A {\n find(): Result<~ > { return find() }\n}\n", ); assert!(has(&l, "Money") || has(&l, "number"), "{l:?}"); assert_none(&l, &["public", "container", "feature", "Ok", "Err"]); diff --git a/crates/pseudoscript-lsp-core/src/analysis.rs b/crates/pseudoscript-lsp-core/src/analysis.rs index 060a8a80..12ccddea 100644 --- a/crates/pseudoscript-lsp-core/src/analysis.rs +++ b/crates/pseudoscript-lsp-core/src/analysis.rs @@ -46,7 +46,7 @@ pub struct DefTarget { } /// Resolves the identifier at `position` in module `from_fqn` to its definition -/// — across files and into `self.`/node members. +/// — across files and into same-node calls / node members. #[must_use] pub fn definition( ws: &Workspace, diff --git a/crates/pseudoscript-lsp-core/src/refs.rs b/crates/pseudoscript-lsp-core/src/refs.rs index 6173276e..3c21ddb9 100644 --- a/crates/pseudoscript-lsp-core/src/refs.rs +++ b/crates/pseudoscript-lsp-core/src/refs.rs @@ -163,8 +163,8 @@ mod tests { #[test] fn references_to_an_operation_include_decl_and_calls() { - // An operation's declaration and its `self.`-call are the same symbol. - let src = "//! m\n\nsystem S {\n run(): void { self.op() }\n op(): void {}\n}\n"; + // An operation's declaration and its bare same-node call are the same symbol. + let src = "//! m\n\nsystem S {\n run(): void { op() }\n op(): void {}\n}\n"; let mods = [("m", src)]; let workspace = ws(&mods); let owned = owned(&mods); diff --git a/crates/pseudoscript-lsp/tests/features/semantic_tokens.feature b/crates/pseudoscript-lsp/tests/features/semantic_tokens.feature index 6b020916..f55ea1d2 100644 --- a/crates/pseudoscript-lsp/tests/features/semantic_tokens.feature +++ b/crates/pseudoscript-lsp/tests/features/semantic_tokens.feature @@ -23,12 +23,12 @@ Feature: LSP semantic tokens And the "id" token has type "property" And the "uuid" token has type "type" - Scenario: callables, parameters, types, self, and calls + Scenario: callables, parameters, types, and bare same-node calls Given the inline source: """ system S { run(name: string): uuid { - return self.alloc(name) + return alloc(name) } } """ @@ -37,7 +37,6 @@ Feature: LSP semantic tokens And the "run" token is declared And the "name" token has type "parameter" And the "string" token has type "type" - And the "self" token has type "keyword" And the "alloc" token has type "method" Scenario: a macro invocation is one decorator span diff --git a/crates/pseudoscript-model/src/check.rs b/crates/pseudoscript-model/src/check.rs index d051f361..12eba8ee 100644 --- a/crates/pseudoscript-model/src/check.rs +++ b/crates/pseudoscript-model/src/check.rs @@ -618,22 +618,43 @@ impl Checker<'_> { for_each_expr(block, &mut |expr| self.check_call_at(expr, owner, vars)); } - /// Checks one call's arity and argument types when its receiver resolves to a - /// same-module callable. Only the first segment is the call on the receiver. + /// Checks one call's arity and argument types when it resolves to a + /// same-module callable: a bare same-node call `Name(args)` (§5.1) on the + /// enclosing node, or a `receiver.method(args)` whose first segment resolves + /// to a same-module node. fn check_call_at(&mut self, expr: &Expr, owner: &str, vars: &FxHashMap) { - let ExprKind::Postfix { base, segments } = &expr.kind else { - return; - }; - let Some(seg) = segments.first() else { return }; - let Some(args) = &seg.call_args else { return }; - let Some(node) = self.call_receiver_node(base, owner) else { - return; - }; + match &expr.kind { + ExprKind::OwnCall { name, args } => { + self.check_call_signature(owner, &name.name, name.span, args, vars); + } + ExprKind::Postfix { base, segments } => { + let Some(seg) = segments.first() else { return }; + let Some(args) = &seg.call_args else { return }; + let Some(node) = self.call_receiver_node(base) else { + return; + }; + self.check_call_signature(&node, &seg.name.name, seg.span, args, vars); + } + _ => {} + } + } + + /// Checks a resolved call's arity against `node`'s callable `method`, then + /// its argument types. A name not naming a callable of `node` is left to the + /// existence checks (`check_self_call_at` / cross-module resolution). + fn check_call_signature( + &mut self, + node: &str, + method: &str, + span: Span, + args: &[Expr], + vars: &FxHashMap, + ) { let Some(params) = self .model - .members(&node) + .members(node) .iter() - .find(|m| m.kind == MemberKind::Callable && m.name == seg.name.name) + .find(|m| m.kind == MemberKind::Callable && m.name == method) .map(|m| m.param_types.clone()) else { return; @@ -642,10 +663,9 @@ impl Checker<'_> { self.check_arg_types(args, ¶ms, vars); } else { self.error( - seg.span, + span, format!( - "callable `{}` expects {} argument(s), got {}", - seg.name.name, + "callable `{method}` expects {} argument(s), got {}", params.len(), args.len() ), @@ -674,14 +694,14 @@ impl Checker<'_> { } } - /// The same-module node a call's receiver resolves to: the enclosing node for - /// `self`, or a node named by the receiver path's leaf. `None` for a value - /// receiver, a name that is not a node, or a qualified path into another - /// module — a cross-module node's members are not in this single-module - /// model (ADR-022), and a leaf-only match would land on the wrong node. - fn call_receiver_node(&self, base: &Expr, owner: &str) -> Option { + /// The same-module node a `receiver.method` call's receiver resolves to: a + /// node named by the receiver path's leaf. `None` for a value receiver, a + /// name that is not a node, or a qualified path into another module — a + /// cross-module node's members are not in this single-module model (ADR-022), + /// and a leaf-only match would land on the wrong node. A bare same-node call + /// `Name(args)` resolves directly on the enclosing node, not here (§5.1). + fn call_receiver_node(&self, base: &Expr) -> Option { match &base.kind { - ExprKind::Ref(Ref::SelfNode(_)) => Some(owner.to_owned()), ExprKind::Ref(Ref::Path(path)) => { if path.segments.len() > 1 && !self.model.module_path.is_empty() { let module = &path.segments[..path.segments.len() - 1]; @@ -902,23 +922,19 @@ impl Checker<'_> { } } - /// §5.1 / ADR-004: `self.Name(args)` MUST name a callable of the enclosing - /// node `owner`. + /// §5.1 / ADR-041: a bare same-node call `Name(args)` MUST name a callable of + /// the enclosing node `owner`. fn check_self_calls(&mut self, block: &Block, owner: &str) { for_each_expr(block, &mut |expr| self.check_self_call_at(expr, owner)); } - /// Checks one `self.Method(args)` call: the first segment, when a call - /// directly on `self`, must name a callable of the enclosing node. + /// Checks one bare same-node call `Name(args)`: `Name` must name a callable + /// of the enclosing node. fn check_self_call_at(&mut self, expr: &Expr, owner: &str) { - let ExprKind::Postfix { base, segments } = &expr.kind else { + let ExprKind::OwnCall { name, .. } = &expr.kind else { return; }; - if matches!(&base.kind, ExprKind::Ref(Ref::SelfNode(_))) - && let Some(seg) = segments.first() - && seg.call_args.is_some() - && !self.owner_has_callable(owner, &seg.name.name) - { + if !self.owner_has_callable(owner, &name.name) { let hint = { let cands: Vec<&str> = self .model @@ -927,13 +943,13 @@ impl Checker<'_> { .filter(|m| m.kind == MemberKind::Callable) .map(|m| m.name.as_str()) .collect(); - suggest(&seg.name.name, &cands) + suggest(&name.name, &cands) }; self.error( - seg.span, + name.span, format!( - "`self.{}` does not name a callable of `{owner}`{hint}", - seg.name.name + "`{}` does not name a callable of `{owner}`{hint}", + name.name ), ); } @@ -1150,27 +1166,31 @@ impl Checker<'_> { } } - /// The declared return type of a `Receiver.Method(args)` call whose receiver - /// resolves in-module (`self` or a same-module node) and whose `Method` is a - /// callable of that node, as a [`Ty`]; `None` otherwise. + /// The declared return type of a call whose callee resolves in-module, as a + /// [`Ty`]; `None` otherwise. Covers a bare same-node call `Name(args)` on the + /// enclosing node (§5.1) and a `Receiver.Method(args)` whose receiver is a + /// same-module node, when the callee is a callable of that node. fn call_return(&self, expr: &Expr, owner: &str) -> Option { let mut expr = expr; while let ExprKind::Paren(inner) = &expr.kind { expr = inner; } - let ExprKind::Postfix { base, segments } = &expr.kind else { - return None; - }; - let [seg] = segments.as_slice() else { - return None; + let (node, method): (String, &str) = match &expr.kind { + ExprKind::OwnCall { name, .. } => (owner.to_owned(), name.name.as_str()), + ExprKind::Postfix { base, segments } => { + let [seg] = segments.as_slice() else { + return None; + }; + seg.call_args.as_ref()?; // a call segment, not a field access + (self.call_receiver_node(base)?, seg.name.name.as_str()) + } + _ => return None, }; - seg.call_args.as_ref()?; // a call segment, not a field access - let node = self.call_receiver_node(base, owner)?; let member = self .model .members(&node) .iter() - .find(|m| m.kind == MemberKind::Callable && m.name == seg.name.name)?; + .find(|m| m.kind == MemberKind::Callable && m.name == method)?; Some(ty_from_rendered(&member.ty)) } @@ -1726,6 +1746,11 @@ fn walk_expr(expr: &Expr, f: &mut impl FnMut(&Expr)) { payload: Some(payload), .. } => walk_expr(payload, f), + ExprKind::OwnCall { args, .. } => { + for arg in args { + walk_expr(arg, f); + } + } ExprKind::Unary { expr, .. } | ExprKind::Paren(expr) => walk_expr(expr, f), ExprKind::Binary { left, right, .. } => { walk_expr(left, f); diff --git a/crates/pseudoscript-model/src/check/cross_module.rs b/crates/pseudoscript-model/src/check/cross_module.rs index cde1cc1c..cb11fb51 100644 --- a/crates/pseudoscript-model/src/check/cross_module.rs +++ b/crates/pseudoscript-model/src/check/cross_module.rs @@ -197,7 +197,13 @@ impl Ctx<'_> { self.check_expr(right); } ExprKind::Ref(Ref::Path(path)) => self.check_value_ref(path), - ExprKind::Ref(Ref::SelfNode(_)) | ExprKind::Literal(_) => {} + // A same-node call is in-module; only its args can cross a boundary. + ExprKind::OwnCall { args, .. } => { + for arg in args { + self.check_expr(arg); + } + } + ExprKind::Literal(_) => {} } } diff --git a/crates/pseudoscript-model/src/check/result_flow.rs b/crates/pseudoscript-model/src/check/result_flow.rs index e94eff8d..09604cf2 100644 --- a/crates/pseudoscript-model/src/check/result_flow.rs +++ b/crates/pseudoscript-model/src/check/result_flow.rs @@ -207,6 +207,11 @@ fn check_expr(expr: &Expr, env: &Bindings, out: &mut Vec) { check_expr(left, env, out); check_expr(right, env, out); } + ExprKind::OwnCall { args, .. } => { + for arg in args { + check_expr(arg, env, out); + } + } ExprKind::Ref(_) | ExprKind::Literal(_) => {} } } diff --git a/crates/pseudoscript-model/src/complete.rs b/crates/pseudoscript-model/src/complete.rs index e9e27d2c..4d3564bc 100644 --- a/crates/pseudoscript-model/src/complete.rs +++ b/crates/pseudoscript-model/src/complete.rs @@ -82,7 +82,7 @@ pub fn completion(ws: &Workspace, from_fqn: &str, src: &str, offset: u32) -> Vec // A `container`'s parent must be a `system`, a `component`'s a `container` // (§4); only those kinds are offered. A feature target is any node. Some((i, TokenKind::KwFor)) => node_items(ws, from_fqn, parent_kind(&tokens, i)), - _ => general_items(ws, from_fqn), + _ => general_items(ws, from_fqn, offset), } } @@ -323,12 +323,16 @@ fn type_items(ws: &Workspace) -> Vec { primitives.chain(declared).collect() } -/// Keywords, this module's own symbols, and the other modules in the workspace -/// (so a cross-module reference can be started — pick the module, then `::` -/// drills into its public symbols). -fn general_items(ws: &Workspace, from_fqn: &str) -> Vec { +/// Keywords, this module's own symbols, the enclosing node's callables (bare +/// same-node calls, §5.1, ADR-041), and the other modules in the workspace (so a +/// cross-module reference can be started — pick the module, then `::` drills into +/// its public symbols). +fn general_items(ws: &Workspace, from_fqn: &str, offset: u32) -> Vec { + // `self` stays a reserved word only to diagnose the removed `self.` form + // (ADR-041); it MUST NOT appear in a model, so never offer it. let keywords = TokenKind::KEYWORDS .iter() + .filter(|k| **k != "self") .map(|k| item(k, CompletionKind::Keyword, "keyword")); let modules = other_modules(ws, from_fqn); let Some(entry) = ws.module(from_fqn) else { @@ -338,7 +342,24 @@ fn general_items(ws: &Workspace, from_fqn: &str) -> Vec { .model .symbols() .map(|s| item(&s.name, symbol_kind(s.kind), &s.fqn)); - keywords.chain(symbols).chain(modules).collect() + // Inside a node body, the enclosing node's own callables are reachable as + // bare same-node calls `Name(args)` — private siblings included (same node). + let own_calls: Vec = enclosing_node(&entry.ast, offset) + .map(|node| { + entry + .model + .members(&node) + .iter() + .filter(|m| m.kind == MemberKind::Callable) + .map(|m| item(&m.name, CompletionKind::Method, &m.detail)) + .collect() + }) + .unwrap_or_default(); + keywords + .chain(symbols) + .chain(own_calls) + .chain(modules) + .collect() } /// The completion kind for a declared symbol. @@ -482,11 +503,13 @@ mod tests { } #[test] - fn members_after_self_dot() { + fn siblings_complete_as_bare_calls() { + // §5.1, ADR-041: inside a node body a sibling callable completes as a + // bare same-node call `Name(args)` — no `self.` qualifier. let src = - "//! m\n\nsystem S {\n run(): void {\n self.\n }\n helper(x: number): uuid;\n}\n"; + "//! m\n\nsystem S {\n run(): void {\n he\n }\n helper(x: number): uuid;\n}\n"; let ws = workspace(&[("m", src)]); - let offset = (src.find("self.").unwrap() + "self.".len()) as u32; + let offset = (src.find(" he").unwrap() + " he".len()) as u32; let labels = labels_at(&ws, "m", src, offset); assert!(labels.contains(&"helper".to_owned()), "{labels:?}"); assert!(labels.contains(&"run".to_owned()), "{labels:?}"); @@ -588,7 +611,10 @@ mod tests { // governs — and must not leak the general keyword set. #[test] - fn members_after_self_dot_with_prefix() { + fn legacy_self_dot_still_completes_members() { + // `self.` is removed syntax (ADR-041), but the token-based member + // completion still resolves it gracefully so a user mid-migration is + // not stranded; the `.` narrowing scope must not leak the keyword set. let src = "//! m\n\nsystem S {\n run(): void {\n self.he\n }\n helper(x: number): uuid;\n}\n"; let ws = workspace(&[("m", src)]); let offset = (src.find("self.he").unwrap() + "self.he".len()) as u32; diff --git a/crates/pseudoscript-model/src/graph.rs b/crates/pseudoscript-model/src/graph.rs index acaa592c..d6c991d8 100644 --- a/crates/pseudoscript-model/src/graph.rs +++ b/crates/pseudoscript-model/src/graph.rs @@ -282,8 +282,16 @@ pub enum Step { /// The invoked method name. method: String, }, - /// A `self.method(..)` call — a self-message (ADR-004). + /// A same-node call `method(..)` — a self-message whose callee body the + /// renderer follows, exactly as a direct call to a disclosed callee + /// (§5.1, §9.2, ADR-041). SelfCall { + /// The invoked callable, resolved on the enclosing node. + method: String, + }, + /// A method on a local value or chain intermediate (`x.f()`) — a leaf + /// self-message; it names no node callable and has no body to follow. + LocalCall { /// The invoked method name. method: String, }, @@ -707,7 +715,7 @@ impl Builder<'_> { for arg in args { self.trace_expr(arg, owner_fqn, module, entry, out); } - self.emit_call(base.as_ref(), &base_target, seg, owner_fqn, out); + self.emit_call(&base_target, seg, owner_fqn, out); } } } @@ -730,6 +738,16 @@ impl Builder<'_> { } } } + ExprKind::OwnCall { name, args } => { + // §9.2: a same-node call. Args trace left-to-right first, then + // the call itself; the renderer follows the callee's body. + for arg in args { + self.trace_expr(arg, owner_fqn, module, entry, out); + } + out.push(Step::SelfCall { + method: name.name.clone(), + }); + } ExprKind::Marker { payload, .. } => { if let Some(payload) = payload { self.trace_expr(payload, owner_fqn, module, entry, out); @@ -756,15 +774,14 @@ impl Builder<'_> { entry: &ModuleEntry, out: &mut Vec, ) -> CallTarget { - match &base.kind { - ExprKind::Ref(Ref::SelfNode(_)) => CallTarget::SelfNode, - ExprKind::Ref(Ref::Path(path)) => { - CallTarget::Node(self.canonicalize(&path_str(path), module)) - } - _ => { - self.trace_expr(base, owner_fqn, module, entry, out); - CallTarget::Local - } + // A local value, a chain intermediate, or a same-node call result: + // trace the base (a same-node call emits its own step) and treat any + // `.method(..)` over it as local. + if let ExprKind::Ref(Ref::Path(path)) = &base.kind { + CallTarget::Node(self.canonicalize(&path_str(path), module)) + } else { + self.trace_expr(base, owner_fqn, module, entry, out); + CallTarget::Local } } @@ -772,7 +789,6 @@ impl Builder<'_> { /// `.method(args)` segment over a resolved base. fn emit_call( &mut self, - base: &Expr, base_target: &CallTarget, seg: &PostfixSeg, owner_fqn: &str, @@ -780,9 +796,6 @@ impl Builder<'_> { ) { let method = seg.name.name.clone(); match base_target { - CallTarget::SelfNode if is_self(base) => { - out.push(Step::SelfCall { method }); - } CallTarget::Node(target_fqn) => { out.push(Step::Call { target_fqn: target_fqn.clone(), @@ -801,8 +814,8 @@ impl Builder<'_> { } } // A method on a local value / intermediate result (`x.f()`, - // `a.b().c()`): a self-message on the owner — local to the body. - _ => out.push(Step::SelfCall { method }), + // `a.b().c()`): a leaf self-message on the owner — local to the body. + CallTarget::Local => out.push(Step::LocalCall { method }), } } @@ -856,8 +869,6 @@ impl Builder<'_> { /// How a postfix chain's base resolves for call-edge purposes. enum CallTarget { - /// `self` — calls are self-messages on the owner. - SelfNode, /// A named node, resolved to this FQN. Node(String), /// A local value or an intermediate result of an earlier call. @@ -877,7 +888,7 @@ fn resolve_path(path: &Path, module: &str) -> String { /// call whose leading target is a node (`Web.lookup()` → `Web`), or `self`. A /// bare binding reference (`a`) does not name a node, so it yields `None`: only /// a call's *receiver* is a node, a lone identifier is a local binding. -fn expr_node_fqn(expr: &Expr, owner_fqn: &str, _module: &str) -> Option { +fn expr_node_fqn(expr: &Expr, _owner_fqn: &str, _module: &str) -> Option { let ExprKind::Postfix { base, segments } = &expr.kind else { return None; }; @@ -888,7 +899,6 @@ fn expr_node_fqn(expr: &Expr, owner_fqn: &str, _module: &str) -> Option } match &base.kind { ExprKind::Ref(Ref::Path(path)) => Some(path_str(path)), - ExprKind::Ref(Ref::SelfNode(_)) => Some(owner_fqn.to_owned()), _ => None, } } @@ -1019,11 +1029,6 @@ fn path_str(path: &Path) -> String { .join("::") } -/// Whether an expression is exactly `self`. -fn is_self(expr: &Expr) -> bool { - matches!(&expr.kind, ExprKind::Ref(Ref::SelfNode(_))) -} - /// The `Ok`/`Err`/`Some`/`None` marker of a returned expression, or empty if it /// is none of them. fn return_marker(expr: Option<&Expr>) -> String { @@ -1049,7 +1054,7 @@ fn expr_label(expr: &Expr) -> String { } label } - ExprKind::Ref(Ref::SelfNode(_)) => "self".to_owned(), + ExprKind::OwnCall { name, .. } => format!("{}()", name.name), ExprKind::Ref(Ref::Path(path)) => path_str(path), ExprKind::Unary { op, expr, .. } => format!("{}{}", op.spelling(), expr_label(expr)), // §7.5: a binary condition renders through the same labeller, so an diff --git a/crates/pseudoscript-model/src/infer.rs b/crates/pseudoscript-model/src/infer.rs index a3a274ad..5258ed28 100644 --- a/crates/pseudoscript-model/src/infer.rs +++ b/crates/pseudoscript-model/src/infer.rs @@ -123,6 +123,16 @@ fn expr_type(ws: &Workspace, from_fqn: &str, expr: &ast::Expr) -> Option // `T from …` produces a value of the target type (ADR-035). ast::ExprKind::From { ty, .. } => Some(crate::model::render_type(ty)), ast::ExprKind::Postfix { base, segments } => postfix_type(ws, from_fqn, base, segments), + // §5.1: a bare same-node call resolves to a callable on the enclosing + // node; its type is that callable's declared return type (ADR-041). + ast::ExprKind::OwnCall { name, .. } => { + let node = enclosing_node(&ws.module(from_fqn)?.ast, expr.span.start)?; + ws.module_model(from_fqn)? + .members(&node) + .iter() + .find(|m| m.name == name.name && m.kind == crate::MemberKind::Callable) + .map(|m| m.ty.clone()) + } // §7.5: arithmetic yields `number`, every other operator yields `bool`. ast::ExprKind::Binary { op, .. } => Some( match op { @@ -187,14 +197,9 @@ fn postfix_type( result } -/// The node/data owner a postfix base denotes: `self`'s enclosing node, or the -/// node/data a path names. +/// The node/data owner a postfix base denotes: the node/data a path names. fn base_owner(ws: &Workspace, from_fqn: &str, base: &ast::Expr) -> Option<(String, String)> { match &base.kind { - ast::ExprKind::Ref(ast::Ref::SelfNode(span)) => { - let node = enclosing_node(&ws.module(from_fqn)?.ast, span.start)?; - Some((from_fqn.to_owned(), node)) - } ast::ExprKind::Ref(ast::Ref::Path(path)) => { let segments: Vec<&str> = path.segments.iter().map(|s| s.name.as_str()).collect(); resolve_owner(ws, from_fqn, &segments).or_else(|| { diff --git a/crates/pseudoscript-model/src/resolve.rs b/crates/pseudoscript-model/src/resolve.rs index 6c12bdf5..18d5e190 100644 --- a/crates/pseudoscript-model/src/resolve.rs +++ b/crates/pseudoscript-model/src/resolve.rs @@ -43,8 +43,8 @@ pub fn resolve_at(ws: &Workspace, from_fqn: &str, src: &str, offset: u32) -> Opt } // A member's own declaration name (a callable or field) resolves to itself; - // members live in the member index, not the symbol table, so this is the - // only bare-name form that reaches them (ADR-004: no bare member references). + // members live in the member index, not the symbol table. The other bare-name + // form that reaches a member is a same-node call, handled below (ADR-041). if let Some((owner, member)) = ws .module(from_fqn) .and_then(|entry| entry.model.member_at(clicked)) @@ -59,6 +59,33 @@ pub fn resolve_at(ws: &Workspace, from_fqn: &str, src: &str, offset: u32) -> Opt }); } + // A bare same-node call `Name(args)` (§5.1, ADR-041): the clicked Ident is + // followed by `(` and is not a `::` path tail; it names a callable of the + // enclosing node. (A bare name in value position still does not reach a + // member — ADR-030; the declaration form is handled above.) + let prev_is_colon = idx >= 1 && tokens[idx - 1].kind == TokenKind::ColonColon; + if !prev_is_colon + && tokens + .get(idx + 1) + .is_some_and(|t| t.kind == TokenKind::LParen) + && let Some(entry) = ws.module(from_fqn) + && let Some(node) = enclosing_node(&entry.ast, clicked.start) + && let Some(member) = entry + .model + .members(&node) + .iter() + .find(|m| m.name == tokens[idx].text && m.kind == crate::MemberKind::Callable) + { + let owner_fqn = entry + .model + .symbol(&node) + .map_or_else(|| node.clone(), |s| s.fqn.clone()); + return Some(Hit { + clicked, + ..member_hit(member, &node, &owner_fqn, from_fqn.to_owned()) + }); + } + // Otherwise the clicked token is part of a `::` path (possibly one segment). let segments = path_segments(&tokens, idx); resolve_path(ws, from_fqn, &segments).map(|hit| Hit { clicked, ..hit }) diff --git a/crates/pseudoscript-model/src/semantic.rs b/crates/pseudoscript-model/src/semantic.rs index f069d061..6a400335 100644 --- a/crates/pseudoscript-model/src/semantic.rs +++ b/crates/pseudoscript-model/src/semantic.rs @@ -311,8 +311,15 @@ fn expr_tokens(expr: &ast::Expr, out: &mut Vec) { } } ast::ExprKind::Ref(ast::Ref::Path(path)) => ref_path(path, out), - // `self` is a keyword and literals are coloured by the token pass. - ast::ExprKind::Ref(ast::Ref::SelfNode(_)) | ast::ExprKind::Literal(_) => {} + // A bare same-node call: the callee name colours as a method (§5.1). + ast::ExprKind::OwnCall { name, args } => { + push(out, name.span, SemKind::Method, false); + for arg in args { + expr_tokens(arg, out); + } + } + // Literals are coloured by the token pass. + ast::ExprKind::Literal(_) => {} ast::ExprKind::Unary { expr, .. } => expr_tokens(expr, out), ast::ExprKind::Binary { left, right, .. } => { expr_tokens(left, out); diff --git a/crates/pseudoscript-model/tests/conformance.rs b/crates/pseudoscript-model/tests/conformance.rs index 20c631d3..683b2188 100644 --- a/crates/pseudoscript-model/tests/conformance.rs +++ b/crates/pseudoscript-model/tests/conformance.rs @@ -392,7 +392,10 @@ fn render_steps(steps: &[Step], indent: usize, out: &mut String) { let _ = writeln!(out, "{pad}call {target_fqn}.{method}"); } Step::SelfCall { method } => { - let _ = writeln!(out, "{pad}self.{method}"); + let _ = writeln!(out, "{pad}{method}()"); + } + Step::LocalCall { method } => { + let _ = writeln!(out, "{pad}.{method}()"); } Step::Return { marker } if marker.is_empty() => { let _ = writeln!(out, "{pad}return"); diff --git a/crates/pseudoscript-model/tests/features/argument_types.feature b/crates/pseudoscript-model/tests/features/argument_types.feature index ffd8c3b3..6c8316ee 100644 --- a/crates/pseudoscript-model/tests/features/argument_types.feature +++ b/crates/pseudoscript-model/tests/features/argument_types.feature @@ -11,7 +11,7 @@ Feature: Call argument types (LANG.md §5.1) //! example public system S; public container C for S { - run(): void { self.take("x") } + run(): void { take("x") } take(n: number): void { } } """ @@ -24,7 +24,7 @@ Feature: Call argument types (LANG.md §5.1) //! example public system S; public container C for S { - run(): void { self.take(5) } + run(): void { take(5) } take(n: number): void { } } """ @@ -37,7 +37,7 @@ Feature: Call argument types (LANG.md §5.1) public data Item { id: number } public system S; public container C for S { - run(a: Item, b: Item): void { self.take(Item[] from { a, b }) } + run(a: Item, b: Item): void { take(Item[] from { a, b }) } take(xs: Item[]): void { } } """ diff --git a/crates/pseudoscript-model/tests/features/call_arity.feature b/crates/pseudoscript-model/tests/features/call_arity.feature index 255ccd36..bc402a08 100644 --- a/crates/pseudoscript-model/tests/features/call_arity.feature +++ b/crates/pseudoscript-model/tests/features/call_arity.feature @@ -1,6 +1,6 @@ Feature: Call arity matches the callable's parameters (LANG.md §5.1) - A call to a resolvable same-module callable — via `self.` or a node — must + A call to a resolvable same-module callable — a bare same-node call or a node — must pass as many arguments as the callable declares. Cross-module callees are not visible here and are not checked. @@ -10,7 +10,7 @@ Feature: Call arity matches the callable's parameters (LANG.md §5.1) //! example public system S; public container C for S { - run(): void { self.add(1, 2, 3) } + run(): void { add(1, 2, 3) } add(a: number, b: number): number { return a } } """ @@ -38,7 +38,7 @@ Feature: Call arity matches the callable's parameters (LANG.md §5.1) //! example public system S; public container C for S { - run(): number { return self.add(1, 2) } + run(): number { return add(1, 2) } add(a: number, b: number): number { return a } } """ diff --git a/crates/pseudoscript-model/tests/features/conditions.feature b/crates/pseudoscript-model/tests/features/conditions.feature index e3b9b6d8..41c6f908 100644 --- a/crates/pseudoscript-model/tests/features/conditions.feature +++ b/crates/pseudoscript-model/tests/features/conditions.feature @@ -1,7 +1,7 @@ Feature: `if`/`while` conditions are boolean (LANG.md §7) A condition whose type is statically determinable must be `bool`. Accessor and - call conditions (`r.isErr`, `self.ready()`) infer to `Unknown` and are not + call conditions (`r.isErr`, `ready()`) infer to `Unknown` and are not checked. Scenario: A non-bool `if` condition is rejected diff --git a/crates/pseudoscript-model/tests/features/cross_module.feature b/crates/pseudoscript-model/tests/features/cross_module.feature index 0a92c410..465e5cc9 100644 --- a/crates/pseudoscript-model/tests/features/cross_module.feature +++ b/crates/pseudoscript-model/tests/features/cross_module.feature @@ -106,7 +106,7 @@ Feature: Cross-module visibility resolution (LANG.md §8.2, ADR-010) Given the workspace modules: | fqn | source | | a | //! a\npublic data Money { amount: number } | - | b | //! b\npublic system Sys;\npublic container Box for b::Sys {\n total(): a::Money { return self.total() }\n} | + | b | //! b\npublic system Sys;\npublic container Box for b::Sys {\n total(): a::Money { return total() }\n} | When I check the workspace Then the workspace has no errors @@ -114,7 +114,7 @@ Feature: Cross-module visibility resolution (LANG.md §8.2, ADR-010) Given the workspace modules: | fqn | source | | a | //! a\ndata Money { amount: number } | - | b | //! b\npublic system Sys;\npublic container Box for b::Sys {\n total(): a::Money { return self.total() }\n} | + | b | //! b\npublic system Sys;\npublic container Box for b::Sys {\n total(): a::Money { return total() }\n} | When I check the workspace Then the workspace diagnostics include "type `a::Money` is private to its module" @@ -130,6 +130,6 @@ Feature: Cross-module visibility resolution (LANG.md §8.2, ADR-010) Given the workspace modules: | fqn | source | | a | //! a\npublic system Sys; | - | b | //! b\npublic system Other;\npublic container Box for b::Other {\n find(): Option { return self.find() }\n} | + | b | //! b\npublic system Other;\npublic container Box for b::Other {\n find(): Option { return find() }\n} | When I check the workspace Then the workspace diagnostics include "dangling cross-module reference `a::Missing`: target does not resolve" diff --git a/crates/pseudoscript-model/tests/features/graph.feature b/crates/pseudoscript-model/tests/features/graph.feature index bf6fc681..aaf4174d 100644 --- a/crates/pseudoscript-model/tests/features/graph.feature +++ b/crates/pseudoscript-model/tests/features/graph.feature @@ -69,7 +69,7 @@ Feature: Resolved relationship graph (LANG.md §9) public system Shop; public container Web for shop::Shop { public checkout(): void { - a = number from self.price() + a = number from price() cart = shop::Cart from { Web.lookup() } } price(): number { return 0 } @@ -78,7 +78,7 @@ Feature: Resolved relationship graph (LANG.md §9) """ Then the trace of "shop::Web::checkout" is: """ - self.price + price() call shop::Web.lookup """ And there is a "provenance" edge from "shop::Web" to "shop::Cart" @@ -92,7 +92,7 @@ Feature: Resolved relationship graph (LANG.md §9) public container Web for shop::Shop { public each(items: shop::Item[]): void { for (it in items) { - self.handle() + handle() } } handle(): void { } @@ -101,7 +101,7 @@ Feature: Resolved relationship graph (LANG.md §9) Then the trace of "shop::Web::each" is: """ loop (items) - self.handle + handle() """ Scenario: a binary condition renders in the alt frame label (§7.5) @@ -113,7 +113,7 @@ Feature: Resolved relationship graph (LANG.md §9) public container Web for shop::Shop { public guard(x: number): void { if (x > shop::LIMIT && x >= 0) { - self.handle() + handle() } } handle(): void { } @@ -122,5 +122,5 @@ Feature: Resolved relationship graph (LANG.md §9) Then the trace of "shop::Web::guard" is: """ alt (x > shop::LIMIT && x >= 0) - self.handle + handle() """ diff --git a/crates/pseudoscript-model/tests/features/member_calls.feature b/crates/pseudoscript-model/tests/features/member_calls.feature index c64ed8ee..69a59770 100644 --- a/crates/pseudoscript-model/tests/features/member_calls.feature +++ b/crates/pseudoscript-model/tests/features/member_calls.feature @@ -4,7 +4,7 @@ Feature: Method calls resolve to a declared callable (LANG.md §6) receiver resolves to a same-module node or `data` record. A node receiver must name one of its callables; a `data` record has only fields, so any call on a record value is rejected. Receivers whose type is not inferred (call results, - `::` paths) are not checked (ADR-022); `self.` calls are checked separately. + `::` paths) are not checked (ADR-022); bare same-node calls are checked separately. Scenario: Calling an undeclared method on a node receiver is rejected Given the model file: @@ -72,7 +72,7 @@ Feature: Method calls resolve to a declared callable (LANG.md §6) public system S; public container C for S { fetch(): Conv; - run(): void { self.fetch().anything() } + run(): void { fetch().anything() } } """ Then there are no diagnostics diff --git a/crates/pseudoscript-model/tests/features/rules.feature b/crates/pseudoscript-model/tests/features/rules.feature index 5d11a062..5cd7cce6 100644 --- a/crates/pseudoscript-model/tests/features/rules.feature +++ b/crates/pseudoscript-model/tests/features/rules.feature @@ -97,7 +97,7 @@ Feature: Static rules, one scenario each (LANG.md §2.4, §3.5, §4, §5.1, §6, public system Banking; public container Mainframe for Banking { Get(): Result { - r = Result from self.Fetch() + r = Result from Fetch() if (r.isErr) { return Err(r.error) } @@ -116,7 +116,7 @@ Feature: Static rules, one scenario each (LANG.md §2.4, §3.5, §4, §5.1, §6, public system Banking; public container Mainframe for Banking { Run(): void { - self.Make() + Make() } Make(): Info; } @@ -131,8 +131,8 @@ Feature: Static rules, one scenario each (LANG.md §2.4, §3.5, §4, §5.1, §6, public system Banking; public container Mainframe for Banking { Run(): void { - r = Info from self.Make() - r = Info from self.Make() + r = Info from Make() + r = Info from Make() } Make(): Info; } @@ -173,7 +173,7 @@ Feature: Static rules, one scenario each (LANG.md §2.4, §3.5, §4, §5.1, §6, public system Banking; public container Mainframe for Banking { Get(): Result { - r = Result from self.Fetch() + r = Result from Fetch() if (r.isOk) { return Ok(r.error) } diff --git a/crates/pseudoscript-model/tests/features/self_calls.feature b/crates/pseudoscript-model/tests/features/self_calls.feature index ec61196f..d40df9f9 100644 --- a/crates/pseudoscript-model/tests/features/self_calls.feature +++ b/crates/pseudoscript-model/tests/features/self_calls.feature @@ -1,27 +1,28 @@ -Feature: `self.` calls resolve to a same-node callable (LANG.md §5.1, ADR-004) +Feature: Bare same-node calls resolve to a same-node callable (LANG.md §5.1, ADR-041) - `self` is the enclosing node; `self.Name(args)` invokes one of its callables. - A `self.` call naming no callable of the enclosing node MUST be rejected. + A same-node callable is invoked by a bare call `Name(args)`. A bare call + naming no callable of the enclosing node MUST be rejected. The removed `self.` + qualifier is diagnosed. - Scenario: A self-call to an undeclared callable is rejected + Scenario: A same-node call to an undeclared callable is rejected Given the model file: """ //! example public system S; public container C for S { - run(): void { self.missing() } + run(): void { missing() } } """ - Then the diagnostics include "`self.missing` does not name a callable of `C`" + Then the diagnostics include "`missing` does not name a callable of `C`" And there is exactly 1 diagnostic - Scenario: A self-call to a same-node callable is well-formed + Scenario: A same-node call to a sibling callable is well-formed Given the model file: """ //! example public system S; public container C for S { - run(): void { self.helper() } + run(): void { helper() } helper(): void { } } """ @@ -33,7 +34,19 @@ Feature: `self.` calls resolve to a same-node callable (LANG.md §5.1, ADR-004) //! example public system S; public container C for S { - loopy(): void { self.loopy() } + loopy(): void { loopy() } } """ Then there are no diagnostics + + Scenario: The removed `self.` qualifier is diagnosed + Given the model file: + """ + //! example + public system S; + public container C for S { + run(): void { helper() } + helper(): void { self.helper() } + } + """ + Then the diagnostics include "`self.` is removed; call `Name(args)` directly (ADR-041)" diff --git a/crates/pseudoscript-model/tests/features/suggestions.feature b/crates/pseudoscript-model/tests/features/suggestions.feature index 240fb5f3..c7e4457c 100644 --- a/crates/pseudoscript-model/tests/features/suggestions.feature +++ b/crates/pseudoscript-model/tests/features/suggestions.feature @@ -33,11 +33,11 @@ Feature: "Did you mean" suggestions (Levenshtein) //! example public system S; public container C for S { - run(): void { self.helpr() } + run(): void { helpr() } helper(): void { } } """ - Then the diagnostics include "`self.helpr` does not name a callable of `C`; did you mean `helper`?" + Then the diagnostics include "`helpr` does not name a callable of `C`; did you mean `helper`?" Scenario: A distant typo gets no suggestion Given the model file: diff --git a/crates/pseudoscript-syntax/src/ast.rs b/crates/pseudoscript-syntax/src/ast.rs index b14ce4d6..a935eaa5 100644 --- a/crates/pseudoscript-syntax/src/ast.rs +++ b/crates/pseudoscript-syntax/src/ast.rs @@ -409,7 +409,15 @@ pub enum ExprKind { base: Box, segments: Vec, }, - /// `self` or an FQN (§10 `Ref`). + /// A bare same-node call `Name(args)` — a sibling callable, or the enclosing + /// callable itself for recursion (§5.1, §10 `Call`, ADR-041). + OwnCall { + /// The invoked callable's name; resolves on the enclosing node. + name: Ident, + /// The call arguments. + args: Vec, + }, + /// An FQN (§10 `Ref`). Ref(Ref), /// A string / number / bool literal (ADR-013). Literal(Literal), @@ -545,8 +553,6 @@ pub struct PostfixSeg { /// A reference primary (§10 `Ref`). #[derive(Debug, Clone, PartialEq)] pub enum Ref { - /// `self` — the enclosing node (ADR-004). - SelfNode(Span), /// An identifier or `::`-separated path (a node FQN). Path(Path), } diff --git a/crates/pseudoscript-syntax/src/parser.rs b/crates/pseudoscript-syntax/src/parser.rs index e1610321..8654e665 100644 --- a/crates/pseudoscript-syntax/src/parser.rs +++ b/crates/pseudoscript-syntax/src/parser.rs @@ -1259,10 +1259,38 @@ impl Parser { } } Some(TokenKind::KwSelf) => { + // `self.` is removed (ADR-041); a same-node call is bare + // `Name(args)`. Recover `self.Name(args)` as that bare call so + // only this diagnostic surfaces and the body still resolves. let token = self.bump().expect("peeked self"); - Expr { - kind: ExprKind::Ref(Ref::SelfNode(token.span)), - span: token.span, + if self.eat(TokenKind::Dot).is_some() { + let name = self.expect_ident("callable name"); + let (args, end) = if self.at(TokenKind::LParen) { + self.parse_call_args() + } else { + (Vec::new(), name.span.end) + }; + let span = Span::new(token.span.start, end); + self.error( + span, + "`self.` is removed; call `Name(args)` directly (ADR-041)", + ); + Expr { + kind: ExprKind::OwnCall { name, args }, + span, + } + } else { + self.error( + token.span, + "`self` is removed; call a same-node callable as `Name(args)` (ADR-041)", + ); + Expr { + kind: ExprKind::Ref(Ref::Path(Path { + segments: Vec::new(), + span: token.span, + })), + span: token.span, + } } } Some(TokenKind::LParen) => { @@ -1282,9 +1310,22 @@ impl Parser { // plain value reference; a following `<` is the less-than // operator (§7.5), left for the precedence cascade. let path = self.parse_path(); - Expr { - span: path.span, - kind: ExprKind::Ref(Ref::Path(path)), + // A single-segment path immediately followed by `(` is a bare + // same-node call `Name(args)` (§5.1, ADR-041); a longer path or + // no `(` is a value reference, any `.method(…)` left to postfix. + if path.segments.len() == 1 && self.at(TokenKind::LParen) { + let start = path.span.start; + let name = path.segments.into_iter().next().expect("len == 1"); + let (args, end) = self.parse_call_args(); + Expr { + span: Span::new(start, end), + kind: ExprKind::OwnCall { name, args }, + } + } else { + Expr { + span: path.span, + kind: ExprKind::Ref(Ref::Path(path)), + } } } _ => { @@ -1405,20 +1446,11 @@ impl Parser { while self.at(TokenKind::Dot) { let dot = self.bump().expect("peeked `.`"); let name = self.expect_ident("member name"); - let mut end = name.span.end; - let call_args = if self.at(TokenKind::LParen) { - self.bump(); - let mut args = Vec::new(); - while !self.is_eof() && !self.at(TokenKind::RParen) { - args.push(self.parse_expr()); - if self.eat(TokenKind::Comma).is_none() { - break; - } - } - end = self.eat(TokenKind::RParen).map_or(end, |t| t.span.end); - Some(args) + let (call_args, end) = if self.at(TokenKind::LParen) { + let (args, end) = self.parse_call_args(); + (Some(args), end) } else { - None + (None, name.span.end) }; segments.push(PostfixSeg { span: Span::new(dot.span.start, end), @@ -1436,6 +1468,24 @@ impl Parser { } } + /// Parses a call argument list `"(" [ Expr { "," Expr } ] ")"`, the current + /// token being the open paren. Returns the arguments and the end position + /// (the open paren's end when the list is unterminated). + fn parse_call_args(&mut self) -> (Vec, u32) { + let open = self.bump().expect("peeked `(`"); + let mut args = Vec::new(); + while !self.is_eof() && !self.at(TokenKind::RParen) { + args.push(self.parse_expr()); + if self.eat(TokenKind::Comma).is_none() { + break; + } + } + let end = self + .eat(TokenKind::RParen) + .map_or(open.span.end, |t| t.span.end); + (args, end) + } + fn parse_literal(&mut self) -> Option { match self.peek_kind()? { TokenKind::String => { diff --git a/crates/pseudoscript-syntax/tests/conformance.rs b/crates/pseudoscript-syntax/tests/conformance.rs index c41e1cbc..70cfca1d 100644 --- a/crates/pseudoscript-syntax/tests/conformance.rs +++ b/crates/pseudoscript-syntax/tests/conformance.rs @@ -48,7 +48,7 @@ public container Web for Shop { return Err(line.error) } } - r = Result from self.finalize(cart) + r = Result from finalize(cart) return Ok(r.value) } diff --git a/crates/pseudoscript/tests/eval.rs b/crates/pseudoscript/tests/eval.rs index 049ae2c9..ccfa78cd 100644 --- a/crates/pseudoscript/tests/eval.rs +++ b/crates/pseudoscript/tests/eval.rs @@ -27,7 +27,7 @@ public system S;\n\ public data Money;\n\ \n\ public container C for S {\n\ - run(): void { self.charge(\"free\") }\n\ + run(): void { charge(\"free\") }\n\ charge(amt: Money): void { }\n\ }\n"; let output = pds_eval().write_stdin(src).output().expect("run pds eval"); diff --git a/decisions/041-drop-self-qualifier.md b/decisions/041-drop-self-qualifier.md new file mode 100644 index 00000000..22696358 --- /dev/null +++ b/decisions/041-drop-self-qualifier.md @@ -0,0 +1,32 @@ +# ADR-041 — Same-node calls are bare; `self.` is dropped + +**Status:** Accepted +**Supersedes:** ADR-004 +**Affects:** LANG.md §3.3, §5.1, §8.1, §9.2, §10 + +## Context + +ADR-004 gave a same-node callable the notation `self.Name(args)` and reserved bare `Name(args)` as non-resolving. The qualifier became the only notation for a sibling or recursive call. + +It also became a silent modelling trap. A `self.` call renders as a collapsed self-message: the renderer draws the self-arrow but does not follow the callee's body, so any cross-boundary call inside that body never reaches the sequence diagram. A callable `postMessage` delegating to `sendEvent`, whose body is `Topic.produce(event)`, rendered the self-arrow to `sendEvent` and dropped the Kafka publish entirely — with no diagnostic. The model passed `pds check`; the downstream interaction was invisible (issue #71). + +A direct call (`Node.method(args)`) does not have this problem: the renderer follows a disclosed callee's body and emits its calls (§9.2). The divergence was the `self.`-specific collapse. + +## Decision + +- A same-node callable is invoked by a bare call `Name(args)` — a sibling, or the enclosing callable itself for recursion. The `self.` qualifier is removed. +- A bare name **in call position** (immediately followed by `(`) resolves to a callable on the enclosing node. A bare name not in call position is unchanged: it resolves only to a parameter, a binding, or a `for` binding (§8.1, ADR-030). +- `self` stays a reserved word (§2.3) so the parser diagnoses the removed `self.` form and points at the bare call. `self` MUST NOT appear in a model. +- Sequence rendering: a same-node call renders as a self-message **and** the renderer follows the callable's body inline, emitting its cross-boundary calls, exactly as a direct call to a disclosed callee does. Recursion is stack-guarded — an in-flight callee renders as a single self-message with no expansion (§9.2). A method on a local value or chain intermediate (`x.f()`) stays a leaf self-message; it names no node callable and has no body to follow. + +## Consequences + +- §10: `Ref` drops `self`; a bare call `Name "(" [ Args ] ")"` is added as a primary. +- §5.1: the same-node-call clause is rewritten — bare call, recursion included. +- §8.1: a bare name in call position resolves to a same-node callable; the value-position rule is unchanged. +- §9.2: a same-node call expands its callee's body; the silent drop is gone. +- The checker resolves a bare call to the enclosing node's callables and applies the same arity and argument-type checks as any call (ADR-022, ADR-023); a name matching no callable on the node is reported as unresolved. +- The implementation splits the trace step: a same-node call follows its body, a local-value method stays a leaf — both still render as self-messages. +- The worked model, the bundled samples, the conformance cases, and the authoring skill are migrated to the bare form. +- Rejected alternative: keep `self.` and only fix the renderer to follow its body (issue #71's fallback). The qualifier carries no information the enclosing scope does not already supply, and its collapsed self-message was the source of the silent drop. A bare call is indistinguishable from any other call in the model, so the renderer follows it under one rule — one call shape, one rendering. Two spellings for one call is the divergence ADR-036 settled against. +- The call-vs-construction ambiguity does not arise: construction is `Type from { … }` (§7.2), never `Name(args)`; a bare name followed by `(` is unambiguously a call. diff --git a/decisions/README.md b/decisions/README.md index 30f48f74..39129d1e 100644 --- a/decisions/README.md +++ b/decisions/README.md @@ -22,7 +22,7 @@ Read in full to see why `CtorExpr` became `ResultMarker` and how this reinforces ## [004 — Self/sibling calls via `self.`](004-self-calls.md) -`self` refers to the enclosing node; same-node callables are invoked as `self.Name(args)`. Bare `Name(args)` does not resolve. +`self` refers to the enclosing node; same-node callables are invoked as `self.Name(args)`. Bare `Name(args)` does not resolve. **Superseded by ADR-041** — `self.` is dropped; a same-node call is bare `Name(args)`. Read in full for the sequence-diagram rendering (self-message on the lifeline) and the `self`-only-in-body scoping rule. @@ -241,3 +241,9 @@ Read in full for the value-namespace rule, the FQN-only resolution, and the reje Every callable MUST declare a return type; `F()` without one is rejected and `void` is the explicit nothing-spelling (`F(): void`, still composable as `Result`). §10's `Callable` production requires `":" Type`; the parser recovers a missing type as `void` with a syntax diagnostic. Mandatory signatures make a call to any resolvable callable a determinable `return` operand, extending the §5.1 type-match clause cross-module without widening ADR-022's inference. Read in full for the Java/C#-precedent rationale and the rejected implicit-void and full-typing alternatives. + +## [041 — Same-node calls are bare; `self.` is dropped](041-drop-self-qualifier.md) + +`self.Name(args)` is removed; a same-node callable is invoked by a bare call `Name(args)`. A bare name in call position resolves to a callable on the enclosing node; `self` stays reserved only to diagnose the removed form. The renderer follows a same-node call's body and emits its cross-boundary calls, ending the silent-drop trap (issue #71) ADR-004's collapsed self-message caused. **Supersedes ADR-004.** + +Read in full for the call-vs-construction non-ambiguity, the same-node-vs-local-value rendering split, and the rejected fix-renderer-only alternative. diff --git a/model/cli.pds b/model/cli.pds index 46e53411..eb5883f0 100644 --- a/model/cli.pds +++ b/model/cli.pds @@ -55,7 +55,7 @@ public container Cli for context::Pseudoscript { /// Generate the documentation site for the workspace containing `path`, with no /// `--format` override so the manifest `[doc].format` or HTML decides. public runDoc(path: string): Result { - built = Result from cli::DocCmd.run(path, self.noFormatOverride()) + built = Result from cli::DocCmd.run(path, noFormatOverride()) if (built.isErr) { return Err(built.error) } @@ -92,7 +92,7 @@ component Loader for cli::Cli { findRoot(start: string): Result { found = Result from project::Project.findRoot(start) if (found.isErr) { - return Err(self.ioError(found.error)) + return Err(ioError(found.error)) } return Ok(found.value) } @@ -101,15 +101,15 @@ component Loader for cli::Cli { /// resolve its declared dependency modules (§8.3) into the workspace. The /// resolved output directory is `/`, taken from the manifest. load(root: string): Result { - config = Result from self.loadManifest(root) + config = Result from loadManifest(root) if (config.isErr) { return Err(config.error) } - modules = Result from self.loadModules(root) + modules = Result from loadModules(root) if (modules.isErr) { return Err(modules.error) } - dependencies = Result from self.loadDependencies(root) + dependencies = Result from loadDependencies(root) if (dependencies.isErr) { return Err(dependencies.error) } @@ -126,7 +126,7 @@ component Loader for cli::Cli { loadModules(root: string): Result { loaded = Result from project::Project.load(root) if (loaded.isErr) { - return Err(self.ioError(loaded.error)) + return Err(ioError(loaded.error)) } return Ok(loaded.value) } @@ -151,11 +151,11 @@ component Loader for cli::Cli { component InitCmd for cli::Cli { #[manual] public run(path: string, name: string): Result { - exists = Result from self.manifestExists(path) + exists = Result from manifestExists(path) if (exists.isErr) { return Err(exists.error) } - return self.writeFiles(path, name) + return writeFiles(path, name) } /// Whether `/pds.toml` already exists — refuse to clobber a workspace. @@ -190,21 +190,21 @@ component DocCmd for cli::Cli { if (project.isErr) { return Err(project.error) } - format = string from self.resolveFormat(cliFormat, project.value.format) + format = string from resolveFormat(cliFormat, project.value.format) perModule = model::ModuleDiagnostics[] from model::Model.checkWorkspaceModules(project.value.modules, project.value.dependencies) - self.reportModules(perModule) + reportModules(perModule) prepared = doc::DiagnosticInput[] from doc::Doc.prepareDiagnostics(project.value.modules, perModule) graph = Graph from model::Model.graph(project.value.modules) - site = Result from self.renderSite(graph, project.value.config, format, prepared) + site = Result from renderSite(graph, project.value.config, format, prepared) if (site.isErr) { return Err(site.error) } - written = Result from self.write(site.value, project.value.outDir) + written = Result from write(site.value, project.value.outDir) if (written.isErr) { return Err(written.error) } - if (self.isHtml(format)) { - self.copyLogo(root.value, project.value) + if (isHtml(format)) { + copyLogo(root.value, project.value) } return Ok(format) } @@ -223,14 +223,14 @@ component DocCmd for cli::Cli { /// infallible flat-Markdown site. Both receive the prepared diagnostics so /// the health report ships in either format. renderSite(graph: model::Graph, config: doc::DocConfig, format: string, diagnostics: doc::DiagnosticInput[]): Result { - if (self.isHtml(format)) { + if (isHtml(format)) { html = Result from doc::Doc.render(graph, config, diagnostics) if (html.isErr) { - return Err(self.renderError(html.error)) + return Err(renderError(html.error)) } return Ok(html.value) } - return Ok(self.renderMarkdown(graph, config, diagnostics)) + return Ok(renderMarkdown(graph, config, diagnostics)) } /// Whether the resolved format is HTML (the SSR site) rather than Markdown. @@ -256,7 +256,7 @@ component DocCmd for cli::Cli { if (roots.isErr) { return Err(roots.error) } - return self.buildEach(roots.value, cliFormat) + return buildEach(roots.value, cliFormat) } /// Build each discovered workspace in order, collecting failures; errors after @@ -270,14 +270,14 @@ component DocCmd for cli::Cli { /// returns after writing the site. #[manual] public serve(path: string, cliFormat: string, serve: bool, watch: bool, port: number): Result { - built = Result from self.run(path, cliFormat) + built = Result from run(path, cliFormat) if (built.isErr) { return Err(built.error) } - if (!self.isHtml(built.value)) { + if (!isHtml(built.value)) { return Ok } - if (!self.shouldServe(serve, watch)) { + if (!shouldServe(serve, watch)) { return Ok } if (watch) { @@ -310,12 +310,12 @@ component CheckCmd for cli::Cli { public run(path: string): Result { root = Result from cli::Loader.findRoot(path) if (root.isErr) { - if (self.isDirectory(path)) { + if (isDirectory(path)) { return Err(root.error) } - return self.checkRootless(path) + return checkRootless(path) } - return self.checkWorkspace(root.value) + return checkWorkspace(root.value) } /// Whether `path` is a directory — only a rootless file falls back to the @@ -334,8 +334,8 @@ component CheckCmd for cli::Cli { return Err(project.error) } perModule = model::ModuleDiagnostics[] from model::Model.checkWorkspaceModules(project.value.modules, project.value.dependencies) - self.reportModules(perModule) - if (self.anyModuleError(perModule)) { + reportModules(perModule) + if (anyModuleError(perModule)) { err = IoError from { perModule } return Err(err) } @@ -356,12 +356,12 @@ component CheckCmd for cli::Cli { /// The lenient path: a file outside any workspace is checked as one anonymous /// module, lenient about full qualification. checkRootless(path: string): Result { - text = Result from self.readSource(path) + text = Result from readSource(path) if (text.isErr) { return Err(text.error) } diagnostics = syntax::Diagnostic[] from model::Model.check(text.value) - if (self.anyError(diagnostics)) { + if (anyError(diagnostics)) { err = IoError from { diagnostics } return Err(err) } @@ -383,7 +383,7 @@ component CheckCmd for cli::Cli { if (roots.isErr) { return Err(roots.error) } - return self.checkEach(roots.value) + return checkEach(roots.value) } /// Check each discovered workspace in order, collecting failures. @@ -398,7 +398,7 @@ component EvalCmd for cli::Cli { #[manual] public run(text: string): Result { diagnostics = syntax::Diagnostic[] from model::Model.check(text) - if (self.anyError(diagnostics)) { + if (anyError(diagnostics)) { err = IoError from { diagnostics } return Err(err) } @@ -420,9 +420,9 @@ component FmtCmd for cli::Cli { return Err(out.error) } if (write) { - self.overwrite(out.value) + overwrite(out.value) } else { - self.print(out.value) + print(out.value) } return Ok } @@ -439,7 +439,7 @@ component TokensCmd for cli::Cli { #[manual] public run(text: string): Result { stream = string from syntax::Syntax.renderTokens(text) - self.print(stream) + print(stream) return Ok } @@ -486,7 +486,7 @@ component OutlineCmd for cli::Cli { return Err(modules.error) } graph = Graph from model::Model.graph(modules.value) - self.print(self.render(graph)) + print(render(graph)) return Ok } @@ -507,8 +507,8 @@ component OutlineCmd for cli::Cli { component SvgCmd for cli::Cli { #[manual] public run(path: string, symbol: string, view: string, target: string, theme: string): Result { - if (!self.isKnownTheme(theme)) { - return Err(self.unknownTheme(theme)) + if (!isKnownTheme(theme)) { + return Err(unknownTheme(theme)) } root = Result from cli::Loader.findRoot(path) if (root.isErr) { @@ -519,11 +519,11 @@ component SvgCmd for cli::Cli { return Err(modules.error) } graph = Graph from model::Model.graph(modules.value) - scene = Result from self.projectChosen(graph, symbol, view, target) + scene = Result from projectChosen(graph, symbol, view, target) if (scene.isErr) { - return Err(self.emitError(scene.error)) + return Err(emitError(scene.error)) } - self.print(self.renderThemed(scene.value, theme)) + print(renderThemed(scene.value, theme)) return Ok } diff --git a/model/doc.pds b/model/doc.pds index e16d388a..e03107a5 100644 --- a/model/doc.pds +++ b/model/doc.pds @@ -221,23 +221,23 @@ component SiteBuilder for doc::Doc { public render(graph: model::Graph, config: doc::DocConfig, diagnostics: doc::DiagnosticInput[]): Result { doc::Urls.build(graph) modules = string[] from doc::Pages.sortedModules(graph) - index = Result from self.emitPage("index.html", doc::Pages.index(graph, config, modules, diagnostics)) + index = Result from emitPage("index.html", doc::Pages.index(graph, config, modules, diagnostics)) if (index.isErr) { return Err(index.error) } - docPages = Result from self.emitDocPages(config, diagnostics) + docPages = Result from emitDocPages(config, diagnostics) if (docPages.isErr) { return Err(docPages.error) } - modulePages = Result from self.emitModulePages(graph, config, modules, diagnostics) + modulePages = Result from emitModulePages(graph, config, modules, diagnostics) if (modulePages.isErr) { return Err(modulePages.error) } - universe = Result from self.emitPage("universe.html", doc::Pages.universePage(graph, config, modules, diagnostics)) + universe = Result from emitPage("universe.html", doc::Pages.universePage(graph, config, modules, diagnostics)) if (universe.isErr) { return Err(universe.error) } - health = Result from self.emitPage("health.html", doc::Pages.healthPage(graph, config, modules, diagnostics)) + health = Result from emitPage("health.html", doc::Pages.healthPage(graph, config, modules, diagnostics)) if (health.isErr) { return Err(health.error) } @@ -273,13 +273,13 @@ component Pages for doc::Doc { /// The index props: the shared chrome, a card per module, the system-context /// diagram, and the stats strip summarising the model and its findings. index(graph: model::Graph, config: doc::DocConfig, modules: string[], diagnostics: doc::DiagnosticInput[]): doc::PageProps { - docGroups = SidebarDocGroup[] from self.docGroups(config, "") - sidebar = SidebarModule[] from self.sidebar(graph, modules, "") - nav = NavLink[] from self.navLinks(diagnostics, "") - crumbs = Crumb[] from self.crumbsOf("index.html") - cards = ModuleCard[] from self.moduleCards(graph, modules) + docGroups = SidebarDocGroup[] from docGroups(config, "") + sidebar = SidebarModule[] from sidebar(graph, modules, "") + nav = NavLink[] from navLinks(diagnostics, "") + crumbs = Crumb[] from crumbsOf("index.html") + cards = ModuleCard[] from moduleCards(graph, modules) context = Diagram from doc::Diagrams.context(graph) - stats = SiteStats from self.stats(graph, diagnostics) + stats = SiteStats from stats(graph, diagnostics) body = IndexPage from { config, context, cards, stats } return PageProps from { config, docGroups, sidebar, nav, crumbs, body } } @@ -287,13 +287,13 @@ component Pages for doc::Doc { /// The universe page's props: the flat snapshot, the traced flows, and each /// placed node's documentation href — everything the 3D island draws. universePage(graph: model::Graph, config: doc::DocConfig, modules: string[], diagnostics: doc::DiagnosticInput[]): doc::PageProps { - docGroups = SidebarDocGroup[] from self.docGroups(config, "") - sidebar = SidebarModule[] from self.sidebar(graph, modules, "") - nav = NavLink[] from self.navLinks(diagnostics, "") - crumbs = Crumb[] from self.crumbsOf("universe.html") + docGroups = SidebarDocGroup[] from docGroups(config, "") + sidebar = SidebarModule[] from sidebar(graph, modules, "") + nav = NavLink[] from navLinks(diagnostics, "") + crumbs = Crumb[] from crumbsOf("universe.html") snapshot = universe::Snapshot from universe::Universe.snapshot(universe::Universe.fromModel(graph)) flows = universe::FlowDef[] from universe::Universe.flows(graph) - hrefs = NodeHref[] from self.nodeHrefs(snapshot) + hrefs = NodeHref[] from nodeHrefs(snapshot) body = UniversePage from { snapshot, flows, hrefs } return PageProps from { config, docGroups, sidebar, nav, crumbs, body } } @@ -301,10 +301,10 @@ component Pages for doc::Doc { /// The health page's props: every prepared diagnostic attributed to its node, /// sorted by severity, module, then line, with the error/warning counts. healthPage(graph: model::Graph, config: doc::DocConfig, modules: string[], diagnostics: doc::DiagnosticInput[]): doc::PageProps { - docGroups = SidebarDocGroup[] from self.docGroups(config, "") - sidebar = SidebarModule[] from self.sidebar(graph, modules, "") - nav = NavLink[] from self.navLinks(diagnostics, "") - crumbs = Crumb[] from self.crumbsOf("health.html") + docGroups = SidebarDocGroup[] from docGroups(config, "") + sidebar = SidebarModule[] from sidebar(graph, modules, "") + nav = NavLink[] from navLinks(diagnostics, "") + crumbs = Crumb[] from crumbsOf("health.html") body = PageBody from doc::Health.page(graph, diagnostics) return PageProps from { config, docGroups, sidebar, nav, crumbs, body } } @@ -328,10 +328,10 @@ component Pages for doc::Doc { /// directory deep (`docs/.html`), so the `../` depth prefix is used for /// the shared chrome. docPage(config: doc::DocConfig, page: doc::DocPage, diagnostics: doc::DiagnosticInput[]): doc::PageProps { - docGroups = SidebarDocGroup[] from self.docGroups(config, "../") - sidebar = SidebarModule[] from self.emptySidebar() - nav = NavLink[] from self.navLinks(diagnostics, "../") - crumbs = Crumb[] from self.crumbsOf(page.path) + docGroups = SidebarDocGroup[] from docGroups(config, "../") + sidebar = SidebarModule[] from emptySidebar() + nav = NavLink[] from navLinks(diagnostics, "../") + crumbs = Crumb[] from crumbsOf(page.path) html = string from doc::Markdown.render(page.markdown) body = DocBody from { page, html } return PageProps from { config, docGroups, sidebar, nav, crumbs, body } @@ -353,12 +353,12 @@ component Pages for doc::Doc { /// One module page's props: the chrome (prefixed `../` for the page's depth) and /// a section per non-callable node declared in the module, sorted by FQN. modulePage(graph: model::Graph, config: doc::DocConfig, module: string, modules: string[], diagnostics: doc::DiagnosticInput[]): doc::PageProps { - docGroups = SidebarDocGroup[] from self.docGroups(config, "../") - sidebar = SidebarModule[] from self.sidebar(graph, modules, "../") - nav = NavLink[] from self.navLinks(diagnostics, "../") - crumbs = Crumb[] from self.crumbsOf(module) - nodes = model::GraphNode[] from self.moduleNodes(graph, module) - sections = NodeSection[] from self.sections(graph, nodes, diagnostics) + docGroups = SidebarDocGroup[] from docGroups(config, "../") + sidebar = SidebarModule[] from sidebar(graph, modules, "../") + nav = NavLink[] from navLinks(diagnostics, "../") + crumbs = Crumb[] from crumbsOf(module) + nodes = model::GraphNode[] from moduleNodes(graph, module) + sections = NodeSection[] from sections(graph, nodes, diagnostics) body = ModulePage from { module, sections } return PageProps from { config, docGroups, sidebar, nav, crumbs, body } } @@ -430,7 +430,7 @@ component Shell for doc::Doc { /// #app wrap(path: string, props: doc::PageProps, rendered: doc::RenderedPage): string { title = string from doc::Escape.text(props.site.name) - return self.document(path, title, props, rendered) + return document(path, title, props, rendered) } /// Assemble the document string from its escaped title, the rendered @@ -446,10 +446,10 @@ component Relationships for doc::Doc { /// The relationship groups for `node`: parent, inbound, then outbound. Empty when /// the node has no parent and no edges. groups(graph: model::Graph, node: model::GraphNode): doc::RelGroup[] { - parent = RelGroup[] from self.parentGroup(graph, node) - inbound = RelGroup[] from self.inboundGroup(graph, node) - outbound = RelGroup[] from self.outboundGroup(graph, node) - return self.collect(parent, inbound, outbound) + parent = RelGroup[] from parentGroup(graph, node) + inbound = RelGroup[] from inboundGroup(graph, node) + outbound = RelGroup[] from outboundGroup(graph, node) + return collect(parent, inbound, outbound) } /// The parent group: a `for` link for a container/component, an `in` link @@ -470,7 +470,7 @@ component Relationships for doc::Doc { /// A `RelItem` for `fqn`: a resolved href when it names a node, absent (rendering /// plain text) otherwise (LANG.md §9.3). item(fqn: string, kind: model::EdgeKind, arrow: bool, label: string): doc::RelItem { - edgeKind = string from self.edgeKindLabel(kind) + edgeKind = string from edgeKindLabel(kind) href = Result from doc::Urls.hrefTo(fqn) if (href.isErr) { return RelItem from { fqn, edgeKind, arrow, label } @@ -490,9 +490,9 @@ component Scenarios for doc::Doc { /// docs, tags, ordered steps, and its flow figure. Empty when the node has no /// scenarios. cards(graph: model::Graph, node: model::GraphNode): doc::ScenarioCard[] { - scenarios = model::Scenario[] from self.scenariosOf(graph, node) + scenarios = model::Scenario[] from scenariosOf(graph, node) flows = doc::Diagram[] from doc::Diagrams.flows(graph, scenarios) - return self.toCards(scenarios, flows) + return toCards(scenarios, flows) } /// The scenarios in the graph whose target FQN is this node. @@ -514,22 +514,22 @@ component Diagrams for doc::Doc { /// diagram on a `container`, an entity diagram on a `data` (LANG.md §9.4), plus a /// sequence diagram per triggered callable it owns. Other kinds embed nothing. forNode(graph: model::Graph, node: model::GraphNode): doc::Diagram[] { - return self.collect(self.boundary(graph, node), self.sequences(graph, node)) + return collect(boundary(graph, node), sequences(graph, node)) } /// The boundary diagram for a node: a container view for a `system`, a component /// view for a `container`, an entity view for a `data`, none for any other kind. boundary(graph: model::Graph, node: model::GraphNode): doc::Diagram[] { - if (self.isSystem(node)) { - return self.one(self.figure(graph, self.containerView(node.fqn), "Containers", "Container diagram")) + if (isSystem(node)) { + return one(figure(graph, containerView(node.fqn), "Containers", "Container diagram")) } - if (self.isContainer(node)) { - return self.one(self.figure(graph, self.componentView(node.fqn), "Components", "Component diagram")) + if (isContainer(node)) { + return one(figure(graph, componentView(node.fqn), "Components", "Component diagram")) } - if (self.isData(node)) { - return self.one(self.figure(graph, self.dataView(node.fqn), "Entities", "Entity diagram")) + if (isData(node)) { + return one(figure(graph, dataView(node.fqn), "Entities", "Entity diagram")) } - return self.none() + return none() } /// One flow figure per scenario: its feature view (LANG.md §9.5), in source order. @@ -537,7 +537,7 @@ component Diagrams for doc::Doc { /// The context diagram for the index page (persons and systems). context(graph: model::Graph): doc::Diagram { - return self.figure(graph, self.contextView(), "Context", "System context") + return figure(graph, contextView(), "Context", "System context") } /// Project `view` into a `Diagram`: render the scene to SVG on success, or an @@ -548,14 +548,14 @@ component Diagrams for doc::Doc { if (scene.isErr) { return Empty from { caption, eyebrow } } - return self.embed(scene.value, caption, eyebrow) + return embed(scene.value, caption, eyebrow) } /// Wrap a laid-out scene in its figure: every variant — C4, sequence, data, /// feature — renders through the emit face under the adaptive palette and /// ships as an `Svg` figure tagged with its view kind. embed(scene: emit::Scene, caption: string, eyebrow: string): doc::Diagram { - return self.svgFigure(scene, caption, eyebrow) + return svgFigure(scene, caption, eyebrow) } /// Render a scene to adaptive-palette SVG through the emit face and wrap it @@ -612,9 +612,9 @@ component Health for doc::Doc { /// The health page body: every finding attributed and sorted by severity, /// module, then line, with the error and warning counts. page(graph: model::Graph, diagnostics: doc::DiagnosticInput[]): doc::PageBody { - entries = HealthEntry[] from self.attributeAll(graph, diagnostics) - errorCount = number from self.countOf(entries, "error") - warningCount = number from self.countOf(entries, "warning") + entries = HealthEntry[] from attributeAll(graph, diagnostics) + errorCount = number from countOf(entries, "error") + warningCount = number from countOf(entries, "warning") return HealthPage from { entries, errorCount, warningCount } } @@ -638,7 +638,7 @@ component SearchIndex for doc::Doc { /// The index file: every entry sorted by href then FQN, serialised as a JS /// assignment of the entry array. public build(graph: model::Graph, config: doc::DocConfig): doc::SiteFile { - entries = SearchEntry[] from self.entries(graph, config) + entries = SearchEntry[] from entries(graph, config) return SiteFile from { entries } } @@ -658,10 +658,10 @@ component Highlight for doc::Doc { /// Highlight `source` as `lang` into class-based HTML spans: `pds` through /// the syntax lexer's token kinds, anything else escaped verbatim. public code(lang: string, source: string): string { - if (self.isPds(lang)) { - return self.pdsTokens(source) + if (isPds(lang)) { + return pdsTokens(source) } - return self.escaped(source) + return escaped(source) } /// Whether the language word names PseudoScript (`pds`, `pseudoscript`). @@ -690,11 +690,11 @@ component Urls for doc::Doc { /// The module-page-relative `href` to `fqn` (`.html#`), or an error /// when `fqn` resolves to no node. hrefTo(fqn: string): Result { - url = Result from self.get(fqn) + url = Result from get(fqn) if (url.isErr) { return Err(url.error) } - return Ok(self.hrefFromModulePage(url.value)) + return Ok(hrefFromModulePage(url.value)) } /// The page path for a module FQN: `module/.html`. diff --git a/model/dot.pds b/model/dot.pds index 85e53066..b2c6c8cc 100644 --- a/model/dot.pds +++ b/model/dot.pds @@ -131,7 +131,7 @@ component Engine for dot::Dot { placed = NodePos[] from dot::Position.assignCoords(graph, ordered) routed = EdgeRoute[] from dot::Splines.route(graph, ordered, placed) framed = ClusterBox[] from dot::Clusters.boxes(graph, placed) - return self.finish(placed, routed, framed) + return finish(placed, routed, framed) } /// Translate the assembled layout so its minimum corner is the origin and @@ -200,8 +200,8 @@ public component Pipeline for dot::Dot { /// Fold the base state through `passes` in order; the last state's placement /// is the result. run(graph: dot::Graph, passes: dot::Pass[]): dot::Layout { - state = dot::LayoutState from self.base(graph) - folded = dot::LayoutState from self.fold(state, passes) + state = dot::LayoutState from base(graph) + folded = dot::LayoutState from fold(state, passes) return folded.layout } diff --git a/model/emit.pds b/model/emit.pds index a465d59a..4924c6d0 100644 --- a/model/emit.pds +++ b/model/emit.pds @@ -202,21 +202,21 @@ component Projector for emit::Emit { /// `of` node's kind first. public project(graph: model::Graph, view: emit::View): Result { if (view.isContext) { - return Ok(self.projectContext(graph)) + return Ok(projectContext(graph)) } if (view.isContainer) { - return self.projectBoundary(graph, view.of, "system", "container") + return projectBoundary(graph, view.of, "system", "container") } if (view.isComponent) { - return self.projectBoundary(graph, view.of, "container", "component") + return projectBoundary(graph, view.of, "container", "component") } if (view.isData) { - return self.projectData(graph, view.of) + return projectData(graph, view.of) } if (view.isFeature) { - return self.projectFeature(graph, view.of) + return projectFeature(graph, view.of) } - return self.projectSequence(graph, view.entry) + return projectSequence(graph, view.entry) } /// Project the diagram that best explains a single symbol, picking the view @@ -247,7 +247,7 @@ component Projector for emit::Emit { /// The context view: every person and system, with inter-system edges and /// triggers. A cross-container call bubbles to a single system → system edge. projectContext(graph: model::Graph): emit::Scene { - nodes = PlacedNode[] from self.collectKinds(graph, "person", "system") + nodes = PlacedNode[] from collectKinds(graph, "person", "system") edges = RoutedEdge[] from emit::Edges.collect(graph, nodes) return emit::Layout.solveC4(C4Scene from { nodes, edges }) } @@ -269,15 +269,15 @@ component Projector for emit::Emit { /// Edges among the resulting node set are lifted to the contained child. /// Errors when `of` is missing or not of `boundary` kind. projectBoundary(graph: model::Graph, of: string, boundary: string, child: string): Result { - anchor = Result from self.requireKind(graph, of, boundary) + anchor = Result from requireKind(graph, of, boundary) if (anchor.isErr) { return Err(anchor.error) } - outer = Option from self.outerFrameOf(graph, of) - inside = PlacedNode[] from self.childrenOf(graph, of, child, outer) - framed = PlacedNode[] from self.withOuterFrame(graph, inside, outer) - actors = PlacedNode[] from self.externalActors(graph, of, child, inside) - nested = PlacedNode[] from self.nestSiblings(graph, actors, outer) + outer = Option from outerFrameOf(graph, of) + inside = PlacedNode[] from childrenOf(graph, of, child, outer) + framed = PlacedNode[] from withOuterFrame(graph, inside, outer) + actors = PlacedNode[] from externalActors(graph, of, child, inside) + nested = PlacedNode[] from nestSiblings(graph, actors, outer) nodes = PlacedNode[] from { framed, nested } edges = RoutedEdge[] from emit::Edges.collect(graph, nodes) return Ok(emit::Layout.solveC4(C4Scene from { of, nodes, edges })) @@ -289,11 +289,11 @@ component Projector for emit::Emit { /// time, not here. Errors when the entry is not a callable, or has no /// disclosed body to trace. projectSequence(graph: model::Graph, entry: string): Result { - node = Result from self.requireKind(graph, entry, "callable") + node = Result from requireKind(graph, entry, "callable") if (node.isErr) { return Err(node.error) } - disclosed = Option from self.bodyOf(graph, entry) + disclosed = Option from bodyOf(graph, entry) if (disclosed.isNone) { return Ok(emit::Trace.blackBox(graph, entry)) } @@ -303,11 +303,11 @@ component Projector for emit::Emit { /// Looks a node up and asserts its C4 kind, mapping a miss to `UnknownNode` /// and a mismatch to `WrongKind`. Reads the kind off the graph's nodes. requireKind(graph: model::Graph, fqn: string, expected: string): Result { - found = Result from self.kindOf(graph, fqn) + found = Result from kindOf(graph, fqn) if (found.isErr) { return Err(UnknownNode from { fqn }) } - if (self.kindMatches(found.value, expected)) { + if (kindMatches(found.value, expected)) { return Ok(found.value) } return Err(WrongKind from { fqn, expected, found.value }) @@ -370,8 +370,8 @@ component Projector for emit::Emit { component Edges for emit::Emit { /// Collect the in-view routed edges for the nodes already placed in a scene. collect(graph: model::Graph, inView: emit::PlacedNode[]): emit::RoutedEdge[] { - routed = RoutedEdge[] from self.route(graph, inView) - return self.sortDedup(routed) + routed = RoutedEdge[] from route(graph, inView) + return sortDedup(routed) } /// Walk the graph's edges, keeping each whose endpoints both resolve in view. @@ -395,7 +395,8 @@ component Edges for emit::Emit { /// participant on first appearance (LANG.md §9.2, §7). A real trigger's /// initiator leads as the first lifeline with a synthesised inbound call; /// absent a trigger the owner leads. A `call` is a message to the target; a -/// disclosed callee expands inline; a `self.` call is a self-message; a return +/// disclosed callee expands inline; a same-node call is a self-message that +/// expands its disclosed body inline too; a return /// marks `Ok`/`Err`; `if`/`else` nests an `alt` frame, `for`/`while` a `loop` /// frame. component Trace for emit::Emit { @@ -406,16 +407,16 @@ component Trace for emit::Emit { /// land on the initiator. The call stack starts at the entry, guarding /// against re-expanding a callable already in flight. walk(graph: model::Graph, entry: string, body: model::Step[]): emit::Scene { - owner = string from self.ownerOf(graph, entry) - actor = Option from self.triggerActorOf(graph, entry) - stack = string[] from self.entryStack(entry) + owner = string from ownerOf(graph, entry) + actor = Option from triggerActorOf(graph, entry) + stack = string[] from entryStack(entry) if (actor.isNone) { - return self.untriggered(graph, entry, body, owner, stack) + return untriggered(graph, entry, body, owner, stack) } - inbound = SeqItem from self.inboundCall(graph, actor.value, owner, entry) - rest = SeqItem[] from self.traceItems(graph, body, owner, actor.value, stack) - items = SeqItem[] from self.prependItem(inbound, rest) - participants = Lifeline[] from self.participantsOf(graph, actor.value, items) + inbound = SeqItem from inboundCall(graph, actor.value, owner, entry) + rest = SeqItem[] from traceItems(graph, body, owner, actor.value, stack) + items = SeqItem[] from prependItem(inbound, rest) + participants = Lifeline[] from participantsOf(graph, actor.value, items) return SequenceScene from { entry, participants, items } } @@ -425,8 +426,8 @@ component Trace for emit::Emit { /// make sense once a real incoming trigger exists. Inner expanded callees /// still return to their callers. untriggered(graph: model::Graph, entry: string, body: model::Step[], owner: string, stack: string[]): emit::Scene { - items = SeqItem[] from self.traceItems(graph, body, owner, self.noCaller(), stack) - participants = Lifeline[] from self.participantsOf(graph, owner, items) + items = SeqItem[] from traceItems(graph, body, owner, noCaller(), stack) + participants = Lifeline[] from participantsOf(graph, owner, items) return SequenceScene from { entry, participants, items } } @@ -444,13 +445,13 @@ component Trace for emit::Emit { /// mutual recursion), closes with a synthesised return of its declared type, /// so every call has its reply. traceCall(graph: model::Graph, target: string, method: string, active: string, stack: string[]): emit::SeqItem[] { - msg = SeqItem from self.callMessage(graph, active, target, method) - disclosed = Option from self.expandableBody(graph, target, method, stack) + msg = SeqItem from callMessage(graph, active, target, method) + disclosed = Option from expandableBody(graph, target, method, stack) if (disclosed.isNone) { - reply = SeqItem from self.syntheticReturn(graph, target, method, active) + reply = SeqItem from syntheticReturn(graph, target, method, active) return SeqItem[] from { msg, reply } } - inner = SeqItem[] from self.traceItems(graph, disclosed.value, target, active, self.pushCall(stack, target, method)) + inner = SeqItem[] from traceItems(graph, disclosed.value, target, active, pushCall(stack, target, method)) return SeqItem[] from { msg, inner } } @@ -475,12 +476,12 @@ component Trace for emit::Emit { /// exactly one request and its reply — unlike a disclosed trace, which /// suppresses the triggerless caller (§9.2). blackBox(graph: model::Graph, entry: string): emit::Scene { - owner = string from self.ownerOf(graph, entry) - actor = string from self.blackBoxActor(graph, entry) - inbound = SeqItem from self.inboundCall(graph, actor, owner, entry) - reply = SeqItem from self.returnItem(graph, owner, actor, entry) + owner = string from ownerOf(graph, entry) + actor = string from blackBoxActor(graph, entry) + inbound = SeqItem from inboundCall(graph, actor, owner, entry) + reply = SeqItem from returnItem(graph, owner, actor, entry) items = SeqItem[] from { inbound, reply } - participants = Lifeline[] from self.participantsOf(graph, actor, items) + participants = Lifeline[] from participantsOf(graph, actor, items) return SequenceScene from { entry, participants, items } } @@ -510,7 +511,8 @@ component Trace for emit::Emit { prependItem(head: emit::SeqItem, rest: emit::SeqItem[]): emit::SeqItem[]; /// Walk a step list for `active` into sequence items: each cross-node call - /// through `traceCall`, each `self.` call as a self-message, each `return` as + /// through `traceCall`, each same-node call as a self-message whose disclosed + /// body expands inline, each local-value method as a leaf self-message, each `return` as /// a message back to `caller` (suppressed when `caller` is the empty marker), /// and `Alt`/`Loop` frames recursing into their bodies with the same caller /// and stack. @@ -539,7 +541,7 @@ component Layout for emit::Emit { /// Place a C4 scene by the `dot` engine with default tweaks and no pins. layoutC4Default(scene: emit::Scene): emit::C4Layout { - return self.layoutC4(scene, self.defaultTweaks(), self.noPins()) + return layoutC4(scene, defaultTweaks(), noPins()) } /// Place a C4 scene under `tweaks` into a `C4Layout`, with `pins` fixing @@ -549,8 +551,8 @@ component Layout for emit::Emit { /// framed boundary) falls back to the scene's own simple coordinates; the /// engine itself never panics. layoutC4(scene: emit::Scene, tweaks: emit::C4Tweaks, pins: emit::GridPin[]): emit::C4Layout { - g = dot::Graph from self.toDotGraph(scene, tweaks) - return self.readBack(scene, self.place(g, tweaks, pins)) + g = dot::Graph from toDotGraph(scene, tweaks) + return readBack(scene, place(g, tweaks, pins)) } /// Run the placement the tweaks select: the experimental grid placer @@ -558,9 +560,9 @@ component Layout for emit::Emit { /// layered pipeline, folded through the pass list the tweaks select. place(g: dot::Graph, tweaks: emit::C4Tweaks, pins: emit::GridPin[]): dot::Layout { if (tweaks.experimentalGrid) { - return dot::Dot.gridLayout(g, self.gridParams(tweaks), self.dotPins(pins)) + return dot::Dot.gridLayout(g, gridParams(tweaks), dotPins(pins)) } - return dot::Dot.runPipeline(g, self.layoutPasses(tweaks)) + return dot::Dot.runPipeline(g, layoutPasses(tweaks)) } /// The pipeline passes the tweaks select: `ShortenLongEdges` when @@ -590,9 +592,9 @@ component Layout for emit::Emit { /// x-positions in first-appearance order, message rows stacked by evaluation /// order, frames sized to their body. solveSequence(scene: emit::Scene): emit::Scene { - metrics = layout::Metrics from self.sequenceMetrics() - placed = layout::SequenceLayout from layout::Layout.layout(self.toSequenceDiagram(scene), metrics) - return self.fromSequenceLayout(scene, placed) + metrics = layout::Metrics from sequenceMetrics() + placed = layout::SequenceLayout from layout::Layout.layout(toSequenceDiagram(scene), metrics) + return fromSequenceLayout(scene, placed) } /// The sequence engine's default metrics — the one source of truth for the @@ -621,15 +623,15 @@ component SvgRenderer for emit::Emit { /// scene variant. public render(scene: emit::Scene): string { if (scene.isC4Scene) { - return self.renderC4(scene) + return renderC4(scene) } if (scene.isSequenceScene) { - return self.renderSequence(scene) + return renderSequence(scene) } if (scene.isDataScene) { - return self.renderData(scene) + return renderData(scene) } - return self.renderFeature(scene) + return renderFeature(scene) } /// Render any scene to SVG under a chosen colour theme. `light` and `dark` @@ -647,10 +649,10 @@ component SvgRenderer for emit::Emit { /// kind eyebrow, bold title, dimmed wrapped description) and routed edges; /// frames the boundary children when the view has an `of`. renderC4(scene: emit::Scene): string { - if (self.layoutFailed(scene)) { - return self.fallbackSvg(scene) + if (layoutFailed(scene)) { + return fallbackSvg(scene) } - return self.emitSvg(scene) + return emitSvg(scene) } /// Draw the sequence: lifeline-head cards with dropping dashed lifelines, @@ -795,12 +797,12 @@ feature ControlFlowBecomesFrames for emit::Trace { and "a for/while becomes a loop frame over its body" } -/// Body calls become left-to-right messages; self-calls loop on the owner. +/// Body calls become left-to-right messages; same-node calls loop on the owner. feature CallsBecomeMessages for emit::Trace { - given "a callable body with calls to other nodes and self-calls" + given "a callable body with calls to other nodes and same-node calls" when "the body is traced" then "each call to another node is a left-to-right message to that lifeline" - and "each self. call is a self-message on the owner's own lifeline" + and "each same-node call is a self-message that expands its disclosed body on the owner's own lifeline" and "every target is registered as a participant on first appearance" } diff --git a/model/format.pds b/model/format.pds index 2ab8648a..1c5a1d3f 100644 --- a/model/format.pds +++ b/model/format.pds @@ -44,8 +44,8 @@ component Formatter for format::Format { /// tree. public format(text: string): Result { parsed = Parsed from syntax::Syntax.parse(text) - if (self.hasErrors(parsed)) { - errors = string[] from self.collectErrors(parsed) + if (hasErrors(parsed)) { + errors = string[] from collectErrors(parsed) err = FormatError from { errors } return Err(err) } @@ -84,8 +84,8 @@ component Printer for format::Format { /// the `//!` inner docs, a blank separator if items follow, then each item in /// source order. print(ast: syntax::Module): string { - state = PrinterState from self.writeModule(ast) - out = string from self.finish(state) + state = PrinterState from writeModule(ast) + out = string from finish(state) return out } @@ -178,7 +178,8 @@ component Printer for format::Format { /// the segment is a call. writePostfixSeg(state: format::PrinterState, seg: syntax::PostfixSeg): format::PrinterState; - /// Emit a reference primary: the literal `self`, or a path. + /// Emit a reference primary: a path (the only `Reference` form since `self` + /// was dropped, ADR-041; a bare same-node call is the `OwnCall` primary). writeRef(state: format::PrinterState, reference: syntax::Reference): format::PrinterState; /// Emit a literal from its raw source text — strings keep their quotes, diff --git a/model/ide.pds b/model/ide.pds index 9eec708a..3b70b480 100644 --- a/model/ide.pds +++ b/model/ide.pds @@ -183,7 +183,7 @@ public component LanguageSession for ide::IdeSession { /// checked against the dependency externals (§8.3) — what the editor adapter /// marks in the gutter after every edit. public diagnostics(): model::ModuleDiagnostics[] { - return self.checkAgainstExternals(self.heldModules(), self.heldExternals()) + return checkAgainstExternals(heldModules(), heldExternals()) } /// Check every module with the dependency modules bound as externals (§8.3), so /// a `dep::module::Node` reference resolves — the externals-aware counterpart of @@ -262,9 +262,9 @@ public component Docs for ide::IdeSession { /// unchanged — diagnostics never cross the boundary). SSR crosses to the /// host's render callback. render(config: ide::DocConfig): ide::RenderedFile[] { - perModule = model::ModuleDiagnostics[] from model::Model.checkWorkspaceModules(self.heldDocModules(), self.heldExternals()) - prepared = doc::DiagnosticInput[] from doc::Doc.prepareDiagnostics(self.heldDocModules(), perModule) - return self.renderWith(config, prepared) + perModule = model::ModuleDiagnostics[] from model::Model.checkWorkspaceModules(heldDocModules(), heldExternals()) + prepared = doc::DiagnosticInput[] from doc::Doc.prepareDiagnostics(heldDocModules(), perModule) + return renderWith(config, prepared) } /// The held workspace's own modules, the check input. @@ -291,15 +291,15 @@ public component Universe for ide::IdeSession { /// The 3D-view snapshot of the held workspace: structural nodes with /// containment and directed traffic-weighted relationships, no positions. universe(): ide::UniverseSnapshot { - graph = universe::SoftwareGraph from universe::Universe.build(self.heldModules()) - return self.toSnapshot(universe::Universe.snapshot(graph)) + graph = universe::SoftwareGraph from universe::Universe.build(heldModules()) + return toSnapshot(universe::Universe.snapshot(graph)) } /// The entry-point flows of the held workspace, traced and lifted by the /// universe crate — the filaments the ForceGraph animates. Replaces the IDE's /// former client-side sequence-walking, so doc site and IDE share one tracer. universeFlows(): universe::FlowDef[] { - graph = model::Graph from model::Model.graph(self.heldModules()) + graph = model::Graph from model::Model.graph(heldModules()) return universe::Universe.flows(graph) } @@ -346,9 +346,9 @@ public component FsAccessAdapter for ide::WebIde { /// module's FQN from its path, LANG.md §8.1), then resolve externals via the /// session. readDependencies(): model::WorkspaceModule[] { - lock = string from self.readLock() - vendored = ide::VendoredInput[] from self.readVendored() - local = ide::LocalInput[] from self.noLocalSources() + lock = string from readLock() + vendored = ide::VendoredInput[] from readVendored() + local = ide::LocalInput[] from noLocalSources() return ide::Workspace.dependencyModules(lock, vendored, local) } /// The consumer's `pds.lock` text, blank when absent. @@ -375,7 +375,7 @@ public component CodeMirrorAdapter for ide::WebIde { onEdit(fqn: string, text: string): void { ide::IdeSession.setSource(fqn, text) diags = model::ModuleDiagnostics[] from ide::LanguageSession.diagnostics() - self.markProblems(diags) + markProblems(diags) } /// The completion source: ask the session for items at the caret. A `.`/`::` /// boundary opens the popup with no prefix typed. @@ -388,7 +388,7 @@ public component CodeMirrorAdapter for ide::WebIde { if (result.isNone) { return } - self.showTooltip(result.value.contents) + showTooltip(result.value.contents) } /// Mark the problems CodeMirror shows in its gutter. markProblems(diags: model::ModuleDiagnostics[]): void; @@ -414,8 +414,8 @@ component LlmSettingsStore for ide::WebIde { /// Apply a provider preset: its pinned endpoint, wire shape, and default /// model become the active settings in one edit. applyPreset(provider: string): void { - preset = ide::LlmSettings from self.presetFor(provider) - self.save(preset) + preset = ide::LlmSettings from presetFor(provider) + save(preset) } /// The pinned settings for a preset id: `ollama` → the local daemon over /// chat with no key; `openai` → the hosted endpoint over chat, key required; @@ -446,7 +446,7 @@ component FimClient for ide::WebIde { /// Route the prompt by the configured wire shape: a native fill-in-the-middle /// route when the provider has one, else a FIM-shaped chat request. complete(prompt: ide::FimPrompt, settings: ide::LlmSettings): Result { - fim = bool from self.usesNativeFim(settings) + fim = bool from usesNativeFim(settings) if (fim) { return ide::LlmProvider.fimComplete(prompt, settings.model) } @@ -463,12 +463,12 @@ component FimClient for ide::WebIde { /// models, then ask for a one-token completion — the first failure comes /// back classified, with its fix hint, instead of a silent bail. testConnection(settings: ide::LlmSettings): Result { - models = Result from self.listModels(settings) + models = Result from listModels(settings) if (models.isErr) { return Err(models.error) } - probe = ide::FimPrompt from self.probePrompt() - answer = Result from self.complete(probe, settings) + probe = ide::FimPrompt from probePrompt() + answer = Result from complete(probe, settings) if (answer.isErr) { return Err(answer.error) } @@ -496,27 +496,27 @@ component GhostText for ide::WebIde { return } settings = ide::LlmSettings from ide::LlmSettingsStore.current() - prompt = ide::FimPrompt from self.assemble(moduleFqn, offset) + prompt = ide::FimPrompt from assemble(moduleFqn, offset) raw = Result from ide::FimClient.complete(prompt, settings) if (raw.isErr) { ide::LlmSettingsStore.reportFailure(raw.error) return } ide::LlmSettingsStore.clearFailure() - blank = bool from self.isBlank(raw.value) + blank = bool from isBlank(raw.value) if (blank) { ide::LlmSettingsStore.noteDrop("empty") return } ide::LlmSettingsStore.clearDrop() - self.show(raw.value) + show(raw.value) } /// The provider context: the windowed buffer around the caret plus the cached /// grammar primer. assemble(moduleFqn: string, offset: number): ide::FimPrompt { - window = string from self.windowAround(moduleFqn, offset) + window = string from windowAround(moduleFqn, offset) symbols = ide::OutlineNode[] from ide::LanguageSession.outline() - primer = string from self.grammarPrimer() + primer = string from grammarPrimer() return ide::FimPrompt from { window, symbols, primer } } /// The capped prefix/suffix slice of the buffer around the caret. @@ -571,7 +571,7 @@ public component DiagramCanvas for ide::WebIde { public component Bootstrap for ide::WebIde { /// Restore from the hash when it carries a workspace; else show the launcher. start(): void { - restored = bool from self.restoreFromHash() + restored = bool from restoreFromHash() if (!restored) { ide::Launcher.show() } @@ -617,7 +617,7 @@ public component Launcher for ide::WebIde { openFolder(): void { picked = Result from ide::FsAccessAdapter.pickFolder() if (picked.isErr) { - self.showPickError(picked.error) + showPickError(picked.error) return } if (!picked.value) { diff --git a/model/lsp.pds b/model/lsp.pds index c7129891..78c6844c 100644 --- a/model/lsp.pds +++ b/model/lsp.pds @@ -60,14 +60,14 @@ component Server for lsp::Lsp { /// causes it. Driven by the editor (`context::Editor.openDocument`). public onChange(doc: model::WorkspaceModule): void { lsp::Store.change(doc) - self.publishAll() + publishAll() } /// `didClose`: drop the unsaved overlay and re-sync to disk so other files stop /// seeing the closed buffer's edits, then republish. onClose(uri: string): void { lsp::Store.close(uri) - self.publishAll() + publishAll() } /// Recompute diagnostics for the whole workspace and push each module's set to @@ -76,7 +76,7 @@ component Server for lsp::Lsp { payloads = model::ModuleDiagnostics[] from lsp::Store.diagnostics() for (p in payloads) { uri = string from lsp::Store.uriOf(p.fqn) - self.publish(uri, p.diagnostics) + publish(uri, p.diagnostics) } } @@ -103,7 +103,7 @@ component Server for lsp::Lsp { return None } target = lsp::DefTarget from found.value - return Some(self.locate(target)) + return Some(locate(target)) } /// Whole-document formatting edit; none when the buffer is already canonical @@ -119,7 +119,7 @@ component Server for lsp::Lsp { locate(target: lsp::DefTarget): lsp::Occurrence { uri = string from lsp::Store.uriOf(target.fqn) targetText = string from lsp::Store.source(uri) - range = lsp_core::Range from self.rangeIn(targetText, target.span) + range = lsp_core::Range from rangeIn(targetText, target.span) return Occurrence from { uri, range } } @@ -140,9 +140,9 @@ component Store for lsp::Lsp { /// under it; a path with no `pds.toml` on the way to the filesystem root leaves /// the store empty (standalone files are then added as they open). discover(rootUri: string): void { - found = bool from self.findRoot(rootUri) + found = bool from findRoot(rootUri) if (found) { - self.loadRoot() + loadRoot() } } @@ -174,8 +174,8 @@ component Store for lsp::Lsp { /// dependency externals (§8.3): ensure those are loaded, then build the /// resolved workspace from the cached local parses with the externals bound. workspace(): model::Workspace { - external = model::WorkspaceModule[] from self.ensureExternals() - return self.buildWithExternals(self.modules(), external) + external = model::WorkspaceModule[] from ensureExternals() + return buildWithExternals(modules(), external) } /// Ensure the workspace's direct-dependency modules (§8.3) are loaded as @@ -201,8 +201,8 @@ component Store for lsp::Lsp { /// workspace, not a fresh externals-blind re-check, keeps a cross-dependency /// reference resolving rather than falsely diagnosing it. diagnostics(): model::ModuleDiagnostics[] { - ws = model::Workspace from self.workspace() - return self.collectDiagnostics(ws) + ws = model::Workspace from workspace() + return collectDiagnostics(ws) } /// Assemble each module's `ModuleDiagnostics` from its cached parse errors and diff --git a/model/model.pds b/model/model.pds index d1e0c3f3..a02a1242 100644 --- a/model/model.pds +++ b/model/model.pds @@ -276,7 +276,7 @@ public component Resolver for model::Model { /// feature adds nothing to this table — its name lives in a separate /// namespace. public build(ast: syntax::Module): model::SymbolTable { - return self.buildWithPath(ast, "") + return buildWithPath(ast, "") } /// Builds the table with a caller-supplied module FQN — the path the workspace @@ -306,7 +306,7 @@ public component Workspace for model::Model { /// graph-projection path. Resolves each module with its caller-supplied FQN so /// the global index keys on the correct cross-module names. public build(modules: model::WorkspaceModule[]): model::ModuleEntry[] { - return self.buildWithExternals(modules, self.noExternals()) + return buildWithExternals(modules, noExternals()) } /// Builds the table with the workspace's §8.3 dependency modules bound as @@ -315,9 +315,9 @@ public component Workspace for model::Model { /// a private external reports `Private`, not a dangling FQN (§8.3). The checks /// path the CLI, the LSP store, and the IDE all route through. public buildWithExternals(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[]): model::ModuleEntry[] { - local = ModuleEntry[] from self.resolveEach(modules) - external = ModuleEntry[] from self.resolveEach(externals) - return self.index(local, external) + local = ModuleEntry[] from resolveEach(modules) + external = ModuleEntry[] from resolveEach(externals) + return index(local, external) } /// Parse and resolve each module into a `ModuleEntry` — its FQN, its AST, and @@ -343,12 +343,12 @@ public component Workspace for model::Model { /// §8.2 visibility rule: a same-module target resolves regardless of /// visibility; a cross-module target resolves only if it is `public`. public resolveQualified(fromModule: string, fqn: string): model::Resolution { - found = Option from self.lookup(fqn) + found = Option from lookup(fqn) if (found.isNone) { return model::Resolution::Missing } sym = Symbol from found.value - if (self.sameModule(fromModule, fqn)) { + if (sameModule(fromModule, fqn)) { return Public from { sym } } if (sym.isPublic) { @@ -371,7 +371,7 @@ component Checks for model::Model { /// the static-analysis errors. The CLI's `pds check` driver. public check(text: string): syntax::Diagnostic[] { parsed = Parsed from syntax::Syntax.parse(text) - static = syntax::Diagnostic[] from self.analyze(parsed.ast) + static = syntax::Diagnostic[] from analyze(parsed.ast) return syntax::Diagnostic[] from { parsed.diagnostics, static } } @@ -380,7 +380,7 @@ component Checks for model::Model { /// diagnostics; the caller supplies the parse diagnostics. public analyze(ast: syntax::Module): syntax::Diagnostic[] { model = SymbolTable from model::Resolver.build(ast) - return self.run(ast, model) + return run(ast, model) } /// Check a multi-module workspace with its §8.3 dependency modules bound as @@ -390,9 +390,9 @@ component Checks for model::Model { /// parse errors come first because the `ModuleEntry` the workspace pass walks /// keeps only the recovered AST and drops each module's parse diagnostics. public checkWorkspace(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[]): syntax::Diagnostic[] { - parse = syntax::Diagnostic[] from self.parseErrors(modules) + parse = syntax::Diagnostic[] from parseErrors(modules) entries = ModuleEntry[] from model::Workspace.buildWithExternals(modules, externals) - workspace = syntax::Diagnostic[] from self.runWorkspace(entries) + workspace = syntax::Diagnostic[] from runWorkspace(entries) return syntax::Diagnostic[] from { parse, workspace } } @@ -415,10 +415,10 @@ component Checks for model::Model { run(ast: syntax::Module, model: model::SymbolTable): syntax::Diagnostic[] { variants = syntax::Diagnostic[] from model::VariantCollision.check(ast) features = syntax::Diagnostic[] from model::FeatureCheck.check(ast, model) - constants = syntax::Diagnostic[] from self.checkConstantCollisions(ast) + constants = syntax::Diagnostic[] from checkConstantCollisions(ast) reserved = syntax::Diagnostic[] from model::ReservedNames.check(ast) typeRefs = syntax::Diagnostic[] from model::TypeRefs.check(ast, model) - items = syntax::Diagnostic[] from self.checkItems(ast) + items = syntax::Diagnostic[] from checkItems(ast) return syntax::Diagnostic[] from { variants, features, constants, reserved, typeRefs, items } } @@ -430,10 +430,10 @@ component Checks for model::Model { /// macro targeting (§2.4), single-assignment rebinds (§7.1), return coverage /// (ADR-016), `Result`/`Option` accessor narrowing (§6), return-type and `from` /// source/target matching — a `return` or `from` source call whose callee - /// resolves in-module (`self.` or a same-module node) carries the callee's + /// resolves in-module (a same-node call or a same-module node) carries the callee's /// declared return type (§5.1, §7.2 — ADR-035, ADR-040), `for` iterates an array - /// (§7.3 — ADR-014), `self.` calls and bare references resolve (§5.1, §8 — - /// ADR-004), `.field` reads name a declared field (§2.2, §3.4), call arity and + /// (§7.3 — ADR-014), same-node calls and bare references resolve (§5.1, §8 — + /// ADR-041), `.field` reads name a declared field (§2.2, §3.4), call arity and /// argument types match (§5.1 — ADR-022), `.method(args)` calls name a callable /// of the receiver's type (§6 — ADR-022), and `if`/`while` conditions are `bool` /// (§7 — ADR-023). Plus, on each structural declaration, the macro-target check @@ -447,7 +447,7 @@ component Checks for model::Model { /// errors, and the architectural warnings. The graph is projected once from the /// resolved entries and handed to `Architecture`, which never holds source. runWorkspace(entries: model::ModuleEntry[]): syntax::Diagnostic[] { - perModule = syntax::Diagnostic[] from self.runEach(entries) + perModule = syntax::Diagnostic[] from runEach(entries) cross = syntax::Diagnostic[] from model::CrossModule.check(entries) graph = model::Graph from model::Builder.graphOf(entries) arch = syntax::Diagnostic[] from model::Architecture.check(graph) @@ -495,9 +495,9 @@ component Architecture for model::Model { /// bypass (PDS-ARCH-001), cyclic dependency (PDS-ARCH-002), and system-boundary /// bypass (PDS-ARCH-003). public check(graph: model::Graph): syntax::Diagnostic[] { - backdoor = syntax::Diagnostic[] from self.checkBackdoor(graph) - cycles = syntax::Diagnostic[] from self.checkCycles(graph) - boundary = syntax::Diagnostic[] from self.checkSystemBoundary(graph) + backdoor = syntax::Diagnostic[] from checkBackdoor(graph) + cycles = syntax::Diagnostic[] from checkCycles(graph) + boundary = syntax::Diagnostic[] from checkSystemBoundary(graph) return syntax::Diagnostic[] from { backdoor, cycles, boundary } } @@ -567,7 +567,7 @@ public component ResultFlow for model::Model { public component ReturnCoverage for model::Model { /// Whether a block returns on every path: any statement diverges. public blockReturns(body: syntax::Module): bool { - return self.stmtReturns(body) + return stmtReturns(body) } /// Whether one statement guarantees a return: a `return`, or an `if`/`else` @@ -651,7 +651,7 @@ component Builder for model::Model { /// then project. The entry point for callers that hold only source. public graph(modules: model::WorkspaceModule[]): model::Graph { entries = ModuleEntry[] from model::Workspace.build(modules) - return Graph from self.graphOf(entries) + return Graph from graphOf(entries) } /// Projects an already-resolved workspace into the graph: collect every node, @@ -661,7 +661,7 @@ component Builder for model::Model { /// so the architectural lints run without re-resolving. public graphOf(entries: model::ModuleEntry[]): model::Graph { for (e in entries) { - self.collectModule(e) + collectModule(e) } return Graph from { entries } } @@ -719,7 +719,7 @@ public data ResolveHit { clicked: syntax::Span, targetModule: string, targetSpan /// Caret resolution — the engine every cursor feature shares (`lsp_core` hover, /// definition, references, rename; the IDE's symbol actions). Tokenizes the /// active source, finds the identifier under the offset, and resolves it across -/// the workspace and its externals: a node or data FQN, a `self.`/member access, +/// the workspace and its externals: a node or data FQN, a same-node call or member access, /// or a local reference. Token-level, so it survives a partial parse. public component CaretResolve for model::Model { /// Resolve the identifier under `offset` in module `fromFqn`'s source; none diff --git a/model/project.pds b/model/project.pds index 2cbbc595..d6017c9c 100644 --- a/model/project.pds +++ b/model/project.pds @@ -37,11 +37,11 @@ component Loader for project::Project { /// Load every `.pds` module under the workspace root into the `(fqn, source)` /// form the model resolves: find the visible files, then read each one. public load(root: string): Result { - files = Result from self.findModules(root) + files = Result from findModules(root) if (files.isErr) { return Err(files.error) } - modules = Result from self.readEach(root, files.value) + modules = Result from readEach(root, files.value) if (modules.isErr) { return Err(modules.error) } diff --git a/model/site/health.html b/model/site/health.html index 087030e3..6b7534f0 100644 --- a/model/site/health.html +++ b/model/site/health.html @@ -11,7 +11,7 @@ -
PseudoScript
Report

Architecture health

No findings.

Generated by pds doc.
+
PseudoScript
Report

Architecture health

No findings.

Generated by pds doc.
diff --git a/model/site/index.html b/model/site/index.html index 41df25ac..ad35ceb2 100644 --- a/model/site/index.html +++ b/model/site/index.html @@ -11,7 +11,7 @@ -
PseudoScript
Architecture documentation

PseudoScript

A C4 model of the workspace: persons, systems, and their containers and +

PseudoScript
Architecture documentation

PseudoScript

A C4 model of the workspace: persons, systems, and their containers and components, with relationships and sequence flows.

  • 3 systems
  • 15 containers
  • 100 components
  • 24 flows
  • 0 findings
Context System context scroll to zoom · drag to pan
PERSONDeveloperAuthor of architecture models: edits `.pds`files in an IDE and runs the CLI.SYSTEMPseudoscriptThe PseudoScript CLI — loads a `.pds`workspace into one resolved graph and…SYSTEMEditorIDEs that speak the Language Server Protocol(VS Code, Neovim, …). The editor spawns `pd…SYSTEMLlmProviderThe author's configured OpenAI-compatiblecompletion provider — hosted (OpenAI,…PERSONVisitorA prospective user reading the landing page.openDocumentrenderDocsserveLanguagechatCompletefimCompletelistModelsopenIdeshowInstall
cli
14 items
context
3 items
doc
42 items
dot
19 items
emit
42 items
format
4 items
ide
23 items
landing
2 items
layout
21 items
lsp
4 items
lsp_core
8 items
model
52 items
project
2 items
syntax
85 items
universe
10 items
3D Universe
The whole model as an explorable scene
Architecture health
Errors, warnings, and principle lints
Generated by pds doc.
diff --git a/model/site/module/cli.html b/model/site/module/cli.html index c2a1e312..20dc584c 100644 --- a/model/site/module/cli.html +++ b/model/site/module/cli.html @@ -11,12 +11,12 @@ -
PseudoScript
Module

cli

data

AddOpts #

public
cli::AddOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDAddOptsurlstringtagstringrevstringbranchstringpathstringnamestring
component

Args #

private
cli::Args

Parses argv with clap-derive into the chosen subcommand and its options, then +

PseudoScript
Module

cli

data

AddOpts #

public
cli::AddOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDAddOptsurlstringtagstringrevstringbranchstringpathstringnamestring
component

Args #

private
cli::Args

Parses argv with clap-derive into the chosen subcommand and its options, then dispatches to the matching command handler.

Parent

Sequence Sequence — dispatch scroll to zoom · drag to pan
SEQUENCEdispatchPERSONcallerCOMPONENTArgsPseudoscript::CliParses argv withclap-derive into the1dispatch(command: cli::Command)↩ return number
component

CheckCmd #

private
cli::CheckCmd

`pds check` — parse and statically check one file, print each diagnostic as `path:line:col: severity: message`, and exit non-zero on any error-severity -diagnostic. Emits no diagram.

Parent

Outbound

Scenarios

CheckExitCode

`pds check` exits non-zero when any error diagnostic is produced.

  • given a .pds source file
  • when the developer runs `pds check` on it
  • then every diagnostic is printed as path:line:col: severity: message
  • but the command exits non-zero if any diagnostic is error-severity
  • and a well-formed model prints nothing and exits zero
Flow Flow — CheckExitCode scroll to zoom · drag to pan
FEATURECheckExitCodefor CheckCmdGIVENa .pds source fileWHENthe developer runs `pds check` on itTHENevery diagnostic is printed aspath:line:col: severity: messageBUTthe command exits non-zero if anydiagnostic is error-severityANDa well-formed model prints nothing andexits zero
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[found.isErr][else]alt[else self.isDirectory()]alt[root.isErr][else]COMPONENTCheckCmdPseudoscript::Cli`pds check` — parseand statically checkCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:1findRoot(start: string)2findRoot(start: string)3findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>4ioError↩ Err<cli::IoError>↩ Ok<string>5isDirectory6checkRootless7checkWorkspace
Sequence Sequence — runAll scroll to zoom · drag to pan
SEQUENCErunAllalt[else roots.isErr]COMPONENTCheckCmdPseudoscript::Cli`pds check` — parseand statically checkCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the project1discoverWorkspaces(root: string)↩ return Result<string[], cli::IoError>2checkEach
data

CheckOpts #

public
cli::CheckOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDCheckOptsfilestringallbool
container

Cli #

public
cli::Cli

`crates/pseudoscript` — the binary crate (`pds`). The composition root and +diagnostic. Emits no diagram.

Parent

Outbound

Scenarios

CheckExitCode

`pds check` exits non-zero when any error diagnostic is produced.

  • given a .pds source file
  • when the developer runs `pds check` on it
  • then every diagnostic is printed as path:line:col: severity: message
  • but the command exits non-zero if any diagnostic is error-severity
  • and a well-formed model prints nothing and exits zero
Flow Flow — CheckExitCode scroll to zoom · drag to pan
FEATURECheckExitCodefor CheckCmdGIVENa .pds source fileWHENthe developer runs `pds check` on itTHENevery diagnostic is printed aspath:line:col: severity: messageBUTthe command exits non-zero if anydiagnostic is error-severityANDa well-formed model prints nothing andexits zero
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[found.isErr][else]alt[anyError()][else]alt[text.isErr][else]alt[else isDirectory()]alt[modules.isErr][else]alt[files.isErr][else]alt[loaded.isErr][else]alt[dependencies.isErr][else]alt[modules.isErr][else]alt[config.isErr][else]loop[entries]alt[anyError()][else]alt[project.isErr][else]alt[root.isErr][else]COMPONENTCheckCmdPseudoscript::Cli`pds check` — parseand statically checkCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:CONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTChecksPseudoscript::ModelStatic analysis(LANG.md §2.2, §2.3,CONTAINERSyntaxPseudoscript`crates/pseudoscript-syntax`.The foundation crate:COMPONENTParserPseudoscript::SyntaxRecursive-descentparser for the §10COMPONENTLexerPseudoscript::SyntaxHand-written lexer forLANG.md §2. One passCOMPONENTResolverPseudoscript::ModelResolves a module'sdeclarations into aCOMPONENTVariantCollisionPseudoscript::Model§3.5 / ADR-006 — unionvariant collision. ACOMPONENTFeatureCheckPseudoscript::Model§5.2 / §8.1 — featurechecks. A feature'sCOMPONENTReservedNamesPseudoscript::Model§2.3 / ADR-012 —reserved-wordCOMPONENTTypeRefsPseudoscript::Model§3.3 / §8.1 —type-referenceCOMPONENTWorkspacePseudoscript::ModelThe resolved set ofmodules keyed by FQNCOMPONENTCrossModulePseudoscript::Model§8.2 — cross-modulevisibility resolution…COMPONENTBuilderPseudoscript::ModelProjects the parsed,resolved workspaceCOMPONENTArchitecturePseudoscript::ModelLANG.md §9 —architectural-princip…1findRoot(start: string)2findRoot(start: string)3findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>4ioError↩ Err<cli::IoError>↩ Ok<string>5isDirectory6checkRootless7readSource↩ Err<cli::IoError>8check(text: string)9check(text: string)10parse(text: string)11parse(text: string)12lex(text: string)↩ return syntax::Lexed13parseModule↩ return syntax::Module14diagnostics↩ return syntax::Parsed↩ return syntax::Parsed15analyze16build(ast: syntax::Module)17buildWithPath↩ return model::SymbolTable↩ return model::SymbolTable18run19check(ast: syntax::Module)↩ return syntax::Diagnostic[]20check(ast: syntax::Module, model: model::SymbolTable)↩ return syntax::Diagnostic[]21checkConstantCollisions22check(ast: syntax::Module)↩ return syntax::Diagnostic[]23check(ast: syntax::Module, model: model::SymbolTable)↩ return syntax::Diagnostic[]24checkItems↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]25anyError↩ Err<cli::IoError>↩ Ok<void>26checkWorkspace27load(root: string)28loadManifest↩ Err<cli::IoError>29loadModules30load(root: string)31load(root: string)32findModules↩ Err<project::IoError>33readEach↩ Err<project::IoError>↩ Ok<model::WorkspaceModule[]>↩ return Result<model::WorkspaceModule[], project::IoError>34ioError↩ Err<cli::IoError>↩ Ok<model::WorkspaceModule[]>↩ Err<cli::IoError>35loadDependencies↩ Err<cli::IoError>↩ Ok<cli::Workspace>↩ Err<cli::IoError>36checkWorkspace(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])37checkWorkspace(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])38parseErrors39buildWithExternals(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])40resolveEach41resolveEach42index↩ return model::ModuleEntry[]43runWorkspace44runEach45check(entries: model::ModuleEntry[])↩ return syntax::Diagnostic[]46graphOf(entries: model::ModuleEntry[])47collectModule↩ return model::Graph48check(graph: model::Graph)49checkBackdoor50checkCycles51checkSystemBoundary↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]52anyError↩ Err<cli::IoError>↩ Ok<void>
Sequence Sequence — runAll scroll to zoom · drag to pan
SEQUENCErunAllalt[else roots.isErr]COMPONENTCheckCmdPseudoscript::Cli`pds check` — parseand statically checkCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the project1discoverWorkspaces(root: string)↩ return Result<string[], cli::IoError>2checkEach
data

CheckOpts #

public
cli::CheckOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDCheckOptsfilestringallbool
container

Cli #

public
cli::Cli

`crates/pseudoscript` — the binary crate (`pds`). The composition root and only I/O edge; a thin frontend that wires the pure library crates to disk, -HTTP, and a filesystem watcher.

Inbound

Outbound

Scenarios

CompositionRoot

The CLI is the composition root and the only I/O edge.

  • given the library crates that are pure over in-memory modules
  • when the CLI runs any subcommand
  • then all file reading, writing, HTTP serving, and watching happen in the CLI
  • and the pure core receives module text and returns values
  • but I/O and load failures are the only things that fail a command, via the exit code
Flow Flow — CompositionRoot scroll to zoom · drag to pan
FEATURECompositionRootfor CliGIVENthe library crates that are pure overin-memory modulesWHENthe CLI runs any subcommandTHENall file reading, writing, HTTPserving, and watching happen in theCLIANDthe pure core receives module text andreturns valuesBUTI/O and load failures are the onlythings that fail a command, via theexit code
ParseSubcommand

argv is parsed into one subcommand and dispatched.

  • given a command line for one of init, doc, check, eval, fmt, tokens, outline, svg, lsp, lang, skill, add, install, update, remove, list, or upgrade
  • when the CLI starts
  • then clap parses argv into the chosen subcommand and its options
  • and the matching command handler is invoked
  • but an unrecognised command or bad option is rejected with a usage error
Flow Flow — ParseSubcommand scroll to zoom · drag to pan
FEATUREParseSubcommandfor CliGIVENa command line for one of init, doc,check, eval, fmt, tokens, outline,svg, lsp, lang, skill, add, install,update, remove, list, or upgradeWHENthe CLI startsTHENclap parses argv into the chosensubcommand and its optionsANDthe matching command handler isinvokedBUTan unrecognised command or bad optionis rejected with a usage error
Components Component diagram scroll to zoom · drag to pan
PseudoscriptCliCOMPONENTInitCmd`pds init` — bootstrap a workspace: write`pds.toml` and a starter `main.pds`. Refuse…COMPONENTArgsParses argv with clap-derive into the chosensubcommand and its options, then dispatches…COMPONENTLoaderThe CLI loader: resolves the project rootand reads its modules through the `project`…COMPONENTDocCmd`pds doc` — the headline command (ADR-017).Load the workspace, check it per module…COMPONENTCheckCmd`pds check` — parse and statically check onefile, print each diagnostic as…COMPONENTEvalCmd`pds eval` — read a model from stdin andstatically check it, printing each…COMPONENTFmtCmd`pds fmt` — format to canonicalPseudoScript; `--write` overwrites the file…COMPONENTTokensCmd`pds tokens` — print the conformance tokenstream (`KIND@line:col "lexeme"`) to stdout…COMPONENTLspHost`pds lsp` — boot a Tokio runtime and launchthe language server over stdio. Spawned as …COMPONENTReferenceCmd`pds lang` (alias `spec`) and `pds skill` —print the bundled, version-pinned language…COMPONENTOutlineCmd`pds outline` — walk the workspace'smodules, build its graph, and print the…COMPONENTSvgCmd`pds svg` — render a single diagram to aself-contained SVG on stdout. With…COMPONENTDeps`pds add`/`install`/`update`/`remove`/`list`— git workspace dependency management…COMPONENTUpgradeCmd`pds upgrade` — download a release andinstall it over the running binary.COMPONENTHttpServerHTTP host for the generated site(`--serve`/`--watch`): `tiny_http` on…COMPONENTWatcherFilesystem watcher (`--watch`, via`notify`): watches the project root…CONTAINERDoc`crates/pseudoscript-doc`. Turns a resolvedgraph into a Svelte-rendered,…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…CONTAINERProject`crates/pseudoscript-project`. Thedisk-facing loader: resolves the workspace…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…discoverWorkspacesfindRootloadcheckcheckWorkspaceModulesservediscoverWorkspacesfindRootloadwatchprepareDiagnosticsrenderrenderMarkdowncheckWorkspaceModulesgraphcheckformatfindRootloadrunStdiofindRootloadModulesgraphfindRootloadModulesgraphrenderTokensparseparse
data

Command #

public
cli::Command

The subcommand clap parsed from argv, with its resolved options.

Entities Entity diagram scroll to zoom · drag to pan
UNIONCommandInitCmdDocOptsCheckOptsEvalOptsFmtOptsTokensOptsOutlineOptsSvgOptsLspOptsLangOptsSkillOptsAddOptsInstallOptsUpdateOptsRemoveOptsListOptsUpgradeOptsRECORDDocOptspathstringserveboolwatchboolportnumberallboolformatstringRECORDCheckOptsfilestringallboolRECORDFmtOptsfilestringwriteboolRECORDTokensOptsfilestringRECORDOutlineOptspathstringRECORDSvgOptspathstringsymbolstringviewstringtargetstringthemestringRECORDAddOptsurlstringtagstringrevstringbranchstringpathstringnamestringRECORDRemoveOptsnamestringRECORDListOptsrootstringRECORDUpgradeOptsversionstring
component

Deps #

private
cli::Deps

`pds add`/`install`/`update`/`remove`/`list` — git workspace dependency +HTTP, and a filesystem watcher.

Inbound

Outbound

Scenarios

CompositionRoot

The CLI is the composition root and the only I/O edge.

  • given the library crates that are pure over in-memory modules
  • when the CLI runs any subcommand
  • then all file reading, writing, HTTP serving, and watching happen in the CLI
  • and the pure core receives module text and returns values
  • but I/O and load failures are the only things that fail a command, via the exit code
Flow Flow — CompositionRoot scroll to zoom · drag to pan
FEATURECompositionRootfor CliGIVENthe library crates that are pure overin-memory modulesWHENthe CLI runs any subcommandTHENall file reading, writing, HTTPserving, and watching happen in theCLIANDthe pure core receives module text andreturns valuesBUTI/O and load failures are the onlythings that fail a command, via theexit code
ParseSubcommand

argv is parsed into one subcommand and dispatched.

  • given a command line for one of init, doc, check, eval, fmt, tokens, outline, svg, lsp, lang, skill, add, install, update, remove, list, or upgrade
  • when the CLI starts
  • then clap parses argv into the chosen subcommand and its options
  • and the matching command handler is invoked
  • but an unrecognised command or bad option is rejected with a usage error
Flow Flow — ParseSubcommand scroll to zoom · drag to pan
FEATUREParseSubcommandfor CliGIVENa command line for one of init, doc,check, eval, fmt, tokens, outline,svg, lsp, lang, skill, add, install,update, remove, list, or upgradeWHENthe CLI startsTHENclap parses argv into the chosensubcommand and its optionsANDthe matching command handler isinvokedBUTan unrecognised command or bad optionis rejected with a usage error
Components Component diagram scroll to zoom · drag to pan
PseudoscriptCliCOMPONENTInitCmd`pds init` — bootstrap a workspace: write`pds.toml` and a starter `main.pds`. Refuse…COMPONENTArgsParses argv with clap-derive into the chosensubcommand and its options, then dispatches…COMPONENTLoaderThe CLI loader: resolves the project rootand reads its modules through the `project`…COMPONENTDocCmd`pds doc` — the headline command (ADR-017).Load the workspace, check it per module…COMPONENTCheckCmd`pds check` — parse and statically check onefile, print each diagnostic as…COMPONENTEvalCmd`pds eval` — read a model from stdin andstatically check it, printing each…COMPONENTFmtCmd`pds fmt` — format to canonicalPseudoScript; `--write` overwrites the file…COMPONENTTokensCmd`pds tokens` — print the conformance tokenstream (`KIND@line:col "lexeme"`) to stdout…COMPONENTLspHost`pds lsp` — boot a Tokio runtime and launchthe language server over stdio. Spawned as …COMPONENTReferenceCmd`pds lang` (alias `spec`) and `pds skill` —print the bundled, version-pinned language…COMPONENTOutlineCmd`pds outline` — walk the workspace'smodules, build its graph, and print the…COMPONENTSvgCmd`pds svg` — render a single diagram to aself-contained SVG on stdout. With…COMPONENTDeps`pds add`/`install`/`update`/`remove`/`list`— git workspace dependency management…COMPONENTUpgradeCmd`pds upgrade` — download a release andinstall it over the running binary.COMPONENTHttpServerHTTP host for the generated site(`--serve`/`--watch`): `tiny_http` on…COMPONENTWatcherFilesystem watcher (`--watch`, via`notify`): watches the project root…CONTAINERDoc`crates/pseudoscript-doc`. Turns a resolvedgraph into a Svelte-rendered,…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…CONTAINERProject`crates/pseudoscript-project`. Thedisk-facing loader: resolves the workspace…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…discoverWorkspacesfindRootloadcheckcheckWorkspaceservediscoverWorkspacesfindRootloadwatchprepareDiagnosticsrenderrenderMarkdowncheckWorkspaceModulesgraphcheckformatfindRootloadrunStdiofindRootloadModulesgraphfindRootloadModulesgraphrenderTokensparseparse
data

Command #

public
cli::Command

The subcommand clap parsed from argv, with its resolved options.

Entities Entity diagram scroll to zoom · drag to pan
UNIONCommandInitCmdDocOptsCheckOptsEvalOptsFmtOptsTokensOptsOutlineOptsSvgOptsLspOptsLangOptsSkillOptsAddOptsInstallOptsUpdateOptsRemoveOptsListOptsUpgradeOptsRECORDDocOptspathstringserveboolwatchboolportnumberallboolformatstringRECORDCheckOptsfilestringallboolRECORDFmtOptsfilestringwriteboolRECORDTokensOptsfilestringRECORDOutlineOptspathstringRECORDSvgOptspathstringsymbolstringviewstringtargetstringthemestringRECORDAddOptsurlstringtagstringrevstringbranchstringpathstringnamestringRECORDRemoveOptsnamestringRECORDListOptsrootstringRECORDUpgradeOptsversionstring
component

Deps #

private
cli::Deps

`pds add`/`install`/`update`/`remove`/`list` — git workspace dependency management (§8.3). `add` resolves a git URL into `pds.toml` + `pds.lock` and vendors it; `install` restores `pds_modules/` from the lock; `update` re-pins; `remove` drops one; `list` discovers every workspace under a root. @@ -28,34 +28,34 @@ HTML site (every diagram as server SVG, logo copied) or a flat Markdown site (SVG assets, no logo). `--serve` hosts the HTML site over HTTP; `--watch` adds a filesystem watcher and browser live reload; both are skipped for -Markdown output, which only writes.

#headline

Parent

Inbound

Outbound

Scenarios

DocPipeline

`pds doc` runs the headline pipeline end to end.

  • given a project rooted at a pds.toml with one or more .pds modules
  • and no --format override, so the HTML default applies
  • when the developer runs `pds doc`
  • then the workspace is loaded and checked
  • and the resolved graph is built and rendered to the HTML site
  • and every site file is written under the output directory
  • and the configured logo is copied beside the site
Flow Flow — DocPipeline scroll to zoom · drag to pan
FEATUREDocPipelinefor DocCmdGIVENa project rooted at a pds.toml withone or more .pds modulesANDno --format override, so the HTMLdefault appliesWHENthe developer runs `pds doc`THENthe workspace is loaded and checkedANDthe resolved graph is built andrendered to the HTML siteANDevery site file is written under theoutput directoryANDthe configured logo is copied besidethe site
ResolveDocFormat

The output format is resolved by precedence and forks the renderer.

  • given a workspace whose `[doc].format` and the `--format` flag may each set a format
  • when the developer runs `pds doc`
  • then an explicit `--format` wins over the manifest `[doc].format`, else HTML
  • and HTML renders the SSR site and copies the logo
  • but Markdown renders the flat site with its SVG inlined and copies no logo
Flow Flow — ResolveDocFormat scroll to zoom · drag to pan
FEATUREResolveDocFormatfor DocCmdGIVENa workspace whose `[doc].format` andthe `--format` flag may each set aformatWHENthe developer runs `pds doc`THENan explicit `--format` wins over themanifest `[doc].format`, else HTMLANDHTML renders the SSR site and copiesthe logoBUTMarkdown renders the flat site withits SVG inlined and copies no logo
MarkdownSkipsServing

Markdown output writes but never serves or watches.

  • given the resolved format is Markdown
  • when the developer runs `pds doc --serve` or `--watch`
  • then the Markdown site is written to the output directory
  • but serving and watching are skipped, so the command returns after writing
Flow Flow — MarkdownSkipsServing scroll to zoom · drag to pan
FEATUREMarkdownSkipsServingfor DocCmdGIVENthe resolved format is MarkdownWHENthe developer runs `pds doc --serve`or `--watch`THENthe Markdown site is written to theoutput directoryBUTserving and watching are skipped, sothe command returns after writing
CheckIsNonFatal

The workspace check is reported but never aborts generation.

  • given a workspace whose model has warnings or errors
  • when the developer runs `pds doc`
  • then every diagnostic is printed to stderr
  • but generation continues like `cargo doc`, so a partial model still documents
  • and only an I/O or load failure exits non-zero
Flow Flow — CheckIsNonFatal scroll to zoom · drag to pan
FEATURECheckIsNonFatalfor DocCmdGIVENa workspace whose model has warningsor errorsWHENthe developer runs `pds doc`THENevery diagnostic is printed to stderrBUTgeneration continues like `cargo doc`,so a partial model still documentsANDonly an I/O or load failure exitsnon-zero
Sequence Sequence — runAll scroll to zoom · drag to pan
SEQUENCErunAllalt[else roots.isErr]COMPONENTDocCmdPseudoscript::Cli`pds doc` — theheadline commandCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the project1discoverWorkspaces(root: string)↩ return Result<string[], cli::IoError>2buildEach
Sequence Sequence — serve scroll to zoom · drag to pan
SEQUENCEservealt[watch]alt[else !self.shouldServe()]alt[else !self.isHtml()]alt[else built.isErr]COMPONENTDocCmdPseudoscript::Cli`pds doc` — theheadline commandCOMPONENTWatcherPseudoscript::CliFilesystem watcher(`--watch`, viaCOMPONENTHttpServerPseudoscript::CliHTTP host for thegenerated site1run2isHtml3shouldServe4watch(root: string, port: number)↩ return Result<void, cli::IoError>5serve(path: string, port: number, reload: bool)↩ return Result<void, cli::IoError>
data

DocOpts #

public
cli::DocOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDDocOptspathstringserveboolwatchboolportnumberallboolformatstring
component

EvalCmd #

private
cli::EvalCmd

`pds eval` — read a model from stdin and statically check it, printing each +Markdown output, which only writes.

#headline

Parent

Inbound

Outbound

Scenarios

DocPipeline

`pds doc` runs the headline pipeline end to end.

  • given a project rooted at a pds.toml with one or more .pds modules
  • and no --format override, so the HTML default applies
  • when the developer runs `pds doc`
  • then the workspace is loaded and checked
  • and the resolved graph is built and rendered to the HTML site
  • and every site file is written under the output directory
  • and the configured logo is copied beside the site
Flow Flow — DocPipeline scroll to zoom · drag to pan
FEATUREDocPipelinefor DocCmdGIVENa project rooted at a pds.toml withone or more .pds modulesANDno --format override, so the HTMLdefault appliesWHENthe developer runs `pds doc`THENthe workspace is loaded and checkedANDthe resolved graph is built andrendered to the HTML siteANDevery site file is written under theoutput directoryANDthe configured logo is copied besidethe site
ResolveDocFormat

The output format is resolved by precedence and forks the renderer.

  • given a workspace whose `[doc].format` and the `--format` flag may each set a format
  • when the developer runs `pds doc`
  • then an explicit `--format` wins over the manifest `[doc].format`, else HTML
  • and HTML renders the SSR site and copies the logo
  • but Markdown renders the flat site with its SVG inlined and copies no logo
Flow Flow — ResolveDocFormat scroll to zoom · drag to pan
FEATUREResolveDocFormatfor DocCmdGIVENa workspace whose `[doc].format` andthe `--format` flag may each set aformatWHENthe developer runs `pds doc`THENan explicit `--format` wins over themanifest `[doc].format`, else HTMLANDHTML renders the SSR site and copiesthe logoBUTMarkdown renders the flat site withits SVG inlined and copies no logo
MarkdownSkipsServing

Markdown output writes but never serves or watches.

  • given the resolved format is Markdown
  • when the developer runs `pds doc --serve` or `--watch`
  • then the Markdown site is written to the output directory
  • but serving and watching are skipped, so the command returns after writing
Flow Flow — MarkdownSkipsServing scroll to zoom · drag to pan
FEATUREMarkdownSkipsServingfor DocCmdGIVENthe resolved format is MarkdownWHENthe developer runs `pds doc --serve`or `--watch`THENthe Markdown site is written to theoutput directoryBUTserving and watching are skipped, sothe command returns after writing
CheckIsNonFatal

The workspace check is reported but never aborts generation.

  • given a workspace whose model has warnings or errors
  • when the developer runs `pds doc`
  • then every diagnostic is printed to stderr
  • but generation continues like `cargo doc`, so a partial model still documents
  • and only an I/O or load failure exits non-zero
Flow Flow — CheckIsNonFatal scroll to zoom · drag to pan
FEATURECheckIsNonFatalfor DocCmdGIVENa workspace whose model has warningsor errorsWHENthe developer runs `pds doc`THENevery diagnostic is printed to stderrBUTgeneration continues like `cargo doc`,so a partial model still documentsANDonly an I/O or load failure exitsnon-zero
Sequence Sequence — runAll scroll to zoom · drag to pan
SEQUENCErunAllalt[else roots.isErr]COMPONENTDocCmdPseudoscript::Cli`pds doc` — theheadline commandCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the project1discoverWorkspaces(root: string)↩ return Result<string[], cli::IoError>2buildEach
Sequence Sequence — serve scroll to zoom · drag to pan
SEQUENCEservealt[found.isErr][else]alt[modules.isErr][else]alt[files.isErr][else]alt[loaded.isErr][else]alt[dependencies.isErr][else]alt[modules.isErr][else]alt[config.isErr][else]loop[entries]alt[kindMatches()][else]alt[found.isErr][else]alt[anchor.isErr][else]alt[kindMatches()][else]alt[found.isErr][else]alt[anchor.isErr][else]alt[kindMatches()][else]alt[found.isErr][else]alt[actor.isNone][else]alt[disclosed.isNone][else]alt[node.isErr][else]alt[view.isFeature][else]alt[view.isData][else]alt[view.isComponent][else]alt[view.isContainer][else]alt[view.isContext][else]alt[scene.isErr][else]alt[rendered.isErr][else]alt[rendered.isErr][else]alt[rendered.isErr][else]alt[health.isErr][else]alt[universe.isErr][else]alt[modulePages.isErr][else]alt[docPages.isErr][else]alt[index.isErr][else]alt[html.isErr][else]alt[isHtml()][else]alt[isHtml()]alt[written.isErr][else]alt[site.isErr][else]alt[project.isErr][else]alt[root.isErr][else]alt[watch]alt[else !shouldServe()]alt[else !isHtml()]alt[else built.isErr]COMPONENTDocCmdPseudoscript::Cli`pds doc` — theheadline commandCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:CONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTChecksPseudoscript::ModelStatic analysis(LANG.md §2.2, §2.3,CONTAINERDocPseudoscript`crates/pseudoscript-doc`.Turns a resolved grap…COMPONENTHealthPseudoscript::DocPositions the host'sdiagnostics in theCOMPONENTBuilderPseudoscript::ModelProjects the parsed,resolved workspaceCOMPONENTWorkspacePseudoscript::ModelThe resolved set ofmodules keyed by FQNCOMPONENTSiteBuilderPseudoscript::DocOrchestrates the wholesite: build the URLCOMPONENTUrlsPseudoscript::DocMaps every node FQN toits page path andCOMPONENTPagesPseudoscript::DocProjects the resolvedgraph into per-pageCOMPONENTDiagramsPseudoscript::DocThe bridge into`emit`: project a vie…CONTAINEREmitPseudoscript`crates/pseudoscript-emit`.Projects a view into …COMPONENTProjectorPseudoscript::EmitProjects a `View` outof the graph (LANG.mdCOMPONENTEdgesPseudoscript::EmitBuilds the routed-edgeset for a C4 sceneCOMPONENTLayoutPseudoscript::EmitAssigns geometry.Projection stamps eac…COMPONENTTracePseudoscript::EmitWalks a callable'sbody trace intoCOMPONENTSsrPseudoscript::DocThe server-side renderboundary: aCOMPONENTShellPseudoscript::DocOwns the documentshell that wraps eachCOMPONENTEscapePseudoscript::DocAll user text — nodenames, `///` docs,CONTAINERUniversePseudoscript`crates/pseudoscript-universe`.Maps the resolved C4COMPONENTAdapterPseudoscript::UniverseAdapts a resolvedmodel into theCOMPONENTFlattenPseudoscript::UniverseFlattens the softwaregraph into theCOMPONENTFlowTracerPseudoscript::UniverseTraces everyentry-point flow: aCOMPONENTSearchIndexPseudoscript::DocBuilds the staticfull-text search inde…COMPONENTAssetsPseudoscript::DocShips the prebuiltpresentation bundles,COMPONENTMarkdownSitePseudoscript::DocThe static Markdownoutput mode: turns th…COMPONENTWatcherPseudoscript::CliFilesystem watcher(`--watch`, viaCOMPONENTHttpServerPseudoscript::CliHTTP host for thegenerated site1run2findRoot(start: string)3findRoot(start: string)4findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>5ioError↩ Err<cli::IoError>↩ Ok<string>↩ Err<cli::IoError>6load(root: string)7loadManifest↩ Err<cli::IoError>8loadModules9load(root: string)10load(root: string)11findModules↩ Err<project::IoError>12readEach↩ Err<project::IoError>↩ Ok<model::WorkspaceModule[]>↩ return Result<model::WorkspaceModule[], project::IoError>13ioError↩ Err<cli::IoError>↩ Ok<model::WorkspaceModule[]>↩ Err<cli::IoError>14loadDependencies↩ Err<cli::IoError>↩ Ok<cli::Workspace>↩ Err<cli::IoError>15resolveFormat16checkWorkspaceModules(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])17checkWorkspaceModules(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])↩ return model::ModuleDiagnostics[]↩ return model::ModuleDiagnostics[]18reportModules19prepareDiagnostics(modules: model::WorkspaceModule[], perModule: model::ModuleDiagnostics[])20prepare(modules: model::WorkspaceModule[], perModule: model::ModuleDiagnostics[])↩ return doc::DiagnosticInput[]↩ return doc::DiagnosticInput[]21graph(modules: model::WorkspaceModule[])22graph(modules: model::WorkspaceModule[])23build(modules: model::WorkspaceModule[])24noExternals25buildWithExternals26resolveEach27resolveEach28index↩ return model::ModuleEntry[]↩ return model::ModuleEntry[]29graphOf30collectModule↩ return model::Graph↩ return model::Graph↩ return model::Graph31renderSite32isHtml33render(graph: model::Graph, config: doc::DocConfig, diagnostics: doc::DiagnosticInput[])34render(graph: model::Graph, config: doc::DocConfig, diagnostics: doc::DiagnosticInput[])35build(graph: model::Graph)↩ return36sortedModules(graph: model::Graph)↩ return string[]37index(graph: model::Graph, config: doc::DocConfig, modules: string[], diagnostics: doc::DiagnosticInput[])38docGroups39sidebar40navLinks41crumbsOf42moduleCards43context(graph: model::Graph)44contextView45figure46project(graph: model::Graph, view: emit::View)47project(graph: model::Graph, view: emit::View)48projectContext49collectKinds50collect(graph: model::Graph, inView: emit::PlacedNode[])51route52sortDedup↩ return emit::RoutedEdge[]53solveC4(scene: emit::Scene)↩ return emit::Scene↩ return emit::Scene↩ Ok<emit::Scene>54projectBoundary55requireKind56kindOf↩ Err<emit::EmitError>57kindMatches↩ Ok<string>↩ Err<emit::EmitError>↩ Err<emit::EmitError>58outerFrameOf59childrenOf60withOuterFrame61externalActors62nestSiblings63collect(graph: model::Graph, inView: emit::PlacedNode[])64route65sortDedup↩ return emit::RoutedEdge[]66solveC4(scene: emit::Scene)↩ return emit::Scene↩ Ok<emit::Scene>↩ return Result<emit::Scene, emit::EmitError>67projectBoundary68requireKind69kindOf↩ Err<emit::EmitError>70kindMatches↩ Ok<string>↩ Err<emit::EmitError>↩ Err<emit::EmitError>71outerFrameOf72childrenOf73withOuterFrame74externalActors75nestSiblings76collect(graph: model::Graph, inView: emit::PlacedNode[])77route78sortDedup↩ return emit::RoutedEdge[]79solveC4(scene: emit::Scene)↩ return emit::Scene↩ Ok<emit::Scene>↩ return Result<emit::Scene, emit::EmitError>80projectData↩ return Result<emit::Scene, emit::EmitError>81projectFeature↩ return Result<emit::Scene, emit::EmitError>82projectSequence83requireKind84kindOf↩ Err<emit::EmitError>85kindMatches↩ Ok<string>↩ Err<emit::EmitError>↩ Err<emit::EmitError>86bodyOf87blackBox(graph: model::Graph, entry: string)88ownerOf89blackBoxActor90inboundCall91returnItem92participantsOf↩ return emit::Scene↩ Ok<emit::Scene>93walk(graph: model::Graph, entry: string, body: model::Step[])94ownerOf95triggerActorOf96entryStack97untriggered98noCaller99traceItems100participantsOf↩ return emit::Scene↩ return emit::Scene101inboundCall102traceItems103prependItem104participantsOf↩ return emit::Scene↩ Ok<emit::Scene>↩ return Result<emit::Scene, emit::EmitError>↩ return Result<emit::Scene, emit::EmitError>↩ return doc::Diagram105embed106svgFigure↩ return doc::Diagram↩ return doc::Diagram↩ return doc::Diagram107stats↩ return doc::PageProps108emitPage109renderPage(props: doc::PageProps)↩ return Result<doc::RenderedPage, doc::RenderError>↩ Err<doc::RenderError>110wrap(path: string, props: doc::PageProps, rendered: doc::RenderedPage)111text(text: string)↩ return string112document↩ return string↩ Ok<doc::SiteFile>↩ Err<doc::RenderError>113emitDocPages↩ Err<doc::RenderError>114emitModulePages↩ Err<doc::RenderError>115universePage(graph: model::Graph, config: doc::DocConfig, modules: string[], diagnostics: doc::DiagnosticInput[])116docGroups117sidebar118navLinks119crumbsOf120fromModel(graph: model::Graph)121fromModel(graph: model::Graph)122placeStructural123wireContainment124tallyTraffic↩ return universe::SoftwareGraph↩ return universe::SoftwareGraph125snapshot(graph: universe::SoftwareGraph)126snapshot(graph: universe::SoftwareGraph)127nodesOf128edgesOf↩ return universe::Snapshot↩ return universe::Snapshot129flows(graph: model::Graph)130flows(graph: model::Graph)131entryPoints132traceAll↩ return universe::FlowDef[]↩ return universe::FlowDef[]133nodeHrefs↩ return doc::PageProps134emitPage135renderPage(props: doc::PageProps)↩ return Result<doc::RenderedPage, doc::RenderError>↩ Err<doc::RenderError>136wrap(path: string, props: doc::PageProps, rendered: doc::RenderedPage)137text(text: string)↩ return string138document↩ return string↩ Ok<doc::SiteFile>↩ Err<doc::RenderError>139healthPage(graph: model::Graph, config: doc::DocConfig, modules: string[], diagnostics: doc::DiagnosticInput[])140docGroups141sidebar142navLinks143crumbsOf144page(graph: model::Graph, diagnostics: doc::DiagnosticInput[])145attributeAll146countOf147countOf↩ return doc::PageBody↩ return doc::PageProps148emitPage149renderPage(props: doc::PageProps)↩ return Result<doc::RenderedPage, doc::RenderError>↩ Err<doc::RenderError>150wrap(path: string, props: doc::PageProps, rendered: doc::RenderedPage)151text(text: string)↩ return string152document↩ return string↩ Ok<doc::SiteFile>↩ Err<doc::RenderError>153build(graph: model::Graph, config: doc::DocConfig)154entries↩ return doc::SiteFile155shared()↩ return doc::SiteFile[]↩ Ok<doc::Site>↩ return Result<doc::Site, doc::RenderError>156renderError↩ Err<cli::IoError>↩ Ok<doc::Site>157renderMarkdown158renderMarkdown(graph: model::Graph, config: doc::DocConfig, diagnostics: doc::DiagnosticInput[])159buildAll(graph: model::Graph, config: doc::DocConfig, diagnostics: doc::DiagnosticInput[])↩ return doc::PageProps[]160render(pages: doc::PageProps[], theme: doc::Theme)↩ return doc::Site↩ return doc::Site↩ return doc::Site↩ Ok<doc::Site>↩ Err<cli::IoError>161write↩ Err<cli::IoError>162isHtml163copyLogo↩ Ok<string>164isHtml165shouldServe166watch(root: string, port: number)↩ return Result<void, cli::IoError>167serve(path: string, port: number, reload: bool)↩ return Result<void, cli::IoError>
data

DocOpts #

public
cli::DocOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDDocOptspathstringserveboolwatchboolportnumberallboolformatstring
component

EvalCmd #

private
cli::EvalCmd

`pds eval` — read a model from stdin and statically check it, printing each diagnostic as `<stdin>:line:col: severity: message` and exiting non-zero on any error. The fileless path: an agent pipes a snippet to check it without -writing a file.

Parent

Outbound

Scenarios

EvalExitCode

`pds eval` reads stdin and exits non-zero when any error diagnostic is produced.

  • given a model piped to stdin
  • when the developer or an agent runs `pds eval`
  • then every diagnostic is printed as <stdin>:line:col: severity: message
  • but the command exits non-zero if any diagnostic is error-severity
  • and a well-formed model prints nothing and exits zero
Flow Flow — EvalExitCode scroll to zoom · drag to pan
FEATUREEvalExitCodefor EvalCmdGIVENa model piped to stdinWHENthe developer or an agent runs `pdseval`THENevery diagnostic is printed as<stdin>:line:col: severity: messageBUTthe command exits non-zero if anydiagnostic is error-severityANDa well-formed model prints nothing andexits zero
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunCOMPONENTEvalCmdPseudoscript::Cli`pds eval` — read amodel from stdin andCONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTChecksPseudoscript::ModelStatic analysis(LANG.md §2.2, §2.3,CONTAINERSyntaxPseudoscript`crates/pseudoscript-syntax`.The foundation crate:COMPONENTParserPseudoscript::SyntaxRecursive-descentparser for the §10COMPONENTLexerPseudoscript::SyntaxHand-written lexer forLANG.md §2. One pass1check(text: string)2check(text: string)3parse(text: string)4parse(text: string)5lex(text: string)↩ return syntax::Lexed6parseModule7diagnostics↩ return syntax::Parsed↩ return syntax::Parsed8analyze↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]9anyError
component

FmtCmd #

private
cli::FmtCmd

`pds fmt` — format to canonical PseudoScript; `--write` overwrites the file in +writing a file.

Parent

Outbound

Scenarios

EvalExitCode

`pds eval` reads stdin and exits non-zero when any error diagnostic is produced.

  • given a model piped to stdin
  • when the developer or an agent runs `pds eval`
  • then every diagnostic is printed as <stdin>:line:col: severity: message
  • but the command exits non-zero if any diagnostic is error-severity
  • and a well-formed model prints nothing and exits zero
Flow Flow — EvalExitCode scroll to zoom · drag to pan
FEATUREEvalExitCodefor EvalCmdGIVENa model piped to stdinWHENthe developer or an agent runs `pdseval`THENevery diagnostic is printed as<stdin>:line:col: severity: messageBUTthe command exits non-zero if anydiagnostic is error-severityANDa well-formed model prints nothing andexits zero
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunCOMPONENTEvalCmdPseudoscript::Cli`pds eval` — read amodel from stdin andCONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTChecksPseudoscript::ModelStatic analysis(LANG.md §2.2, §2.3,CONTAINERSyntaxPseudoscript`crates/pseudoscript-syntax`.The foundation crate:COMPONENTParserPseudoscript::SyntaxRecursive-descentparser for the §10COMPONENTLexerPseudoscript::SyntaxHand-written lexer forLANG.md §2. One passCOMPONENTResolverPseudoscript::ModelResolves a module'sdeclarations into aCOMPONENTVariantCollisionPseudoscript::Model§3.5 / ADR-006 — unionvariant collision. ACOMPONENTFeatureCheckPseudoscript::Model§5.2 / §8.1 — featurechecks. A feature'sCOMPONENTReservedNamesPseudoscript::Model§2.3 / ADR-012 —reserved-wordCOMPONENTTypeRefsPseudoscript::Model§3.3 / §8.1 —type-reference1check(text: string)2check(text: string)3parse(text: string)4parse(text: string)5lex(text: string)↩ return syntax::Lexed6parseModule↩ return syntax::Module7diagnostics↩ return syntax::Parsed↩ return syntax::Parsed8analyze9build(ast: syntax::Module)10buildWithPath↩ return model::SymbolTable↩ return model::SymbolTable11run12check(ast: syntax::Module)↩ return syntax::Diagnostic[]13check(ast: syntax::Module, model: model::SymbolTable)↩ return syntax::Diagnostic[]14checkConstantCollisions15check(ast: syntax::Module)↩ return syntax::Diagnostic[]16check(ast: syntax::Module, model: model::SymbolTable)↩ return syntax::Diagnostic[]17checkItems↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]18anyError
component

FmtCmd #

private
cli::FmtCmd

`pds fmt` — format to canonical PseudoScript; `--write` overwrites the file in place, otherwise prints to stdout. A parse error is reported and the file is -left untouched.

Parent

Outbound

Scenarios

FormatInPlaceOrStdout

`pds fmt --write` overwrites in place; otherwise it prints.

  • given a .pds source file
  • when the developer runs `pds fmt`
  • then the source is parsed and pretty-printed to canonical PseudoScript
  • and with `--write` the file is overwritten in place
  • but without `--write` the canonical text is printed to stdout
  • and unparseable source is reported and the file is left untouched
Flow Flow — FormatInPlaceOrStdout scroll to zoom · drag to pan
FEATUREFormatInPlaceOrStdoutfor FmtCmdGIVENa .pds source fileWHENthe developer runs `pds fmt`THENthe source is parsed andpretty-printed to canonicalPseudoScriptANDwith `--write` the file is overwrittenin placeBUTwithout `--write` the canonical textis printed to stdoutANDunparseable source is reported and thefile is left untouched
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[self.hasErrors()][else]alt[write][else]alt[else out.isErr]COMPONENTFmtCmdPseudoscript::Cli`pds fmt` — format tocanonicalCONTAINERFormatPseudoscript`crates/pseudoscript-format`.The canonicalCOMPONENTFormatterPseudoscript::FormatDrives the headlineflow: parse theCONTAINERSyntaxPseudoscript`crates/pseudoscript-syntax`.The foundation crate:COMPONENTParserPseudoscript::SyntaxRecursive-descentparser for the §10COMPONENTLexerPseudoscript::SyntaxHand-written lexer forLANG.md §2. One passCOMPONENTPrinterPseudoscript::FormatThe canonicalpretty-printer: walks1format(text: string)2format(text: string)3parse(text: string)4parse(text: string)5lex(text: string)↩ return syntax::Lexed6parseModule7diagnostics↩ return syntax::Parsed↩ return syntax::Parsed8hasErrors9collectErrors↩ Err<format::FormatError>10print(ast: syntax::Module)11writeModule12finish↩ return string↩ Ok<string>↩ return Result<string, format::FormatError>13overwrite14print
data

FmtOpts #

public
cli::FmtOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDFmtOptsfilestringwritebool
component

HttpServer #

private
cli::HttpServer

HTTP host for the generated site (`--serve`/`--watch`): `tiny_http` on +left untouched.

Parent

Outbound

Scenarios

FormatInPlaceOrStdout

`pds fmt --write` overwrites in place; otherwise it prints.

  • given a .pds source file
  • when the developer runs `pds fmt`
  • then the source is parsed and pretty-printed to canonical PseudoScript
  • and with `--write` the file is overwritten in place
  • but without `--write` the canonical text is printed to stdout
  • and unparseable source is reported and the file is left untouched
Flow Flow — FormatInPlaceOrStdout scroll to zoom · drag to pan
FEATUREFormatInPlaceOrStdoutfor FmtCmdGIVENa .pds source fileWHENthe developer runs `pds fmt`THENthe source is parsed andpretty-printed to canonicalPseudoScriptANDwith `--write` the file is overwrittenin placeBUTwithout `--write` the canonical textis printed to stdoutANDunparseable source is reported and thefile is left untouched
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[hasErrors()][else]alt[write][else]alt[else out.isErr]COMPONENTFmtCmdPseudoscript::Cli`pds fmt` — format tocanonicalCONTAINERFormatPseudoscript`crates/pseudoscript-format`.The canonicalCOMPONENTFormatterPseudoscript::FormatDrives the headlineflow: parse theCONTAINERSyntaxPseudoscript`crates/pseudoscript-syntax`.The foundation crate:COMPONENTParserPseudoscript::SyntaxRecursive-descentparser for the §10COMPONENTLexerPseudoscript::SyntaxHand-written lexer forLANG.md §2. One passCOMPONENTPrinterPseudoscript::FormatThe canonicalpretty-printer: walks1format(text: string)2format(text: string)3parse(text: string)4parse(text: string)5lex(text: string)↩ return syntax::Lexed6parseModule↩ return syntax::Module7diagnostics↩ return syntax::Parsed↩ return syntax::Parsed8hasErrors9collectErrors↩ Err<format::FormatError>10print(ast: syntax::Module)11writeModule12finish↩ return string↩ Ok<string>↩ return Result<string, format::FormatError>13overwrite14print
data

FmtOpts #

public
cli::FmtOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDFmtOptsfilestringwritebool
component

HttpServer #

private
cli::HttpServer

HTTP host for the generated site (`--serve`/`--watch`): `tiny_http` on `127.0.0.1:port`, maps `/` to `index.html`, rejects paths escaping the output dir, and on watch injects a live-reload poll and answers `/__livereload` with the current version. Blocks until the process is stopped.

Parent

Inbound

Scenarios

ServeOverHttp

`pds doc --serve` hosts the generated site over HTTP on localhost.

  • given a generated documentation site
  • when the developer runs `pds doc --serve`
  • then the site is hosted over HTTP on 127.0.0.1 at the chosen port
  • and `/` maps to index.html
  • but a request path that escapes the output directory yields 404
Flow Flow — ServeOverHttp scroll to zoom · drag to pan
FEATUREServeOverHttpfor HttpServerGIVENa generated documentation siteWHENthe developer runs `pds doc --serve`THENthe site is hosted over HTTP on127.0.0.1 at the chosen portAND`/` maps to index.htmlBUTa request path that escapes the outputdirectory yields 404
Sequence Sequence — serve scroll to zoom · drag to pan
SEQUENCEservePERSONclientCOMPONENTHttpServerPseudoscript::CliHTTP host for thegenerated site1serve(path: string, port: number, reload: bool)↩ return Result<void, cli::IoError>
component

InitCmd #

private
cli::InitCmd

`pds init` — bootstrap a workspace: write `pds.toml` and a starter `main.pds`. Refuses to overwrite an existing manifest; the starter is written only when -absent.

Parent

Outbound

  • from cli::Result

Scenarios

InitWorkspace

`pds init` bootstraps a workspace and refuses to clobber an existing one.

  • given a target directory with no pds.toml
  • when the developer runs `pds init`
  • then the directory is created if absent
  • and a pds.toml carrying a [doc] table is written
  • and a starter main.pds is written when none exists
  • but an existing pds.toml aborts the command without overwriting it
Flow Flow — InitWorkspace scroll to zoom · drag to pan
FEATUREInitWorkspacefor InitCmdGIVENa target directory with no pds.tomlWHENthe developer runs `pds init`THENthe directory is created if absentANDa pds.toml carrying a [doc] table iswrittenANDa starter main.pds is written whennone existsBUTan existing pds.toml aborts thecommand without overwriting it
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[else exists.isErr]COMPONENTInitCmdPseudoscript::Cli`pds init` — bootstrapa workspace: write1manifestExists2writeFiles
data

IoError #

public
cli::IoError

A filesystem, parse-config, or serving failure surfaced to the CLI exit code.

Entities Entity diagram scroll to zoom · drag to pan
RECORDIoErrormessagestring
data

ListOpts #

public
cli::ListOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDListOptsrootstring
component

Loader #

private
cli::Loader

The CLI loader: resolves the project root and reads its modules through the +absent.

Parent

Scenarios

InitWorkspace

`pds init` bootstraps a workspace and refuses to clobber an existing one.

  • given a target directory with no pds.toml
  • when the developer runs `pds init`
  • then the directory is created if absent
  • and a pds.toml carrying a [doc] table is written
  • and a starter main.pds is written when none exists
  • but an existing pds.toml aborts the command without overwriting it
Flow Flow — InitWorkspace scroll to zoom · drag to pan
FEATUREInitWorkspacefor InitCmdGIVENa target directory with no pds.tomlWHENthe developer runs `pds init`THENthe directory is created if absentANDa pds.toml carrying a [doc] table iswrittenANDa starter main.pds is written whennone existsBUTan existing pds.toml aborts thecommand without overwriting it
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[else exists.isErr]COMPONENTInitCmdPseudoscript::Cli`pds init` — bootstrapa workspace: write1manifestExists2writeFiles
data

IoError #

public
cli::IoError

A filesystem, parse-config, or serving failure surfaced to the CLI exit code.

Entities Entity diagram scroll to zoom · drag to pan
RECORDIoErrormessagestring
data

ListOpts #

public
cli::ListOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDListOptsrootstring
component

Loader #

private
cli::Loader

The CLI loader: resolves the project root and reads its modules through the `project` crate (the shared filesystem edge), then parses the cli-specific `[doc]` table on top. Root-finding and module-walking are `project`'s job; -the manifest's doc config is the CLI's.

Parent

Inbound

Outbound

  • call project::Project · findRoot
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • call project::Project · load
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result

Scenarios

ResolveProjectRoot

The project root is found by walking up to the nearest pds.toml.

  • given a path somewhere inside a project tree
  • when the CLI loads the workspace
  • then it walks ancestor directories to the nearest pds.toml
  • and the [doc] config and every .pds module beneath it load, sorted by FQN
  • but a tree with no pds.toml is an error
Flow Flow — ResolveProjectRoot scroll to zoom · drag to pan
FEATUREResolveProjectRootfor LoaderGIVENa path somewhere inside a project treeWHENthe CLI loads the workspaceTHENit walks ancestor directories to thenearest pds.tomlANDthe [doc] config and every .pds modulebeneath it load, sorted by FQNBUTa tree with no pds.toml is an error
component

LspHost #

private
cli::LspHost

`pds lsp` — boot a Tokio runtime and launch the language server over stdio. +the manifest's doc config is the CLI's.

Parent

Inbound

Outbound

  • call project::Project · findRoot
  • call project::Project · load
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result
  • from cli::Result

Scenarios

ResolveProjectRoot

The project root is found by walking up to the nearest pds.toml.

  • given a path somewhere inside a project tree
  • when the CLI loads the workspace
  • then it walks ancestor directories to the nearest pds.toml
  • and the [doc] config and every .pds module beneath it load, sorted by FQN
  • but a tree with no pds.toml is an error
Flow Flow — ResolveProjectRoot scroll to zoom · drag to pan
FEATUREResolveProjectRootfor LoaderGIVENa path somewhere inside a project treeWHENthe CLI loads the workspaceTHENit walks ancestor directories to thenearest pds.tomlANDthe [doc] config and every .pds modulebeneath it load, sorted by FQNBUTa tree with no pds.toml is an error
component

LspHost #

private
cli::LspHost

`pds lsp` — boot a Tokio runtime and launch the language server over stdio. Spawned as a child process by an editor (`context::Editor.openDocument`).

Parent

Inbound

Outbound

Scenarios

LaunchLanguageServer

`pds lsp` launches the language server over stdio.

  • given an editor that speaks the Language Server Protocol
  • when the editor spawns `pds lsp` as a child process
  • then a Tokio runtime boots and the server runs over stdio
  • and the editor drives it with document changes and renders its diagnostics
Flow Flow — LaunchLanguageServer scroll to zoom · drag to pan
FEATURELaunchLanguageServerfor LspHostGIVENan editor that speaks the LanguageServer ProtocolWHENthe editor spawns `pds lsp` as a childprocessTHENa Tokio runtime boots and the serverruns over stdioANDthe editor drives it with documentchanges and renders its diagnostics
component

OutlineCmd #

private
cli::OutlineCmd

`pds outline` — walk the workspace's modules, build its graph, and print the symbol outline as JSON: each node's `fqn`, `name`, `kind`, `parent`, whether it is a triggered flow entry, and its declaration site. The structure tree an editor draws. Outlining reads the walked modules straight, skipping the manifest `[doc]` parse and dependency resolution: the structure tree never depends on -presentation config or external modules.

Parent

Outbound

Scenarios

OutlineAsJson

`pds outline` prints the workspace symbol tree as JSON.

  • given a workspace under the path
  • when the developer runs `pds outline`
  • then the workspace's modules are walked and its graph is built
  • and each node's fqn, name, kind, parent, triggered flag, and declaration site is printed as JSON
  • but the manifest [doc] config and dependency modules are not loaded
Flow Flow — OutlineAsJson scroll to zoom · drag to pan
FEATUREOutlineAsJsonfor OutlineCmdGIVENa workspace under the pathWHENthe developer runs `pds outline`THENthe workspace's modules are walked andits graph is builtANDeach node's fqn, name, kind, parent,triggered flag, and declaration siteis printed as JSONBUTthe manifest [doc] config anddependency modules are not loaded
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[found.isErr][else]alt[modules.isErr][else]alt[files.isErr][else]alt[loaded.isErr][else]alt[else modules.isErr]alt[else root.isErr]COMPONENTOutlineCmdPseudoscript::Cli`pds outline` — walkthe workspace'sCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:CONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTBuilderPseudoscript::ModelProjects the parsed,resolved workspaceCOMPONENTWorkspacePseudoscript::ModelThe resolved set ofmodules keyed by FQN1findRoot(start: string)2findRoot(start: string)3findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>4ioError↩ Err<cli::IoError>↩ Ok<string>5loadModules(root: string)6load(root: string)7load(root: string)8findModules↩ Err<project::IoError>9readEach↩ Err<project::IoError>↩ Ok<model::WorkspaceModule[]>↩ return Result<model::WorkspaceModule[], project::IoError>10ioError↩ Err<cli::IoError>↩ Ok<model::WorkspaceModule[]>11graph(modules: model::WorkspaceModule[])12graph(modules: model::WorkspaceModule[])13build(modules: model::WorkspaceModule[])14noExternals15buildWithExternals↩ return model::ModuleEntry[]16graphOf↩ return model::Graph↩ return model::Graph17render18print
data

OutlineOpts #

public
cli::OutlineOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDOutlineOptspathstring
component

ReferenceCmd #

private
cli::ReferenceCmd

`pds lang` (alias `spec`) and `pds skill` — print the bundled, version-pinned +presentation config or external modules.

Parent

Outbound

Scenarios

OutlineAsJson

`pds outline` prints the workspace symbol tree as JSON.

  • given a workspace under the path
  • when the developer runs `pds outline`
  • then the workspace's modules are walked and its graph is built
  • and each node's fqn, name, kind, parent, triggered flag, and declaration site is printed as JSON
  • but the manifest [doc] config and dependency modules are not loaded
Flow Flow — OutlineAsJson scroll to zoom · drag to pan
FEATUREOutlineAsJsonfor OutlineCmdGIVENa workspace under the pathWHENthe developer runs `pds outline`THENthe workspace's modules are walked andits graph is builtANDeach node's fqn, name, kind, parent,triggered flag, and declaration siteis printed as JSONBUTthe manifest [doc] config anddependency modules are not loaded
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[found.isErr][else]alt[modules.isErr][else]alt[files.isErr][else]alt[loaded.isErr][else]loop[entries]alt[else modules.isErr]alt[else root.isErr]COMPONENTOutlineCmdPseudoscript::Cli`pds outline` — walkthe workspace'sCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:CONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTBuilderPseudoscript::ModelProjects the parsed,resolved workspaceCOMPONENTWorkspacePseudoscript::ModelThe resolved set ofmodules keyed by FQN1findRoot(start: string)2findRoot(start: string)3findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>4ioError↩ Err<cli::IoError>↩ Ok<string>5loadModules(root: string)6load(root: string)7load(root: string)8findModules↩ Err<project::IoError>9readEach↩ Err<project::IoError>↩ Ok<model::WorkspaceModule[]>↩ return Result<model::WorkspaceModule[], project::IoError>10ioError↩ Err<cli::IoError>↩ Ok<model::WorkspaceModule[]>11graph(modules: model::WorkspaceModule[])12graph(modules: model::WorkspaceModule[])13build(modules: model::WorkspaceModule[])14noExternals15buildWithExternals16resolveEach17resolveEach18index↩ return model::ModuleEntry[]↩ return model::ModuleEntry[]19graphOf20collectModule↩ return model::Graph↩ return model::Graph↩ return model::Graph21render22print
data

OutlineOpts #

public
cli::OutlineOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDOutlineOptspathstring
component

ReferenceCmd #

private
cli::ReferenceCmd

`pds lang` (alias `spec`) and `pds skill` — print the bundled, version-pinned language reference and the authoring skill to stdout. Fed to an LLM to author `.pds`; no workspace needed.

Parent

Scenarios

PrintReference

`pds lang`/`pds skill` print the bundled reference and authoring skill.

  • given no workspace is needed
  • when the developer runs `pds lang` or `pds skill`
  • then the version-pinned language reference or the authoring skill is printed to stdout
Flow Flow — PrintReference scroll to zoom · drag to pan
FEATUREPrintReferencefor ReferenceCmdGIVENno workspace is neededWHENthe developer runs `pds lang` or `pdsskill`THENthe version-pinned language referenceor the authoring skill is printed tostdout
Sequence Sequence — lang scroll to zoom · drag to pan
SEQUENCElangPERSONcallerCOMPONENTReferenceCmdPseudoscript::Cli`pds lang` (alias`spec`) and `pds1lang()↩ return
Sequence Sequence — skill scroll to zoom · drag to pan
SEQUENCEskillPERSONcallerCOMPONENTReferenceCmdPseudoscript::Cli`pds lang` (alias`spec`) and `pds1skill()↩ return
data

RemoveOpts #

public
cli::RemoveOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDRemoveOptsnamestring
component

SvgCmd #

private
cli::SvgCmd

`pds svg` — render a single diagram to a self-contained SVG on stdout. With `--symbol`, draws that symbol's fitting view; otherwise draws `--view` (paired with `--target`) over the whole workspace. The static counterpart of the IDE canvas. Like `pds outline`, it reads the walked modules straight, skipping the manifest `[doc]` parse and dependency resolution: a diagram never depends on -presentation config or external modules.

Parent

Outbound

Scenarios

RenderOneSvg

`pds svg` renders one diagram to a self-contained SVG.

  • given a workspace and either a --symbol or a --view/--target selection
  • when the developer runs `pds svg`
  • then the chosen view is projected and rendered to a standalone SVG on stdout
  • but a missing or wrong-kind target fails non-zero with the projection error
Flow Flow — RenderOneSvg scroll to zoom · drag to pan
FEATURERenderOneSvgfor SvgCmdGIVENa workspace and either a --symbol or a--view/--target selectionWHENthe developer runs `pds svg`THENthe chosen view is projected andrendered to a standalone SVG on stdoutBUTa missing or wrong-kind target failsnon-zero with the projection error
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[found.isErr][else]alt[modules.isErr][else]alt[files.isErr][else]alt[loaded.isErr][else]alt[scene.isErr][else]alt[else modules.isErr]alt[else root.isErr]alt[!self.isKnownTheme()][else]COMPONENTSvgCmdPseudoscript::Cli`pds svg` — render asingle diagram to aCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:CONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTBuilderPseudoscript::ModelProjects the parsed,resolved workspaceCOMPONENTWorkspacePseudoscript::ModelThe resolved set ofmodules keyed by FQN1isKnownTheme2unknownTheme3findRoot(start: string)4findRoot(start: string)5findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>6ioError↩ Err<cli::IoError>↩ Ok<string>7loadModules(root: string)8load(root: string)9load(root: string)10findModules↩ Err<project::IoError>11readEach↩ Err<project::IoError>↩ Ok<model::WorkspaceModule[]>↩ return Result<model::WorkspaceModule[], project::IoError>12ioError↩ Err<cli::IoError>↩ Ok<model::WorkspaceModule[]>13graph(modules: model::WorkspaceModule[])14graph(modules: model::WorkspaceModule[])15build(modules: model::WorkspaceModule[])16noExternals17buildWithExternals↩ return model::ModuleEntry[]18graphOf↩ return model::Graph↩ return model::Graph19projectChosen20emitError21renderThemed22print
data

SvgOpts #

public
cli::SvgOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDSvgOptspathstringsymbolstringviewstringtargetstringthemestring
component

TokensCmd #

private
cli::TokensCmd

`pds tokens` — print the conformance token stream (`KIND@line:col "lexeme"`) -to stdout, for debugging the lexer.

Parent

Outbound

Scenarios

PrintTokenStream

`pds tokens` prints the conformance token stream.

  • given a .pds source file
  • when the developer runs `pds tokens`
  • then the lexical token stream is printed as KIND@line:col \"lexeme\"
Flow Flow — PrintTokenStream scroll to zoom · drag to pan
FEATUREPrintTokenStreamfor TokensCmdGIVENa .pds source fileWHENthe developer runs `pds tokens`THENthe lexical token stream is printed asKIND@line:col \"lexeme\"
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunCOMPONENTTokensCmdPseudoscript::Cli`pds tokens` — printthe conformance tokenCONTAINERSyntaxPseudoscript`crates/pseudoscript-syntax`.The foundation crate:COMPONENTLexerPseudoscript::SyntaxHand-written lexer forLANG.md §2. One passCOMPONENTLineIndexPseudoscript::SyntaxPrecomputed newlineoffsets turning a byt…1renderTokens(text: string)2renderTokens(text: string)3tokenize4build(src: string)↩ return syntax::LineIndex5renderStream↩ return string↩ return string6print
data

TokensOpts #

public
cli::TokensOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDTokensOptsfilestring
component

UpgradeCmd #

private
cli::UpgradeCmd

`pds upgrade` — download a release and install it over the running binary.

Parent

Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunPERSONcallerCOMPONENTUpgradeCmdPseudoscript::Cli`pds upgrade` —download a release an…1run(version: string)↩ return Result<void, cli::IoError>
data

UpgradeOpts #

public
cli::UpgradeOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDUpgradeOptsversionstring
component

Watcher #

private
cli::Watcher

Filesystem watcher (`--watch`, via `notify`): watches the project root +presentation config or external modules.

Parent

Outbound

Scenarios

RenderOneSvg

`pds svg` renders one diagram to a self-contained SVG.

  • given a workspace and either a --symbol or a --view/--target selection
  • when the developer runs `pds svg`
  • then the chosen view is projected and rendered to a standalone SVG on stdout
  • but a missing or wrong-kind target fails non-zero with the projection error
Flow Flow — RenderOneSvg scroll to zoom · drag to pan
FEATURERenderOneSvgfor SvgCmdGIVENa workspace and either a --symbol or a--view/--target selectionWHENthe developer runs `pds svg`THENthe chosen view is projected andrendered to a standalone SVG on stdoutBUTa missing or wrong-kind target failsnon-zero with the projection error
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[found.isErr][else]alt[modules.isErr][else]alt[files.isErr][else]alt[loaded.isErr][else]loop[entries]alt[scene.isErr][else]alt[else modules.isErr]alt[else root.isErr]alt[!isKnownTheme()][else]COMPONENTSvgCmdPseudoscript::Cli`pds svg` — render asingle diagram to aCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:CONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTBuilderPseudoscript::ModelProjects the parsed,resolved workspaceCOMPONENTWorkspacePseudoscript::ModelThe resolved set ofmodules keyed by FQN1isKnownTheme2unknownTheme3findRoot(start: string)4findRoot(start: string)5findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>6ioError↩ Err<cli::IoError>↩ Ok<string>7loadModules(root: string)8load(root: string)9load(root: string)10findModules↩ Err<project::IoError>11readEach↩ Err<project::IoError>↩ Ok<model::WorkspaceModule[]>↩ return Result<model::WorkspaceModule[], project::IoError>12ioError↩ Err<cli::IoError>↩ Ok<model::WorkspaceModule[]>13graph(modules: model::WorkspaceModule[])14graph(modules: model::WorkspaceModule[])15build(modules: model::WorkspaceModule[])16noExternals17buildWithExternals18resolveEach19resolveEach20index↩ return model::ModuleEntry[]↩ return model::ModuleEntry[]21graphOf22collectModule↩ return model::Graph↩ return model::Graph↩ return model::Graph23projectChosen24emitError25renderThemed26print
data

SvgOpts #

public
cli::SvgOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDSvgOptspathstringsymbolstringviewstringtargetstringthemestring
component

TokensCmd #

private
cli::TokensCmd

`pds tokens` — print the conformance token stream (`KIND@line:col "lexeme"`) +to stdout, for debugging the lexer.

Parent

Outbound

Scenarios

PrintTokenStream

`pds tokens` prints the conformance token stream.

  • given a .pds source file
  • when the developer runs `pds tokens`
  • then the lexical token stream is printed as KIND@line:col \"lexeme\"
Flow Flow — PrintTokenStream scroll to zoom · drag to pan
FEATUREPrintTokenStreamfor TokensCmdGIVENa .pds source fileWHENthe developer runs `pds tokens`THENthe lexical token stream is printed asKIND@line:col \"lexeme\"
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunCOMPONENTTokensCmdPseudoscript::Cli`pds tokens` — printthe conformance tokenCONTAINERSyntaxPseudoscript`crates/pseudoscript-syntax`.The foundation crate:COMPONENTLexerPseudoscript::SyntaxHand-written lexer forLANG.md §2. One passCOMPONENTLineIndexPseudoscript::SyntaxPrecomputed newlineoffsets turning a byt…1renderTokens(text: string)2renderTokens(text: string)3tokenize4lex↩ return syntax::Token[]5build(src: string)↩ return syntax::LineIndex6renderStream↩ return string↩ return string7print
data

TokensOpts #

public
cli::TokensOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDTokensOptsfilestring
component

UpgradeCmd #

private
cli::UpgradeCmd

`pds upgrade` — download a release and install it over the running binary.

Parent

Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunPERSONcallerCOMPONENTUpgradeCmdPseudoscript::Cli`pds upgrade` —download a release an…1run(version: string)↩ return Result<void, cli::IoError>
data

UpgradeOpts #

public
cli::UpgradeOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDUpgradeOptsversionstring
component

Watcher #

private
cli::Watcher

Filesystem watcher (`--watch`, via `notify`): watches the project root recursively, debounces each save burst, and on a relevant change rebuilds the site and bumps the version the browser's live-reload poll reads. Events under the output dir are ignored so writing the site never re-triggers a build.

Parent

Inbound

Scenarios

WatchAndLiveReload

`pds doc --watch` rebuilds on change and live-reloads the browser.

  • given a site served with `--watch`
  • when a .pds file or pds.toml under the root changes
  • then the watcher debounces the save burst and rebuilds the site
  • and the live-reload version is bumped
  • and the browser, polling /__livereload, reloads to the new version
  • but writes under the output directory are ignored so the build does not loop
Flow Flow — WatchAndLiveReload scroll to zoom · drag to pan
FEATUREWatchAndLiveReloadfor WatcherGIVENa site served with `--watch`WHENa .pds file or pds.toml under the rootchangesTHENthe watcher debounces the save burstand rebuilds the siteANDthe live-reload version is bumpedANDthe browser, polling /__livereload,reloads to the new versionBUTwrites under the output directory areignored so the build does not loop
data

Workspace #

public
cli::Workspace

The loaded project: the `[doc]` config, the resolved output directory diff --git a/model/site/module/context.html b/model/site/module/context.html index f0e5880c..ed52982a 100644 --- a/model/site/module/context.html +++ b/model/site/module/context.html @@ -11,12 +11,12 @@ -

PseudoScript
Module

context

person

Developer #

public
context::Developer

Author of architecture models: edits `.pds` files in an IDE and runs the CLI.

Outbound

Sequence Sequence — editModel scroll to zoom · drag to pan
SEQUENCEeditModelPERSONDeveloperAuthor of architecturemodels: edits `.pds`SYSTEMEditorIDEs that speak theLanguage ServerSYSTEMPseudoscriptThe PseudoScript CLI —loads a `.pds`CONTAINERCliPseudoscript`crates/pseudoscript`— the binary crateCOMPONENTLspHostPseudoscript::Cli`pds lsp` — boot aTokio runtime andCONTAINERLspPseudoscript`crates/pseudoscript-lsp`.The stdio languageCOMPONENTServerPseudoscript::LspThe tower-lsp`Backend`: owns theCOMPONENTStorePseudoscript::LspThe workspace documentstore: the server's1openDocument(doc: model::WorkspaceModule)2serveLanguage(doc: model::WorkspaceModule)3runLsp()4run()5runStdio()6runStdio()↩ return↩ Ok<void>↩ return Result<void, cli::IoError>7onChange(doc: model::WorkspaceModule)8onChange(doc: model::WorkspaceModule)9change(doc: model::WorkspaceModule)↩ return10publishAll
Sequence Sequence — renderDocs scroll to zoom · drag to pan
SEQUENCErenderDocsalt[found.isErr][else]alt[dependencies.isErr][else]alt[modules.isErr][else]alt[config.isErr][else]alt[self.isHtml()]alt[written.isErr][else]alt[site.isErr][else]alt[project.isErr][else]alt[root.isErr][else]alt[built.isErr][else]PERSONDeveloperAuthor of architecturemodels: edits `.pds`SYSTEMPseudoscriptThe PseudoScript CLI —loads a `.pds`CONTAINERCliPseudoscript`crates/pseudoscript`— the binary crateCOMPONENTDocCmdPseudoscript::Cli`pds doc` — theheadline commandCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:CONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTChecksPseudoscript::ModelStatic analysis(LANG.md §2.2, §2.3,CONTAINERDocPseudoscript`crates/pseudoscript-doc`.Turns a resolved grap…COMPONENTHealthPseudoscript::DocPositions the host'sdiagnostics in theCOMPONENTBuilderPseudoscript::ModelProjects the parsed,resolved workspaceCOMPONENTWorkspacePseudoscript::ModelThe resolved set ofmodules keyed by FQN1renderDocs(path: string)2runDoc(path: string)3noFormatOverride4run(path: string, cliFormat: string)5findRoot(start: string)6findRoot(start: string)7findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>8ioError↩ Err<cli::IoError>↩ Ok<string>↩ Err<cli::IoError>9load(root: string)10loadManifest↩ Err<cli::IoError>11loadModules↩ Err<cli::IoError>12loadDependencies↩ Err<cli::IoError>↩ Ok<cli::Workspace>↩ Err<cli::IoError>13resolveFormat14checkWorkspaceModules(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])15checkWorkspaceModules(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])↩ return model::ModuleDiagnostics[]↩ return model::ModuleDiagnostics[]16reportModules17prepareDiagnostics(modules: model::WorkspaceModule[], perModule: model::ModuleDiagnostics[])18prepare(modules: model::WorkspaceModule[], perModule: model::ModuleDiagnostics[])↩ return doc::DiagnosticInput[]↩ return doc::DiagnosticInput[]19graph(modules: model::WorkspaceModule[])20graph(modules: model::WorkspaceModule[])21build(modules: model::WorkspaceModule[])22noExternals23buildWithExternals↩ return model::ModuleEntry[]24graphOf↩ return model::Graph↩ return model::Graph25renderSite↩ Err<cli::IoError>26write↩ Err<cli::IoError>27isHtml28copyLogo↩ Ok<string>↩ Err<cli::IoError>↩ Ok<void>
system

Editor #

public
context::Editor

IDEs that speak the Language Server Protocol (VS Code, Neovim, …). The editor +

PseudoScript
Module

context

person

Developer #

public
context::Developer

Author of architecture models: edits `.pds` files in an IDE and runs the CLI.

Outbound

Sequence Sequence — editModel scroll to zoom · drag to pan
SEQUENCEeditModelloop[payloads]PERSONDeveloperAuthor of architecturemodels: edits `.pds`SYSTEMEditorIDEs that speak theLanguage ServerSYSTEMPseudoscriptThe PseudoScript CLI —loads a `.pds`CONTAINERCliPseudoscript`crates/pseudoscript`— the binary crateCOMPONENTLspHostPseudoscript::Cli`pds lsp` — boot aTokio runtime andCONTAINERLspPseudoscript`crates/pseudoscript-lsp`.The stdio languageCOMPONENTServerPseudoscript::LspThe tower-lsp`Backend`: owns theCOMPONENTStorePseudoscript::LspThe workspace documentstore: the server's1openDocument(doc: model::WorkspaceModule)2serveLanguage(doc: model::WorkspaceModule)3runLsp()4run()5runStdio()6runStdio()↩ return↩ Ok<void>↩ return Result<void, cli::IoError>7onChange(doc: model::WorkspaceModule)8onChange(doc: model::WorkspaceModule)9change(doc: model::WorkspaceModule)↩ return10publishAll11diagnostics()12workspace13ensureExternals14modules15buildWithExternals↩ return model::Workspace16collectDiagnostics↩ return model::ModuleDiagnostics[]17uriOf(fqn: string)↩ return string18publish
Sequence Sequence — renderDocs scroll to zoom · drag to pan
SEQUENCErenderDocsalt[found.isErr][else]alt[modules.isErr][else]alt[files.isErr][else]alt[loaded.isErr][else]alt[dependencies.isErr][else]alt[modules.isErr][else]alt[config.isErr][else]loop[entries]alt[kindMatches()][else]alt[found.isErr][else]alt[anchor.isErr][else]alt[kindMatches()][else]alt[found.isErr][else]alt[anchor.isErr][else]alt[kindMatches()][else]alt[found.isErr][else]alt[actor.isNone][else]alt[disclosed.isNone][else]alt[node.isErr][else]alt[view.isFeature][else]alt[view.isData][else]alt[view.isComponent][else]alt[view.isContainer][else]alt[view.isContext][else]alt[scene.isErr][else]alt[rendered.isErr][else]alt[rendered.isErr][else]alt[rendered.isErr][else]alt[health.isErr][else]alt[universe.isErr][else]alt[modulePages.isErr][else]alt[docPages.isErr][else]alt[index.isErr][else]alt[html.isErr][else]alt[isHtml()][else]alt[isHtml()]alt[written.isErr][else]alt[site.isErr][else]alt[project.isErr][else]alt[root.isErr][else]alt[built.isErr][else]PERSONDeveloperAuthor of architecturemodels: edits `.pds`SYSTEMPseudoscriptThe PseudoScript CLI —loads a `.pds`CONTAINERCliPseudoscript`crates/pseudoscript`— the binary crateCOMPONENTDocCmdPseudoscript::Cli`pds doc` — theheadline commandCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:CONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTChecksPseudoscript::ModelStatic analysis(LANG.md §2.2, §2.3,CONTAINERDocPseudoscript`crates/pseudoscript-doc`.Turns a resolved grap…COMPONENTHealthPseudoscript::DocPositions the host'sdiagnostics in theCOMPONENTBuilderPseudoscript::ModelProjects the parsed,resolved workspaceCOMPONENTWorkspacePseudoscript::ModelThe resolved set ofmodules keyed by FQNCOMPONENTSiteBuilderPseudoscript::DocOrchestrates the wholesite: build the URLCOMPONENTUrlsPseudoscript::DocMaps every node FQN toits page path andCOMPONENTPagesPseudoscript::DocProjects the resolvedgraph into per-pageCOMPONENTDiagramsPseudoscript::DocThe bridge into`emit`: project a vie…CONTAINEREmitPseudoscript`crates/pseudoscript-emit`.Projects a view into …COMPONENTProjectorPseudoscript::EmitProjects a `View` outof the graph (LANG.mdCOMPONENTEdgesPseudoscript::EmitBuilds the routed-edgeset for a C4 sceneCOMPONENTLayoutPseudoscript::EmitAssigns geometry.Projection stamps eac…COMPONENTTracePseudoscript::EmitWalks a callable'sbody trace intoCOMPONENTSsrPseudoscript::DocThe server-side renderboundary: aCOMPONENTShellPseudoscript::DocOwns the documentshell that wraps eachCOMPONENTEscapePseudoscript::DocAll user text — nodenames, `///` docs,CONTAINERUniversePseudoscript`crates/pseudoscript-universe`.Maps the resolved C4COMPONENTAdapterPseudoscript::UniverseAdapts a resolvedmodel into theCOMPONENTFlattenPseudoscript::UniverseFlattens the softwaregraph into theCOMPONENTFlowTracerPseudoscript::UniverseTraces everyentry-point flow: aCOMPONENTSearchIndexPseudoscript::DocBuilds the staticfull-text search inde…COMPONENTAssetsPseudoscript::DocShips the prebuiltpresentation bundles,COMPONENTMarkdownSitePseudoscript::DocThe static Markdownoutput mode: turns th…1renderDocs(path: string)2runDoc(path: string)3noFormatOverride4run(path: string, cliFormat: string)5findRoot(start: string)6findRoot(start: string)7findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>8ioError↩ Err<cli::IoError>↩ Ok<string>↩ Err<cli::IoError>9load(root: string)10loadManifest↩ Err<cli::IoError>11loadModules12load(root: string)13load(root: string)14findModules↩ Err<project::IoError>15readEach↩ Err<project::IoError>↩ Ok<model::WorkspaceModule[]>↩ return Result<model::WorkspaceModule[], project::IoError>16ioError↩ Err<cli::IoError>↩ Ok<model::WorkspaceModule[]>↩ Err<cli::IoError>17loadDependencies↩ Err<cli::IoError>↩ Ok<cli::Workspace>↩ Err<cli::IoError>18resolveFormat19checkWorkspaceModules(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])20checkWorkspaceModules(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])↩ return model::ModuleDiagnostics[]↩ return model::ModuleDiagnostics[]21reportModules22prepareDiagnostics(modules: model::WorkspaceModule[], perModule: model::ModuleDiagnostics[])23prepare(modules: model::WorkspaceModule[], perModule: model::ModuleDiagnostics[])↩ return doc::DiagnosticInput[]↩ return doc::DiagnosticInput[]24graph(modules: model::WorkspaceModule[])25graph(modules: model::WorkspaceModule[])26build(modules: model::WorkspaceModule[])27noExternals28buildWithExternals29resolveEach30resolveEach31index↩ return model::ModuleEntry[]↩ return model::ModuleEntry[]32graphOf33collectModule↩ return model::Graph↩ return model::Graph↩ return model::Graph34renderSite35isHtml36render(graph: model::Graph, config: doc::DocConfig, diagnostics: doc::DiagnosticInput[])37render(graph: model::Graph, config: doc::DocConfig, diagnostics: doc::DiagnosticInput[])38build(graph: model::Graph)↩ return39sortedModules(graph: model::Graph)↩ return string[]40index(graph: model::Graph, config: doc::DocConfig, modules: string[], diagnostics: doc::DiagnosticInput[])41docGroups42sidebar43navLinks44crumbsOf45moduleCards46context(graph: model::Graph)47contextView48figure49project(graph: model::Graph, view: emit::View)50project(graph: model::Graph, view: emit::View)51projectContext52collectKinds53collect(graph: model::Graph, inView: emit::PlacedNode[])54route55sortDedup↩ return emit::RoutedEdge[]56solveC4(scene: emit::Scene)↩ return emit::Scene↩ return emit::Scene↩ Ok<emit::Scene>57projectBoundary58requireKind59kindOf↩ Err<emit::EmitError>60kindMatches↩ Ok<string>↩ Err<emit::EmitError>↩ Err<emit::EmitError>61outerFrameOf62childrenOf63withOuterFrame64externalActors65nestSiblings66collect(graph: model::Graph, inView: emit::PlacedNode[])67route68sortDedup↩ return emit::RoutedEdge[]69solveC4(scene: emit::Scene)↩ return emit::Scene↩ Ok<emit::Scene>↩ return Result<emit::Scene, emit::EmitError>70projectBoundary71requireKind72kindOf↩ Err<emit::EmitError>73kindMatches↩ Ok<string>↩ Err<emit::EmitError>↩ Err<emit::EmitError>74outerFrameOf75childrenOf76withOuterFrame77externalActors78nestSiblings79collect(graph: model::Graph, inView: emit::PlacedNode[])80route81sortDedup↩ return emit::RoutedEdge[]82solveC4(scene: emit::Scene)↩ return emit::Scene↩ Ok<emit::Scene>↩ return Result<emit::Scene, emit::EmitError>83projectData↩ return Result<emit::Scene, emit::EmitError>84projectFeature↩ return Result<emit::Scene, emit::EmitError>85projectSequence86requireKind87kindOf↩ Err<emit::EmitError>88kindMatches↩ Ok<string>↩ Err<emit::EmitError>↩ Err<emit::EmitError>89bodyOf90blackBox(graph: model::Graph, entry: string)91ownerOf92blackBoxActor93inboundCall94returnItem95participantsOf↩ return emit::Scene↩ Ok<emit::Scene>96walk(graph: model::Graph, entry: string, body: model::Step[])97ownerOf98triggerActorOf99entryStack100untriggered101noCaller102traceItems103participantsOf↩ return emit::Scene↩ return emit::Scene104inboundCall105traceItems106prependItem107participantsOf↩ return emit::Scene↩ Ok<emit::Scene>↩ return Result<emit::Scene, emit::EmitError>↩ return Result<emit::Scene, emit::EmitError>↩ return doc::Diagram108embed109svgFigure↩ return doc::Diagram↩ return doc::Diagram↩ return doc::Diagram110stats↩ return doc::PageProps111emitPage112renderPage(props: doc::PageProps)↩ return Result<doc::RenderedPage, doc::RenderError>↩ Err<doc::RenderError>113wrap(path: string, props: doc::PageProps, rendered: doc::RenderedPage)114text(text: string)↩ return string115document↩ return string↩ Ok<doc::SiteFile>↩ Err<doc::RenderError>116emitDocPages↩ Err<doc::RenderError>117emitModulePages↩ Err<doc::RenderError>118universePage(graph: model::Graph, config: doc::DocConfig, modules: string[], diagnostics: doc::DiagnosticInput[])119docGroups120sidebar121navLinks122crumbsOf123fromModel(graph: model::Graph)124fromModel(graph: model::Graph)125placeStructural126wireContainment127tallyTraffic↩ return universe::SoftwareGraph↩ return universe::SoftwareGraph128snapshot(graph: universe::SoftwareGraph)129snapshot(graph: universe::SoftwareGraph)130nodesOf131edgesOf↩ return universe::Snapshot↩ return universe::Snapshot132flows(graph: model::Graph)133flows(graph: model::Graph)134entryPoints135traceAll↩ return universe::FlowDef[]↩ return universe::FlowDef[]136nodeHrefs↩ return doc::PageProps137emitPage138renderPage(props: doc::PageProps)↩ return Result<doc::RenderedPage, doc::RenderError>↩ Err<doc::RenderError>139wrap(path: string, props: doc::PageProps, rendered: doc::RenderedPage)140text(text: string)↩ return string141document↩ return string↩ Ok<doc::SiteFile>↩ Err<doc::RenderError>142healthPage(graph: model::Graph, config: doc::DocConfig, modules: string[], diagnostics: doc::DiagnosticInput[])143docGroups144sidebar145navLinks146crumbsOf147page(graph: model::Graph, diagnostics: doc::DiagnosticInput[])148attributeAll149countOf150countOf↩ return doc::PageBody↩ return doc::PageProps151emitPage152renderPage(props: doc::PageProps)↩ return Result<doc::RenderedPage, doc::RenderError>↩ Err<doc::RenderError>153wrap(path: string, props: doc::PageProps, rendered: doc::RenderedPage)154text(text: string)↩ return string155document↩ return string↩ Ok<doc::SiteFile>↩ Err<doc::RenderError>156build(graph: model::Graph, config: doc::DocConfig)157entries↩ return doc::SiteFile158shared()↩ return doc::SiteFile[]↩ Ok<doc::Site>↩ return Result<doc::Site, doc::RenderError>159renderError↩ Err<cli::IoError>↩ Ok<doc::Site>160renderMarkdown161renderMarkdown(graph: model::Graph, config: doc::DocConfig, diagnostics: doc::DiagnosticInput[])162buildAll(graph: model::Graph, config: doc::DocConfig, diagnostics: doc::DiagnosticInput[])↩ return doc::PageProps[]163render(pages: doc::PageProps[], theme: doc::Theme)↩ return doc::Site↩ return doc::Site↩ return doc::Site↩ Ok<doc::Site>↩ Err<cli::IoError>164write↩ Err<cli::IoError>165isHtml166copyLogo↩ Ok<string>↩ Err<cli::IoError>↩ Ok<void>
system

Editor #

public
context::Editor

IDEs that speak the Language Server Protocol (VS Code, Neovim, …). The editor spawns `pds lsp` as a child process and drives it over stdio: it streams document changes to the server and renders the diagnostics it publishes.

Inbound

Outbound

Containers Container diagram scroll to zoom · drag to pan
PERSONDeveloperAuthor of architecture models: edits `.pds`files in an IDE and runs the CLI.SYSTEMPseudoscriptThe PseudoScript CLI — loads a `.pds`workspace into one resolved graph and…renderDocs
system

Pseudoscript #

public
context::Pseudoscript

The PseudoScript CLI — loads a `.pds` workspace into one resolved graph and documents it as a static site, or serves the language to editors. Cross-system callers couple to these published faces; the containers stay behind them.

#headline

Inbound

Outbound

Scenarios

DocumentAWorkspace

Render a `.pds` workspace to a browsable documentation site — the headline -flow, aggregating load, check, graph, project, and write.

#headline
  • given a directory holding a pds.toml and one or more .pds modules
  • and the modules form a well-formed C4 model
  • when the developer runs `pds doc` against the directory
  • then every module is loaded into one resolved graph
  • and C4 and sequence diagrams are projected as scene geometry the site's client islands draw
  • and a static site is written under the configured output directory
Flow Flow — DocumentAWorkspace scroll to zoom · drag to pan
FEATUREDocumentAWorkspacefor PseudoscriptGIVENa directory holding a pds.toml and oneor more .pds modulesANDthe modules form a well-formed C4modelWHENthe developer runs `pds doc` againstthe directoryTHENevery module is loaded into oneresolved graphANDC4 and sequence diagrams are projectedas scene geometry the site's clientislands drawANDa static site is written under theconfigured output directory
CheckAModel

Statically validate a model and report what is wrong.

  • given a .pds source file
  • when the developer runs `pds check` on it
  • then the source is parsed with error recovery
  • and resolution, visibility, Result-flow, and return-coverage checks run
  • and every violation is reported as a diagnostic
  • but a well-formed model reports nothing and exits zero
Flow Flow — CheckAModel scroll to zoom · drag to pan
FEATURECheckAModelfor PseudoscriptGIVENa .pds source fileWHENthe developer runs `pds check` on itTHENthe source is parsed with errorrecoveryANDresolution, visibility, Result-flow,and return-coverage checks runANDevery violation is reported as adiagnosticBUTa well-formed model reports nothingand exits zero
FormatAModel

Reformat a model to one canonical form.

  • given a .pds source file with non-canonical spacing
  • when the developer runs `pds fmt`
  • then the source is parsed and pretty-printed to canonical PseudoScript
  • and comments and blank-line runs are preserved
  • but unparseable source is rejected without rewriting the file
Flow Flow — FormatAModel scroll to zoom · drag to pan
FEATUREFormatAModelfor PseudoscriptGIVENa .pds source file with non-canonicalspacingWHENthe developer runs `pds fmt`THENthe source is parsed andpretty-printed to canonicalPseudoScriptANDcomments and blank-line runs arepreservedBUTunparseable source is rejected withoutrewriting the file
EditModelInIde

Author a model in an editor with live diagnostics.

  • given an editor that speaks the Language Server Protocol
  • and `pds lsp` running as a child process over stdio
  • when the author changes a document
  • then the server re-checks the document from its current text
  • and diagnostics are published back to the editor
Flow Flow — EditModelInIde scroll to zoom · drag to pan
FEATUREEditModelInIdefor PseudoscriptGIVENan editor that speaks the LanguageServer ProtocolAND`pds lsp` running as a child processover stdioWHENthe author changes a documentTHENthe server re-checks the document fromits current textANDdiagnostics are published back to theeditor
ServeLiveDocs

Preview docs that rebuild as the model changes.

  • given a generated documentation site
  • when the developer runs `pds doc --serve --watch`
  • then the site is hosted over HTTP on localhost
  • and a change to any .pds or pds.toml rebuilds the site
  • and the browser live-reloads to the new version
Flow Flow — ServeLiveDocs scroll to zoom · drag to pan
FEATUREServeLiveDocsfor PseudoscriptGIVENa generated documentation siteWHENthe developer runs `pds doc --serve--watch`THENthe site is hosted over HTTP onlocalhostANDa change to any .pds or pds.tomlrebuilds the siteANDthe browser live-reloads to the newversion
Containers Container diagram scroll to zoom · drag to pan
PseudoscriptCONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERDoc`crates/pseudoscript-doc`. Turns a resolvedgraph into a Svelte-rendered,…CONTAINERDot`crates/pseudoscript-dot`. Runs thefour-pass layered pipeline over a `Graph` t…CONTAINEREmit`crates/pseudoscript-emit`. Projects a viewinto a `Scene` and renders it to SVG; C4…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERIdeSession`crates/pseudoscript-ide` — the IDEapplication, Rust compiled to a single wasm…CONTAINERWebIde`web-ide` — the IDE at `ide.pdscript.dev`: aSvelteKit shell on Cloudflare Workers stati…CONTAINERLanding`web-landing` — the marketing site at`pdscript.dev`. A static Svelte build on…CONTAINERLayout`crates/pseudoscript-layout`. Thegeometry/text `Core` and the sequence…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERLspCore`crates/pseudoscript-lsp-core`. The singlehome for language intelligence as…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…CONTAINERProject`crates/pseudoscript-project`. Thedisk-facing loader: resolves the workspace…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…CONTAINERUniverse`crates/pseudoscript-universe`. Maps theresolved C4 model into the software graph…PERSONDeveloperAuthor of architecture models: edits `.pds`files in an IDE and runs the CLI.SYSTEMEditorIDEs that speak the Language Server Protocol(VS Code, Neovim, …). The editor spawns `pd…SYSTEMLlmProviderThe author's configured OpenAI-compatiblecompletion provider — hosted (OpenAI,…PERSONVisitorA prospective user reading the landing page.prepareDiagnosticsrenderrenderMarkdownformatrunStdiocheckcheckWorkspaceModulesgraphfindRootloadrenderTokensopenDocumentprojectflowsfromModelsnapshotgridLayoutrunPipelinelayoutparseprepareDiagnosticscheckcheckWorkspaceModulesgraphbuildflowssnapshotcompletedependencyModulesdiagnosticshovermountoutlinesetSourcechatCompletefimCompletelistModelsopenopenIdeshowInstalldefinitionformatEdithovercheckparseprojectgraph
Generated by pds doc.
+flow, aggregating load, check, graph, project, and write.

#headline
  • given a directory holding a pds.toml and one or more .pds modules
  • and the modules form a well-formed C4 model
  • when the developer runs `pds doc` against the directory
  • then every module is loaded into one resolved graph
  • and C4 and sequence diagrams are projected as scene geometry the site's client islands draw
  • and a static site is written under the configured output directory
Flow Flow — DocumentAWorkspace scroll to zoom · drag to pan
FEATUREDocumentAWorkspacefor PseudoscriptGIVENa directory holding a pds.toml and oneor more .pds modulesANDthe modules form a well-formed C4modelWHENthe developer runs `pds doc` againstthe directoryTHENevery module is loaded into oneresolved graphANDC4 and sequence diagrams are projectedas scene geometry the site's clientislands drawANDa static site is written under theconfigured output directory
CheckAModel

Statically validate a model and report what is wrong.

  • given a .pds source file
  • when the developer runs `pds check` on it
  • then the source is parsed with error recovery
  • and resolution, visibility, Result-flow, and return-coverage checks run
  • and every violation is reported as a diagnostic
  • but a well-formed model reports nothing and exits zero
Flow Flow — CheckAModel scroll to zoom · drag to pan
FEATURECheckAModelfor PseudoscriptGIVENa .pds source fileWHENthe developer runs `pds check` on itTHENthe source is parsed with errorrecoveryANDresolution, visibility, Result-flow,and return-coverage checks runANDevery violation is reported as adiagnosticBUTa well-formed model reports nothingand exits zero
FormatAModel

Reformat a model to one canonical form.

  • given a .pds source file with non-canonical spacing
  • when the developer runs `pds fmt`
  • then the source is parsed and pretty-printed to canonical PseudoScript
  • and comments and blank-line runs are preserved
  • but unparseable source is rejected without rewriting the file
Flow Flow — FormatAModel scroll to zoom · drag to pan
FEATUREFormatAModelfor PseudoscriptGIVENa .pds source file with non-canonicalspacingWHENthe developer runs `pds fmt`THENthe source is parsed andpretty-printed to canonicalPseudoScriptANDcomments and blank-line runs arepreservedBUTunparseable source is rejected withoutrewriting the file
EditModelInIde

Author a model in an editor with live diagnostics.

  • given an editor that speaks the Language Server Protocol
  • and `pds lsp` running as a child process over stdio
  • when the author changes a document
  • then the server re-checks the document from its current text
  • and diagnostics are published back to the editor
Flow Flow — EditModelInIde scroll to zoom · drag to pan
FEATUREEditModelInIdefor PseudoscriptGIVENan editor that speaks the LanguageServer ProtocolAND`pds lsp` running as a child processover stdioWHENthe author changes a documentTHENthe server re-checks the document fromits current textANDdiagnostics are published back to theeditor
ServeLiveDocs

Preview docs that rebuild as the model changes.

  • given a generated documentation site
  • when the developer runs `pds doc --serve --watch`
  • then the site is hosted over HTTP on localhost
  • and a change to any .pds or pds.toml rebuilds the site
  • and the browser live-reloads to the new version
Flow Flow — ServeLiveDocs scroll to zoom · drag to pan
FEATUREServeLiveDocsfor PseudoscriptGIVENa generated documentation siteWHENthe developer runs `pds doc --serve--watch`THENthe site is hosted over HTTP onlocalhostANDa change to any .pds or pds.tomlrebuilds the siteANDthe browser live-reloads to the newversion
Containers Container diagram scroll to zoom · drag to pan
PseudoscriptCONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERDoc`crates/pseudoscript-doc`. Turns a resolvedgraph into a Svelte-rendered,…CONTAINERDot`crates/pseudoscript-dot`. Runs thefour-pass layered pipeline over a `Graph` t…CONTAINEREmit`crates/pseudoscript-emit`. Projects a viewinto a `Scene` and renders it to SVG; C4…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERIdeSession`crates/pseudoscript-ide` — the IDEapplication, Rust compiled to a single wasm…CONTAINERWebIde`web-ide` — the IDE at `ide.pdscript.dev`: aSvelteKit shell on Cloudflare Workers stati…CONTAINERLanding`web-landing` — the marketing site at`pdscript.dev`. A static Svelte build on…CONTAINERLayout`crates/pseudoscript-layout`. Thegeometry/text `Core` and the sequence…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERLspCore`crates/pseudoscript-lsp-core`. The singlehome for language intelligence as…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…CONTAINERProject`crates/pseudoscript-project`. Thedisk-facing loader: resolves the workspace…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…CONTAINERUniverse`crates/pseudoscript-universe`. Maps theresolved C4 model into the software graph…PERSONDeveloperAuthor of architecture models: edits `.pds`files in an IDE and runs the CLI.SYSTEMEditorIDEs that speak the Language Server Protocol(VS Code, Neovim, …). The editor spawns `pd…SYSTEMLlmProviderThe author's configured OpenAI-compatiblecompletion provider — hosted (OpenAI,…PERSONVisitorA prospective user reading the landing page.prepareDiagnosticsrenderrenderMarkdownformatrunStdiocheckcheckWorkspacecheckWorkspaceModulesgraphfindRootloadrenderTokensopenDocumentprojectflowsfromModelsnapshotgridLayoutrunPipelinelayoutparseprepareDiagnosticscheckcheckWorkspaceModulesgraphbuildflowssnapshotcompletedependencyModulesdiagnosticshovermountoutlinesetSourcechatCompletefimCompletelistModelsopenopenIdeshowInstalldefinitionformatEdithovercheckparseprojectgraph
Generated by pds doc.
diff --git a/model/site/module/doc.html b/model/site/module/doc.html index 79cc23da..ae87bcb1 100644 --- a/model/site/module/doc.html +++ b/model/site/module/doc.html @@ -11,13 +11,13 @@ -
PseudoScript
Module

doc

component

Assets #

private
doc::Assets

Ships the prebuilt presentation bundles, authored in the `web/` Svelte package and +

PseudoScript
Module

doc

component

Assets #

private
doc::Assets

Ships the prebuilt presentation bundles, authored in the `web/` Svelte package and embedded at build time (LANG.md §9.3). `style.css`, `client.js`, and `universe.js` ship once at the site root; `ssr.js` is build-time only — the engine (`Doc::Ssr`) evaluates it and it is never written to the site. The universe bundle is the only one that carries WebGL; the SSR bundle never does.

Parent

Inbound

Outbound

Scenarios

SharedAssetsShipOnce

Shared assets ship once and every page links them.

  • given a multi-page site
  • when it is generated
  • then style.css and client.js are emitted once at the site root
  • and every page links them by a depth-relative path rather than inlining them
Flow Flow — SharedAssetsShipOnce scroll to zoom · drag to pan
FEATURESharedAssetsShipOncefor AssetsGIVENa multi-page siteWHENit is generatedTHENstyle.css and client.js are emittedonce at the site rootANDevery page links them by adepth-relative path rather thaninlining them
data

Call #

public
doc::Call
Entities Entity diagram scroll to zoom · drag to pan
RECORDCallmessagestring
data

Codec #

public
doc::Codec
Entities Entity diagram scroll to zoom · drag to pan
RECORDCodecmessagestring
data

Crumb #

public
doc::Crumb

One breadcrumb hop: its label and href; the trailing crumb (the current -page) carries no href.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDCrumblabelstringhrefstring
data

DiagnosticInput #

public
doc::DiagnosticInput

One host-prepared diagnostic, positioned in its module's source: severity +page) carries no href.

Entities Entity diagram scroll to zoom · drag to pan
RECORDCrumblabelstringhrefstring
data

DiagnosticInput #

public
doc::DiagnosticInput

One host-prepared diagnostic, positioned in its module's source: severity word (`error`/`warning`), the stable rule code and its principle-article URL (empty for plain diagnostics), the message, and the 1-based line/column with the byte span. The host computes line/column once — this crate never sees @@ -47,10 +47,10 @@ whose section it belongs on, and builds the health page and the per-section badges. Attribution is positional: the node whose declaration starts closest before the diagnostic's span owns it, a callable lifting to its -owner; a span no node encloses falls back to the module page.

Parent

Inbound

Outbound

Scenarios

HealthPageListsDiagnostics

The health page lists every finding; affected sections carry badges.

  • given host-prepared diagnostics including an architecture lint
  • when the site is rendered
  • then the health page lists each finding with severity, code, location, and its principle-article link
  • and each entry deep-links to the owning node's documentation section
  • and the affected section shows an inline badge
  • but a clean model renders an empty health page, not a missing one
Flow Flow — HealthPageListsDiagnostics scroll to zoom · drag to pan
FEATUREHealthPageListsDiagnosticsfor HealthGIVENhost-prepared diagnostics including anarchitecture lintWHENthe site is renderedTHENthe health page lists each findingwith severity, code, location, and itsprinciple-article linkANDeach entry deep-links to the owningnode's documentation sectionANDthe affected section shows an inlinebadgeBUTa clean model renders an empty healthpage, not a missing one
data

HealthEntry #

public
doc::HealthEntry

One architecture-health finding, attributed to the node whose section it +owner; a span no node encloses falls back to the module page.

Parent

Inbound

Outbound

Scenarios

HealthPageListsDiagnostics

The health page lists every finding; affected sections carry badges.

  • given host-prepared diagnostics including an architecture lint
  • when the site is rendered
  • then the health page lists each finding with severity, code, location, and its principle-article link
  • and each entry deep-links to the owning node's documentation section
  • and the affected section shows an inline badge
  • but a clean model renders an empty health page, not a missing one
Flow Flow — HealthPageListsDiagnostics scroll to zoom · drag to pan
FEATUREHealthPageListsDiagnosticsfor HealthGIVENhost-prepared diagnostics including anarchitecture lintWHENthe site is renderedTHENthe health page lists each findingwith severity, code, location, and itsprinciple-article linkANDeach entry deep-links to the owningnode's documentation sectionANDthe affected section shows an inlinebadgeBUTa clean model renders an empty healthpage, not a missing one
data

HealthEntry #

public
doc::HealthEntry

One architecture-health finding, attributed to the node whose section it belongs on: the diagnostic fields plus the owning node's FQN and the (prefixed) href to its section — the module page when no node encloses the -span.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDHealthEntrymodulestringseveritystringcodestringcodeUrlstringmessagestringlinenumbercolumnnumbernodeFqnstringhrefstring
data

HealthPage #

public
doc::HealthPage
Entities Entity diagram scroll to zoom · drag to pan
RECORDHealthPageentriesdoc::HealthEntry[]errorCountnumberwarningCountnumberRECORDHealthEntrymodulestringseveritystringcodestringcodeUrlstringmessagestringlinenumbercolumnnumbernodeFqnstringhrefstring
component

Highlight #

private
doc::Highlight

Highlights fenced code blocks at build time, so the shipped site needs no +span.

Entities Entity diagram scroll to zoom · drag to pan
RECORDHealthEntrymodulestringseveritystringcodestringcodeUrlstringmessagestringlinenumbercolumnnumbernodeFqnstringhrefstring
data

HealthPage #

public
doc::HealthPage
Entities Entity diagram scroll to zoom · drag to pan
RECORDHealthPageentriesdoc::HealthEntry[]errorCountnumberwarningCountnumberRECORDHealthEntrymodulestringseveritystringcodestringcodeUrlstringmessagestringlinenumbercolumnnumbernodeFqnstringhrefstring
component

Highlight #

private
doc::Highlight

Highlights fenced code blocks at build time, so the shipped site needs no client highlighter and one deterministic output serves every theme: PseudoScript through the toolchain's own lexer, emitting class-based spans coloured by the site stylesheet. Any other language passes through escaped @@ -65,11 +65,11 @@ (nodes by level, edges with traffic, each flow's legs); the health page as a table with article links. No SSR engine, no shared assets, no logo — the engine-free site for wikis and code hosts.

Parent

Inbound

Scenarios

MarkdownSiteMirrorsHtml

The Markdown site is the engine-free twin of the HTML site.

  • given the same resolved graph and configuration
  • when the Markdown site is rendered
  • then one .md per page mirrors the HTML site's paths
  • and each diagram is written as a standalone themed .svg asset referenced as an image
  • but no SSR engine runs and no shared assets or logo are emitted
Flow Flow — MarkdownSiteMirrorsHtml scroll to zoom · drag to pan
FEATUREMarkdownSiteMirrorsHtmlfor MarkdownSiteGIVENthe same resolved graph andconfigurationWHENthe Markdown site is renderedTHENone .md per page mirrors the HTMLsite's pathsANDeach diagram is written as astandalone themed .svg assetreferenced as an imageBUTno SSR engine runs and no sharedassets or logo are emitted
data

ModuleCard #

public
doc::ModuleCard

A module card on the index: its FQN, the (prefixed) href to its page, and an -"N item(s)" line.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleCardnamestringhrefstringmetastring
data

ModulePage #

public
doc::ModulePage
Entities Entity diagram scroll to zoom · drag to pan
RECORDModulePagenamestringsectionsdoc::NodeSection[]RECORDNodeSectionidstringkindstringnamestringfqnstringvisibilitystringsummarystringextendedstringtagsstring[]relationshipsdoc::RelGroup[]scenariosdoc::ScenarioCard[]diagramsdoc::Diagram[]diagnosticsdoc::SectionDiagnostic[]
data

NodeHref #

public
doc::NodeHref

A universe node's documentation link: its id and the (prefixed) href to its -section, so clicking a sphere can navigate to the docs.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeHrefidstringhrefstring
data

NodeSection #

public
doc::NodeSection

One node's documentation section: head fields, `///` docs, tags, relationship +"N item(s)" line.

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleCardnamestringhrefstringmetastring
data

ModulePage #

public
doc::ModulePage
Entities Entity diagram scroll to zoom · drag to pan
RECORDModulePagenamestringsectionsdoc::NodeSection[]RECORDNodeSectionidstringkindstringnamestringfqnstringvisibilitystringsummarystringextendedstringtagsstring[]relationshipsdoc::RelGroup[]scenariosdoc::ScenarioCard[]diagramsdoc::Diagram[]diagnosticsdoc::SectionDiagnostic[]
data

NodeHref #

public
doc::NodeHref

A universe node's documentation link: its id and the (prefixed) href to its +section, so clicking a sphere can navigate to the docs.

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeHrefidstringhrefstring
data

NodeSection #

public
doc::NodeSection

One node's documentation section: head fields, `///` docs, tags, relationship groups, scenario cards, embedded diagrams, and the health findings attributed -to the node (rendered as inline badges).

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeSectionidstringkindstringnamestringfqnstringvisibilitystringsummarystringextendedstringtagsstring[]relationshipsdoc::RelGroup[]scenariosdoc::ScenarioCard[]diagramsdoc::Diagram[]diagnosticsdoc::SectionDiagnostic[]RECORDRelGrouptitlestringitemsdoc::RelItem[]RECORDScenarioCardnamestringsummarystringextendedstringtagsstring[]stepsdoc::Step[]flowdoc::DiagramUNIONDiagramSvgEmptyRECORDSectionDiagnosticseveritystringcodestringcodeUrlstringmessagestringlinenumber
data

NodeUrl #

public
doc::NodeUrl

A resolved cross-reference target: the module page it lives on and its in-page +to the node (rendered as inline badges).

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeSectionidstringkindstringnamestringfqnstringvisibilitystringsummarystringextendedstringtagsstring[]relationshipsdoc::RelGroup[]scenariosdoc::ScenarioCard[]diagramsdoc::Diagram[]diagnosticsdoc::SectionDiagnostic[]RECORDRelGrouptitlestringitemsdoc::RelItem[]RECORDScenarioCardnamestringsummarystringextendedstringtagsstring[]stepsdoc::Step[]flowdoc::DiagramUNIONDiagramSvgEmptyRECORDSectionDiagnosticseveritystringcodestringcodeUrlstringmessagestringlinenumber
data

NodeUrl #

public
doc::NodeUrl

A resolved cross-reference target: the module page it lives on and its in-page anchor id. A cross-link uses these to build an `href`; an unresolved FQN has no entry and renders as plain text.

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeUrlpagestringanchorstring
data

PageBody #

public
doc::PageBody

The page body: the landing index, one authored doc page, one module's page, the 3D universe, or the architecture-health report.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
UNIONPageBodyIndexPageDocBodyModulePageUniversePageHealthPageRECORDIndexPagetitlestringcontextDiagramdoc::Diagramcardsdoc::ModuleCard[]statsdoc::SiteStatsRECORDDocBodytitlestringhtmlstringRECORDModulePagenamestringsectionsdoc::NodeSection[]RECORDUniversePagenodesuniverse::NodeOut[]edgesuniverse::EdgeOut[]flowsuniverse::FlowDef[]hrefsdoc::NodeHref[]RECORDHealthPageentriesdoc::HealthEntry[]errorCountnumberwarningCountnumber
data

PageProps #

public
doc::PageProps

The serialisable model for one page, handed to the Svelte server renderer. @@ -82,23 +82,23 @@ also embedded in the document, for its 3D island — every other page ships no page data.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDPagePropssitedoc::SiteInfodocGroupsdoc::SidebarDocGroup[]sidebardoc::SidebarModule[]navdoc::NavLink[]crumbsdoc::Crumb[]pagedoc::PageBodyRECORDSiteInfonamestringthemestringlogoFilenamestringprefixstringRECORDSidebarDocGrouptitlestringitemsdoc::SidebarDocItem[]RECORDSidebarModulelabelstringhrefstringnodesdoc::SidebarNode[]RECORDNavLinklabelstringhrefstringbadgestringRECORDCrumblabelstringhrefstringUNIONPageBodyIndexPageDocBodyModulePageUniversePageHealthPage
component

Pages #

private
doc::Pages

Projects the resolved graph into per-page `PageProps` — pure data, no markup. Builds the index props (title, context diagram, module cards), each module page's -node sections, and the depth-prefixed sidebar tree mirroring the C4 hierarchy.

Parent

Inbound

Outbound

Scenarios

UniversePageShipsStructureAndFlows

The universe page ships the 3D structure and its flows.

  • given a resolved model with entry-point flows
  • when the universe page is built
  • then the flat snapshot, the traced flows, and each node's documentation href are embedded
  • and the 3D island lays the graph out in the browser and links spheres to their docs
  • but a browser without WebGL keeps the server-rendered fallback listing
Flow Flow — UniversePageShipsStructureAndFlows scroll to zoom · drag to pan
FEATUREUniversePageShipsStructureAndFlowsfor PagesGIVENa resolved model with entry-pointflowsWHENthe universe page is builtTHENthe flat snapshot, the traced flows,and each node's documentation href areembeddedANDthe 3D island lays the graph out inthe browser and links spheres to theirdocsBUTa browser without WebGL keeps theserver-rendered fallback listing
SidebarMirrorsHierarchy

The sidebar tree mirrors the C4 hierarchy.

  • given modules whose nodes nest containers, components, and declarations
  • when the sidebar is rendered
  • then each module holds its top-level nodes and every node nests its same-module children
Flow Flow — SidebarMirrorsHierarchy scroll to zoom · drag to pan
FEATURESidebarMirrorsHierarchyfor PagesGIVENmodules whose nodes nest containers,components, and declarationsWHENthe sidebar is renderedTHENeach module holds its top-level nodesand every node nests its same-modulechildren
data

RelGroup #

public
doc::RelGroup

One relationship group ("Parent", "Inbound", or "Outbound") and its endpoints.

Entities Entity diagram scroll to zoom · drag to pan
RECORDRelGrouptitlestringitemsdoc::RelItem[]RECORDRelItemedgeKindstringarrowboolfqnstringhrefstringlabelstring
data

RelItem #

public
doc::RelItem

One relationship endpoint: the edge-kind word, whether to draw the outbound +node sections, and the depth-prefixed sidebar tree mirroring the C4 hierarchy.

Parent

Inbound

Outbound

Scenarios

UniversePageShipsStructureAndFlows

The universe page ships the 3D structure and its flows.

  • given a resolved model with entry-point flows
  • when the universe page is built
  • then the flat snapshot, the traced flows, and each node's documentation href are embedded
  • and the 3D island lays the graph out in the browser and links spheres to their docs
  • but a browser without WebGL keeps the server-rendered fallback listing
Flow Flow — UniversePageShipsStructureAndFlows scroll to zoom · drag to pan
FEATUREUniversePageShipsStructureAndFlowsfor PagesGIVENa resolved model with entry-pointflowsWHENthe universe page is builtTHENthe flat snapshot, the traced flows,and each node's documentation href areembeddedANDthe 3D island lays the graph out inthe browser and links spheres to theirdocsBUTa browser without WebGL keeps theserver-rendered fallback listing
SidebarMirrorsHierarchy

The sidebar tree mirrors the C4 hierarchy.

  • given modules whose nodes nest containers, components, and declarations
  • when the sidebar is rendered
  • then each module holds its top-level nodes and every node nests its same-module children
Flow Flow — SidebarMirrorsHierarchy scroll to zoom · drag to pan
FEATURESidebarMirrorsHierarchyfor PagesGIVENmodules whose nodes nest containers,components, and declarationsWHENthe sidebar is renderedTHENeach module holds its top-level nodesand every node nests its same-modulechildren
data

RelGroup #

public
doc::RelGroup

One relationship group ("Parent", "Inbound", or "Outbound") and its endpoints.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDRelGrouptitlestringitemsdoc::RelItem[]RECORDRelItemedgeKindstringarrowboolfqnstringhrefstringlabelstring
data

RelItem #

public
doc::RelItem

One relationship endpoint: the edge-kind word, whether to draw the outbound arrow, the endpoint FQN, its resolved href (absent → plain text), and any label.

Entities Entity diagram scroll to zoom · drag to pan
RECORDRelItemedgeKindstringarrowboolfqnstringhrefstringlabelstring
component

Relationships #

private
doc::Relationships

Renders a node's relationships (LANG.md §9.3): its `for`/owner parent, inbound edges, and outbound edges, skipping the structural `for`-parent edge kind. Each -endpoint is a cross-link when its FQN resolves, plain text otherwise.

Parent

Inbound

Outbound

data

RenderError #

public
doc::RenderError

Why server-rendering a page failed. Every variant is a defect in the bundle, the +endpoint is a cross-link when its FQN resolves, plain text otherwise.

Parent

Inbound

Outbound

data

RenderError #

public
doc::RenderError

Why server-rendering a page failed. Every variant is a defect in the bundle, the engine, or the props codec — never user model data; well-formed props always render.

Entities Entity diagram scroll to zoom · drag to pan
UNIONRenderErrorEngineCallCodecRECORDEnginemessagestringRECORDCallmessagestringRECORDCodecmessagestring
data

RenderedPage #

public
doc::RenderedPage

The server-render result for one page: the `<svelte:head>` contents and the rendered body markup, dropped into the document shell.

Entities Entity diagram scroll to zoom · drag to pan
RECORDRenderedPageheadstringbodystring
data

ScenarioCard #

public
doc::ScenarioCard

One BDD scenario card: name, `///` docs, tags, the ordered steps, and the feature's flow figure (LANG.md §9.5).

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDScenarioCardnamestringsummarystringextendedstringtagsstring[]stepsdoc::Step[]flowdoc::DiagramRECORDStepkeywordstringtextstringUNIONDiagramSvgEmpty
component

Scenarios #

private
doc::Scenarios

Renders the BDD scenario cards on a node's page: each `feature` targeting the node becomes its given/when/then steps and its flow figure as a card (LANG.md §5.2, -§9.3, §9.5). Empty when the node has no features.

Parent

Inbound

Outbound

Scenarios

RenderScenarioCards

Feature scenarios render on their target node's page (§9.3).

  • given a model whose nodes carry `feature` scenarios
  • when the site is generated
  • then each node's page lists its scenarios as given/when/then cards
  • but a node with no features renders no scenarios section
Flow Flow — RenderScenarioCards scroll to zoom · drag to pan
FEATURERenderScenarioCardsfor ScenariosGIVENa model whose nodes carry `feature`scenariosWHENthe site is generatedTHENeach node's page lists its scenariosas given/when/then cardsBUTa node with no features renders noscenarios section
data

SearchEntry #

public
doc::SearchEntry

One record in the static full-text search index: the symbol or page's FQN, +§9.3, §9.5). Empty when the node has no features.

Parent

Inbound

Outbound

Scenarios

RenderScenarioCards

Feature scenarios render on their target node's page (§9.3).

  • given a model whose nodes carry `feature` scenarios
  • when the site is generated
  • then each node's page lists its scenarios as given/when/then cards
  • but a node with no features renders no scenarios section
Flow Flow — RenderScenarioCards scroll to zoom · drag to pan
FEATURERenderScenarioCardsfor ScenariosGIVENa model whose nodes carry `feature`scenariosWHENthe site is generatedTHENeach node's page lists its scenariosas given/when/then cardsBUTa node with no features renders noscenarios section
data

SearchEntry #

public
doc::SearchEntry

One record in the static full-text search index: the symbol or page's FQN, display name, kind word, one-line summary, plain-text body, declaring module, and root-relative href. Sorted by href then FQN so the index is -deterministic.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDSearchEntryfqnstringnamestringkindstringsummarystringtextstringmodulestringhrefstring
component

SearchIndex #

private
doc::SearchIndex

Builds the static full-text search index the client palette queries: one +deterministic.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSearchEntryfqnstringnamestringkindstringsummarystringtextstringmodulestringhrefstring
component

SearchIndex #

private
doc::SearchIndex

Builds the static full-text search index the client palette queries: one record per linkable node, module page, and authored doc page, plus the universe and health pages. Shipped as a classic-script JS assignment (`search-index.js` setting a window global) so it loads under `file://` — -never fetched.

Parent

Inbound

Outbound

Scenarios

SearchIndexIsStatic

The search index is static and file://-safe.

  • given a generated site
  • when the search palette opens
  • then the index loads as a classic script setting a window global, never fetched
  • and entries cover nodes, modules, authored docs, and the universe and health pages
  • and the index is sorted and deterministic
Flow Flow — SearchIndexIsStatic scroll to zoom · drag to pan
FEATURESearchIndexIsStaticfor SearchIndexGIVENa generated siteWHENthe search palette opensTHENthe index loads as a classic scriptsetting a window global, never fetchedANDentries cover nodes, modules, authoreddocs, and the universe and healthpagesANDthe index is sorted and deterministic
data

SectionDiagnostic #

public
doc::SectionDiagnostic

One inline badge on a node's section: the severity, rule code, article URL, +never fetched.

Parent

Inbound

Outbound

Scenarios

SearchIndexIsStatic

The search index is static and file://-safe.

  • given a generated site
  • when the search palette opens
  • then the index loads as a classic script setting a window global, never fetched
  • and entries cover nodes, modules, authored docs, and the universe and health pages
  • and the index is sorted and deterministic
Flow Flow — SearchIndexIsStatic scroll to zoom · drag to pan
FEATURESearchIndexIsStaticfor SearchIndexGIVENa generated siteWHENthe search palette opensTHENthe index loads as a classic scriptsetting a window global, never fetchedANDentries cover nodes, modules, authoreddocs, and the universe and healthpagesANDthe index is sorted and deterministic
data

SectionDiagnostic #

public
doc::SectionDiagnostic

One inline badge on a node's section: the severity, rule code, article URL, message, and source line of a finding attributed to that node.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDSectionDiagnosticseveritystringcodestringcodeUrlstringmessagestringlinenumber
component

Shell #

private
doc::Shell

Owns the document shell that wraps each server-rendered body — the part Rust renders, not Svelte: doctype, `<html data-theme>`, font + stylesheet links, the theme pre-paint script, and the classic deferred scripts. Scripts are @@ -106,19 +106,19 @@ the site works opened from disk (`file://`). Only the universe page embeds its props (`window.__DATA__`) — for its 3D island; every other page ships no page data and the client only progressively enhances.

#app

Parent

Inbound

Outbound

Scenarios

OnlyUniverseEmbedsData

Only the universe page carries page data; everything else is pure SSR.

  • given a generated site
  • when the document shells are assembled
  • then the universe page embeds its props as window.__DATA__ for the 3D island
  • and every script is a classic deferred script so the site works from file://
  • but no other page embeds page data — the client only progressively enhances
Flow Flow — OnlyUniverseEmbedsData scroll to zoom · drag to pan
FEATUREOnlyUniverseEmbedsDatafor ShellGIVENa generated siteWHENthe document shells are assembledTHENthe universe page embeds its props aswindow.__DATA__ for the 3D islandANDevery script is a classic deferredscript so the site works from file://BUTno other page embeds page data — theclient only progressively enhances
SystemThemeFollowsOs

The theme follows the OS by default, overridable in-page and in config.

  • given a DocConfig carrying the system theme
  • when the document shell is rendered
  • then a pre-paint script applies the stored preference, else the OS scheme, else the configured default
  • and diagram SVGs follow the active scheme through the --pds-* variables
  • but a light or dark config pins the default without removing the toggle
Flow Flow — SystemThemeFollowsOs scroll to zoom · drag to pan
FEATURESystemThemeFollowsOsfor ShellGIVENa DocConfig carrying the system themeWHENthe document shell is renderedTHENa pre-paint script applies the storedpreference, else the OS scheme, elsethe configured defaultANDdiagram SVGs follow the active schemethrough the --pds-* variablesBUTa light or dark config pins thedefault without removing the toggle
data

SidebarDocGroup #

public
doc::SidebarDocGroup

One `[[doc.sidebar]]` group in the authored-doc navigation: a heading and its -page links, shown above the module tree.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDSidebarDocGrouptitlestringitemsdoc::SidebarDocItem[]RECORDSidebarDocItemtitlestringhrefstring
data

SidebarDocItem #

public
doc::SidebarDocItem

One authored doc-page link in the sidebar: its title and the page href, already +page links, shown above the module tree.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSidebarDocGrouptitlestringitemsdoc::SidebarDocItem[]RECORDSidebarDocItemtitlestringhrefstring
data

SidebarDocItem #

public
doc::SidebarDocItem

One authored doc-page link in the sidebar: its title and the page href, already prefixed for the page's depth.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSidebarDocItemtitlestringhrefstring
data

SidebarModule #

public
doc::SidebarModule

One sidebar entry: a module-page link and its node tree, hrefs already prefixed -for the page's depth.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDSidebarModulelabelstringhrefstringnodesdoc::SidebarNode[]RECORDSidebarNodenamestringfqnstringkindstringhrefstringchildrendoc::SidebarNode[]
data

SidebarNode #

public
doc::SidebarNode

One node in the sidebar tree, recursing into its same-module children.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSidebarNodenamestringfqnstringkindstringhrefstringchildrendoc::SidebarNode[]
data

Site #

public
doc::Site

The whole generated site as in-memory files, in deterministic order: the index, +for the page's depth.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSidebarModulelabelstringhrefstringnodesdoc::SidebarNode[]RECORDSidebarNodenamestringfqnstringkindstringhrefstringchildrendoc::SidebarNode[]
data

SidebarNode #

public
doc::SidebarNode

One node in the sidebar tree, recursing into its same-module children.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSidebarNodenamestringfqnstringkindstringhrefstringchildrendoc::SidebarNode[]
data

Site #

public
doc::Site

The whole generated site as in-memory files, in deterministic order: the index, one page per authored doc (`[[doc.sidebar]]`, in declaration order), then one page per module sorted by FQN, plus the shared assets. The doc crate does no I/O; the CLI writes each file under the configured output directory.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSitefilesdoc::SiteFile[]RECORDSiteFilepathstringcontentsstring
component

SiteBuilder #

private
doc::SiteBuilder

Orchestrates the whole site: build the URL map, project each page's props, server render it through the SSR engine, wrap it in the document shell, and ship the shared assets plus the search index. Pure: returns in-memory `Site` files, -writes none.

Parent

Inbound

Outbound

Scenarios

DeterministicGeneration

Generation is deterministic and pure.

  • given the same resolved graph and configuration rendered twice
  • when the two sites are compared
  • then modules and nodes are ordered by FQN with no clock or randomness consulted
  • and the file lists are byte-for-byte identical
Flow Flow — DeterministicGeneration scroll to zoom · drag to pan
FEATUREDeterministicGenerationfor SiteBuilderGIVENthe same resolved graph andconfiguration rendered twiceWHENthe two sites are comparedTHENmodules and nodes are ordered by FQNwith no clock or randomness consultedANDthe file lists are byte-for-byteidentical
data

SiteFile #

public
doc::SiteFile

One generated file: a site-root-relative `/`-separated path (`index.html`, +writes none.

Parent

Inbound

Outbound

Scenarios

DeterministicGeneration

Generation is deterministic and pure.

  • given the same resolved graph and configuration rendered twice
  • when the two sites are compared
  • then modules and nodes are ordered by FQN with no clock or randomness consulted
  • and the file lists are byte-for-byte identical
Flow Flow — DeterministicGeneration scroll to zoom · drag to pan
FEATUREDeterministicGenerationfor SiteBuilderGIVENthe same resolved graph andconfiguration rendered twiceWHENthe two sites are comparedTHENmodules and nodes are ordered by FQNwith no clock or randomness consultedANDthe file lists are byte-for-byteidentical
data

SiteFile #

public
doc::SiteFile

One generated file: a site-root-relative `/`-separated path (`index.html`, `module/banking.core.html`, `style.css`, `client.js`) and its complete contents.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDSiteFilepathstringcontentsstring
data

SiteInfo #

public
doc::SiteInfo

Site-wide presentation, identical across pages: the title, the `light`/`dark`/`system` theme word, the optional logo filename, and the `../` prefix to the site root for this page's depth.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSiteInfonamestringthemestringlogoFilenamestringprefixstring
data

SiteStats #

public
doc::SiteStats

The index page's stats strip: how many systems, containers, components, -flows, and health findings the model carries.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDSiteStatssystemsnumbercontainersnumbercomponentsnumberflowsnumberfindingsnumber
component

Ssr #

private
doc::Ssr

The server-side render boundary: a JSON-string-in / JSON-string-out seam to the +flows, and health findings the model carries.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSiteStatssystemsnumbercontainersnumbercomponentsnumberflowsnumberfindingsnumber
component

Ssr #

private
doc::Ssr

The server-side render boundary: a JSON-string-in / JSON-string-out seam to the JavaScript renderer. The native build embeds a `QuickJS` engine that evaluates the prebuilt `ssr.js` bundle (`Doc::Assets`) in-process; a wasm host implements the same seam against its own JS engine. A defect here is a build-asset fault, never @@ -128,7 +128,7 @@ `Dark` pin the scheme.

Entities Entity diagram scroll to zoom · drag to pan
UNIONThemeLightDarkSystem
data

UniversePage #

public
doc::UniversePage
Entities Entity diagram scroll to zoom · drag to pan
RECORDUniversePagenodesuniverse::NodeOut[]edgesuniverse::EdgeOut[]flowsuniverse::FlowDef[]hrefsdoc::NodeHref[]RECORDNodeOutidstringlevelstringparentstringRECORDEdgeOutsourcestringtostringtrafficnumberRECORDFlowDeffqnstringnamestringcolorstringhopsuniverse::FlowHop[]RECORDNodeHrefidstringhrefstring
component

Urls #

private
doc::Urls

Maps every node FQN to its page path and anchor, and resolves cross-references to module-page-relative `href`s. A module page is `module/<dotted-fqn>.html` (`::` → `.`); a node is the `#<slug>` anchor within it. Only an FQN naming a real -node produces a link (LANG.md §9.3).

Parent

Inbound

Outbound

  • from doc::Result
  • from doc::Result

Scenarios

CrossLinksResolve

Cross-links resolve to anchors; unresolved references stay plain text.

  • given a relationship endpoint named by FQN
  • when the link is rendered
  • then an FQN naming a real node becomes an anchor link to its section
  • but an unresolved or synthesised endpoint renders as plain text
Flow Flow — CrossLinksResolve scroll to zoom · drag to pan
FEATURECrossLinksResolvefor UrlsGIVENa relationship endpoint named by FQNWHENthe link is renderedTHENan FQN naming a real node becomes ananchor link to its sectionBUTan unresolved or synthesised endpointrenders as plain text
Generated by pds doc.
+node produces a link (LANG.md §9.3).

Parent

Inbound

Outbound

  • from doc::Result

Scenarios

CrossLinksResolve

Cross-links resolve to anchors; unresolved references stay plain text.

  • given a relationship endpoint named by FQN
  • when the link is rendered
  • then an FQN naming a real node becomes an anchor link to its section
  • but an unresolved or synthesised endpoint renders as plain text
Flow Flow — CrossLinksResolve scroll to zoom · drag to pan
FEATURECrossLinksResolvefor UrlsGIVENa relationship endpoint named by FQNWHENthe link is renderedTHENan FQN naming a real node becomes ananchor link to its sectionBUTan unresolved or synthesised endpointrenders as plain text
Generated by pds doc.
diff --git a/model/site/module/dot.html b/model/site/module/dot.html index 024bc476..47951380 100644 --- a/model/site/module/dot.html +++ b/model/site/module/dot.html @@ -11,7 +11,7 @@ -
PseudoScript
Module

dot

data

Box2 #

private
dot::Box2

An axis-aligned box: top-left corner and extent.

Entities Entity diagram scroll to zoom · drag to pan
RECORDBox2xnumberynumberwnumberhnumber
data

Cluster #

private
dot::Cluster

A cluster (a `subgraph cluster_*`): its id, optional parent cluster, member +

PseudoScript
Module

dot

data

Box2 #

private
dot::Box2

An axis-aligned box: top-left corner and extent.

Entities Entity diagram scroll to zoom · drag to pan
RECORDBox2xnumberynumberwnumberhnumber
data

Cluster #

private
dot::Cluster

A cluster (a `subgraph cluster_*`): its id, optional parent cluster, member node ids, the margin kept outside its members, and the header band reserved on the title side.

Entities Entity diagram scroll to zoom · drag to pan
RECORDClusteridstringparentstringmembersstring[]marginnumberheadernumber
data

ClusterBox #

private
dot::ClusterBox

A laid-out cluster: its id and bounding box.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDClusterBoxidstringbboxdot::Box2RECORDBox2xnumberynumberwnumberhnumber
component

Clusters #

public
dot::Clusters

Cluster framing: compute each cluster's bounding box bottom-up so a nested cluster's box encloses its children (grown by their margins) and its direct @@ -23,7 +23,7 @@ `tail` and `head`, plus where its label sits.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDEdgeRoutetailstringheadstringsplinedot::Pt[]polylinedot::Pt[]labelPosdot::PtRECORDPtxnumberynumber
component

Engine #

private
dot::Engine

The layered engine: runs the faithful four-pass `dot` pipeline — rank, order, position, splines — then frames the clusters and shifts the whole layout to the origin. Deterministic and panic-free.

Parent

Inbound

Outbound

Scenarios

FaithfulFourPassPipeline

The pipeline is a faithful four-pass port, run in order.

  • given an input graph of sized nodes, edges, and clusters
  • when the graph is laid out
  • then ranks are assigned, nodes ordered within ranks, x-coordinates placed, and edges routed as splines
  • and the passes run in dot's order: rank, then order, then position, then splines
Flow Flow — FaithfulFourPassPipeline scroll to zoom · drag to pan
FEATUREFaithfulFourPassPipelinefor EngineGIVENan input graph of sized nodes, edges,and clustersWHENthe graph is laid outTHENranks are assigned, nodes orderedwithin ranks, x-coordinates placed,and edges routed as splinesANDthe passes run in dot's order: rank,then order, then position, thensplines
DeterministicAndPanicFree

Layout is deterministic and never panics.

  • given the same input graph laid out twice
  • when the layouts are compared
  • then the placements are identical
  • and an empty graph yields an empty layout
  • but no input — however extreme its rank spans — panics or hangs
Flow Flow — DeterministicAndPanicFree scroll to zoom · drag to pan
FEATUREDeterministicAndPanicFreefor EngineGIVENthe same input graph laid out twiceWHENthe layouts are comparedTHENthe placements are identicalANDan empty graph yields an empty layoutBUTno input — however extreme its rankspans — panics or hangs
data

Graph #

public
dot::Graph

The input graph the engine lays out: nodes, edges, clusters, the rank and node -separations, the rank direction, and any same-rank constraints.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDGraphnodesdot::Node[]edgesdot::Edge[]clustersdot::Cluster[]ranksepnumbernodesepnumberrankdirdot::RankDirsameRankstring[]RECORDNodeidstringwidthnumberheightnumberRECORDEdgetailstringheadstringminlennumberweightnumberlabeldot::SizeRECORDClusteridstringparentstringmembersstring[]marginnumberheadernumberUNIONRankDirTopBottomLeftRight
component

Grid #

public
dot::Grid

The experimental grid placer: an alternative to the layered pipeline that +separations, the rank direction, and any same-rank constraints.

Entities Entity diagram scroll to zoom · drag to pan
RECORDGraphnodesdot::Node[]edgesdot::Edge[]clustersdot::Cluster[]ranksepnumbernodesepnumberrankdirdot::RankDirsameRankstring[]RECORDNodeidstringwidthnumberheightnumberRECORDEdgetailstringheadstringminlennumberweightnumberlabeldot::SizeRECORDClusteridstringparentstringmembersstring[]marginnumberheadernumberUNIONRankDirTopBottomLeftRight
component

Grid #

public
dot::Grid

The experimental grid placer: an alternative to the layered pipeline that snaps nodes to a grid, honouring drag-to-pin cells and searching for a placement that minimises crossings, distance, and against-flow edges.

Parent

Inbound

Scenarios

GridPlacerHonoursPins

The grid placer honours pinned cells while it searches.

  • given a graph and a set of drag-to-pin cells
  • when the experimental grid placer runs
  • then each pinned node stays in its cell
  • and the remaining nodes are placed to minimise crossings, distance, and against-flow edges
Flow Flow — GridPlacerHonoursPins scroll to zoom · drag to pan
FEATUREGridPlacerHonoursPinsfor GridGIVENa graph and a set of drag-to-pin cellsWHENthe experimental grid placer runsTHENeach pinned node stays in its cellANDthe remaining nodes are placed tominimise crossings, distance, andagainst-flow edges
data

GridMeta #

private
dot::GridMeta

Grid metadata carried back when the experimental grid placer ran: the grid dimensions, the cell pitch (centre-to-centre), the pixel centre of cell (0,0), @@ -36,7 +36,7 @@ metadata.

Entities Entity diagram scroll to zoom · drag to pan
RECORDLayoutbboxdot::Box2nodesdot::NodePos[]edgesdot::EdgeRoute[]clustersdot::ClusterBox[]gridOption<dot::GridMeta>RECORDBox2xnumberynumberwnumberhnumberRECORDNodePosidstringcenterdot::PtwidthnumberheightnumberRECORDEdgeRoutetailstringheadstringsplinedot::Pt[]polylinedot::Pt[]labelPosdot::PtRECORDClusterBoxidstringbboxdot::Box2
data

LayoutState #

public
dot::LayoutState

The structure that flows through a pipeline: the (possibly pass-mutated) input graph and its current placement. A pass receives one, returns one, and the framework hands it to the next pass; a re-ranking pass may edit `graph` -and re-run the base layout.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDLayoutStategraphdot::Graphlayoutdot::LayoutRECORDGraphnodesdot::Node[]edgesdot::Edge[]clustersdot::Cluster[]ranksepnumbernodesepnumberrankdirdot::RankDirsameRankstring[]RECORDLayoutbboxdot::Box2nodesdot::NodePos[]edgesdot::EdgeRoute[]clustersdot::ClusterBox[]gridOption<dot::GridMeta>
data

Node #

private
dot::Node

An input node: its id and its rendered size (the placer reserves this box).

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeidstringwidthnumberheightnumber
data

NodePos #

private
dot::NodePos

A placed node: its id, centre point, and reserved size.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodePosidstringcenterdot::PtwidthnumberheightnumberRECORDPtxnumberynumber
component

Optimize #

public
dot::Optimize

The `ShortenLongEdges` pass: a bounded, deterministic post-layout refinement. +and re-run the base layout.

Entities Entity diagram scroll to zoom · drag to pan
RECORDLayoutStategraphdot::Graphlayoutdot::LayoutRECORDGraphnodesdot::Node[]edgesdot::Edge[]clustersdot::Cluster[]ranksepnumbernodesepnumberrankdirdot::RankDirsameRankstring[]RECORDLayoutbboxdot::Box2nodesdot::NodePos[]edgesdot::EdgeRoute[]clustersdot::ClusterBox[]gridOption<dot::GridMeta>
data

Node #

private
dot::Node

An input node: its id and its rendered size (the placer reserves this box).

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeidstringwidthnumberheightnumber
data

NodePos #

private
dot::NodePos

A placed node: its id, centre point, and reserved size.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodePosidstringcenterdot::PtwidthnumberheightnumberRECORDPtxnumberynumber
component

Optimize #

public
dot::Optimize

The `ShortenLongEdges` pass: a bounded, deterministic post-layout refinement. Greedily search for same-rank moves that reduce the sum of squared edge lengths (never merging across a cluster boundary), then re-lay-out with the improving moves applied.

Parent

component

Oracle #

private
dot::Oracle

The test oracle: lays the same graph out with the real `dot` binary and @@ -50,7 +50,7 @@ caller resolves the FQN) at a row and column. The IDE's drag-to-pin.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPinnodenumberrownumbercolnumber
component

Pipeline #

public
dot::Pipeline

The composable post-layout pipeline: the base layout produces the starting `LayoutState`; each `Pass` folds it into the next. A pass adjusts geometry directly or edits the input graph (e.g. adds same-rank hints) and re-runs the -base layout.

Parent

Inbound

Outbound

component

Position #

public
dot::Position

Pass 3 — positioning: assign x-coordinates by network simplex on an auxiliary +base layout.

Parent

Inbound

component

Position #

public
dot::Position

Pass 3 — positioning: assign x-coordinates by network simplex on an auxiliary graph (aligning nodes and straightening long edges), and y-coordinates per rank stacked with `ranksep` plus any label and cluster-header room.

Parent

Inbound

Outbound

data

Pt #

private
dot::Pt

A point in layout coordinates.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPtxnumberynumber
component

Rank #

public
dot::Rank

Pass 1 — rank assignment: give each node an integer rank by network simplex, banding each cluster onto contiguous ranks and honouring same-rank constraints.

Parent

Inbound

Outbound

  • from dot::string
data

RankDir #

private
dot::RankDir

The rank direction: top-to-bottom (the C4 default) or left-to-right.

Entities Entity diagram scroll to zoom · drag to pan
UNIONRankDirTopBottomLeftRight
data

SearchMode #

private
dot::SearchMode

How the experimental grid placer searches for a placement: pick automatically diff --git a/model/site/module/emit.html b/model/site/module/emit.html index 300401eb..ca74cbf3 100644 --- a/model/site/module/emit.html +++ b/model/site/module/emit.html @@ -11,7 +11,7 @@ -

PseudoScript
Module

emit

data

BoundaryFrame #

private
emit::BoundaryFrame

An enclosing frame of a boundary view: the boundary node's FQN (so the canvas +

PseudoScript
Module

emit

data

BoundaryFrame #

private
emit::BoundaryFrame

An enclosing frame of a boundary view: the boundary node's FQN (so the canvas can drill into it), title, C4 kind (frame accent), and the cluster rectangle.

Entities Entity diagram scroll to zoom · drag to pan
RECORDBoundaryFramefqnstringtitlestringkindstringrectemit::RectRECORDRectxnumberynumberwnumberhnumber
data

C4EdgeKind #

private
emit::C4EdgeKind

The relationship a routed edge expresses: a body `call`, a synthesised `trigger` from an initiator, or a `from` `provenance` link. Maps from `model::EdgeKind`, dropping the structural `for`-parent link.

Entities Entity diagram scroll to zoom · drag to pan
UNIONC4EdgeKindCallTriggerProvenanceRECORDCallmessagestringUNIONTriggerOnEventScheduleHttpManual
data

C4Layout #

public
emit::C4Layout

A dot-placed C4 view for the interactive canvas and the static SVG: canvas @@ -25,7 +25,7 @@ referencing and referenced FQNs and the field driving the reference.

Entities Entity diagram scroll to zoom · drag to pan
RECORDDataLinksourcestringtostringfieldstring
data

DataScene #

public
emit::DataScene
Entities Entity diagram scroll to zoom · drag to pan
RECORDDataSceneofstringentitiesemit::DataEntity[]linksemit::DataLink[]widthnumberheightnumberRECORDDataEntityfqnstringlabelstringformemit::EntityFormrowsemit::EntityRow[]focalboolrectemit::RectRECORDDataLinksourcestringtostringfieldstring
component

Edges #

private
emit::Edges

Builds the routed-edge set for a C4 scene from the graph's edges: maps each `model::EdgeKind` to a `C4EdgeKind` (dropping `for`-parent links), lifts each endpoint to the in-view node it belongs to, drops self-loops and -out-of-view edges, then sorts and de-duplicates.

Parent

Inbound

Outbound

container

Emit #

public
emit::Emit

`crates/pseudoscript-emit`. Projects a view into a `Scene` and renders it to +out-of-view edges, then sorts and de-duplicates.

Parent

Inbound

Outbound

container

Emit #

public
emit::Emit

`crates/pseudoscript-emit`. Projects a view into a `Scene` and renders it to SVG; C4 views are placed by the `dot` layered engine, the sequence/data/feature views by the matching `layout` engine.

#headline

Inbound

Outbound

Scenarios

ProjectAView

A view projects to a notation-neutral scene, then to SVG.

  • given a resolved graph and a chosen view
  • when the view is projected
  • then the relevant nodes and edges are selected and laid out into a Scene
  • and the Scene renders to standalone SVG
  • but a missing or wrong-kind target fails with an EmitError
Flow Flow — ProjectAView scroll to zoom · drag to pan
FEATUREProjectAViewfor EmitGIVENa resolved graph and a chosen viewWHENthe view is projectedTHENthe relevant nodes and edges areselected and laid out into a SceneANDthe Scene renders to standalone SVGBUTa missing or wrong-kind target failswith an EmitError
SceneIsDeterministic

The Scene IR is the conformance surface: notation-neutral and deterministic.

  • given the same resolved graph and view projected twice
  • when the scenes are compared
  • then node order is source-declaration order
  • and parallel edges merge into one multi-label edge, sorted by from, to, then kind
  • but renderer coordinates never appear in the golden
Flow Flow — SceneIsDeterministic scroll to zoom · drag to pan
FEATURESceneIsDeterministicfor EmitGIVENthe same resolved graph and viewprojected twiceWHENthe scenes are comparedTHENnode order is source-declaration orderANDparallel edges merge into onemulti-label edge, sorted by from, to,then kindBUTrenderer coordinates never appear inthe golden
Components Component diagram scroll to zoom · drag to pan
PseudoscriptEmitCOMPONENTProjectorProjects a `View` out of the graph (LANG.md§9): dispatches on the view variant,…COMPONENTEdgesBuilds the routed-edge set for a C4 scenefrom the graph's edges: maps each…COMPONENTTraceWalks a callable's body trace into orderedsequence items, registering each participan…COMPONENTLayoutAssigns geometry. Projection stamps each C4scene with simple row-flow coordinates…COMPONENTSvgRendererRenders a laid-out `Scene` to standalone SVGmarkup — string-building, no template engin…CONTAINERDoc`crates/pseudoscript-doc`. Turns a resolvedgraph into a Svelte-rendered,…CONTAINERDot`crates/pseudoscript-dot`. Runs thefour-pass layered pipeline over a `Graph` t…CONTAINERLayout`crates/pseudoscript-layout`. Thegeometry/text `Core` and the sequence…CONTAINERUniverse`crates/pseudoscript-universe`. Maps theresolved C4 model into the software graph…flowsfromModelsnapshotgridLayoutrunPipelinelayoutcollectsolveC4blackBoxwalk
data

EmitError #

public
emit::EmitError

Why projecting a view failed: the target FQN names no node, or names a node of the wrong kind for the requested view.

Entities Entity diagram scroll to zoom · drag to pan
UNIONEmitErrorUnknownNodeWrongKindRECORDUnknownNodefqnstringRECORDWrongKindfqnstringexpectedstringfoundstring
data

EntityForm #

private
emit::EntityForm

The disclosed form of a data entity, driving the card's eyebrow and rows: a @@ -50,35 +50,36 @@ carries. The real placement runs at render/canvas time: `layoutC4` drives the `dot` layered engine (rank/order/position/splines), framing boundary children as a cluster, tuned by per-diagram `C4Tweaks` and drag-to-pin cells. The -sequence/data/feature scenes are placed by the matching `layout` engine.

Parent

Inbound

Outbound

Scenarios

LayoutDelegatesToDot

C4 layout is delegated to the `dot` layered engine.

  • given a projected C4 scene
  • when the scene is laid out
  • then it is translated into a dot input graph and placed by the dot layered engine
  • and a boundary view's children are framed as a dot cluster
  • but the engine tolerates cycles and never panics, so the placement stays deterministic
Flow Flow — LayoutDelegatesToDot scroll to zoom · drag to pan
FEATURELayoutDelegatesToDotfor LayoutGIVENa projected C4 sceneWHENthe scene is laid outTHENit is translated into a dot inputgraph and placed by the dot layeredengineANDa boundary view's children are framedas a dot clusterBUTthe engine tolerates cycles and neverpanics, so the placement staysdeterministic
TweaksAndPinsTuneC4Layout

Per-diagram tweaks and pins tune the C4 placement.

  • given a C4 scene and the UI's layout tweaks
  • when the scene is laid out with those tweaks
  • then the long-edge optimiser, reading direction, and spacing follow the tweaks
  • and under experimental grid placement, drag-to-pin cells fix their nodes
Flow Flow — TweaksAndPinsTuneC4Layout scroll to zoom · drag to pan
FEATURETweaksAndPinsTuneC4Layoutfor LayoutGIVENa C4 scene and the UI's layout tweaksWHENthe scene is laid out with thosetweaksTHENthe long-edge optimiser, readingdirection, and spacing follow thetweaksANDunder experimental grid placement,drag-to-pin cells fix their nodes
data

Lifeline #

private
emit::Lifeline

A sequence lifeline (a participant): its FQN, C4 kind for the head card, the +sequence/data/feature scenes are placed by the matching `layout` engine.

Parent

Inbound

Outbound

Scenarios

LayoutDelegatesToDot

C4 layout is delegated to the `dot` layered engine.

  • given a projected C4 scene
  • when the scene is laid out
  • then it is translated into a dot input graph and placed by the dot layered engine
  • and a boundary view's children are framed as a dot cluster
  • but the engine tolerates cycles and never panics, so the placement stays deterministic
Flow Flow — LayoutDelegatesToDot scroll to zoom · drag to pan
FEATURELayoutDelegatesToDotfor LayoutGIVENa projected C4 sceneWHENthe scene is laid outTHENit is translated into a dot inputgraph and placed by the dot layeredengineANDa boundary view's children are framedas a dot clusterBUTthe engine tolerates cycles and neverpanics, so the placement staysdeterministic
TweaksAndPinsTuneC4Layout

Per-diagram tweaks and pins tune the C4 placement.

  • given a C4 scene and the UI's layout tweaks
  • when the scene is laid out with those tweaks
  • then the long-edge optimiser, reading direction, and spacing follow the tweaks
  • and under experimental grid placement, drag-to-pin cells fix their nodes
Flow Flow — TweaksAndPinsTuneC4Layout scroll to zoom · drag to pan
FEATURETweaksAndPinsTuneC4Layoutfor LayoutGIVENa C4 scene and the UI's layout tweaksWHENthe scene is laid out with thosetweaksTHENthe long-edge optimiser, readingdirection, and spacing follow thetweaksANDunder experimental grid placement,drag-to-pin cells fix their nodes
data

Lifeline #

private
emit::Lifeline

A sequence lifeline (a participant): its FQN, C4 kind for the head card, the node's `///` summary shown dimmed under the name, and the structural ancestry path under a container/component name. No coordinate — the sequence layout -assigns the lifeline x.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDLifelinefqnstringkindstringsummarystringparentPathstring
data

Message #

private
emit::Message

A message between two lifelines (or a self-message). `label` is the method +assigns the lifeline x.

Entities Entity diagram scroll to zoom · drag to pan
RECORDLifelinefqnstringkindstringsummarystringparentPathstring
data

Message #

private
emit::Message

A message between two lifelines (or a self-message). `label` is the method name, or `Ok`/`Err`/empty for a return; `detail` is the type detail shown after it — a call's `(params): ret` signature or a return's concrete type.

Entities Entity diagram scroll to zoom · drag to pan
RECORDMessagesourcestringtostringkindemit::MessageKindlabelstringdetailstringUNIONMessageKindCallMsgReturnMsgSelfMsg
data

MessageItem #

private
emit::MessageItem
Entities Entity diagram scroll to zoom · drag to pan
RECORDMessageItemmessageemit::MessageRECORDMessagesourcestringtostringkindemit::MessageKindlabelstringdetailstring
data

MessageKind #

private
emit::MessageKind

The kind of a sequence message: a `call` to another lifeline, a `return` to the caller, or a `self`-message on the owner's own lifeline.

Entities Entity diagram scroll to zoom · drag to pan
UNIONMessageKindCallMsgReturnMsgSelfMsg
data

PlacedNode #

private
emit::PlacedNode

A node placed in a C4 view: its FQN, C4 kind, display label, optional `///` summary (the card's dimmed description), the boundary it sits inside, and the -layout rectangle assigned by the placer.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPlacedNodefqnstringkindstringlabelstringsummarystringboundarystringrectemit::RectRECORDRectxnumberynumberwnumberhnumber
data

PointI #

private
emit::PointI

An integer point on the canvas (a rounded layout coordinate).

Entities Entity diagram scroll to zoom · drag to pan
RECORDPointIxnumberynumber
component

Projector #

private
emit::Projector

Projects a `View` out of the graph (LANG.md §9): dispatches on the view +layout rectangle assigned by the placer.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPlacedNodefqnstringkindstringlabelstringsummarystringboundarystringrectemit::RectRECORDRectxnumberynumberwnumberhnumber
data

PointI #

private
emit::PointI

An integer point on the canvas (a rounded layout coordinate).

Entities Entity diagram scroll to zoom · drag to pan
RECORDPointIxnumberynumber
component

Projector #

private
emit::Projector

Projects a `View` out of the graph (LANG.md §9): dispatches on the view variant, collecting nodes and edges for a C4 scene or tracing a callable body for a sequence scene, then hands off to the placer. Fails with `EmitError` -when the view's target is missing or the wrong kind.

Parent

Inbound

Outbound

Scenarios

DispatchOnViewKind

Each view kind dispatches to its projection.

  • given a graph and a View variant
  • when project runs
  • then Context and the boundary views build a C4Scene
  • and Sequence traces the entry callable's body into a SequenceScene
  • and Data builds an entity (ER) scene and Feature builds a flow scene
Flow Flow — DispatchOnViewKind scroll to zoom · drag to pan
FEATUREDispatchOnViewKindfor ProjectorGIVENa graph and a View variantWHENproject runsTHENContext and the boundary views build aC4SceneANDSequence traces the entry callable'sbody into a SequenceSceneANDData builds an entity (ER) scene andFeature builds a flow scene
ProjectSymbolPicksAView

Project-symbol picks the view that best explains one symbol.

  • given a single symbol FQN — a callable, system, container, component, or data type
  • when the symbol is projected
  • then a callable traces as a sequence, a system or container with children shows them, a data type shows its entity view
  • and a childless boundary falls back to the view that frames it as a peer
  • and an FQN naming no graph node projects its feature flow view
  • but an FQN naming neither a node nor a feature fails with EmitError::UnknownNode
Flow Flow — ProjectSymbolPicksAView scroll to zoom · drag to pan
FEATUREProjectSymbolPicksAViewfor ProjectorGIVENa single symbol FQN — a callable,system, container, component, or datatypeWHENthe symbol is projectedTHENa callable traces as a sequence, asystem or container with childrenshows them, a data type shows itsentity viewANDa childless boundary falls back to theview that frames it as a peerANDan FQN naming no graph node projectsits feature flow viewBUTan FQN naming neither a node nor afeature fails withEmitError::UnknownNode
DataAndFeatureViews

The data and feature views project their own scene families.

  • given a Data view of a data type, or a Feature view of a scenario
  • when the view is projected
  • then the Data view collects the focal entity, its referenced types, and the links between them
  • and the Feature view lays the scenario's given/when/then steps out as a flow
Flow Flow — DataAndFeatureViews scroll to zoom · drag to pan
FEATUREDataAndFeatureViewsfor ProjectorGIVENa Data view of a data type, or aFeature view of a scenarioWHENthe view is projectedTHENthe Data view collects the focalentity, its referenced types, and thelinks between themANDthe Feature view lays the scenario'sgiven/when/then steps out as a flow
UnknownNodeFails

A missing node fails the projection.

  • given a boundary or sequence view whose target FQN names no node
  • when the view is projected
  • then projection fails with EmitError::UnknownNode
Flow Flow — UnknownNodeFails scroll to zoom · drag to pan
FEATUREUnknownNodeFailsfor ProjectorGIVENa boundary or sequence view whosetarget FQN names no nodeWHENthe view is projectedTHENprojection fails withEmitError::UnknownNode
WrongKindFails

A target of the wrong kind fails the projection.

  • given a container view whose of node is not a system
  • when the view is projected
  • then projection fails with EmitError::WrongKind carrying expected and found
Flow Flow — WrongKindFails scroll to zoom · drag to pan
FEATUREWrongKindFailsfor ProjectorGIVENa container view whose of node is nota systemWHENthe view is projectedTHENprojection fails withEmitError::WrongKind carrying expectedand found
BlackBoxEntryTracesSignature

A black-box sequence entry still traces — its signature is the trace.

  • given a sequence view whose entry callable is black-boxed (no disclosed body)
  • when the view is projected
  • then the trace is the single inbound call and its return the signature describes
  • but a non-callable entry still fails with EmitError::WrongKind
Flow Flow — BlackBoxEntryTracesSignature scroll to zoom · drag to pan
FEATUREBlackBoxEntryTracesSignaturefor ProjectorGIVENa sequence view whose entry callableis black-boxed (no disclosed body)WHENthe view is projectedTHENthe trace is the single inbound calland its return the signature describesBUTa non-callable entry still fails withEmitError::WrongKind
data

Rect #

private
emit::Rect

An axis-aligned layout rectangle in renderer coordinates.

Entities Entity diagram scroll to zoom · drag to pan
RECORDRectxnumberynumberwnumberhnumber
data

RoutedEdge #

private
emit::RoutedEdge

An edge routed between two C4 nodes: its endpoints, kind, and the merged call +when the view's target is missing or the wrong kind.

Parent

Inbound

Outbound

Scenarios

DispatchOnViewKind

Each view kind dispatches to its projection.

  • given a graph and a View variant
  • when project runs
  • then Context and the boundary views build a C4Scene
  • and Sequence traces the entry callable's body into a SequenceScene
  • and Data builds an entity (ER) scene and Feature builds a flow scene
Flow Flow — DispatchOnViewKind scroll to zoom · drag to pan
FEATUREDispatchOnViewKindfor ProjectorGIVENa graph and a View variantWHENproject runsTHENContext and the boundary views build aC4SceneANDSequence traces the entry callable'sbody into a SequenceSceneANDData builds an entity (ER) scene andFeature builds a flow scene
ProjectSymbolPicksAView

Project-symbol picks the view that best explains one symbol.

  • given a single symbol FQN — a callable, system, container, component, or data type
  • when the symbol is projected
  • then a callable traces as a sequence, a system or container with children shows them, a data type shows its entity view
  • and a childless boundary falls back to the view that frames it as a peer
  • and an FQN naming no graph node projects its feature flow view
  • but an FQN naming neither a node nor a feature fails with EmitError::UnknownNode
Flow Flow — ProjectSymbolPicksAView scroll to zoom · drag to pan
FEATUREProjectSymbolPicksAViewfor ProjectorGIVENa single symbol FQN — a callable,system, container, component, or datatypeWHENthe symbol is projectedTHENa callable traces as a sequence, asystem or container with childrenshows them, a data type shows itsentity viewANDa childless boundary falls back to theview that frames it as a peerANDan FQN naming no graph node projectsits feature flow viewBUTan FQN naming neither a node nor afeature fails withEmitError::UnknownNode
DataAndFeatureViews

The data and feature views project their own scene families.

  • given a Data view of a data type, or a Feature view of a scenario
  • when the view is projected
  • then the Data view collects the focal entity, its referenced types, and the links between them
  • and the Feature view lays the scenario's given/when/then steps out as a flow
Flow Flow — DataAndFeatureViews scroll to zoom · drag to pan
FEATUREDataAndFeatureViewsfor ProjectorGIVENa Data view of a data type, or aFeature view of a scenarioWHENthe view is projectedTHENthe Data view collects the focalentity, its referenced types, and thelinks between themANDthe Feature view lays the scenario'sgiven/when/then steps out as a flow
UnknownNodeFails

A missing node fails the projection.

  • given a boundary or sequence view whose target FQN names no node
  • when the view is projected
  • then projection fails with EmitError::UnknownNode
Flow Flow — UnknownNodeFails scroll to zoom · drag to pan
FEATUREUnknownNodeFailsfor ProjectorGIVENa boundary or sequence view whosetarget FQN names no nodeWHENthe view is projectedTHENprojection fails withEmitError::UnknownNode
WrongKindFails

A target of the wrong kind fails the projection.

  • given a container view whose of node is not a system
  • when the view is projected
  • then projection fails with EmitError::WrongKind carrying expected and found
Flow Flow — WrongKindFails scroll to zoom · drag to pan
FEATUREWrongKindFailsfor ProjectorGIVENa container view whose of node is nota systemWHENthe view is projectedTHENprojection fails withEmitError::WrongKind carrying expectedand found
BlackBoxEntryTracesSignature

A black-box sequence entry still traces — its signature is the trace.

  • given a sequence view whose entry callable is black-boxed (no disclosed body)
  • when the view is projected
  • then the trace is the single inbound call and its return the signature describes
  • but a non-callable entry still fails with EmitError::WrongKind
Flow Flow — BlackBoxEntryTracesSignature scroll to zoom · drag to pan
FEATUREBlackBoxEntryTracesSignaturefor ProjectorGIVENa sequence view whose entry callableis black-boxed (no disclosed body)WHENthe view is projectedTHENthe trace is the single inbound calland its return the signature describesBUTa non-callable entry still fails withEmitError::WrongKind
data

Rect #

private
emit::Rect

An axis-aligned layout rectangle in renderer coordinates.

Entities Entity diagram scroll to zoom · drag to pan
RECORDRectxnumberynumberwnumberhnumber
data

RoutedEdge #

private
emit::RoutedEdge

An edge routed between two C4 nodes: its endpoints, kind, and the merged call labels (sorted and de-duplicated; empty for a trigger or provenance edge). Parallel calls between the same pair collapse into one multi-label edge. `source` is the wire field `from`, renamed because `from` is a PseudoScript -keyword.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDRoutedEdgesourcestringtostringkindemit::C4EdgeKindlabelsstring[]UNIONC4EdgeKindCallTriggerProvenance
data

Scene #

public
emit::Scene

A laid-out diagram: the notation-neutral IR the SVG renderer consumes. A C4 +keyword.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDRoutedEdgesourcestringtostringkindemit::C4EdgeKindlabelsstring[]UNIONC4EdgeKindCallTriggerProvenance
data

Scene #

public
emit::Scene

A laid-out diagram: the notation-neutral IR the SVG renderer consumes. A C4 scene carries placed nodes and routed edges; a sequence scene carries lifelines and ordered messages with nested frames. This IR is the generation conformance surface (ADR-017): coordinates are carried for the renderer only, -never serialised to the golden.

Entities Entity diagram scroll to zoom · drag to pan
UNIONSceneC4SceneSequenceSceneDataSceneFeatureSceneRECORDC4Sceneviewemit::C4ViewofOption<string>nodesemit::PlacedNode[]edgesemit::RoutedEdge[]RECORDSequenceSceneentrystringparticipantsemit::Lifeline[]itemsemit::SeqItem[]RECORDDataSceneofstringentitiesemit::DataEntity[]linksemit::DataLink[]widthnumberheightnumberRECORDFeatureSceneentrystringtargetFqnstringtargetLabelstringnamestringstepsemit::FeatureStepNode[]widthnumberheightnumber
data

SeqItem #

private
emit::SeqItem

One ordered item in a sequence trace: a message or a nested frame.

Entities Entity diagram scroll to zoom · drag to pan
UNIONSeqItemMessageItemFrameItemRECORDMessageItemmessageemit::MessageRECORDFrameItemframeemit::Frame
data

Sequence #

public
emit::Sequence
Entities Entity diagram scroll to zoom · drag to pan
RECORDSequenceentrystring
data

SequenceScene #

public
emit::SequenceScene
Entities Entity diagram scroll to zoom · drag to pan
RECORDSequenceSceneentrystringparticipantsemit::Lifeline[]itemsemit::SeqItem[]RECORDLifelinefqnstringkindstringsummarystringparentPathstringUNIONSeqItemMessageItemFrameItem
component

SvgRenderer #

private
emit::SvgRenderer

Renders a laid-out `Scene` to standalone SVG markup — string-building, no +never serialised to the golden.

Entities Entity diagram scroll to zoom · drag to pan
UNIONSceneC4SceneSequenceSceneDataSceneFeatureSceneRECORDC4Sceneviewemit::C4ViewofOption<string>nodesemit::PlacedNode[]edgesemit::RoutedEdge[]RECORDSequenceSceneentrystringparticipantsemit::Lifeline[]itemsemit::SeqItem[]RECORDDataSceneofstringentitiesemit::DataEntity[]linksemit::DataLink[]widthnumberheightnumberRECORDFeatureSceneentrystringtargetFqnstringtargetLabelstringnamestringstepsemit::FeatureStepNode[]widthnumberheightnumber
data

SeqItem #

private
emit::SeqItem

One ordered item in a sequence trace: a message or a nested frame.

Entities Entity diagram scroll to zoom · drag to pan
UNIONSeqItemMessageItemFrameItemRECORDMessageItemmessageemit::MessageRECORDFrameItemframeemit::Frame
data

Sequence #

public
emit::Sequence
Entities Entity diagram scroll to zoom · drag to pan
RECORDSequenceentrystring
data

SequenceScene #

public
emit::SequenceScene
Entities Entity diagram scroll to zoom · drag to pan
RECORDSequenceSceneentrystringparticipantsemit::Lifeline[]itemsemit::SeqItem[]RECORDLifelinefqnstringkindstringsummarystringparentPathstringUNIONSeqItemMessageItemFrameItem
component

SvgRenderer #

private
emit::SvgRenderer

Renders a laid-out `Scene` to standalone SVG markup — string-building, no template engine and no headless browser (LANG.md §9.3, ADR-017). Dispatches on the scene variant; the layout engine is wrapped so no input panics the render, falling back to the scene's own simple coordinates.

Parent

Inbound

Scenarios

RenderSvgAsString

SVG is built as a string — no headless browser.

  • given a laid-out Scene
  • when render runs
  • then a self-contained SVG document is built by string concatenation
  • but no template engine or headless browser is invoked
Flow Flow — RenderSvgAsString scroll to zoom · drag to pan
FEATURERenderSvgAsStringfor SvgRendererGIVENa laid-out SceneWHENrender runsTHENa self-contained SVG document is builtby string concatenationBUTno template engine or headless browseris invoked
AdaptiveSvgUsesCssVariables

The adaptive theme defers colour choice to the host stylesheet.

  • given a scene rendered under the adaptive theme
  • when the SVG is emitted
  • then every palette role paints as a --pds-* CSS variable with the light value as fallback
  • and the light and dark outputs stay byte-identical to their literal palettes
Flow Flow — AdaptiveSvgUsesCssVariables scroll to zoom · drag to pan
FEATUREAdaptiveSvgUsesCssVariablesfor SvgRendererGIVENa scene rendered under the adaptivethemeWHENthe SVG is emittedTHENevery palette role paints as a --pds-*CSS variable with the light value asfallbackANDthe light and dark outputs staybyte-identical to their literalpalettes
LayoutFallbackIsPanicSafe

A failed layout degrades to simple coordinates rather than crashing.

  • given a scene the layout engine cannot place, or an empty view
  • when the C4 scene is rendered
  • then rendering falls back to the scene's own simple coordinates
  • but the render never panics
Flow Flow — LayoutFallbackIsPanicSafe scroll to zoom · drag to pan
FEATURELayoutFallbackIsPanicSafefor SvgRendererGIVENa scene the layout engine cannotplace, or an empty viewWHENthe C4 scene is renderedTHENrendering falls back to the scene'sown simple coordinatesBUTthe render never panics
component

Trace #

private
emit::Trace

Walks a callable's body trace into ordered sequence items, registering each participant on first appearance (LANG.md §9.2, §7). A real trigger's initiator leads as the first lifeline with a synthesised inbound call; absent a trigger the owner leads. A `call` is a message to the target; a -disclosed callee expands inline; a `self.` call is a self-message; a return +disclosed callee expands inline; a same-node call is a self-message that +expands its disclosed body inline too; a return marks `Ok`/`Err`; `if`/`else` nests an `alt` frame, `for`/`while` a `loop` -frame.

Parent

Inbound

Outbound

Scenarios

ControlFlowBecomesFrames

Control flow becomes nested frames in the trace.

  • given a callable body with if/else and for/while
  • when the body is traced
  • then an if/else becomes an alt frame over its branches
  • and a for/while becomes a loop frame over its body
Flow Flow — ControlFlowBecomesFrames scroll to zoom · drag to pan
FEATUREControlFlowBecomesFramesfor TraceGIVENa callable body with if/else andfor/whileWHENthe body is tracedTHENan if/else becomes an alt frame overits branchesANDa for/while becomes a loop frame overits body
CallsBecomeMessages

Body calls become left-to-right messages; self-calls loop on the owner.

  • given a callable body with calls to other nodes and self-calls
  • when the body is traced
  • then each call to another node is a left-to-right message to that lifeline
  • and each self. call is a self-message on the owner's own lifeline
  • and every target is registered as a participant on first appearance
Flow Flow — CallsBecomeMessages scroll to zoom · drag to pan
FEATURECallsBecomeMessagesfor TraceGIVENa callable body with calls to othernodes and self-callsWHENthe body is tracedTHENeach call to another node is aleft-to-right message to that lifelineANDeach self. call is a self-message onthe owner's own lifelineANDevery target is registered as aparticipant on first appearance
DisclosedCalleesExpandInline

Disclosed callees expand inline; black boxes and recursion stay single calls.

  • given a traced body whose calls reach disclosed, black-box, and recursive callees
  • when each call is traced
  • then a disclosed callee's body expands inline, the active lifeline switching to it
  • and its own returns flow back to its caller
  • but a black-box callee, or one already in flight on the call stack, is one message closed by a synthesised return of its declared type
Flow Flow — DisclosedCalleesExpandInline scroll to zoom · drag to pan
FEATUREDisclosedCalleesExpandInlinefor TraceGIVENa traced body whose calls reachdisclosed, black-box, and recursivecalleesWHENeach call is tracedTHENa disclosed callee's body expandsinline, the active lifeline switchingto itANDits own returns flow back to itscallerBUTa black-box callee, or one already inflight on the call stack, is onemessage closed by a synthesised returnof its declared type
TriggerlessEntrySuppressesReturns

A triggerless entry suppresses its own returns.

  • given a sequence entry that bears no trigger macro
  • when its body is traced
  • then the owner leads with no inbound call and the entry's returns are suppressed
  • but inner expanded callees still return to their callers
Flow Flow — TriggerlessEntrySuppressesReturns scroll to zoom · drag to pan
FEATURETriggerlessEntrySuppressesReturnsfor TraceGIVENa sequence entry that bears no triggermacroWHENits body is tracedTHENthe owner leads with no inbound calland the entry's returns are suppressedBUTinner expanded callees still return totheir callers
data

UnknownNode #

public
emit::UnknownNode
Entities Entity diagram scroll to zoom · drag to pan
RECORDUnknownNodefqnstring
data

View #

public
emit::View

Which view to project from the graph (LANG.md §9). Context is the C1 whole; +frame.

Parent

Inbound

Scenarios

ControlFlowBecomesFrames

Control flow becomes nested frames in the trace.

  • given a callable body with if/else and for/while
  • when the body is traced
  • then an if/else becomes an alt frame over its branches
  • and a for/while becomes a loop frame over its body
Flow Flow — ControlFlowBecomesFrames scroll to zoom · drag to pan
FEATUREControlFlowBecomesFramesfor TraceGIVENa callable body with if/else andfor/whileWHENthe body is tracedTHENan if/else becomes an alt frame overits branchesANDa for/while becomes a loop frame overits body
CallsBecomeMessages

Body calls become left-to-right messages; same-node calls loop on the owner.

  • given a callable body with calls to other nodes and same-node calls
  • when the body is traced
  • then each call to another node is a left-to-right message to that lifeline
  • and each same-node call is a self-message that expands its disclosed body on the owner's own lifeline
  • and every target is registered as a participant on first appearance
Flow Flow — CallsBecomeMessages scroll to zoom · drag to pan
FEATURECallsBecomeMessagesfor TraceGIVENa callable body with calls to othernodes and same-node callsWHENthe body is tracedTHENeach call to another node is aleft-to-right message to that lifelineANDeach same-node call is a self-messagethat expands its disclosed body on theowner's own lifelineANDevery target is registered as aparticipant on first appearance
DisclosedCalleesExpandInline

Disclosed callees expand inline; black boxes and recursion stay single calls.

  • given a traced body whose calls reach disclosed, black-box, and recursive callees
  • when each call is traced
  • then a disclosed callee's body expands inline, the active lifeline switching to it
  • and its own returns flow back to its caller
  • but a black-box callee, or one already in flight on the call stack, is one message closed by a synthesised return of its declared type
Flow Flow — DisclosedCalleesExpandInline scroll to zoom · drag to pan
FEATUREDisclosedCalleesExpandInlinefor TraceGIVENa traced body whose calls reachdisclosed, black-box, and recursivecalleesWHENeach call is tracedTHENa disclosed callee's body expandsinline, the active lifeline switchingto itANDits own returns flow back to itscallerBUTa black-box callee, or one already inflight on the call stack, is onemessage closed by a synthesised returnof its declared type
TriggerlessEntrySuppressesReturns

A triggerless entry suppresses its own returns.

  • given a sequence entry that bears no trigger macro
  • when its body is traced
  • then the owner leads with no inbound call and the entry's returns are suppressed
  • but inner expanded callees still return to their callers
Flow Flow — TriggerlessEntrySuppressesReturns scroll to zoom · drag to pan
FEATURETriggerlessEntrySuppressesReturnsfor TraceGIVENa sequence entry that bears no triggermacroWHENits body is tracedTHENthe owner leads with no inbound calland the entry's returns are suppressedBUTinner expanded callees still return totheir callers
data

UnknownNode #

public
emit::UnknownNode
Entities Entity diagram scroll to zoom · drag to pan
RECORDUnknownNodefqnstring
data

View #

public
emit::View

Which view to project from the graph (LANG.md §9). Context is the C1 whole; Container/Component zoom into one boundary; Sequence traces one entry point; Data draws a `data` type's entity (ER) view (§9.4); Feature draws a `feature` scenario's flow (§9.5).

Entities Entity diagram scroll to zoom · drag to pan
UNIONViewContextContainerComponentSequenceDataFeatureRECORDContainerofstringRECORDComponentofstringRECORDSequenceentrystringRECORDDataofstringRECORDFeatureofstring
data

WrongKind #

public
emit::WrongKind
Entities Entity diagram scroll to zoom · drag to pan
RECORDWrongKindfqnstringexpectedstringfoundstring
Generated by pds doc.
diff --git a/model/site/module/format.html b/model/site/module/format.html index e32890be..a244236a 100644 --- a/model/site/module/format.html +++ b/model/site/module/format.html @@ -11,20 +11,20 @@ -
PseudoScript
Module

format

container

Format #

public
format::Format

`crates/pseudoscript-format`. The canonical formatter: parse, then +

PseudoScript
Module

format

container

Format #

public
format::Format

`crates/pseudoscript-format`. The canonical formatter: parse, then pretty-print the tree to one canonical form. The string-to-string entry the CLI and LSP depend on.

Inbound

Outbound

Scenarios

FormatIsIdempotent

Formatting the output again changes nothing.

  • given a parseable .pds source
  • when it is formatted and the result is formatted a second time
  • then the first pass yields canonical text
  • and the second pass returns that text unchanged
Flow Flow — FormatIsIdempotent scroll to zoom · drag to pan
FEATUREFormatIsIdempotentfor FormatGIVENa parseable .pds sourceWHENit is formatted and the result isformatted a second timeTHENthe first pass yields canonical textANDthe second pass returns that textunchanged
FormatPreservesSemantics

Reformatting only touches layout, never meaning.

  • given a parseable .pds source
  • when it is formatted
  • then the result re-parses to a structurally equivalent tree
  • but only whitespace and comment layout differ from the source
Flow Flow — FormatPreservesSemantics scroll to zoom · drag to pan
FEATUREFormatPreservesSemanticsfor FormatGIVENa parseable .pds sourceWHENit is formattedTHENthe result re-parses to a structurallyequivalent treeBUTonly whitespace and comment layoutdiffer from the source
Components Component diagram scroll to zoom · drag to pan
PseudoscriptFormatCOMPONENTFormatterDrives the headline flow: parse the source,short-circuit to `FormatError::Parse` if an…COMPONENTPrinterThe canonical pretty-printer: walks the ASTtop-down, appending to a buffer, and emits…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…renderTokensprintparse
data

FormatError #

public
format::FormatError

Why formatting failed. The only failure is unparseable input: `Parse` carries the rendered error messages (one per diagnostic) for context, and the caller keeps its original text.

Entities Entity diagram scroll to zoom · drag to pan
UNIONFormatErrorParseRECORDParsemessagesstring[]
component

Formatter #

private
format::Formatter

Drives the headline flow: parse the source, short-circuit to `FormatError::Parse` if any error diagnostic surfaced, else hand the tree to -the printer for canonical text.

Parent

Inbound

Outbound

Scenarios

ParseErrorsShortCircuit

Unparseable source short-circuits and is left untouched.

  • given source with at least one error-severity parse diagnostic
  • when it is formatted
  • then formatting returns FormatError::Parse carrying the rendered messages
  • but the source is not rewritten and the caller keeps the original text
Flow Flow — ParseErrorsShortCircuit scroll to zoom · drag to pan
FEATUREParseErrorsShortCircuitfor FormatterGIVENsource with at least oneerror-severity parse diagnosticWHENit is formattedTHENformatting returns FormatError::Parsecarrying the rendered messagesBUTthe source is not rewritten and thecaller keeps the original text
OnlyErrorsBlockFormatting

Warnings and info never block formatting.

  • given source that parses with only warning or info diagnostics
  • when it is formatted
  • then the tree is pretty-printed to canonical text
  • but the non-error diagnostics do not short-circuit the formatter
Flow Flow — OnlyErrorsBlockFormatting scroll to zoom · drag to pan
FEATUREOnlyErrorsBlockFormattingfor FormatterGIVENsource that parses with only warningor info diagnosticsWHENit is formattedTHENthe tree is pretty-printed tocanonical textBUTthe non-error diagnostics do notshort-circuit the formatter
data

Parse #

public
format::Parse
Entities Entity diagram scroll to zoom · drag to pan
RECORDParsemessagesstring[]
component

Printer #

private
format::Printer

The canonical pretty-printer: walks the AST top-down, appending to a buffer, +the printer for canonical text.

Parent

Inbound

Outbound

Scenarios

ParseErrorsShortCircuit

Unparseable source short-circuits and is left untouched.

  • given source with at least one error-severity parse diagnostic
  • when it is formatted
  • then formatting returns FormatError::Parse carrying the rendered messages
  • but the source is not rewritten and the caller keeps the original text
Flow Flow — ParseErrorsShortCircuit scroll to zoom · drag to pan
FEATUREParseErrorsShortCircuitfor FormatterGIVENsource with at least oneerror-severity parse diagnosticWHENit is formattedTHENformatting returns FormatError::Parsecarrying the rendered messagesBUTthe source is not rewritten and thecaller keeps the original text
OnlyErrorsBlockFormatting

Warnings and info never block formatting.

  • given source that parses with only warning or info diagnostics
  • when it is formatted
  • then the tree is pretty-printed to canonical text
  • but the non-error diagnostics do not short-circuit the formatter
Flow Flow — OnlyErrorsBlockFormatting scroll to zoom · drag to pan
FEATUREOnlyErrorsBlockFormattingfor FormatterGIVENsource that parses with only warningor info diagnosticsWHENit is formattedTHENthe tree is pretty-printed tocanonical textBUTthe non-error diagnostics do notshort-circuit the formatter
data

Parse #

public
format::Parse
Entities Entity diagram scroll to zoom · drag to pan
RECORDParsemessagesstring[]
component

Printer #

private
format::Printer

The canonical pretty-printer: walks the AST top-down, appending to a buffer, and emits one canonical form. Indentation is a level counter (two spaces each); leading trivia is normalised — blank-line runs collapse to at most one separator and `//` / `/* */` comments reproduce at the current indent in source order. Internals are black-boxed per construct; the top-level `print` -flow is disclosed.

Parent

Inbound

Outbound

Scenarios

CanonicalRecord

Records render on one line.

  • given a data record declaration
  • when it is printed
  • then the fields render inline as { a: T, b: U }
  • and an empty record renders as { }
Flow Flow — CanonicalRecord scroll to zoom · drag to pan
FEATURECanonicalRecordfor PrinterGIVENa data record declarationWHENit is printedTHENthe fields render inline as { a: T, b:U }ANDan empty record renders as { }
CanonicalUnion

Unions stack one variant per line.

  • given a data union declaration
  • when it is printed
  • then the body opens with ` =` on the declaration line
  • and each variant prints as `| Name` on its own line, indented one level
Flow Flow — CanonicalUnion scroll to zoom · drag to pan
FEATURECanonicalUnionfor PrinterGIVENa data union declarationWHENit is printedTHENthe body opens with ` =` on thedeclaration lineANDeach variant prints as `| Name` on itsown line, indented one level
CanonicalFeature

Features render one step per line.

  • given a feature declaration with given/when/then steps
  • when it is printed
  • then each step prints on its own line, keyword then prose
  • but the keywords are not column-aligned, keeping the form idempotent
Flow Flow — CanonicalFeature scroll to zoom · drag to pan
FEATURECanonicalFeaturefor PrinterGIVENa feature declaration withgiven/when/then stepsWHENit is printedTHENeach step prints on its own line,keyword then proseBUTthe keywords are not column-aligned,keeping the form idempotent
TwoSpaceIndent

Indentation is two spaces per nesting level.

  • given a disclosed node, block, union, or feature body
  • when its members are printed
  • then each nesting level adds two spaces of indentation
Flow Flow — TwoSpaceIndent scroll to zoom · drag to pan
FEATURETwoSpaceIndentfor PrinterGIVENa disclosed node, block, union, orfeature bodyWHENits members are printedTHENeach nesting level adds two spaces ofindentation
TriviaPreserved

Comments and blank-line runs survive; runs collapse to one.

  • given source interleaving declarations with comments and runs of blank lines
  • when it is printed
  • then each comment reproduces on its own line at the current indent
  • and a run of blank lines collapses to a single blank separator
  • but the first member in a block or file gets no leading blank line
Flow Flow — TriviaPreserved scroll to zoom · drag to pan
FEATURETriviaPreservedfor PrinterGIVENsource interleaving declarations withcomments and runs of blank linesWHENit is printedTHENeach comment reproduces on its ownline at the current indentANDa run of blank lines collapses to asingle blank separatorBUTthe first member in a block or filegets no leading blank line
BodyFormsPreserved

Black-box and disclosed forms are each kept, never converted.

  • given a mix of black-box `;` and disclosed `{ }` nodes and callables
  • when they are printed
  • then a black-box body stays `;`
  • and a disclosed body keeps its `{ }`, one member per line
  • but an empty disclosed body renders ` { }`
Flow Flow — BodyFormsPreserved scroll to zoom · drag to pan
FEATUREBodyFormsPreservedfor PrinterGIVENa mix of black-box `;` and disclosed`{ }` nodes and callablesWHENthey are printedTHENa black-box body stays `;`ANDa disclosed body keeps its `{ }`, onemember per lineBUTan empty disclosed body renders ` { }`
data

PrinterState #

private
format::PrinterState

The running pretty-printer state: the text buffer being built, the current +flow is disclosed.

Parent

Inbound

Outbound

  • from format::string

Scenarios

CanonicalRecord

Records render on one line.

  • given a data record declaration
  • when it is printed
  • then the fields render inline as { a: T, b: U }
  • and an empty record renders as { }
Flow Flow — CanonicalRecord scroll to zoom · drag to pan
FEATURECanonicalRecordfor PrinterGIVENa data record declarationWHENit is printedTHENthe fields render inline as { a: T, b:U }ANDan empty record renders as { }
CanonicalUnion

Unions stack one variant per line.

  • given a data union declaration
  • when it is printed
  • then the body opens with ` =` on the declaration line
  • and each variant prints as `| Name` on its own line, indented one level
Flow Flow — CanonicalUnion scroll to zoom · drag to pan
FEATURECanonicalUnionfor PrinterGIVENa data union declarationWHENit is printedTHENthe body opens with ` =` on thedeclaration lineANDeach variant prints as `| Name` on itsown line, indented one level
CanonicalFeature

Features render one step per line.

  • given a feature declaration with given/when/then steps
  • when it is printed
  • then each step prints on its own line, keyword then prose
  • but the keywords are not column-aligned, keeping the form idempotent
Flow Flow — CanonicalFeature scroll to zoom · drag to pan
FEATURECanonicalFeaturefor PrinterGIVENa feature declaration withgiven/when/then stepsWHENit is printedTHENeach step prints on its own line,keyword then proseBUTthe keywords are not column-aligned,keeping the form idempotent
TwoSpaceIndent

Indentation is two spaces per nesting level.

  • given a disclosed node, block, union, or feature body
  • when its members are printed
  • then each nesting level adds two spaces of indentation
Flow Flow — TwoSpaceIndent scroll to zoom · drag to pan
FEATURETwoSpaceIndentfor PrinterGIVENa disclosed node, block, union, orfeature bodyWHENits members are printedTHENeach nesting level adds two spaces ofindentation
TriviaPreserved

Comments and blank-line runs survive; runs collapse to one.

  • given source interleaving declarations with comments and runs of blank lines
  • when it is printed
  • then each comment reproduces on its own line at the current indent
  • and a run of blank lines collapses to a single blank separator
  • but the first member in a block or file gets no leading blank line
Flow Flow — TriviaPreserved scroll to zoom · drag to pan
FEATURETriviaPreservedfor PrinterGIVENsource interleaving declarations withcomments and runs of blank linesWHENit is printedTHENeach comment reproduces on its ownline at the current indentANDa run of blank lines collapses to asingle blank separatorBUTthe first member in a block or filegets no leading blank line
BodyFormsPreserved

Black-box and disclosed forms are each kept, never converted.

  • given a mix of black-box `;` and disclosed `{ }` nodes and callables
  • when they are printed
  • then a black-box body stays `;`
  • and a disclosed body keeps its `{ }`, one member per line
  • but an empty disclosed body renders ` { }`
Flow Flow — BodyFormsPreserved scroll to zoom · drag to pan
FEATUREBodyFormsPreservedfor PrinterGIVENa mix of black-box `;` and disclosed`{ }` nodes and callablesWHENthey are printedTHENa black-box body stays `;`ANDa disclosed body keeps its `{ }`, onemember per lineBUTan empty disclosed body renders ` { }`
data

PrinterState #

private
format::PrinterState

The running pretty-printer state: the text buffer being built, the current nesting depth (two spaces each), and whether the current line has had its -indentation written yet so further writes append in place.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDPrinterStateoutstringindentnumberlineStartedbool
Generated by pds doc.
+indentation written yet so further writes append in place.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPrinterStateoutstringindentnumberlineStartedbool
Generated by pds doc.
diff --git a/model/site/module/ide.html b/model/site/module/ide.html index 3d71cfcb..88d0e89a 100644 --- a/model/site/module/ide.html +++ b/model/site/module/ide.html @@ -11,12 +11,12 @@ -
PseudoScript
Module

ide

component

Bootstrap #

public
ide::Bootstrap

Boots the IDE in a browser tab: load the one wasm bundle (IdeSession), then +

PseudoScript
Module

ide

component

Bootstrap #

public
ide::Bootstrap

Boots the IDE in a browser tab: load the one wasm bundle (IdeSession), then restore the URL hash's workspace — a share link mounts in memory and needs no disk — or fall back to the launcher. File System Access support gates only the disk features (open folder, save, watch): without it those actions are disabled with a notice, while share links and the bundled examples -still open.

Parent

Inbound

Outbound

Scenarios

DiskGatesOnlyDiskFeatures

Missing File System Access disables disk features, never the IDE.

  • given a browser without the File System Access API (Firefox, Safari)
  • when the IDE boots
  • then share links and bundled examples still open in memory
  • and the disk actions — open folder, save, watch — are disabled with a notice naming the supported browsers
  • but no full-screen wall blocks the product
Flow Flow — DiskGatesOnlyDiskFeatures scroll to zoom · drag to pan
FEATUREDiskGatesOnlyDiskFeaturesfor BootstrapGIVENa browser without the File SystemAccess API (Firefox, Safari)WHENthe IDE bootsTHENshare links and bundled examples stillopen in memoryANDthe disk actions — open folder, save,watch — are disabled with a noticenaming the supported browsersBUTno full-screen wall blocks the product
data

BrowserWorkspace #

public
ide::BrowserWorkspace

The in-browser workspace state the session holds: the open `.pds` modules, the +still open.

Parent

Inbound

Outbound

Scenarios

DiskGatesOnlyDiskFeatures

Missing File System Access disables disk features, never the IDE.

  • given a browser without the File System Access API (Firefox, Safari)
  • when the IDE boots
  • then share links and bundled examples still open in memory
  • and the disk actions — open folder, save, watch — are disabled with a notice naming the supported browsers
  • but no full-screen wall blocks the product
Flow Flow — DiskGatesOnlyDiskFeatures scroll to zoom · drag to pan
FEATUREDiskGatesOnlyDiskFeaturesfor BootstrapGIVENa browser without the File SystemAccess API (Firefox, Safari)WHENthe IDE bootsTHENshare links and bundled examples stillopen in memoryANDthe disk actions — open folder, save,watch — are disabled with a noticenaming the supported browsersBUTno full-screen wall blocks the product
data

BrowserWorkspace #

public
ide::BrowserWorkspace

The in-browser workspace state the session holds: the open `.pds` modules, the `pds.toml` manifest text, and the dependency modules resolved from `pds_modules/` as externals (LANG.md §8.3). Held in memory — a decoded sample/share link or a local directory loaded through the file-system port. @@ -46,18 +46,18 @@ Ollama, and vLLM. Stateless — the caller hands it the settings snapshot and owns cancellation (`GhostText` aborts the in-flight request on the next keystroke; the client honours the abort). Every failure comes back as a -classified `ProviderError`, so the caller can surface why a request bailed.

Parent

Inbound

Outbound

data

FimPrompt #

public
ide::FimPrompt

The assembled fill-in-the-middle request: the windowed buffer text before and +classified `ProviderError`, so the caller can surface why a request bailed.

Parent

Inbound

Outbound

data

FimPrompt #

public
ide::FimPrompt

The assembled fill-in-the-middle request: the windowed buffer text before and after the caret, and the cached grammar primer that steers a general model to -emit valid PseudoScript.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDFimPromptprefixstringsuffixstringprimerstring
component

FsAccessAdapter #

public
ide::FsAccessAdapter

The file-system adapter over the browser File System Access API: directory +emit valid PseudoScript.

Entities Entity diagram scroll to zoom · drag to pan
RECORDFimPromptprefixstringsuffixstringprimerstring
component

FsAccessAdapter #

public
ide::FsAccessAdapter

The file-system adapter over the browser File System Access API: directory picker, recursive walk for `.pds` modules, deriving each module's flat FQN from its path (LANG.md §8.1, ADR-031), `pds.lock` + `pds_modules/` reads for dependency externals, and per-file read/write through handles. The only place FS-Access specifics live; it pushes what it reads into the session via -`mount`.

Parent

Inbound

Outbound

component

GhostText #

private
ide::GhostText

Inline ghost-text completion over CodeMirror 6, beside the grammar dropdown: +`mount`.

Parent

Inbound

Outbound

component

GhostText #

private
ide::GhostText

Inline ghost-text completion over CodeMirror 6, beside the grammar dropdown: structural candidates stay local and deterministic in `CodeMirrorAdapter`; the remote model supplies only multi-token greyed text. CodeMirror has no native inline-suggestion UI, so this is a custom view plugin rendering a -widget decoration at the caret — Tab accepts, Esc dismisses, any edit clears.

Parent

Outbound

Scenarios

GhostTextSuggests

Ghost text comes from the configured provider, rendered as-is for the +widget decoration at the caret — Tab accepts, Esc dismisses, any edit clears.

Parent

Outbound

Scenarios

GhostTextSuggests

Ghost text comes from the configured provider, rendered as-is for the author to judge.

  • given AI completion enabled with a configured OpenAI-compatible provider
  • when the author pauses typing
  • then the windowed prefix/suffix and the grammar primer go to the provider
  • and the suggestion renders as greyed inline text — Tab accepts, Esc dismisses
  • but the suggestion is the author's to judge — accepting one with a syntax error lights the live diagnostics — and a provider failure surfaces on the AI status chip with the reason; it never blocks typing
Flow Flow — GhostTextSuggests scroll to zoom · drag to pan
FEATUREGhostTextSuggestsfor GhostTextGIVENAI completion enabled with aconfigured OpenAI-compatible providerWHENthe author pauses typingTHENthe windowed prefix/suffix and thegrammar primer go to the providerANDthe suggestion renders as greyedinline text — Tab accepts, EscdismissesBUTthe suggestion is the author's tojudge — accepting one with a syntaxerror lights the live diagnostics —and a provider failure surfaces on theAI status chip with the reason; itnever blocks typing
StructuralCompletionStaysLocal

The remote model augments, never replaces, the local grammar completer.

  • given the grammar dropdown completer answering from the wasm session
  • when AI completion is enabled beside it
  • then structural candidates stay local and deterministic
  • and the remote model supplies only multi-token inline suggestions
  • but with AI completion off or unconfigured, the editor behaves exactly as before
Flow Flow — StructuralCompletionStaysLocal scroll to zoom · drag to pan
FEATUREStructuralCompletionStaysLocalfor GhostTextGIVENthe grammar dropdown completeranswering from the wasm sessionWHENAI completion is enabled beside itTHENstructural candidates stay local anddeterministicANDthe remote model supplies onlymulti-token inline suggestionsBUTwith AI completion off orunconfigured, the editor behavesexactly as before
data

GridPin #

public
ide::GridPin

A node the user has dragged onto a grid cell, identified by FQN. Carried inside `LayoutTweaks`; honoured only under experimental grid placement.

Entities Entity diagram scroll to zoom · drag to pan
RECORDGridPinfqnstringrownumbercolnumber
container

IdeSession #

public
ide::IdeSession

`crates/pseudoscript-ide` — the IDE application, Rust compiled to a single wasm. It owns the workspace state and is the whole browser API: the host @@ -89,16 +89,16 @@ OpenAI-compatible endpoint, the bring-your-own API key (stored in localStorage, sent only to the configured endpoint), the model id, and the wire shape (`"fim"` for a native fill-in-the-middle route, `"chat"` for the -chat-completions fallback).

Entities Entity diagram scroll to zoom · drag to pan
RECORDLlmSettingsenabledboolproviderstringbaseUrlstringapiKeystringmodelstringmodestring
component

LlmSettingsStore #

private
ide::LlmSettingsStore

The author's AI-completion settings, persisted to browser localStorage and +chat-completions fallback).

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDLlmSettingsenabledboolproviderstringbaseUrlstringapiKeystringmodelstringmodestring
component

LlmSettingsStore #

private
ide::LlmSettingsStore

The author's AI-completion settings, persisted to browser localStorage and edited through the Settings dialog's "AI Completion" tab. Bring-your-own key: it never leaves the tab except on requests to the configured endpoint. Setup is preset-first: picking a provider applies its pinned endpoint and wire shape, so only the Custom preset exposes the raw fields. The store also carries the session's last completion failure (never persisted) so the -status chip and the settings tab can show why ghost text is bailing.

Parent

Inbound

Outbound

Scenarios

GuidedProviderSetup

Setup is preset-first; the connection test explains a failure instead of +status chip and the settings tab can show why ghost text is bailing.

Parent

Inbound

Outbound

Scenarios

GuidedProviderSetup

Setup is preset-first; the connection test explains a failure instead of leaving the author guessing.

  • given the Settings dialog's AI Completion tab
  • when the author picks the Ollama or OpenAI preset
  • then the endpoint and wire shape are pinned by the preset — no raw URL to type
  • and the model dropdown fills from the provider's live model list
  • and Test connection round-trips the provider and reports success or the classified failure with its fix hint
  • but the Custom preset still exposes every field for any OpenAI-compatible endpoint
Flow Flow — GuidedProviderSetup scroll to zoom · drag to pan
FEATUREGuidedProviderSetupfor LlmSettingsStoreGIVENthe Settings dialog's AI CompletiontabWHENthe author picks the Ollama or OpenAIpresetTHENthe endpoint and wire shape are pinnedby the preset — no raw URL to typeANDthe model dropdown fills from theprovider's live model listANDTest connection round-trips theprovider and reports success or theclassified failure with its fix hintBUTthe Custom preset still exposes everyfield for any OpenAI-compatibleendpoint
data

LocalInput #

public
ide::LocalInput

One local-source dependency file the host reads for `dependencyModules`: the dependency name (ADR-026), its FQN within the dependency workspace, and its -source.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDLocalInputnamestringfqnstringsourcestring
data

Occurrence #

public
ide::Occurrence

One occurrence of a symbol: the module it lies in, its line/column span, the +source.

Entities Entity diagram scroll to zoom · drag to pan
RECORDLocalInputnamestringfqnstringsourcestring
data

Occurrence #

public
ide::Occurrence

One occurrence of a symbol: the module it lies in, its line/column span, the source line text with the match offsets within it, and whether it is the declaration site.

Entities Entity diagram scroll to zoom · drag to pan
RECORDOccurrencefqnstringlinenumbercolnumberendLinenumberendColnumbertextstringmatchStartnumbermatchEndnumberdeclbool
data

OutlineNode #

public
ide::OutlineNode

One row of the workspace outline: a node's FQN, simple name, C4 kind, containment parent (absent on roots), whether it is a triggered flow entry, @@ -127,7 +127,7 @@ weighted edges, no positions (the renderer lays them out). The typed boundary form of a `universe::Snapshot`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDUniverseSnapshotnodeside::UniverseNode[]edgeside::UniverseEdge[]RECORDUniverseNodeidstringlevelstringparentOption<string>RECORDUniverseEdgesourcestringtostringtrafficnumber
data

VendoredInput #

public
ide::VendoredInput

One vendored git-dependency file the host reads for `dependencyModules`: its `pds_modules/` slug, its FQN within the dependency workspace (the host's -path→FQN derivation, LANG.md §8.1), and its source.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDVendoredInputslugstringfqnstringsourcestring
container

WebIde #

public
ide::WebIde

`web-ide` — the IDE at `ide.pdscript.dev`: a SvelteKit shell on Cloudflare +path→FQN derivation, LANG.md §8.1), and its source.

Entities Entity diagram scroll to zoom · drag to pan
RECORDVendoredInputslugstringfqnstringsourcestring
container

WebIde #

public
ide::WebIde

`web-ide` — the IDE at `ide.pdscript.dev`: a SvelteKit shell on Cloudflare Workers static assets. Pure glue — it loads the one wasm bundle and binds the adapters to the session's ports. It holds no language logic.

Inbound

Outbound

Scenarios

JsOnlyAtAdapters

JavaScript exists only in the adapters plus the host's path→FQN derivation; all language and projection logic is Rust.

  • given the IDE session, the language queries, and diagram projection all in Rust
  • when the application touches the file system or the editor surface
  • then an adapter — `FsAccessAdapter`, `CodeMirrorAdapter` — pushes state into the typed session and applies the values it returns
  • and those adapters are the only JavaScript: File System Access and CodeMirror specifics live there
  • but the FS adapter also derives each module's flat FQN from its path (LANG.md §8.1, ADR-031) — the one workspace rule the host runs before pushing modules to the Rust core
Flow Flow — JsOnlyAtAdapters scroll to zoom · drag to pan
FEATUREJsOnlyAtAdaptersfor WebIdeGIVENthe IDE session, the language queries,and diagram projection all in RustWHENthe application touches the filesystem or the editor surfaceTHENan adapter — `FsAccessAdapter`,`CodeMirrorAdapter` — pushes stateinto the typed session and applies thevalues it returnsANDthose adapters are the onlyJavaScript: File System Access andCodeMirror specifics live thereBUTthe FS adapter also derives eachmodule's flat FQN from its path(LANG.md §8.1, ADR-031) — the oneworkspace rule the host runs beforepushing modules to the Rust core
EditInBrowser

Editing a model in the browser checks and redraws it live, with no backend.

  • given a `.pds` module open in the browser IDE
  • when the author edits it through the CodeMirror adapter
  • then the edit drives the Rust session, which re-checks against the externals
  • and diagnostics and the projected C4 or sequence diagram update live
  • but nothing is sent to a server
Flow Flow — EditInBrowser scroll to zoom · drag to pan
FEATUREEditInBrowserfor WebIdeGIVENa `.pds` module open in the browserIDEWHENthe author edits it through theCodeMirror adapterTHENthe edit drives the Rust session,which re-checks against the externalsANDdiagnostics and the projected C4 orsequence diagram update liveBUTnothing is sent to a server
Components Component diagram scroll to zoom · drag to pan
PseudoscriptWebIdeCOMPONENTFsAccessAdapterThe file-system adapter over the browserFile System Access API: directory picker,…COMPONENTCodeMirrorAdapterThe editor adapter over CodeMirror 6: thetext/cursor model, the completion source,…COMPONENTLlmSettingsStoreThe author's AI-completion settings,persisted to browser localStorage and edite…COMPONENTFimClientProvider-agnostic completion client: one`complete` contract over OpenAI-compatible…COMPONENTGhostTextInline ghost-text completion over CodeMirror6, beside the grammar dropdown: structural…COMPONENTDiagramCanvasThe diagram canvas: draws the **JSON**`Scene` interactively (Svelte Flow pan/zoom…COMPONENTBootstrapBoots the IDE in a browser tab: load the onewasm bundle (IdeSession), then restore the…COMPONENTSamplesThe bundled example catalogue, discovered atbuild time from the samples folder (one…COMPONENTLauncherThe project launcher — the first surface.Offers the recents, open-a-folder, New…CONTAINERIdeSession`crates/pseudoscript-ide` — the IDEapplication, Rust compiled to a single wasm…SYSTEMLlmProviderThe author's configured OpenAI-compatiblecompletion provider — hosted (OpenAI,…CONTAINERLanding`web-landing` — the marketing site at`pdscript.dev`. A static Svelte build on…showcompletediagnosticshoversetSourcechatCompletefimCompletelistModelsdependencyModulescompleteoutlineclearDropclearFailurecurrentisEnablednoteDropreportFailurepickFolderreadDependenciesreadModulesmountworkspaceOf
component

Workspace #

public
ide::Workspace

The in-memory project the session holds: the parsed modules keyed by FQN (an diff --git a/model/site/module/landing.html b/model/site/module/landing.html index ceb77957..0e555c2f 100644 --- a/model/site/module/landing.html +++ b/model/site/module/landing.html @@ -11,7 +11,7 @@ -

PseudoScript
Module

landing

container

Landing #

public
landing::Landing

`web-landing` — the marketing site at `pdscript.dev`. A static Svelte build on +

PseudoScript
Module

landing

container

Landing #

public
landing::Landing

`web-landing` — the marketing site at `pdscript.dev`. A static Svelte build on Cloudflare Workers static assets; no backend. It routes a visitor to one of three surfaces and otherwise just tells the model-driven story.

Inbound

Outbound

Scenarios

OpenTheIde

The landing page's one job: get a visitor into the product.

#headline
  • given a visitor on pdscript.dev
  • when they choose to try it in the browser
  • then the zero-install Web IDE opens at ide.pdscript.dev
Flow Flow — OpenTheIde scroll to zoom · drag to pan
FEATUREOpenTheIdefor LandingGIVENa visitor on pdscript.devWHENthey choose to try it in the browserTHENthe zero-install Web IDE opens atide.pdscript.dev
Components Component diagram scroll to zoom · drag to pan
PseudoscriptCONTAINERWebIde`web-ide` — the IDE at `ide.pdscript.dev`: aSvelteKit shell on Cloudflare Workers stati…PERSONVisitorA prospective user reading the landing page.
person

Visitor #

public
landing::Visitor

A prospective user reading the landing page.

Outbound

Sequence Sequence — installCli scroll to zoom · drag to pan
SEQUENCEinstallCliPERSONVisitorA prospective userreading the landingCONTAINERLandingPseudoscript`web-landing` — themarketing site at1showInstall()↩ return
Sequence Sequence — tryInBrowser scroll to zoom · drag to pan
SEQUENCEtryInBrowseralt[!restored]PERSONVisitorA prospective userreading the landingCONTAINERLandingPseudoscript`web-landing` — themarketing site atCONTAINERWebIdePseudoscript`web-ide` — the IDE at`ide.pdscript.dev`: aCOMPONENTBootstrapPseudoscript::WebIdeBoots the IDE in abrowser tab: load theCOMPONENTLauncherPseudoscript::WebIdeThe project launcher —the first surface.1openIde()2open()3start()4restoreFromHash5show()↩ return
Generated by pds doc.
diff --git a/model/site/module/layout.html b/model/site/module/layout.html index 3b75de1a..c3c39148 100644 --- a/model/site/module/layout.html +++ b/model/site/module/layout.html @@ -11,7 +11,7 @@ -
PseudoScript
Module

layout

data

Activation #

private
layout::Activation

An execution-activation bar on a lifeline, spanning a participant's first-to- +

PseudoScript
Module

layout

data

Activation #

private
layout::Activation

An execution-activation bar on a lifeline, spanning a participant's first-to- last involvement; `owner` marks the entry's focus lifeline.

Entities Entity diagram scroll to zoom · drag to pan
RECORDActivationparticipantstringxnumbertopnumberbottomnumberownerbool
component

Core #

public
layout::Core

The shared geometry/text core: measures label and title widths, wraps descriptions to a width, and accumulates bounding boxes. Every engine builds on it, so text sizing and bounds math live in exactly one place.

Parent

Scenarios

SharedGeometryCore

The geometry/text core is the single home for sizing and bounds.

  • given an engine that must size labels and accumulate a bounding box
  • when it measures text or grows its bounds
  • then it calls the shared core rather than re-implementing the math
  • and text sizing and bounds accumulation live in exactly one place
Flow Flow — SharedGeometryCore scroll to zoom · drag to pan
FEATURESharedGeometryCorefor CoreGIVENan engine that must size labels andaccumulate a bounding boxWHENit measures text or grows its boundsTHENit calls the shared core rather thanre-implementing the mathANDtext sizing and bounds accumulationlive in exactly one place
data

Diagram #

public
layout::Diagram

A structural sequence diagram: the participants (lifelines) and the ordered @@ -28,7 +28,7 @@ dimmed detail after it (a call signature or return type). `source` is the wire field `from`, renamed because `from` is a PseudoScript keyword.

Entities Entity diagram scroll to zoom · drag to pan
RECORDMessagesourcestringtostringkindlayout::MsgKindlabelstringdetailstringUNIONMsgKindCallReturnSelfMsg
data

MessageItem #

private
layout::MessageItem
Entities Entity diagram scroll to zoom · drag to pan
RECORDMessageItemmessagelayout::MessageRECORDMessagesourcestringtostringkindlayout::MsgKindlabelstringdetailstring
data

Metrics #

public
layout::Metrics

Tunable spacing and font metrics for the sequence engine — head-card sizing, row advance per message kind, fragment padding. Field detail is the engine's -concern; the defaults are the one source of truth consumers start from.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
BLACKBOXMetrics
data

MsgKind #

private
layout::MsgKind

The kind of a sequence message: a call to another lifeline, a return to the +concern; the defaults are the one source of truth consumers start from.

Entities Entity diagram scroll to zoom · drag to pan
BLACKBOXMetrics
data

MsgKind #

private
layout::MsgKind

The kind of a sequence message: a call to another lifeline, a return to the caller, or a self-message on the sender's own lifeline.

Entities Entity diagram scroll to zoom · drag to pan
UNIONMsgKindCallReturnSelfMsgRECORDCallmessagestringRECORDReturnmarkerstring
data

Participant #

private
layout::Participant

One lifeline: its id (FQN), display label, C4 kind for the head card, optional summary, and the ancestry path shown under the name for container/component lifelines.

Entities Entity diagram scroll to zoom · drag to pan
RECORDParticipantidstringlabelstringkindstringsummarystringparentPathstring
data

PlacedFragment #

private
layout::PlacedFragment

A placed fragment frame: its box, the operator-tab label (the first section's diff --git a/model/site/module/lsp.html b/model/site/module/lsp.html index f1fd5579..284d4488 100644 --- a/model/site/module/lsp.html +++ b/model/site/module/lsp.html @@ -11,24 +11,24 @@ -

PseudoScript
Module

lsp

data

DefTarget #

private
lsp::DefTarget

A go-to-definition target straight from `lsp_core`: the FQN of the module the +

PseudoScript
Module

lsp

data

DefTarget #

private
lsp::DefTarget

A go-to-definition target straight from `lsp_core`: the FQN of the module the definition lives in, and its span within that module's source. The server maps `fqn` to a file URI — the target file, not the file the request came from.

Entities Entity diagram scroll to zoom · drag to pan
RECORDDefTargetfqnstringspansyntax::SpanRECORDSpanstartnumberendnumber
container

Lsp #

public
lsp::Lsp

`crates/pseudoscript-lsp`. The stdio language server (tower-lsp): workspace diagnostics on change, and hover, definition, completion, references, rename, semantic tokens, symbols, folding, and formatting — every language answer delegated to `lsp_core`. Owns the transport, the document store, and the -URI↔FQN mapping, nothing more.

Inbound

Outbound

Components Component diagram scroll to zoom · drag to pan
PseudoscriptLspCOMPONENTServerThe tower-lsp `Backend`: owns the stdiotransport, the document store, the server…COMPONENTStoreThe workspace document store: the server'sown filesystem edge. Discovers the project…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERLspCore`crates/pseudoscript-lsp-core`. The singlehome for language intelligence as…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…checkcheckWorkspaceModulesgraphchangeclosediagnosticsdiscoverfqnForsourceuriOfworkspacedefinitionformatEdithovercheck
data

Occurrence #

private
lsp::Occurrence

One resolved editor location: the file URI a target FQN maps back to, and the +URI↔FQN mapping, nothing more.

Inbound

Outbound

Components Component diagram scroll to zoom · drag to pan
PseudoscriptLspCOMPONENTServerThe tower-lsp `Backend`: owns the stdiotransport, the document store, the server…COMPONENTStoreThe workspace document store: the server'sown filesystem edge. Discovers the project…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERLspCore`crates/pseudoscript-lsp-core`. The singlehome for language intelligence as…changeclosediagnosticsdiscoverfqnForsourceuriOfworkspacedefinitionformatEdithover
data

Occurrence #

private
lsp::Occurrence

One resolved editor location: the file URI a target FQN maps back to, and the range within it. The server's transport-level mapping of a `lsp_core` answer.

Entities Entity diagram scroll to zoom · drag to pan
RECORDOccurrenceuristringrangelsp_core::RangeRECORDRangestartlsp_core::Positionendlsp_core::Position
data

OpenDocument #

private
lsp::OpenDocument

One open editor buffer: its document URI, current source text, and the editor's version counter. The buffer overlays on-disk text until closed.

Entities Entity diagram scroll to zoom · drag to pan
RECORDOpenDocumenturistringtextstringversionnumber
component

Server #

private
lsp::Server

The tower-lsp `Backend`: owns the stdio transport, the document store, the server lifecycle, and request routing. Holds no language logic — it locks the store, hands the active text and the resolved workspace to a `lsp_core` -handler, and maps the result back to file locations.

Parent

Inbound

Outbound

Scenarios

SpawnedOverStdio

The editor spawns `pds lsp` as a child process and drives it over stdio.

  • given an editor that speaks the Language Server Protocol
  • when it needs language support for a .pds document
  • then it spawns `pds lsp` as a child process
  • and the server reads requests and writes responses over stdin and stdout
Flow Flow — SpawnedOverStdio scroll to zoom · drag to pan
FEATURESpawnedOverStdiofor ServerGIVENan editor that speaks the LanguageServer ProtocolWHENit needs language support for a .pdsdocumentTHENit spawns `pds lsp` as a child processANDthe server reads requests and writesresponses over stdin and stdout
RepublishOnChange

Every change re-checks and republishes diagnostics for the whole workspace.

  • given a document open in the editor
  • when the editor sends didOpen, didChange, or didClose
  • then the store re-converges from the document's current text
  • and every module's diagnostics are published against its own file
  • but a cross-file issue surfaces in the file that causes it
Flow Flow — RepublishOnChange scroll to zoom · drag to pan
FEATURERepublishOnChangefor ServerGIVENa document open in the editorWHENthe editor sends didOpen, didChange,or didCloseTHENthe store re-converges from thedocument's current textANDevery module's diagnostics arepublished against its own fileBUTa cross-file issue surfaces in thefile that causes it
FullDocumentSync

Full document sync: each change carries the entire new text.

  • given the server advertised full text-document sync
  • when the editor sends a didChange notification
  • then the last content change carries the whole new document text
  • and the store replaces the buffer wholesale rather than patching a range
Flow Flow — FullDocumentSync scroll to zoom · drag to pan
FEATUREFullDocumentSyncfor ServerGIVENthe server advertised fulltext-document syncWHENthe editor sends a didChangenotificationTHENthe last content change carries thewhole new document textANDthe store replaces the bufferwholesale rather than patching a range
AnswerFromCurrentText

All requests are answered from the document's current source.

  • given a document with unsaved edits open in the editor
  • when the editor requests hover, definition, completion, or formatting
  • then the active buffer's current text is handed to lsp_core
  • but the on-disk version is not consulted while a buffer is open
Flow Flow — AnswerFromCurrentText scroll to zoom · drag to pan
FEATUREAnswerFromCurrentTextfor ServerGIVENa document with unsaved edits open inthe editorWHENthe editor requests hover, definition,completion, or formattingTHENthe active buffer's current text ishanded to lsp_coreBUTthe on-disk version is not consultedwhile a buffer is open
DelegatesAllLanguageLogic

The server owns no language logic — it delegates to lsp_core.

  • given a request that needs parsing, checking, resolution, or formatting
  • when the server handles it
  • then every language answer is computed by the lsp_core handlers
  • and checking delegates to the model crate
  • but the server adds no language rules of its own — only transport, the disk walk, and URI mapping
Flow Flow — DelegatesAllLanguageLogic scroll to zoom · drag to pan
FEATUREDelegatesAllLanguageLogicfor ServerGIVENa request that needs parsing,checking, resolution, or formattingWHENthe server handles itTHENevery language answer is computed bythe lsp_core handlersANDchecking delegates to the model crateBUTthe server adds no language rules ofits own — only transport, the diskwalk, and URI mapping
DefinitionJumpsToDeclaration

Go-to-definition jumps to the declaring span, across files.

  • given the cursor on a reference to a node, member, or data type
  • when the editor requests go-to-definition
  • then lsp_core resolves the reference to its declaring module FQN and span
  • and the server maps that FQN back to its file URI, even in another module
Flow Flow — DefinitionJumpsToDeclaration scroll to zoom · drag to pan
FEATUREDefinitionJumpsToDeclarationfor ServerGIVENthe cursor on a reference to a node,member, or data typeWHENthe editor requests go-to-definitionTHENlsp_core resolves the reference to itsdeclaring module FQN and spanANDthe server maps that FQN back to itsfile URI, even in another module
component

Store #

private
lsp::Store

The workspace document store: the server's own filesystem edge. Discovers the +handler, and maps the result back to file locations.

Parent

Inbound

Outbound

Scenarios

SpawnedOverStdio

The editor spawns `pds lsp` as a child process and drives it over stdio.

  • given an editor that speaks the Language Server Protocol
  • when it needs language support for a .pds document
  • then it spawns `pds lsp` as a child process
  • and the server reads requests and writes responses over stdin and stdout
Flow Flow — SpawnedOverStdio scroll to zoom · drag to pan
FEATURESpawnedOverStdiofor ServerGIVENan editor that speaks the LanguageServer ProtocolWHENit needs language support for a .pdsdocumentTHENit spawns `pds lsp` as a child processANDthe server reads requests and writesresponses over stdin and stdout
RepublishOnChange

Every change re-checks and republishes diagnostics for the whole workspace.

  • given a document open in the editor
  • when the editor sends didOpen, didChange, or didClose
  • then the store re-converges from the document's current text
  • and every module's diagnostics are published against its own file
  • but a cross-file issue surfaces in the file that causes it
Flow Flow — RepublishOnChange scroll to zoom · drag to pan
FEATURERepublishOnChangefor ServerGIVENa document open in the editorWHENthe editor sends didOpen, didChange,or didCloseTHENthe store re-converges from thedocument's current textANDevery module's diagnostics arepublished against its own fileBUTa cross-file issue surfaces in thefile that causes it
FullDocumentSync

Full document sync: each change carries the entire new text.

  • given the server advertised full text-document sync
  • when the editor sends a didChange notification
  • then the last content change carries the whole new document text
  • and the store replaces the buffer wholesale rather than patching a range
Flow Flow — FullDocumentSync scroll to zoom · drag to pan
FEATUREFullDocumentSyncfor ServerGIVENthe server advertised fulltext-document syncWHENthe editor sends a didChangenotificationTHENthe last content change carries thewhole new document textANDthe store replaces the bufferwholesale rather than patching a range
AnswerFromCurrentText

All requests are answered from the document's current source.

  • given a document with unsaved edits open in the editor
  • when the editor requests hover, definition, completion, or formatting
  • then the active buffer's current text is handed to lsp_core
  • but the on-disk version is not consulted while a buffer is open
Flow Flow — AnswerFromCurrentText scroll to zoom · drag to pan
FEATUREAnswerFromCurrentTextfor ServerGIVENa document with unsaved edits open inthe editorWHENthe editor requests hover, definition,completion, or formattingTHENthe active buffer's current text ishanded to lsp_coreBUTthe on-disk version is not consultedwhile a buffer is open
DelegatesAllLanguageLogic

The server owns no language logic — it delegates to lsp_core.

  • given a request that needs parsing, checking, resolution, or formatting
  • when the server handles it
  • then every language answer is computed by the lsp_core handlers
  • and checking delegates to the model crate
  • but the server adds no language rules of its own — only transport, the disk walk, and URI mapping
Flow Flow — DelegatesAllLanguageLogic scroll to zoom · drag to pan
FEATUREDelegatesAllLanguageLogicfor ServerGIVENa request that needs parsing,checking, resolution, or formattingWHENthe server handles itTHENevery language answer is computed bythe lsp_core handlersANDchecking delegates to the model crateBUTthe server adds no language rules ofits own — only transport, the diskwalk, and URI mapping
DefinitionJumpsToDeclaration

Go-to-definition jumps to the declaring span, across files.

  • given the cursor on a reference to a node, member, or data type
  • when the editor requests go-to-definition
  • then lsp_core resolves the reference to its declaring module FQN and span
  • and the server maps that FQN back to its file URI, even in another module
Flow Flow — DefinitionJumpsToDeclaration scroll to zoom · drag to pan
FEATUREDefinitionJumpsToDeclarationfor ServerGIVENthe cursor on a reference to a node,member, or data typeWHENthe editor requests go-to-definitionTHENlsp_core resolves the reference to itsdeclaring module FQN and spanANDthe server maps that FQN back to itsfile URI, even in another module
component

Store #

private
lsp::Store

The workspace document store: the server's own filesystem edge. Discovers the project root (`pds.toml`, §8.1) by walking up from the opened URI, walks the tree for every visible `.pds` file, derives each module's FQN from its path, and overlays open buffers on disk text. Caches each parse and memoises the resolved `model::Workspace` — built from the local parses with the workspace's direct-dependency externals bound (§8.3) — both invalidated on any edit. The -externals are cached separately and reload only on a dependency change.

Parent

Inbound

Outbound

Generated by pds doc.
+externals are cached separately and reload only on a dependency change.

Parent

Inbound

Outbound

  • from model::ModuleDiagnostics
  • from lsp::string
  • from lsp::string
  • from lsp::string
  • from lsp::string
  • from lsp::string
  • from lsp::string
  • from lsp::string
  • from lsp::string
Generated by pds doc.
diff --git a/model/site/module/lsp_core.html b/model/site/module/lsp_core.html index 5c251fcf..f8fc36aa 100644 --- a/model/site/module/lsp_core.html +++ b/model/site/module/lsp_core.html @@ -11,7 +11,7 @@ -
PseudoScript
Module

lsp_core

component

Analysis #

private
lsp_core::Analysis

Document-level analysis: parse-and-check diagnostics, Markdown hover for the +

PseudoScript
Module

lsp_core

component

Analysis #

private
lsp_core::Analysis

Document-level analysis: parse-and-check diagnostics, Markdown hover for the symbol under the caret (falling back to an inferred type), go-to-definition, inlay hints, and the canonical format edit. Resolution is delegated to `model`; this maps the result into LSP shapes.

Parent

Inbound

Outbound

Scenarios

ResolutionDelegatedToModel

Resolution is delegated to the model, not re-implemented.

  • given a cursor feature — hover, definition, references, completion
  • when the symbol under the caret must be resolved
  • then resolution runs through model's resolver against the workspace and externals
  • and this crate only maps the resolved answer into the LSP shape
Flow Flow — ResolutionDelegatedToModel scroll to zoom · drag to pan
FEATUREResolutionDelegatedToModelfor AnalysisGIVENa cursor feature — hover, definition,references, completionWHENthe symbol under the caret must beresolvedTHENresolution runs through model'sresolver against the workspace andexternalsANDthis crate only maps the resolvedanswer into the LSP shape
HoverShowsDocSummary

Hover shows the `///` summary of the symbol under the caret.

  • given the caret resting on a declared node, data type, or member
  • when hover runs
  • then the symbol's kind and FQN, or its member signature, is shown
  • and its `///` summary is appended under the title
Flow Flow — HoverShowsDocSummary scroll to zoom · drag to pan
FEATUREHoverShowsDocSummaryfor AnalysisGIVENthe caret resting on a declared node,data type, or memberWHENhover runsTHENthe symbol's kind and FQN, or itsmember signature, is shownANDits `///` summary is appended underthe title
HoverFallsBackToInferredType

An unresolved caret on a local binding falls back to its inferred type.

  • given the caret resting on a local binding rather than a declaration
  • when hover finds no declared symbol there
  • then the binding's inferred type is shown as `name: Type`
  • but an expression that cannot be typed yields no hover
Flow Flow — HoverFallsBackToInferredType scroll to zoom · drag to pan
FEATUREHoverFallsBackToInferredTypefor AnalysisGIVENthe caret resting on a local bindingrather than a declarationWHENhover finds no declared symbol thereTHENthe binding's inferred type is shownas `name: Type`BUTan expression that cannot be typedyields no hover
ResolutionSurvivesPartialParse

Resolution survives a partial parse by working at the token level.

  • given a document that does not fully parse
  • when the caret rests on an identifier in a well-formed region
  • then resolution still tokenizes and resolves that identifier
  • but a caret on whitespace, punctuation, or an unknown name yields nothing
Flow Flow — ResolutionSurvivesPartialParse scroll to zoom · drag to pan
FEATUREResolutionSurvivesPartialParsefor AnalysisGIVENa document that does not fully parseWHENthe caret rests on an identifier in awell-formed regionTHENresolution still tokenizes andresolves that identifierBUTa caret on whitespace, punctuation, oran unknown name yields nothing
FormatOrLeaveUntouched

Whole-document format produces an edit, or nothing on a parse error.

  • given a document buffer
  • when a format edit is requested
  • then a parseable document yields one whole-document edit to canonical form
  • but an unparseable document yields no edit
Flow Flow — FormatOrLeaveUntouched scroll to zoom · drag to pan
FEATUREFormatOrLeaveUntouchedfor AnalysisGIVENa document bufferWHENa format edit is requestedTHENa parseable document yields onewhole-document edit to canonical formBUTan unparseable document yields no edit
component

Complete #

public
lsp_core::Complete

Completion: the candidates offered at a byte offset, resolved across the @@ -28,10 +28,10 @@ parser/checker's byte-span diagnostics; the code and its URL pass through unchanged.

Entities Entity diagram scroll to zoom · drag to pan
RECORDDiagnosticrangelsp_core::RangeseveritynumbermessagestringcodestringcodeDescriptionstringRECORDRangestartlsp_core::Positionendlsp_core::Position
data

Hover #

public
lsp_core::Hover

Markdown hover content the editor renders in a tooltip.

Entities Entity diagram scroll to zoom · drag to pan
RECORDHovercontentsstring
container

LspCore #

public
lsp_core::LspCore

`crates/pseudoscript-lsp-core`. The single home for language intelligence as transport-neutral handlers — the same logic the stdio server and the browser -wasm both call.

Inbound

Outbound

Scenarios

TransportNeutralHandlers

One implementation answers from current text, transport-free.

  • given a buffer's current text and a caret position
  • when a language query runs
  • then the answer is computed as a pure text-plus-position function
  • but no transport, async runtime, or tower-lsp is involved — both edges share it
Flow Flow — TransportNeutralHandlers scroll to zoom · drag to pan
FEATURETransportNeutralHandlersfor LspCoreGIVENa buffer's current text and a caretpositionWHENa language query runsTHENthe answer is computed as a puretext-plus-position functionBUTno transport, async runtime, ortower-lsp is involved — both edgesshare it
Components Component diagram scroll to zoom · drag to pan
PseudoscriptLspCoreCOMPONENTAnalysisDocument-level analysis: parse-and-checkdiagnostics, Markdown hover for the symbol…COMPONENTCompleteCompletion: the candidates offered at a byteoffset, resolved across the workspace and…COMPONENTConvertPosition conversion: the single home formapping between byte offsets and UTF-16…COMPONENTRefsReferences and rename: every occurrence ofthe symbol under the caret across the…COMPONENTSemanticSemantic tokens: AST-aware highlighting thatcolours each token by its declared role,…COMPONENTSymbolsDocument and workspace structure: theoutline symbols, the foldable ranges, and…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…check
data

Position #

public
lsp_core::Position

A zero-based caret position: line and UTF-16 character offset within the +wasm both call.

Inbound

Outbound

Scenarios

TransportNeutralHandlers

One implementation answers from current text, transport-free.

  • given a buffer's current text and a caret position
  • when a language query runs
  • then the answer is computed as a pure text-plus-position function
  • but no transport, async runtime, or tower-lsp is involved — both edges share it
Flow Flow — TransportNeutralHandlers scroll to zoom · drag to pan
FEATURETransportNeutralHandlersfor LspCoreGIVENa buffer's current text and a caretpositionWHENa language query runsTHENthe answer is computed as a puretext-plus-position functionBUTno transport, async runtime, ortower-lsp is involved — both edgesshare it
Components Component diagram scroll to zoom · drag to pan
PseudoscriptLspCoreCOMPONENTAnalysisDocument-level analysis: parse-and-checkdiagnostics, Markdown hover for the symbol…COMPONENTCompleteCompletion: the candidates offered at a byteoffset, resolved across the workspace and…COMPONENTConvertPosition conversion: the single home formapping between byte offsets and UTF-16…COMPONENTRefsReferences and rename: every occurrence ofthe symbol under the caret across the…COMPONENTSemanticSemantic tokens: AST-aware highlighting thatcolours each token by its declared role,…COMPONENTSymbolsDocument and workspace structure: theoutline symbols, the foldable ranges, and…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…check
data

Position #

public
lsp_core::Position

A zero-based caret position: line and UTF-16 character offset within the line. This and the shapes below model the standalone `lsp_types` vocabulary the crate returns (pinned to the version tower-lsp re-exports, wasm-safe), -so the server edge passes values through with no conversion.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPositionlinenumbercharacternumber
data

Range #

public
lsp_core::Range

A half-open text range between two positions.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDRangestartlsp_core::Positionendlsp_core::PositionRECORDPositionlinenumbercharacternumber
component

Refs #

public
lsp_core::Refs

References and rename: every occurrence of the symbol under the caret across +so the server edge passes values through with no conversion.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPositionlinenumbercharacternumber
data

Range #

public
lsp_core::Range

A half-open text range between two positions.

Entities Entity diagram scroll to zoom · drag to pan
RECORDRangestartlsp_core::Positionendlsp_core::PositionRECORDPositionlinenumbercharacternumber
component

Refs #

public
lsp_core::Refs

References and rename: every occurrence of the symbol under the caret across the workspace, the document highlights for it, and the workspace-wide rename edits.

Parent

Scenarios

RenameAcrossWorkspace

Rename rewrites every occurrence of one definition across the workspace.

  • given the caret on a renameable symbol
  • when rename runs
  • then every identifier resolving to the same definition is collected
  • and each occurrence is rewritten across all files that reference it
  • but a `::` module qualifier is never treated as an occurrence
Flow Flow — RenameAcrossWorkspace scroll to zoom · drag to pan
FEATURERenameAcrossWorkspacefor RefsGIVENthe caret on a renameable symbolWHENrename runsTHENevery identifier resolving to the samedefinition is collectedANDeach occurrence is rewritten acrossall files that reference itBUTa `::` module qualifier is nevertreated as an occurrence
component

Semantic #

public
lsp_core::Semantic

Semantic tokens: AST-aware highlighting that colours each token by its declared role, plus the legend the editor binds.

Parent

Scenarios

ColourByDeclaredRole

Semantic tokens colour identifiers by their declared role.

  • given a parsed module
  • when full semantic tokens are requested
  • then each identifier is coloured by its role — node, data, callable, parameter
  • and keywords, docs, and literals are coloured too
  • but overlapping, multi-line, or zero-width spans are dropped before encoding
Flow Flow — ColourByDeclaredRole scroll to zoom · drag to pan
FEATUREColourByDeclaredRolefor SemanticGIVENa parsed moduleWHENfull semantic tokens are requestedTHENeach identifier is coloured by itsrole — node, data, callable, parameterANDkeywords, docs, and literals arecoloured tooBUToverlapping, multi-line, or zero-widthspans are dropped before encoding
component

Symbols #

public
lsp_core::Symbols

Document and workspace structure: the outline symbols, the foldable ranges, diff --git a/model/site/module/model.html b/model/site/module/model.html index 93ccca44..e068f78f 100644 --- a/model/site/module/model.html +++ b/model/site/module/model.html @@ -11,7 +11,7 @@ -

PseudoScript
Module

model

data

Alt #

public
model::Alt
Entities Entity diagram scroll to zoom · drag to pan
RECORDAltcondLabelstringthenStepsmodel::Step[]elseStepsmodel::Step[]UNIONStepCallSelfCallReturnAltLoop
data

ArchRule #

public
model::ArchRule

One architectural-principle lint rule (LANG.md §9 — the C4 facade/boundary +

PseudoScript
Module

model

data

Alt #

public
model::Alt
Entities Entity diagram scroll to zoom · drag to pan
RECORDAltcondLabelstringthenStepsmodel::Step[]elseStepsmodel::Step[]UNIONStepCallSelfCallReturnAltLoop
data

ArchRule #

public
model::ArchRule

One architectural-principle lint rule (LANG.md §9 — the C4 facade/boundary principles). `code` is its stable identifier (`PDS-ARCH-001`); `slug` is the filename of the article documenting it under the published principles base URL. Every firing is a `Warning` — a violation advises rather than @@ -21,18 +21,18 @@ not an internal `component` (Facade/Gateway); the module dependency graph SHOULD stay acyclic; a cross-system call SHOULD couple to the other system's boundary, not its containers. Each firing is a `Warning` stamped with the rule's `code` -and `codeDescription` (its article URL); the model stays valid.

Parent

Inbound

Outbound

data

Branch #

public
model::Branch
Entities Entity diagram scroll to zoom · drag to pan
RECORDBranchnamestring
component

Builder #

private
model::Builder

Projects the parsed, resolved workspace into the architecture graph: structural +and `codeDescription` (its article URL); the model stays valid.

Parent

Inbound

Outbound

data

Branch #

public
model::Branch
Entities Entity diagram scroll to zoom · drag to pan
RECORDBranchnamestring
component

Builder #

private
model::Builder

Projects the parsed, resolved workspace into the architecture graph: structural nodes plus edges from `for` parents, body calls, triggers, and `from` provenance, with a sequence trace recorded per disclosed body. A pure projection — no I/O — so the emit crate and a future salsa/LSP layer can both -adopt it.

Parent

Inbound

Outbound

Scenarios

ResolveToOneGraph

One resolved graph feeds every view (§9).

  • given a parsed, resolved workspace
  • when the graph is built
  • then every structural node and callable becomes a graph node
  • and for-parent, call, trigger, and provenance edges are recorded
  • and each disclosed body carries an ordered sequence trace
Flow Flow — ResolveToOneGraph scroll to zoom · drag to pan
FEATUREResolveToOneGraphfor BuilderGIVENa parsed, resolved workspaceWHENthe graph is builtTHENevery structural node and callablebecomes a graph nodeANDfor-parent, call, trigger, andprovenance edges are recordedANDeach disclosed body carries an orderedsequence trace
data

Call #

public
model::Call
Entities Entity diagram scroll to zoom · drag to pan
RECORDCalltargetFqnstringmethodstring
component

CaretResolve #

public
model::CaretResolve

Caret resolution — the engine every cursor feature shares (`lsp_core` hover, +adopt it.

Parent

Inbound

Outbound

Scenarios

ResolveToOneGraph

One resolved graph feeds every view (§9).

  • given a parsed, resolved workspace
  • when the graph is built
  • then every structural node and callable becomes a graph node
  • and for-parent, call, trigger, and provenance edges are recorded
  • and each disclosed body carries an ordered sequence trace
Flow Flow — ResolveToOneGraph scroll to zoom · drag to pan
FEATUREResolveToOneGraphfor BuilderGIVENa parsed, resolved workspaceWHENthe graph is builtTHENevery structural node and callablebecomes a graph nodeANDfor-parent, call, trigger, andprovenance edges are recordedANDeach disclosed body carries an orderedsequence trace
data

Call #

public
model::Call
Entities Entity diagram scroll to zoom · drag to pan
RECORDCalltargetFqnstringmethodstring
component

CaretResolve #

public
model::CaretResolve

Caret resolution — the engine every cursor feature shares (`lsp_core` hover, definition, references, rename; the IDE's symbol actions). Tokenizes the active source, finds the identifier under the offset, and resolves it across -the workspace and its externals: a node or data FQN, a `self.`/member access, +the workspace and its externals: a node or data FQN, a same-node call or member access, or a local reference. Token-level, so it survives a partial parse.

Parent

component

Checks #

private
model::Checks

Static analysis (LANG.md §2.2, §2.3, §2.4, §3.3, §3.4, §3.5, §4, §5.1, §5.2, §6, §7, §8): builds the symbol tables, then runs the well-formedness checks. Every entry returns a `syntax::Diagnostic[]`; well-formed input yields an empty one. -Checks are conservative — each rule fires only when the violation is certain.

Parent

Inbound

Outbound

Scenarios

DiagnosticsAreData

Well-formed input yields no diagnostics: a check returns data, never throws.

  • given a well-formed module
  • when it is checked
  • then the returned diagnostic list is empty
  • but the check never throws or aborts
Flow Flow — DiagnosticsAreData scroll to zoom · drag to pan
FEATUREDiagnosticsAreDatafor ChecksGIVENa well-formed moduleWHENit is checkedTHENthe returned diagnostic list is emptyBUTthe check never throws or aborts
ErrorAttributedToReferrer

A cross-module visibility error is attributed to the referrer (§8.2).

  • given module B referencing a private node in module A
  • when the workspace is checked per module
  • then the diagnostic lands in module B, where the reference is written
  • but module A, the declarer, stays clean
Flow Flow — ErrorAttributedToReferrer scroll to zoom · drag to pan
FEATUREErrorAttributedToReferrerfor ChecksGIVENmodule B referencing a private node inmodule AWHENthe workspace is checked per moduleTHENthe diagnostic lands in module B,where the reference is writtenBUTmodule A, the declarer, stays clean
data

Commit #

public
model::Commit
Entities Entity diagram scroll to zoom · drag to pan
RECORDCommithashstring
component

Completion #

public
model::Completion

Context-aware completion (the model-native producer `lsp_core` maps to LSP +Checks are conservative — each rule fires only when the violation is certain.

Parent

Inbound

Outbound

Scenarios

DiagnosticsAreData

Well-formed input yields no diagnostics: a check returns data, never throws.

  • given a well-formed module
  • when it is checked
  • then the returned diagnostic list is empty
  • but the check never throws or aborts
Flow Flow — DiagnosticsAreData scroll to zoom · drag to pan
FEATUREDiagnosticsAreDatafor ChecksGIVENa well-formed moduleWHENit is checkedTHENthe returned diagnostic list is emptyBUTthe check never throws or aborts
ErrorAttributedToReferrer

A cross-module visibility error is attributed to the referrer (§8.2).

  • given module B referencing a private node in module A
  • when the workspace is checked per module
  • then the diagnostic lands in module B, where the reference is written
  • but module A, the declarer, stays clean
Flow Flow — ErrorAttributedToReferrer scroll to zoom · drag to pan
FEATUREErrorAttributedToReferrerfor ChecksGIVENmodule B referencing a private node inmodule AWHENthe workspace is checked per moduleTHENthe diagnostic lands in module B,where the reference is writtenBUTmodule A, the declarer, stays clean
data

Commit #

public
model::Commit
Entities Entity diagram scroll to zoom · drag to pan
RECORDCommithashstring
component

Completion #

public
model::Completion

Context-aware completion (the model-native producer `lsp_core` maps to LSP items): candidates at a caret offset resolved across the workspace and its externals — members after `.`, a module's public symbols after `::`, the built-in macros after `#[`, types in type position, else keywords and symbols.

Parent

data

ConstantType #

public
model::ConstantType

One `constant`'s FQN paired with its declared primitive type name (§3.6, @@ -77,11 +77,11 @@ statement block, and doc-comment runs.

Parent

data

Git #

public
model::Git
Entities Entity diagram scroll to zoom · drag to pan
RECORDGiturlstringselectormodel::RevsubstringUNIONRevTagBranchCommitDefault
data

Graph #

public
model::Graph

The resolved architecture graph: every node and typed edge across all C4 levels, plus feature scenarios. The single source every view projects from — enough to extract any view without re-reading source. Per-callable sequence -traces (`Step[]`) are held alongside, keyed by the owning callable's FQN.

Entities Entity diagram scroll to zoom · drag to pan
RECORDGraphnodesmodel::GraphNode[]edgesmodel::Edge[]scenariosmodel::Scenario[]RECORDGraphNodefqnstringnamestringkindmodel::NodeKindparentstringmodulestringvisibilitymodel::Visibilityspansyntax::Spantriggersmodel::Trigger[]signaturemodel::Signatureshapemodel::DataShapedocmodel::NodeDocRECORDEdgesourcestringtostringkindmodel::EdgeKindlabelstringspansyntax::SpanRECORDScenarionamestringtargetFqnstringmodulestringspansyntax::Spandocmodel::NodeDocstepsmodel::ScenarioStep[]
data

GraphNode #

public
model::GraphNode

One node in the resolved graph — a structural declaration, a `data` type, or a +traces (`Step[]`) are held alongside, keyed by the owning callable's FQN.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDGraphnodesmodel::GraphNode[]edgesmodel::Edge[]scenariosmodel::Scenario[]RECORDGraphNodefqnstringnamestringkindmodel::NodeKindparentstringmodulestringvisibilitymodel::Visibilityspansyntax::Spantriggersmodel::Trigger[]signaturemodel::Signatureshapemodel::DataShapedocmodel::NodeDocRECORDEdgesourcestringtostringkindmodel::EdgeKindlabelstringspansyntax::SpanRECORDScenarionamestringtargetFqnstringmodulestringspansyntax::Spandocmodel::NodeDocstepsmodel::ScenarioStep[]
data

GraphNode #

public
model::GraphNode

One node in the resolved graph — a structural declaration, a `data` type, or a callable. Carries its FQN, simple name, kind, enclosing-node FQN (`for` parent, owning node, or empty at top level), declaring module, visibility, name span, any trigger macros (callables only), the call signature (callables only), the -disclosed shape (`data` only), and lifted `///` documentation.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDGraphNodefqnstringnamestringkindmodel::NodeKindparentstringmodulestringvisibilitymodel::Visibilityspansyntax::Spantriggersmodel::Trigger[]signaturemodel::Signatureshapemodel::DataShapedocmodel::NodeDocUNIONNodeKindPersonSystemContainerComponentDataCallableUNIONVisibilityPublicPrivateRECORDSpanstartnumberendnumberUNIONTriggerOnEventScheduleHttpManualRECORDSignatureparamsmodel::SigParam[]retstringUNIONDataShapeRecordUnionBlackBoxRECORDNodeDocsummarystringextendedstringtagsstring[]
component

Inference #

public
model::Inference

Local-binding type inference, for inlay hints and hover. Assignments are +disclosed shape (`data` only), and lifted `///` documentation.

Entities Entity diagram scroll to zoom · drag to pan
RECORDGraphNodefqnstringnamestringkindmodel::NodeKindparentstringmodulestringvisibilitymodel::Visibilityspansyntax::Spantriggersmodel::Trigger[]signaturemodel::Signatureshapemodel::DataShapedocmodel::NodeDocUNIONNodeKindPersonSystemContainerComponentDataCallableUNIONVisibilityPublicPrivateRECORDSpanstartnumberendnumberUNIONTriggerOnEventScheduleHttpManualRECORDSignatureparamsmodel::SigParam[]retstringUNIONDataShapeRecordUnionBlackBoxRECORDNodeDocsummarystringextendedstringtagsstring[]
component

Inference #

public
model::Inference

Local-binding type inference, for inlay hints and hover. Assignments are untyped (`x = expr`); this infers each binding's type from its right-hand side — a call's return type, a field access, a `from` expression, or a literal. Best-effort: an un-typeable expression yields nothing rather than a guess.

Parent

data

Local #

public
model::Local
Entities Entity diagram scroll to zoom · drag to pan
RECORDLocalpathstring
data

Lock #

public
model::Lock

A parsed `pds.lock` (§8.4): the pinned dependency graph. A black box here — its @@ -98,10 +98,10 @@ (§5.1) or a `data` record field (§3.4).

Entities Entity diagram scroll to zoom · drag to pan
UNIONMemberKindCallableFieldRECORDFieldnamestringtysyntax::Typespansyntax::Span
container

Model #

public
model::Model

`crates/pseudoscript-model`. AST to one resolved graph; static checks (resolution, visibility, Result flow, return coverage); the §8.3 dependency resolver; and the LSP analysis primitives (completion, folding, semantic -tokens, inference). WASM-safe.

Inbound

Outbound

Components Component diagram scroll to zoom · drag to pan
PseudoscriptModelCOMPONENTResolverResolves a module's declarations into asymbol table (LANG.md §8). FQNs are…COMPONENTWorkspaceThe resolved set of modules keyed by FQN(LANG.md §8). Built once per workspace from…COMPONENTChecksStatic analysis (LANG.md §2.2, §2.3, §2.4,§3.3, §3.4, §3.5, §4, §5.1, §5.2, §6, §7,…COMPONENTCrossModule§8.2 — cross-module visibility resolution.Walks each module's qualified references —…COMPONENTArchitectureLANG.md §9 — architectural-principle lintsover the resolved graph. Beyond §8.2…COMPONENTResultFlow§6 — flow-sensitive `Result` / `Option`typestate. Each binding carries a state…COMPONENTReturnCoverageADR-016 — return coverage. A disclosednon-void callable MUST return on every path…COMPONENTMacroTargeting§2.4 / ADR-015 — macro targeting. Everybuilt-in macro (`onevent`, `schedule`,…COMPONENTParentKind§4 / ADR-010 — C4 parent-kindwell-formedness. A `for` parent links a nod…COMPONENTVariantCollision§3.5 / ADR-006 — union variant collision. Atop-level `data Name` followed by an inline…COMPONENTFeatureCheck§5.2 / §8.1 — feature checks. A feature's`for` target MUST resolve to a node, not a…COMPONENTReservedNames§2.3 / ADR-012 — reserved-word identifiers.A declared identifier MUST NOT be a reserve…COMPONENTTypeRefs§3.3 / §8.1 — type-reference resolution.Every named type in a declaration — a field…COMPONENTBuilderProjects the parsed, resolved workspace intothe architecture graph: structural nodes…COMPONENTDeps§8.3 — the dependency resolver. Parses amanifest's `[dependencies]` and a…COMPONENTCaretResolveCaret resolution — the engine every cursorfeature shares (`lsp_core` hover,…COMPONENTCompletionContext-aware completion (the model-nativeproducer `lsp_core` maps to LSP items):…COMPONENTFoldingThe foldable regions of a module: everymulti-line disclosed declaration and…COMPONENTSemanticAST-aware semantic colouring: eachidentifier classified by its declared role…COMPONENTInferenceLocal-binding type inference, for inlayhints and hover. Assignments are untyped (`…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERIdeSession`crates/pseudoscript-ide` — the IDEapplication, Rust compiled to a single wasm…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERLspCore`crates/pseudoscript-lsp-core`. The singlehome for language intelligence as…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…CONTAINERUniverse`crates/pseudoscript-universe`. Maps theresolved C4 model into the software graph…runStdiorenderTokensbuildflowssnapshotdefinitionformatEdithoverbuildcheckgraphOfcheckcheckcheckbuildcheckcheckbuildWithExternalsparse
data

ModuleDiagnostics #

public
model::ModuleDiagnostics

One workspace module's diagnostics, attributed to its FQN. Every span lies in +tokens, inference). WASM-safe.

Inbound

Outbound

Components Component diagram scroll to zoom · drag to pan
PseudoscriptModelCOMPONENTResolverResolves a module's declarations into asymbol table (LANG.md §8). FQNs are…COMPONENTWorkspaceThe resolved set of modules keyed by FQN(LANG.md §8). Built once per workspace from…COMPONENTChecksStatic analysis (LANG.md §2.2, §2.3, §2.4,§3.3, §3.4, §3.5, §4, §5.1, §5.2, §6, §7,…COMPONENTCrossModule§8.2 — cross-module visibility resolution.Walks each module's qualified references —…COMPONENTArchitectureLANG.md §9 — architectural-principle lintsover the resolved graph. Beyond §8.2…COMPONENTResultFlow§6 — flow-sensitive `Result` / `Option`typestate. Each binding carries a state…COMPONENTReturnCoverageADR-016 — return coverage. A disclosednon-void callable MUST return on every path…COMPONENTMacroTargeting§2.4 / ADR-015 — macro targeting. Everybuilt-in macro (`onevent`, `schedule`,…COMPONENTParentKind§4 / ADR-010 — C4 parent-kindwell-formedness. A `for` parent links a nod…COMPONENTVariantCollision§3.5 / ADR-006 — union variant collision. Atop-level `data Name` followed by an inline…COMPONENTFeatureCheck§5.2 / §8.1 — feature checks. A feature's`for` target MUST resolve to a node, not a…COMPONENTReservedNames§2.3 / ADR-012 — reserved-word identifiers.A declared identifier MUST NOT be a reserve…COMPONENTTypeRefs§3.3 / §8.1 — type-reference resolution.Every named type in a declaration — a field…COMPONENTBuilderProjects the parsed, resolved workspace intothe architecture graph: structural nodes…COMPONENTDeps§8.3 — the dependency resolver. Parses amanifest's `[dependencies]` and a…COMPONENTCaretResolveCaret resolution — the engine every cursorfeature shares (`lsp_core` hover,…COMPONENTCompletionContext-aware completion (the model-nativeproducer `lsp_core` maps to LSP items):…COMPONENTFoldingThe foldable regions of a module: everymulti-line disclosed declaration and…COMPONENTSemanticAST-aware semantic colouring: eachidentifier classified by its declared role…COMPONENTInferenceLocal-binding type inference, for inlayhints and hover. Assignments are untyped (`…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERIdeSession`crates/pseudoscript-ide` — the IDEapplication, Rust compiled to a single wasm…CONTAINERLspCore`crates/pseudoscript-lsp-core`. The singlehome for language intelligence as…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…CONTAINERUniverse`crates/pseudoscript-universe`. Maps theresolved C4 model into the software graph…renderTokensbuildflowssnapshotbuildcheckgraphOfcheckcheckcheckbuildcheckcheckbuildWithExternalsparse
data

ModuleDiagnostics #

public
model::ModuleDiagnostics

One workspace module's diagnostics, attributed to its FQN. Every span lies in that module's own source, so a tool with the FQN-to-file mapping publishes -each list against the right file.

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleDiagnosticsfqnstringdiagnosticssyntax::Diagnostic[]RECORDDiagnosticseveritysyntax::Severityspansyntax::SpancodestringcodeDescriptionstringmessagestring
data

ModuleEntry #

public
model::ModuleEntry

One module's parsed AST, resolved symbol table, and FQN, as held by a -`Workspace`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleEntryfqnstringastsyntax::Modulemodelmodel::SymbolTableRECORDModuleinnerDocssyntax::InnerDoc[]itemssyntax::Item[]spansyntax::SpanRECORDSymbolTablemodulePathstringsymbolsmodel::Symbol[]membersmodel::Member[]unionVariantsmodel::FieldlessVariants[]constantTypesmodel::ConstantType[]
data

NodeDoc #

public
model::NodeDoc

A node's documentation, lifted from its `///` block (LANG.md §2.1): the +each list against the right file.

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleDiagnosticsfqnstringdiagnosticssyntax::Diagnostic[]RECORDDiagnosticseveritysyntax::Severityspansyntax::SpancodestringcodeDescriptionstringmessagestring
data

ModuleEntry #

public
model::ModuleEntry

One module's parsed AST, resolved symbol table, and FQN, as held by a +`Workspace`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleEntryfqnstringastsyntax::Modulemodelmodel::SymbolTableRECORDModuleinnerDocssyntax::InnerDoc[]itemssyntax::Item[]spansyntax::SpanRECORDSymbolTablemodulePathstringsymbolsmodel::Symbol[]membersmodel::Member[]unionVariantsmodel::FieldlessVariants[]constantTypesmodel::ConstantType[]
data

NodeDoc #

public
model::NodeDoc

A node's documentation, lifted from its `///` block (LANG.md §2.1): the summary (compact-diagram text), the extended description (tooltip text), and its tags (` `, including the `#`), in source order.

#name
Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeDocsummarystringextendedstringtagsstring[]
data

NodeKind #

public
model::NodeKind

What kind of model element a `GraphNode` is. Adds `Callable` to the structural @@ -142,7 +142,7 @@ the declaring module's FQN, the span of the feature name (a host's go-to-definition target), lifted `///` documentation, and the ordered given/when/then steps. Steps are prose, not resolved, so a scenario adds no -edges; it renders as a card on its target node's doc page.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDScenarionamestringtargetFqnstringmodulestringspansyntax::Spandocmodel::NodeDocstepsmodel::ScenarioStep[]RECORDSpanstartnumberendnumberRECORDNodeDocsummarystringextendedstringtagsstring[]RECORDScenarioStepkeywordstringtextstring
data

ScenarioStep #

public
model::ScenarioStep

One step of a `Scenario` (LANG.md §5.2): a keyword (`given`/`when`/`then`/ +edges; it renders as a card on its target node's doc page.

Entities Entity diagram scroll to zoom · drag to pan
RECORDScenarionamestringtargetFqnstringmodulestringspansyntax::Spandocmodel::NodeDocstepsmodel::ScenarioStep[]RECORDSpanstartnumberendnumberRECORDNodeDocsummarystringextendedstringtagsstring[]RECORDScenarioStepkeywordstringtextstring
data

ScenarioStep #

public
model::ScenarioStep

One step of a `Scenario` (LANG.md §5.2): a keyword (`given`/`when`/`then`/ `and`/`but`) and its prose, with the string literal's quotes stripped.

Entities Entity diagram scroll to zoom · drag to pan
RECORDScenarioStepkeywordstringtextstring
data

SelfCall #

public
model::SelfCall
Entities Entity diagram scroll to zoom · drag to pan
RECORDSelfCallmethodstring
component

Semantic #

public
model::Semantic

AST-aware semantic colouring: each identifier classified by its declared role (node→namespace, `data`→class, callable→method, parameter, call segment), the spans `lsp_core` delta-encodes for the editor.

Parent

data

SigParam #

public
model::SigParam

One parameter of a callable signature: its name and rendered type.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSigParamnamestringtystring
data

Signature #

public
model::Signature

A callable node's signature (§5.1): its ordered parameters and rendered return @@ -170,10 +170,10 @@ variants reference existing data and never collide.

Parent

Inbound

Outbound

Scenarios

VariantNameCollision

An inline union variant colliding with a prior data name is rejected (§3.5).

  • given a top-level `data Name` and an inline variant `| Name { ... }`
  • when the module is checked
  • then the colliding inline variant is rejected
  • but a bare `| Name` referencing the existing data is accepted
Flow Flow — VariantNameCollision scroll to zoom · drag to pan
FEATUREVariantNameCollisionfor VariantCollisionGIVENa top-level `data Name` and an inlinevariant `| Name { ... }`WHENthe module is checkedTHENthe colliding inline variant isrejectedBUTa bare `| Name` referencing theexisting data is accepted
data

Visibility #

public
model::Visibility

Whether a node is `public` (cross-module addressable) or module-private (LANG.md §8.2).

Entities Entity diagram scroll to zoom · drag to pan
UNIONVisibilityPublicPrivateRECORDPublicsymbolmodel::SymbolRECORDPrivatesymbolmodel::Symbol
component

Workspace #

public
model::Workspace

The resolved set of modules keyed by FQN (LANG.md §8). Built once per workspace from `(fqn, parsed module)` pairs; owns the per-module models and a -global FQN-to-`Symbol` index for cross-module resolution.

Parent

Inbound

Outbound

Scenarios

SameModuleAlwaysResolves

A same-module reference resolves regardless of visibility (§8.2).

  • given a reference whose target is declared in the same module
  • when the reference is resolved
  • then it resolves whether the target is public or private
Flow Flow — SameModuleAlwaysResolves scroll to zoom · drag to pan
FEATURESameModuleAlwaysResolvesfor WorkspaceGIVENa reference whose target is declaredin the same moduleWHENthe reference is resolvedTHENit resolves whether the target ispublic or private
data

WorkspaceModule #

public
model::WorkspaceModule

One `.pds` module of a workspace: its caller-supplied FQN (the loader derives +global FQN-to-`Symbol` index for cross-module resolution.

Parent

Inbound

Outbound

Scenarios

SameModuleAlwaysResolves

A same-module reference resolves regardless of visibility (§8.2).

  • given a reference whose target is declared in the same module
  • when the reference is resolved
  • then it resolves whether the target is public or private
Flow Flow — SameModuleAlwaysResolves scroll to zoom · drag to pan
FEATURESameModuleAlwaysResolvesfor WorkspaceGIVENa reference whose target is declaredin the same moduleWHENthe reference is resolvedTHENit resolves whether the target ispublic or private
data

WorkspaceModule #

public
model::WorkspaceModule

One `.pds` module of a workspace: its caller-supplied FQN (the loader derives it from the file path relative to `pds.toml`, LANG.md §8.1) and its source text. This crate stays pure over in-memory modules; it never touches the -filesystem.

Entities Entity diagram scroll to zoom · drag to pan
RECORDWorkspaceModulefqnstringsourcestring
Generated by pds doc.
+filesystem.

Entities Entity diagram scroll to zoom · drag to pan
RECORDWorkspaceModulefqnstringsourcestring
Generated by pds doc.
diff --git a/model/site/module/project.html b/model/site/module/project.html index 777c34d0..6c5dabe1 100644 --- a/model/site/module/project.html +++ b/model/site/module/project.html @@ -11,14 +11,14 @@ -
PseudoScript
Module

project

component

Deps #

public
project::Deps

Resolves a workspace's declared dependencies into modules the checker binds as +

PseudoScript
Module

project

component

Deps #

public
project::Deps

Resolves a workspace's declared dependencies into modules the checker binds as externals (§8.3): reads `pds.lock` + `pds_modules/`, materialises each direct dependency's `.pds` modules under its dependency-name prefix, and resolves a local path dependency's directory.

Parent

Scenarios

DependenciesLoadAsExternals

Dependencies load as prefixed externals for cross-workspace resolution.

  • given a workspace declaring a git or local dependency, vendored under pds_modules/
  • when its dependency modules are read
  • then each direct dependency's .pds modules load under the dependency-name prefix (§8.3)
  • but the dependency's own pds_modules/ are not re-exported
Flow Flow — DependenciesLoadAsExternals scroll to zoom · drag to pan
FEATUREDependenciesLoadAsExternalsfor DepsGIVENa workspace declaring a git or localdependency, vendored underpds_modules/WHENits dependency modules are readTHENeach direct dependency's .pds modulesload under the dependency-name prefix(§8.3)BUTthe dependency's own pds_modules/ arenot re-exported
data

IoError #

public
project::IoError

A filesystem failure surfaced to the caller: the path or manifest that could not be read, with a human-readable message.

Entities Entity diagram scroll to zoom · drag to pan
RECORDIoErrormessagestring
component

Loader #

private
project::Loader

Resolves and reads a workspace off disk: finds the root by walking up to the nearest `pds.toml`, then walks the tree for visible `.pds` files and loads each as a `(fqn, source)` module — mapping its path to a flat module FQN (§8.1) and -skipping `target/` and `pds_modules/`.

Parent

Inbound

Outbound

  • from project::Result
  • from project::Result

Scenarios

FindWorkspaceRoot

The root is the nearest ancestor holding `pds.toml`.

  • given a path inside a workspace directory tree
  • when the root is resolved
  • then the nearest ancestor directory holding a pds.toml is the root
  • but a tree with no pds.toml up to the filesystem root fails with an IoError
Flow Flow — FindWorkspaceRoot scroll to zoom · drag to pan
FEATUREFindWorkspaceRootfor LoaderGIVENa path inside a workspace directorytreeWHENthe root is resolvedTHENthe nearest ancestor directory holdinga pds.toml is the rootBUTa tree with no pds.toml up to thefilesystem root fails with an IoError
LoadModulesSkippingBuildAndVendor

The walk loads `.pds` modules and skips build and vendor directories.

  • given a workspace whose tree includes target/ and pds_modules/ directories
  • when its modules are loaded
  • then every visible .pds file becomes a (fqn, source) module
  • and each file's path maps to its flat module FQN (§8.1)
  • but files under target/ and pds_modules/ are skipped
Flow Flow — LoadModulesSkippingBuildAndVendor scroll to zoom · drag to pan
FEATURELoadModulesSkippingBuildAndVendorfor LoaderGIVENa workspace whose tree includestarget/ and pds_modules/ directoriesWHENits modules are loadedTHENevery visible .pds file becomes a(fqn, source) moduleANDeach file's path maps to its flatmodule FQN (§8.1)BUTfiles under target/ and pds_modules/are skipped
container

Project #

public
project::Project

`crates/pseudoscript-project`. The disk-facing loader: resolves the workspace +skipping `target/` and `pds_modules/`.

Parent

Inbound

Scenarios

FindWorkspaceRoot

The root is the nearest ancestor holding `pds.toml`.

  • given a path inside a workspace directory tree
  • when the root is resolved
  • then the nearest ancestor directory holding a pds.toml is the root
  • but a tree with no pds.toml up to the filesystem root fails with an IoError
Flow Flow — FindWorkspaceRoot scroll to zoom · drag to pan
FEATUREFindWorkspaceRootfor LoaderGIVENa path inside a workspace directorytreeWHENthe root is resolvedTHENthe nearest ancestor directory holdinga pds.toml is the rootBUTa tree with no pds.toml up to thefilesystem root fails with an IoError
LoadModulesSkippingBuildAndVendor

The walk loads `.pds` modules and skips build and vendor directories.

  • given a workspace whose tree includes target/ and pds_modules/ directories
  • when its modules are loaded
  • then every visible .pds file becomes a (fqn, source) module
  • and each file's path maps to its flat module FQN (§8.1)
  • but files under target/ and pds_modules/ are skipped
Flow Flow — LoadModulesSkippingBuildAndVendor scroll to zoom · drag to pan
FEATURELoadModulesSkippingBuildAndVendorfor LoaderGIVENa workspace whose tree includestarget/ and pds_modules/ directoriesWHENits modules are loadedTHENevery visible .pds file becomes a(fqn, source) moduleANDeach file's path maps to its flatmodule FQN (§8.1)BUTfiles under target/ and pds_modules/are skipped
container

Project #

public
project::Project

`crates/pseudoscript-project`. The disk-facing loader: resolves the workspace root, reads its `.pds` modules, and materialises dependency modules from the vendor directory. The only place the native toolchain touches the filesystem for project loading.

Inbound

Outbound

Components Component diagram scroll to zoom · drag to pan
PseudoscriptProjectCOMPONENTLoaderResolves and reads a workspace off disk:finds the root by walking up to the nearest…COMPONENTDepsResolves a workspace's declared dependenciesinto modules the checker binds as externals…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…
Generated by pds doc.
diff --git a/model/site/module/syntax.html b/model/site/module/syntax.html index 31ba2e03..9723ac0a 100644 --- a/model/site/module/syntax.html +++ b/model/site/module/syntax.html @@ -11,7 +11,7 @@ -
PseudoScript
Module

syntax

data

Assign #

public
syntax::Assign
Entities Entity diagram scroll to zoom · drag to pan
RECORDAssignnamestringvaluesyntax::ExprRECORDExprkindsyntax::ExprKindspansyntax::Span
data

BinOp #

public
syntax::BinOp

A binary operator (§7.5): arithmetic, comparison, equality, and boolean.

Entities Entity diagram scroll to zoom · drag to pan
UNIONBinOpAddSubMulDivRemEqNeLtGtLeGeAndOr
data

Binary #

public
syntax::Binary
Entities Entity diagram scroll to zoom · drag to pan
RECORDBinaryleftsyntax::Expropsyntax::BinOpopSpansyntax::Spanrightsyntax::ExprRECORDExprkindsyntax::ExprKindspansyntax::SpanUNIONBinOpAddSubMulDivRemEqNeLtGtLeGeAndOrRECORDSpanstartnumberendnumber
data

BlankLines #

public
syntax::BlankLines
Entities Entity diagram scroll to zoom · drag to pan
RECORDBlankLinescountnumber
data

Block #

public
syntax::Block

A `{ ... }` statement block (§7): statements in order, plus the brace span.

Entities Entity diagram scroll to zoom · drag to pan
RECORDBlockstmtssyntax::Stmt[]spansyntax::SpanRECORDStmtkindsyntax::StmtKindleadingTriviasyntax::SpannedTrivia[]spansyntax::SpanRECORDSpanstartnumberendnumber
data

BlockComment #

public
syntax::BlockComment
Entities Entity diagram scroll to zoom · drag to pan
RECORDBlockCommenttextstring
data

BodyMember #

public
syntax::BodyMember

A member of a disclosed node body: a callable, or — under error recovery — +

PseudoScript
Module

syntax

data

Assign #

public
syntax::Assign
Entities Entity diagram scroll to zoom · drag to pan
RECORDAssignnamestringvaluesyntax::ExprRECORDExprkindsyntax::ExprKindspansyntax::Span
data

BinOp #

public
syntax::BinOp

A binary operator (§7.5): arithmetic, comparison, equality, and boolean.

Entities Entity diagram scroll to zoom · drag to pan
UNIONBinOpAddSubMulDivRemEqNeLtGtLeGeAndOr
data

Binary #

public
syntax::Binary
Entities Entity diagram scroll to zoom · drag to pan
RECORDBinaryleftsyntax::Expropsyntax::BinOpopSpansyntax::Spanrightsyntax::ExprRECORDExprkindsyntax::ExprKindspansyntax::SpanUNIONBinOpAddSubMulDivRemEqNeLtGtLeGeAndOrRECORDSpanstartnumberendnumber
data

BlankLines #

public
syntax::BlankLines
Entities Entity diagram scroll to zoom · drag to pan
RECORDBlankLinescountnumber
data

Block #

public
syntax::Block

A `{ ... }` statement block (§7): statements in order, plus the brace span.

Entities Entity diagram scroll to zoom · drag to pan
RECORDBlockstmtssyntax::Stmt[]spansyntax::SpanRECORDStmtkindsyntax::StmtKindleadingTriviasyntax::SpannedTrivia[]spansyntax::SpanRECORDSpanstartnumberendnumber
data

BlockComment #

public
syntax::BlockComment
Entities Entity diagram scroll to zoom · drag to pan
RECORDBlockCommenttextstring
data

BodyMember #

public
syntax::BodyMember

A member of a disclosed node body: a callable, or — under error recovery — a nested structural declaration the parser flags as illegal (ADR-011).

Entities Entity diagram scroll to zoom · drag to pan
UNIONBodyMemberCallableMemberDeclMemberRECORDCallableMembercallablesyntax::CallableDeclRECORDDeclMemberdeclsyntax::Declaration
data

BoolLit #

public
syntax::BoolLit
Entities Entity diagram scroll to zoom · drag to pan
RECORDBoolLitvalueboolspansyntax::SpanRECORDSpanstartnumberendnumber
data

CallableDecl #

public
syntax::CallableDecl

A callable (implicit operation) declared inside a disclosed node (§5.1). `returnTy` is required (ADR-040) — a missing return type is a syntax error, recovered as `void`; `body` absent means a black box (`;`).

Entities Entity diagram scroll to zoom · drag to pan
RECORDCallableDecldocsyntax::DocBlockmacrossyntax::Macro[]isPublicboolnamestringparamssyntax::Param[]returnTysyntax::Typebodysyntax::BlockleadingTriviasyntax::SpannedTrivia[]spansyntax::SpanRECORDDocBlocksummarystring[]extendedstring[]tagssyntax::Tag[]RECORDMacronamesyntax::Pathargssyntax::MacroArgsspansyntax::SpanRECORDParamnamestringtysyntax::Typespansyntax::SpanRECORDTypenamesyntax::Pathgenericssyntax::Type[]isArrayboolspansyntax::SpanRECORDBlockstmtssyntax::Stmt[]spansyntax::SpanRECORDSpannedTriviatriviasyntax::Triviaspansyntax::SpanRECORDSpanstartnumberendnumber
data

CallableMember #

public
syntax::CallableMember
Entities Entity diagram scroll to zoom · drag to pan
RECORDCallableMembercallablesyntax::CallableDeclRECORDCallableDecldocsyntax::DocBlockmacrossyntax::Macro[]isPublicboolnamestringparamssyntax::Param[]returnTysyntax::Typebodysyntax::BlockleadingTriviasyntax::SpannedTrivia[]spansyntax::Span
data

Compose #

public
syntax::Compose
Entities Entity diagram scroll to zoom · drag to pan
RECORDComposesourcessyntax::Expr[]RECORDExprkindsyntax::ExprKindspansyntax::Span
data

Constant #

public
syntax::Constant
Entities Entity diagram scroll to zoom · drag to pan
RECORDConstantdeclsyntax::ConstantDeclRECORDConstantDeclnamestringvaluesyntax::Literalspansyntax::Span
data

ConstantDecl #

public
syntax::ConstantDecl

A `constant NAME = Literal` declaration (§3.6, ADR-039): a top-level primitive @@ -24,25 +24,25 @@ tooling; the human-facing text is `message`. `codeDescription` is an optional URL the code resolves to — an article explaining the rule — which the LSP surfaces as the diagnostic's clickable link. Empty when the code carries no -article.

Entities Entity diagram scroll to zoom · drag to pan
RECORDDiagnosticseveritysyntax::Severityspansyntax::SpancodestringcodeDescriptionstringmessagestringUNIONSeverityErrorWarningInfoRECORDSpanstartnumberendnumber
data

DocBlock #

public
syntax::DocBlock

A `///` doc block split into summary and extended on the first blank `///` +article.

Entities Entity diagram scroll to zoom · drag to pan
RECORDDiagnosticseveritysyntax::Severityspansyntax::SpancodestringcodeDescriptionstringmessagestringUNIONSeverityErrorWarningInfoRECORDSpanstartnumberendnumber
data

DocBlock #

public
syntax::DocBlock

A `///` doc block split into summary and extended on the first blank `///` line (ADR-009): summary feeds compact diagrams, extended feeds tooltips, tags carry the ` -` markers.

#name
Entities Entity diagram scroll to zoom · drag to pan
RECORDDocBlocksummarystring[]extendedstring[]tagssyntax::Tag[]RECORDTagtextstringspansyntax::Span
data

Expr #

public
syntax::Expr

An expression (§7, §10): its form and source span.

Entities Entity diagram scroll to zoom · drag to pan
RECORDExprkindsyntax::ExprKindspansyntax::SpanUNIONExprKindMarkerFromPostfixRefLitUnaryBinaryParenRECORDSpanstartnumberendnumber
data

ExprKind #

public
syntax::ExprKind

The expression forms (§10). `Marker` is a built-in generic constructor — +` markers.

#name
Entities Entity diagram scroll to zoom · drag to pan
RECORDDocBlocksummarystring[]extendedstring[]tagssyntax::Tag[]RECORDTagtextstringspansyntax::Span
data

Expr #

public
syntax::Expr

An expression (§7, §10): its form and source span.

Entities Entity diagram scroll to zoom · drag to pan
RECORDExprkindsyntax::ExprKindspansyntax::SpanUNIONExprKindMarkerFromPostfixOwnCallRefLitUnaryBinaryParenRECORDSpanstartnumberendnumber
data

ExprKind #

public
syntax::ExprKind

The expression forms (§10). `Marker` is a built-in generic constructor — `Ok`/`Err` (`Result`) or `Some`/`None` (`Option`); `From` names a target type and its `source`, whose `FromSource` form is the §7.2 vs §7.4 split; -`Postfix` is a `.name`/`.name(..)` access chain (ADR-007); `Unary`/`Binary` -are the §7.5 operator forms. A `Marker` or `From` head is never a binary -operand (§7.5).

Entities Entity diagram scroll to zoom · drag to pan
UNIONExprKindMarkerFromPostfixRefLitUnaryBinaryParenRECORDMarkerkindsyntax::MarkerKindpayloadsyntax::ExprRECORDFromtysyntax::Typesourcesyntax::FromSourceRECORDPostfixbasesyntax::Exprsegmentssyntax::PostfixSeg[]RECORDReftargetsyntax::ReferenceRECORDLitvaluesyntax::LiteralRECORDUnaryopsyntax::UnaryOpopSpansyntax::Spanexprsyntax::ExprRECORDBinaryleftsyntax::Expropsyntax::BinOpopSpansyntax::Spanrightsyntax::ExprRECORDPareninnersyntax::Expr
data

ExprStmt #

public
syntax::ExprStmt
Entities Entity diagram scroll to zoom · drag to pan
RECORDExprStmtexprsyntax::ExprRECORDExprkindsyntax::ExprKindspansyntax::Span
data

FeatureDecl #

public
syntax::FeatureDecl

A `feature Name for Path { given* when+ then+ }` BDD scenario (§5.2). Steps +`Postfix` is a `.name`/`.name(..)` access chain (ADR-007); `OwnCall` is a +bare same-node call `Name(args)` (§5.1, ADR-041); `Unary`/`Binary` are the +§7.5 operator forms. A `Marker` or `From` head is never a binary operand (§7.5).

Entities Entity diagram scroll to zoom · drag to pan
UNIONExprKindMarkerFromPostfixOwnCallRefLitUnaryBinaryParenRECORDMarkerkindsyntax::MarkerKindpayloadsyntax::ExprRECORDFromtysyntax::Typesourcesyntax::FromSourceRECORDPostfixbasesyntax::Exprsegmentssyntax::PostfixSeg[]RECORDOwnCallnamestringargssyntax::Expr[]RECORDReftargetsyntax::ReferenceRECORDLitvaluesyntax::LiteralRECORDUnaryopsyntax::UnaryOpopSpansyntax::Spanexprsyntax::ExprRECORDBinaryleftsyntax::Expropsyntax::BinOpopSpansyntax::Spanrightsyntax::ExprRECORDPareninnersyntax::Expr
data

ExprStmt #

public
syntax::ExprStmt
Entities Entity diagram scroll to zoom · drag to pan
RECORDExprStmtexprsyntax::ExprRECORDExprkindsyntax::ExprKindspansyntax::Span
data

FeatureDecl #

public
syntax::FeatureDecl

A `feature Name for Path { given* when+ then+ }` BDD scenario (§5.2). Steps are prose, not resolved against the model; the strict given→when→then order is enforced by the parser. A feature takes no macros and no `public`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDFeatureDecldocsyntax::DocBlocknamestringtargetsyntax::Pathstepssyntax::FeatureStep[]leadingTriviasyntax::SpannedTrivia[]spansyntax::SpanRECORDDocBlocksummarystring[]extendedstring[]tagssyntax::Tag[]RECORDPathsegmentsstring[]spansyntax::SpanRECORDFeatureStepkindsyntax::StepKindtextstringspansyntax::SpanRECORDSpannedTriviatriviasyntax::Triviaspansyntax::SpanRECORDSpanstartnumberendnumber
data

FeatureItem #

public
syntax::FeatureItem
Entities Entity diagram scroll to zoom · drag to pan
RECORDFeatureItemdeclsyntax::FeatureDeclRECORDFeatureDecldocsyntax::DocBlocknamestringtargetsyntax::Pathstepssyntax::FeatureStep[]leadingTriviasyntax::SpannedTrivia[]spansyntax::Span
data

FeatureStep #

public
syntax::FeatureStep

One step line in a feature flow: a step keyword and its prose string (§5.2).

Entities Entity diagram scroll to zoom · drag to pan
RECORDFeatureStepkindsyntax::StepKindtextstringspansyntax::SpanUNIONStepKindGivenWhenThenAndButRECORDSpanstartnumberendnumber
data

Field #

public
syntax::Field

A record field `name: Type`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDFieldnamestringtysyntax::Typespansyntax::SpanRECORDTypenamesyntax::Pathgenericssyntax::Type[]isArrayboolspansyntax::SpanRECORDSpanstartnumberendnumber
data

For #

public
syntax::For
Entities Entity diagram scroll to zoom · drag to pan
RECORDForbindingstringitersyntax::Exprbodysyntax::BlockRECORDExprkindsyntax::ExprKindspansyntax::SpanRECORDBlockstmtssyntax::Stmt[]spansyntax::Span
data

From #

public
syntax::From
Entities Entity diagram scroll to zoom · drag to pan
RECORDFromtysyntax::Typesourcesyntax::FromSourceRECORDTypenamesyntax::Pathgenericssyntax::Type[]isArrayboolspansyntax::SpanUNIONFromSourceComposeConvert
data

FromSource #

public
syntax::FromSource

The source of a `from` expression (§7.2, §7.4, ADR-035) — the parser branches on the leading token, so the two forms are distinct: a `{` opens `Compose`, a set the target `data` record/variant is built from; anything else is `Convert`, carrying the target type onto one value.

Entities Entity diagram scroll to zoom · drag to pan
UNIONFromSourceComposeConvertRECORDComposesourcessyntax::Expr[]RECORDConvertvaluesyntax::Expr
data

If #

public
syntax::If
Entities Entity diagram scroll to zoom · drag to pan
RECORDIfcondsyntax::ExprthenBlocksyntax::BlockelseBlocksyntax::BlockRECORDExprkindsyntax::ExprKindspansyntax::SpanRECORDBlockstmtssyntax::Stmt[]spansyntax::Span
data

InnerDoc #

public
syntax::InnerDoc

One `//!` inner-doc line documenting the module (§2.1).

Entities Entity diagram scroll to zoom · drag to pan
RECORDInnerDoctextstringspansyntax::SpanRECORDSpanstartnumberendnumber
data

Item #

public
syntax::Item

A top-level item: a documented structural declaration, or a `feature` BDD scenario.

Entities Entity diagram scroll to zoom · drag to pan
UNIONItemDeclItemFeatureItemRECORDDeclItemdeclsyntax::DeclarationRECORDFeatureItemdeclsyntax::FeatureDecl
data

Lexed #

public
syntax::Lexed

The full result of lexing: the conformance token stream plus interleaved -trivia for the formatter.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDLexedtokenssyntax::Token[]triviasyntax::SpannedTrivia[]RECORDTokenkindsyntax::TokenKindspansyntax::SpantextstringRECORDSpannedTriviatriviasyntax::Triviaspansyntax::Span
component

Lexer #

private
syntax::Lexer

Hand-written lexer for LANG.md §2. One pass yields the conformance token +trivia for the formatter.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDLexedtokenssyntax::Token[]triviasyntax::SpannedTrivia[]RECORDTokenkindsyntax::TokenKindspansyntax::SpantextstringRECORDSpannedTriviatriviasyntax::Triviaspansyntax::Span
component

Lexer #

private
syntax::Lexer

Hand-written lexer for LANG.md §2. One pass yields the conformance token stream (comments discarded, `///`→`Doc`+`Tag`, `//!`→`InnerDoc`) and full-fidelity trivia for the formatter. Infallible: lexical anomalies surface -as parser diagnostics, never a failed lex.

#critical

Parent

Inbound

Outbound

Scenarios

LexerNeverStalls

The lexer is greedy and never stalls on bad input.

  • given source containing an unknown byte or an unterminated string
  • when the lexer scans it
  • then the offending bytes are skipped or the string is closed at end of line
  • and lexing reaches the end of input
Flow Flow — LexerNeverStalls scroll to zoom · drag to pan
FEATURELexerNeverStallsfor LexerGIVENsource containing an unknown byte oran unterminated stringWHENthe lexer scans itTHENthe offending bytes are skipped or thestring is closed at end of lineANDlexing reaches the end of input
GreedyKeywordMatch

The longest identifier wins, then a keyword lookup classifies it.

  • given an identifier-start byte
  • when the lexer consumes the run of identifier bytes
  • then a reserved spelling lexes as its keyword kind
  • but a primitive name or `Result` stays an identifier, classified later
Flow Flow — GreedyKeywordMatch scroll to zoom · drag to pan
FEATUREGreedyKeywordMatchfor LexerGIVENan identifier-start byteWHENthe lexer consumes the run ofidentifier bytesTHENa reserved spelling lexes as itskeyword kindBUTa primitive name or `Result` stays anidentifier, classified later
DocCommentDisambiguation

A leading `/` resolves to a comment, doc, or inner doc by its run length.

  • given a line beginning with two or more slashes
  • when the lexer reads the marker
  • then `//!` becomes an inner-doc token
  • and `///` becomes a doc line of prose and tag tokens
  • but plain `//` is discarded as line-comment trivia
Flow Flow — DocCommentDisambiguation scroll to zoom · drag to pan
FEATUREDocCommentDisambiguationfor LexerGIVENa line beginning with two or moreslashesWHENthe lexer reads the markerTHEN`//!` becomes an inner-doc tokenAND`///` becomes a doc line of prose andtag tokensBUTplain `//` is discarded asline-comment trivia
HashDisambiguation

On a `///` line, ` +as parser diagnostics, never a failed lex.

#critical

Parent

Inbound

Outbound

Scenarios

LexerNeverStalls

The lexer is greedy and never stalls on bad input.

  • given source containing an unknown byte or an unterminated string
  • when the lexer scans it
  • then the offending bytes are skipped or the string is closed at end of line
  • and lexing reaches the end of input
Flow Flow — LexerNeverStalls scroll to zoom · drag to pan
FEATURELexerNeverStallsfor LexerGIVENsource containing an unknown byte oran unterminated stringWHENthe lexer scans itTHENthe offending bytes are skipped or thestring is closed at end of lineANDlexing reaches the end of input
GreedyKeywordMatch

The longest identifier wins, then a keyword lookup classifies it.

  • given an identifier-start byte
  • when the lexer consumes the run of identifier bytes
  • then a reserved spelling lexes as its keyword kind
  • but a primitive name or `Result` stays an identifier, classified later
Flow Flow — GreedyKeywordMatch scroll to zoom · drag to pan
FEATUREGreedyKeywordMatchfor LexerGIVENan identifier-start byteWHENthe lexer consumes the run ofidentifier bytesTHENa reserved spelling lexes as itskeyword kindBUTa primitive name or `Result` stays anidentifier, classified later
DocCommentDisambiguation

A leading `/` resolves to a comment, doc, or inner doc by its run length.

  • given a line beginning with two or more slashes
  • when the lexer reads the marker
  • then `//!` becomes an inner-doc token
  • and `///` becomes a doc line of prose and tag tokens
  • but plain `//` is discarded as line-comment trivia
Flow Flow — DocCommentDisambiguation scroll to zoom · drag to pan
FEATUREDocCommentDisambiguationfor LexerGIVENa line beginning with two or moreslashesWHENthe lexer reads the markerTHEN`//!` becomes an inner-doc tokenAND`///` becomes a doc line of prose andtag tokensBUTplain `//` is discarded asline-comment trivia
HashDisambiguation

On a `///` line, ` ` is a tag while `#[` is a macro.

#name
  • given a `#` in the source
  • when the lexer classifies it
  • then `#name` on a doc line becomes a tag token including the `#`
  • and `#[` becomes a macro-open token
  • but a bare `#` in ordinary prose is skipped, with no grammar role
Flow Flow — HashDisambiguation scroll to zoom · drag to pan
FEATUREHashDisambiguationfor LexerGIVENa `#` in the sourceWHENthe lexer classifies itTHEN`#name` on a doc line becomes a tagtoken including the `#`AND`#[` becomes a macro-open tokenBUTa bare `#` in ordinary prose isskipped, with no grammar role
TriviaPreservedForFormatter

Comments and blank-line runs are preserved for the formatter.

  • given source interleaving tokens with comments and blank lines
  • when the lexer runs
  • then the token stream carries no comment trivia
  • and comments and blank-line runs are returned alongside as spanned trivia
Flow Flow — TriviaPreservedForFormatter scroll to zoom · drag to pan
FEATURETriviaPreservedForFormatterfor LexerGIVENsource interleaving tokens withcomments and blank linesWHENthe lexer runsTHENthe token stream carries no commenttriviaANDcomments and blank-line runs arereturned alongside as spanned trivia
ConformanceTokenRendering

Token rendering matches the conformance golden form.

  • given a source string
  • when its tokens are rendered
  • then each token prints as `KIND@line:col \"lexeme\"` on its own line
  • and interior backslashes and quotes in the lexeme are escaped
Flow Flow — ConformanceTokenRendering scroll to zoom · drag to pan
FEATUREConformanceTokenRenderingfor LexerGIVENa source stringWHENits tokens are renderedTHENeach token prints as `KIND@line:col\"lexeme\"` on its own lineANDinterior backslashes and quotes in thelexeme are escaped
data

LineComment #

public
syntax::LineComment
Entities Entity diagram scroll to zoom · drag to pan
RECORDLineCommenttextstring
component

LineIndex #

public
syntax::LineIndex

Precomputed newline offsets turning a byte offset into a 1-based (line, col) pair in O(log n). Built once per source and reused for every lookup; column counts bytes from the line start.

Parent

Inbound

Scenarios

OffsetToLineColumn

A byte offset maps to a 1-based line and column.

  • given a line index built over a source string
  • when a byte offset is looked up
  • then the 1-based line and byte column are returned
  • but an offset past the end clamps to the end of the source
Flow Flow — OffsetToLineColumn scroll to zoom · drag to pan
FEATUREOffsetToLineColumnfor LineIndexGIVENa line index built over a sourcestringWHENa byte offset is looked upTHENthe 1-based line and byte column arereturnedBUTan offset past the end clamps to theend of the source
data

List #

public
syntax::List
Entities Entity diagram scroll to zoom · drag to pan
RECORDListargssyntax::MacroArg[]UNIONMacroArgLiteralArgPathArgNestedArg
data

Lit #

public
syntax::Lit
Entities Entity diagram scroll to zoom · drag to pan
RECORDLitvaluesyntax::LiteralUNIONLiteralStringLitNumberLitBoolLit
data

Literal #

public
syntax::Literal

A literal value (ADR-013). `raw` carries the source text (string literals @@ -54,23 +54,24 @@ `Result`, `KwSome`/`KwNone` build an `Option`.

Entities Entity diagram scroll to zoom · drag to pan
UNIONMarkerKindKwOkKwErrKwSomeKwNone
data

Module #

public
syntax::Module

The typed syntax tree of one module (LANG.md §10): module-level inner docs, then declarations and features in source order. Every node carries a `Span`; declarations and statements also carry leading trivia so the formatter can -reproduce layout.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleinnerDocssyntax::InnerDoc[]itemssyntax::Item[]spansyntax::SpanRECORDInnerDoctextstringspansyntax::SpanUNIONItemDeclItemFeatureItemRECORDSpanstartnumberendnumber
data

NameValue #

public
syntax::NameValue
Entities Entity diagram scroll to zoom · drag to pan
RECORDNameValuevaluesyntax::LiteralUNIONLiteralStringLitNumberLitBoolLit
data

NestedArg #

public
syntax::NestedArg
Entities Entity diagram scroll to zoom · drag to pan
RECORDNestedArgmacrosyntax::MacroRECORDMacronamesyntax::Pathargssyntax::MacroArgsspansyntax::Span
data

Node #

public
syntax::Node
Entities Entity diagram scroll to zoom · drag to pan
RECORDNodenodesyntax::NodeDeclRECORDNodeDeclkindsyntax::NodeKindnamestringparentsyntax::Pathbodysyntax::BodyMember[]spansyntax::Span
data

NodeDecl #

public
syntax::NodeDecl

A `person` / `system` / `container` / `component` declaration. `parent` is +reproduce layout.

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleinnerDocssyntax::InnerDoc[]itemssyntax::Item[]spansyntax::SpanRECORDInnerDoctextstringspansyntax::SpanUNIONItemDeclItemFeatureItemRECORDSpanstartnumberendnumber
data

NameValue #

public
syntax::NameValue
Entities Entity diagram scroll to zoom · drag to pan
RECORDNameValuevaluesyntax::LiteralUNIONLiteralStringLitNumberLitBoolLit
data

NestedArg #

public
syntax::NestedArg
Entities Entity diagram scroll to zoom · drag to pan
RECORDNestedArgmacrosyntax::MacroRECORDMacronamesyntax::Pathargssyntax::MacroArgsspansyntax::Span
data

Node #

public
syntax::Node
Entities Entity diagram scroll to zoom · drag to pan
RECORDNodenodesyntax::NodeDeclRECORDNodeDeclkindsyntax::NodeKindnamestringparentsyntax::Pathbodysyntax::BodyMember[]spansyntax::Span
data

NodeDecl #

public
syntax::NodeDecl

A `person` / `system` / `container` / `component` declaration. `parent` is the `for <Parent>` path, present for container/component. `body` is the -disclosed member list, or absent for a black box (`;`).

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeDeclkindsyntax::NodeKindnamestringparentsyntax::Pathbodysyntax::BodyMember[]spansyntax::SpanUNIONNodeKindPersonSystemContainerComponentRECORDPathsegmentsstring[]spansyntax::SpanUNIONBodyMemberCallableMemberDeclMemberRECORDSpanstartnumberendnumber
data

NodeKind #

public
syntax::NodeKind

The structural keyword class of a node.

Entities Entity diagram scroll to zoom · drag to pan
UNIONNodeKindPersonSystemContainerComponentRECORDContainerofstringRECORDComponentofstring
data

NumberLit #

public
syntax::NumberLit
Entities Entity diagram scroll to zoom · drag to pan
RECORDNumberLitrawstringspansyntax::SpanRECORDSpanstartnumberendnumber
data

Param #

public
syntax::Param

A callable parameter `name: Type`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDParamnamestringtysyntax::Typespansyntax::SpanRECORDTypenamesyntax::Pathgenericssyntax::Type[]isArrayboolspansyntax::SpanRECORDSpanstartnumberendnumber
data

Paren #

public
syntax::Paren
Entities Entity diagram scroll to zoom · drag to pan
RECORDPareninnersyntax::ExprRECORDExprkindsyntax::ExprKindspansyntax::Span
data

Parsed #

public
syntax::Parsed

Parser output: the tree (always present, recovered on error) plus the +disclosed member list, or absent for a black box (`;`).

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeDeclkindsyntax::NodeKindnamestringparentsyntax::Pathbodysyntax::BodyMember[]spansyntax::SpanUNIONNodeKindPersonSystemContainerComponentRECORDPathsegmentsstring[]spansyntax::SpanUNIONBodyMemberCallableMemberDeclMemberRECORDSpanstartnumberendnumber
data

NodeKind #

public
syntax::NodeKind

The structural keyword class of a node.

Entities Entity diagram scroll to zoom · drag to pan
UNIONNodeKindPersonSystemContainerComponentRECORDContainerofstringRECORDComponentofstring
data

NumberLit #

public
syntax::NumberLit
Entities Entity diagram scroll to zoom · drag to pan
RECORDNumberLitrawstringspansyntax::SpanRECORDSpanstartnumberendnumber
data

OwnCall #

public
syntax::OwnCall
Entities Entity diagram scroll to zoom · drag to pan
RECORDOwnCallnamestringargssyntax::Expr[]RECORDExprkindsyntax::ExprKindspansyntax::Span
data

Param #

public
syntax::Param

A callable parameter `name: Type`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDParamnamestringtysyntax::Typespansyntax::SpanRECORDTypenamesyntax::Pathgenericssyntax::Type[]isArrayboolspansyntax::SpanRECORDSpanstartnumberendnumber
data

Paren #

public
syntax::Paren
Entities Entity diagram scroll to zoom · drag to pan
RECORDPareninnersyntax::ExprRECORDExprkindsyntax::ExprKindspansyntax::Span
data

Parsed #

public
syntax::Parsed

Parser output: the tree (always present, recovered on error) plus the diagnostics collected while parsing. Parsing never fails outright.

Entities Entity diagram scroll to zoom · drag to pan
RECORDParsedastsyntax::Modulediagnosticssyntax::Diagnostic[]RECORDModuleinnerDocssyntax::InnerDoc[]itemssyntax::Item[]spansyntax::SpanRECORDDiagnosticseveritysyntax::Severityspansyntax::SpancodestringcodeDescriptionstringmessagestring
component

Parser #

private
syntax::Parser

Recursive-descent parser for the §10 grammar with error recovery: on unexpected input it records a `Diagnostic`, resynchronises to the next statement/declaration boundary, and continues. Always yields a (possibly -partial) `Module`; never panics.

#critical

Parent

Inbound

Outbound

Scenarios

ParsingIsInfallible

Parsing always yields a tree, even on malformed input.

#critical
  • given source text that may contain syntax errors
  • when the parser runs
  • then a syntax tree is returned, recovered around the errors
  • and each error rides alongside as a diagnostic
  • but parsing never throws or aborts
Flow Flow — ParsingIsInfallible scroll to zoom · drag to pan
FEATUREParsingIsInfalliblefor ParserGIVENsource text that may contain syntaxerrorsWHENthe parser runsTHENa syntax tree is returned, recoveredaround the errorsANDeach error rides alongside as adiagnosticBUTparsing never throws or aborts
StrayTokenTerminates

A stray `;` in statement position never spins the block loop (regression).

  • given a callable body with a stray `;` in statement position
  • when the block is parsed
  • then the stray token is reported as a diagnostic
  • and the forward-progress guard advances past it
  • but the surrounding callable still parses
Flow Flow — StrayTokenTerminates scroll to zoom · drag to pan
FEATUREStrayTokenTerminatesfor ParserGIVENa callable body with a stray `;` instatement positionWHENthe block is parsedTHENthe stray token is reported as adiagnosticANDthe forward-progress guard advancespast itBUTthe surrounding callable still parses
MarkerAndFromAreNotOperands

A marker or `from` expression never combines with a binary operator (§7.5).

  • given an expression whose head is a marker or a `Type from ..`
  • when a binary operator follows the head
  • then the operator is reported as a diagnostic
  • and the head expression still parses, with its postfix chain
  • but the operator is left unconsumed for the enclosing context to resync on
Flow Flow — MarkerAndFromAreNotOperands scroll to zoom · drag to pan
FEATUREMarkerAndFromAreNotOperandsfor ParserGIVENan expression whose head is a markeror a `Type from ..`WHENa binary operator follows the headTHENthe operator is reported as adiagnosticANDthe head expression still parses, withits postfix chainBUTthe operator is left unconsumed forthe enclosing context to resync on
DocSummaryBodySplit

A blank `///` line splits the doc block into summary and extended.

  • given a doc block whose lines are separated by one blank `///` line
  • when the doc block is parsed
  • then lines before the blank become the summary
  • and lines after it become the extended description
  • and tags are gathered regardless of which side they sit on
Flow Flow — DocSummaryBodySplit scroll to zoom · drag to pan
FEATUREDocSummaryBodySplitfor ParserGIVENa doc block whose lines are separatedby one blank `///` lineWHENthe doc block is parsedTHENlines before the blank become thesummaryANDlines after it become the extendeddescriptionANDtags are gathered regardless of whichside they sit on
data

Path #

public
syntax::Path

A `::`-separated path of identifiers (§2.2, §10 `Path`); never empty.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPathsegmentsstring[]spansyntax::SpanRECORDSpanstartnumberendnumber
data

PathArg #

public
syntax::PathArg
Entities Entity diagram scroll to zoom · drag to pan
RECORDPathArgpathsyntax::PathRECORDPathsegmentsstring[]spansyntax::Span
data

PathRef #

public
syntax::PathRef
Entities Entity diagram scroll to zoom · drag to pan
RECORDPathRefpathsyntax::PathRECORDPathsegmentsstring[]spansyntax::Span
data

Postfix #

public
syntax::Postfix
Entities Entity diagram scroll to zoom · drag to pan
RECORDPostfixbasesyntax::Exprsegmentssyntax::PostfixSeg[]RECORDExprkindsyntax::ExprKindspansyntax::SpanRECORDPostfixSegnamestringcallArgssyntax::Expr[]spansyntax::Span
data

PostfixSeg #

public
syntax::PostfixSeg

One `.name` or `.name(args)` step in a postfix chain (ADR-007). `callArgs` -present marks a call; absent marks field access.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPostfixSegnamestringcallArgssyntax::Expr[]spansyntax::SpanRECORDExprkindsyntax::ExprKindspansyntax::SpanRECORDSpanstartnumberendnumber
data

Record #

public
syntax::Record
Entities Entity diagram scroll to zoom · drag to pan
RECORDRecordfieldssyntax::Field[]RECORDFieldnamestringtysyntax::Typespansyntax::Span
data

Ref #

public
syntax::Ref
Entities Entity diagram scroll to zoom · drag to pan
RECORDReftargetsyntax::ReferenceUNIONReferenceSelfNodePathRef
data

Reference #

public
syntax::Reference

A reference primary (§10 `Ref`): `self` or an FQN.

Entities Entity diagram scroll to zoom · drag to pan
UNIONReferenceSelfNodePathRefRECORDSelfNodespansyntax::SpanRECORDPathRefpathsyntax::Path
data

Return #

public
syntax::Return
Entities Entity diagram scroll to zoom · drag to pan
RECORDReturnvaluesyntax::ExprRECORDExprkindsyntax::ExprKindspansyntax::Span
data

SelfNode #

public
syntax::SelfNode
Entities Entity diagram scroll to zoom · drag to pan
RECORDSelfNodespansyntax::SpanRECORDSpanstartnumberendnumber
data

Severity #

public
syntax::Severity

Diagnostic severity. `Error` invalidates the input; `Warning`/`Info` advise +partial) `Module`; never panics.

#critical

Parent

Inbound

Outbound

Scenarios

ParsingIsInfallible

Parsing always yields a tree, even on malformed input.

#critical
  • given source text that may contain syntax errors
  • when the parser runs
  • then a syntax tree is returned, recovered around the errors
  • and each error rides alongside as a diagnostic
  • but parsing never throws or aborts
Flow Flow — ParsingIsInfallible scroll to zoom · drag to pan
FEATUREParsingIsInfalliblefor ParserGIVENsource text that may contain syntaxerrorsWHENthe parser runsTHENa syntax tree is returned, recoveredaround the errorsANDeach error rides alongside as adiagnosticBUTparsing never throws or aborts
StrayTokenTerminates

A stray `;` in statement position never spins the block loop (regression).

  • given a callable body with a stray `;` in statement position
  • when the block is parsed
  • then the stray token is reported as a diagnostic
  • and the forward-progress guard advances past it
  • but the surrounding callable still parses
Flow Flow — StrayTokenTerminates scroll to zoom · drag to pan
FEATUREStrayTokenTerminatesfor ParserGIVENa callable body with a stray `;` instatement positionWHENthe block is parsedTHENthe stray token is reported as adiagnosticANDthe forward-progress guard advancespast itBUTthe surrounding callable still parses
MarkerAndFromAreNotOperands

A marker or `from` expression never combines with a binary operator (§7.5).

  • given an expression whose head is a marker or a `Type from ..`
  • when a binary operator follows the head
  • then the operator is reported as a diagnostic
  • and the head expression still parses, with its postfix chain
  • but the operator is left unconsumed for the enclosing context to resync on
Flow Flow — MarkerAndFromAreNotOperands scroll to zoom · drag to pan
FEATUREMarkerAndFromAreNotOperandsfor ParserGIVENan expression whose head is a markeror a `Type from ..`WHENa binary operator follows the headTHENthe operator is reported as adiagnosticANDthe head expression still parses, withits postfix chainBUTthe operator is left unconsumed forthe enclosing context to resync on
DocSummaryBodySplit

A blank `///` line splits the doc block into summary and extended.

  • given a doc block whose lines are separated by one blank `///` line
  • when the doc block is parsed
  • then lines before the blank become the summary
  • and lines after it become the extended description
  • and tags are gathered regardless of which side they sit on
Flow Flow — DocSummaryBodySplit scroll to zoom · drag to pan
FEATUREDocSummaryBodySplitfor ParserGIVENa doc block whose lines are separatedby one blank `///` lineWHENthe doc block is parsedTHENlines before the blank become thesummaryANDlines after it become the extendeddescriptionANDtags are gathered regardless of whichside they sit on
data

Path #

public
syntax::Path

A `::`-separated path of identifiers (§2.2, §10 `Path`); never empty.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPathsegmentsstring[]spansyntax::SpanRECORDSpanstartnumberendnumber
data

PathArg #

public
syntax::PathArg
Entities Entity diagram scroll to zoom · drag to pan
RECORDPathArgpathsyntax::PathRECORDPathsegmentsstring[]spansyntax::Span
data

PathRef #

public
syntax::PathRef
Entities Entity diagram scroll to zoom · drag to pan
RECORDPathRefpathsyntax::PathRECORDPathsegmentsstring[]spansyntax::Span
data

Postfix #

public
syntax::Postfix
Entities Entity diagram scroll to zoom · drag to pan
RECORDPostfixbasesyntax::Exprsegmentssyntax::PostfixSeg[]RECORDExprkindsyntax::ExprKindspansyntax::SpanRECORDPostfixSegnamestringcallArgssyntax::Expr[]spansyntax::Span
data

PostfixSeg #

public
syntax::PostfixSeg

One `.name` or `.name(args)` step in a postfix chain (ADR-007). `callArgs` +present marks a call; absent marks field access.

Entities Entity diagram scroll to zoom · drag to pan
RECORDPostfixSegnamestringcallArgssyntax::Expr[]spansyntax::SpanRECORDExprkindsyntax::ExprKindspansyntax::SpanRECORDSpanstartnumberendnumber
data

Record #

public
syntax::Record
Entities Entity diagram scroll to zoom · drag to pan
RECORDRecordfieldssyntax::Field[]RECORDFieldnamestringtysyntax::Typespansyntax::Span
data

Ref #

public
syntax::Ref
Entities Entity diagram scroll to zoom · drag to pan
RECORDReftargetsyntax::ReferenceUNIONReferencePathRef
data

Reference #

public
syntax::Reference

A reference primary (§10 `Ref`): an FQN. `self` was dropped (ADR-041); a +same-node call is the bare `OwnCall` primary, not a reference.

Entities Entity diagram scroll to zoom · drag to pan
UNIONReferencePathRefRECORDPathRefpathsyntax::Path
data

Return #

public
syntax::Return
Entities Entity diagram scroll to zoom · drag to pan
RECORDReturnvaluesyntax::ExprRECORDExprkindsyntax::ExprKindspansyntax::Span
data

Severity #

public
syntax::Severity

Diagnostic severity. `Error` invalidates the input; `Warning`/`Info` advise and never block compilation.

Entities Entity diagram scroll to zoom · drag to pan
UNIONSeverityErrorWarningInfo
data

Span #

public
syntax::Span

A half-open byte range `[start, end)` into one module's source. Offsets are bytes, not characters; columns derived via `LineIndex` count bytes too, matching the conformance token goldens.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSpanstartnumberendnumber
data

SpannedTrivia #

public
syntax::SpannedTrivia

A trivia element paired with the source span it occupies.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSpannedTriviatriviasyntax::Triviaspansyntax::SpanUNIONTriviaLineCommentBlockCommentBlankLinesRECORDSpanstartnumberendnumber
data

StepKind #

public
syntax::StepKind

The step keyword class of a feature step (§5.2). `And`/`But` continue the preceding step's flow phase.

Entities Entity diagram scroll to zoom · drag to pan
UNIONStepKindGivenWhenThenAndBut
data

Stmt #

public
syntax::Stmt

A statement valid inside a callable body (§7), with the leading trivia that preceded it.

Entities Entity diagram scroll to zoom · drag to pan
RECORDStmtkindsyntax::StmtKindleadingTriviasyntax::SpannedTrivia[]spansyntax::SpanUNIONStmtKindAssignReturnIfForWhileExprStmtRECORDSpannedTriviatriviasyntax::Triviaspansyntax::SpanRECORDSpanstartnumberendnumber
data

StmtKind #

public
syntax::StmtKind

The statement forms (§7).

Entities Entity diagram scroll to zoom · drag to pan
UNIONStmtKindAssignReturnIfForWhileExprStmtRECORDAssignnamestringvaluesyntax::ExprRECORDReturnvaluesyntax::ExprRECORDIfcondsyntax::ExprthenBlocksyntax::BlockelseBlocksyntax::BlockRECORDForbindingstringitersyntax::Exprbodysyntax::BlockRECORDWhilecondsyntax::Exprbodysyntax::BlockRECORDExprStmtexprsyntax::Expr
data

StringLit #

public
syntax::StringLit
Entities Entity diagram scroll to zoom · drag to pan
RECORDStringLitrawstringspansyntax::SpanRECORDSpanstartnumberendnumber
container

Syntax #

public
syntax::Syntax

`crates/pseudoscript-syntax`. The foundation crate: source text to tokens -and a typed AST, emitting the shared `Diagnostic`. WASM-safe and I/O-free.

#critical

Inbound

Outbound

  • from cli::string
  • from format::Parsed
  • from model::Parsed
  • call syntax::Lexer · renderTokens
  • call syntax::Parser · parse
Components Component diagram scroll to zoom · drag to pan
PseudoscriptSyntaxCOMPONENTLexerHand-written lexer for LANG.md §2. One passyields the conformance token stream…COMPONENTLineIndexPrecomputed newline offsets turning a byteoffset into a 1-based (line, col) pair in…COMPONENTParserRecursive-descent parser for the §10 grammarwith error recovery: on unexpected input it…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…formatcheckcheckWorkspaceModulesgraphbuildlex
data

Tag #

public
syntax::Tag

A ` +and a typed AST, emitting the shared `Diagnostic`. WASM-safe and I/O-free.

#critical

Inbound

Outbound

  • from cli::string
  • from format::Parsed
  • from model::Parsed
  • call syntax::Lexer · renderTokens
  • call syntax::Parser · parse
Components Component diagram scroll to zoom · drag to pan
PseudoscriptSyntaxCOMPONENTLexerHand-written lexer for LANG.md §2. One passyields the conformance token stream…COMPONENTLineIndexPrecomputed newline offsets turning a byteoffset into a 1-based (line, col) pair in…COMPONENTParserRecursive-descent parser for the §10 grammarwith error recovery: on unexpected input it…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…formatcheckcheckWorkspacecheckWorkspaceModulesgraphbuildlex
data

Tag #

public
syntax::Tag

A ` ` tag from a doc block, including the leading `#` (§2.4).

#name
Entities Entity diagram scroll to zoom · drag to pan
RECORDTagtextstringspansyntax::SpanRECORDSpanstartnumberendnumber
data

Token #

public
syntax::Token

A lexical token: its kind, source span, and rendered lexeme (LANG.md §2).

For most tokens `text` is the raw source slice. For `Doc`/`InnerDoc` it is the doc text with the marker and surrounding whitespace stripped; for `Tag` -it includes the leading `#`.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDTokenkindsyntax::TokenKindspansyntax::SpantextstringUNIONTokenKindKeywordIdentPunctuationStringLiteralNumberLiteralDocInnerDocTagHashLBracketRECORDSpanstartnumberendnumber
data

TokenKind #

public
syntax::TokenKind

Every lexical token class (LANG.md §2). The `name` rendering (e.g. +it includes the leading `#`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDTokenkindsyntax::TokenKindspansyntax::SpantextstringUNIONTokenKindKeywordIdentPunctuationStringLiteralNumberLiteralDocInnerDocTagHashLBracketRECORDSpanstartnumberendnumber
data

TokenKind #

public
syntax::TokenKind

Every lexical token class (LANG.md §2). The `name` rendering (e.g. `KW_SYSTEM`) is the conformance golden's `KIND`. Primitive type names and `Result` are NOT keywords — they lex as `Ident` and are classified in type position by the model crate.

Entities Entity diagram scroll to zoom · drag to pan
UNIONTokenKindKeywordIdentPunctuationStringLiteralNumberLiteralDocInnerDocTagHashLBracketRECORDInnerDoctextstringspansyntax::SpanRECORDTagtextstringspansyntax::Span
data

Trivia #

public
syntax::Trivia

Non-token source between tokens, preserved for the formatter. Doc comments, diff --git a/model/site/module/universe.html b/model/site/module/universe.html index 8646cedb..5f12c941 100644 --- a/model/site/module/universe.html +++ b/model/site/module/universe.html @@ -11,34 +11,34 @@ -

PseudoScript
Module

universe

component

Adapter #

private
universe::Adapter

Adapts a resolved model into the software graph: keeps only the structural +

PseudoScript
Module

universe

component

Adapter #

private
universe::Adapter

Adapts a resolved model into the software graph: keeps only the structural nodes, hooks each to its structural parent for the containment tree, and lifts every call to the structural level — tallying directed traffic per -caller→callee pair so the edge carries direction.

Parent

Inbound

Outbound

Scenarios

StructuralNodesOnly

Only structural nodes enter the graph; data and callables do not.

  • given a resolved model with systems, containers, components, data, and callables
  • when the model is adapted into the software graph
  • then every system, container, component, and person becomes a graph node
  • but data and callables are not placed
Flow Flow — StructuralNodesOnly scroll to zoom · drag to pan
FEATUREStructuralNodesOnlyfor AdapterGIVENa resolved model with systems,containers, components, data, andcallablesWHENthe model is adapted into the softwaregraphTHENevery system, container, component,and person becomes a graph nodeBUTdata and callables are not placed
CallsLiftAndTallyTraffic

Calls lift to the structural level and tally as directed traffic.

  • given a call from one component's body into another node
  • when relationships are collected
  • then the call lifts to the nearest enclosing structural node on each end
  • and repeated calls between the same pair sum into one directed edge's traffic
  • but a call that lifts to the same node on both ends is dropped
Flow Flow — CallsLiftAndTallyTraffic scroll to zoom · drag to pan
FEATURECallsLiftAndTallyTrafficfor AdapterGIVENa call from one component's body intoanother nodeWHENrelationships are collectedTHENthe call lifts to the nearestenclosing structural node on each endANDrepeated calls between the same pairsum into one directed edge's trafficBUTa call that lifts to the same node onboth ends is dropped
ContainmentTree

Containment is a tree rooted at the top-level systems.

  • given a system holding containers that hold components
  • when the graph is built
  • then each node records its enclosing parent and the ids it contains
  • and the top-level systems are the containment roots, in declaration order
Flow Flow — ContainmentTree scroll to zoom · drag to pan
FEATUREContainmentTreefor AdapterGIVENa system holding containers that holdcomponentsWHENthe graph is builtTHENeach node records its enclosing parentand the ids it containsANDthe top-level systems are thecontainment roots, in declarationorder
data

C4Level #

public
universe::C4Level

The C4 abstraction level a node sits at. Only these four enter the graph; +caller→callee pair so the edge carries direction.

Parent

Inbound

Outbound

Scenarios

StructuralNodesOnly

Only structural nodes enter the graph; data and callables do not.

  • given a resolved model with systems, containers, components, data, and callables
  • when the model is adapted into the software graph
  • then every system, container, component, and person becomes a graph node
  • but data and callables are not placed
Flow Flow — StructuralNodesOnly scroll to zoom · drag to pan
FEATUREStructuralNodesOnlyfor AdapterGIVENa resolved model with systems,containers, components, data, andcallablesWHENthe model is adapted into the softwaregraphTHENevery system, container, component,and person becomes a graph nodeBUTdata and callables are not placed
CallsLiftAndTallyTraffic

Calls lift to the structural level and tally as directed traffic.

  • given a call from one component's body into another node
  • when relationships are collected
  • then the call lifts to the nearest enclosing structural node on each end
  • and repeated calls between the same pair sum into one directed edge's traffic
  • but a call that lifts to the same node on both ends is dropped
Flow Flow — CallsLiftAndTallyTraffic scroll to zoom · drag to pan
FEATURECallsLiftAndTallyTrafficfor AdapterGIVENa call from one component's body intoanother nodeWHENrelationships are collectedTHENthe call lifts to the nearestenclosing structural node on each endANDrepeated calls between the same pairsum into one directed edge's trafficBUTa call that lifts to the same node onboth ends is dropped
ContainmentTree

Containment is a tree rooted at the top-level systems.

  • given a system holding containers that hold components
  • when the graph is built
  • then each node records its enclosing parent and the ids it contains
  • and the top-level systems are the containment roots, in declaration order
Flow Flow — ContainmentTree scroll to zoom · drag to pan
FEATUREContainmentTreefor AdapterGIVENa system holding containers that holdcomponentsWHENthe graph is builtTHENeach node records its enclosing parentand the ids it containsANDthe top-level systems are thecontainment roots, in declarationorder
data

C4Level #

public
universe::C4Level

The C4 abstraction level a node sits at. Only these four enter the graph; data and callables do not — a relationship through them is lifted to the -nearest enclosing structural node.

Entities Entity diagram scroll to zoom · drag to pan
UNIONC4LevelSystemContainerComponentPersonRECORDContainerofstringRECORDComponentofstring
data

EdgeOut #

public
universe::EdgeOut

One relationship in the flat snapshot, with its traffic (call count).

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDEdgeOutsourcestringtostringtrafficnumber
component

Flatten #

private
universe::Flatten

Flattens the software graph into the renderer-facing snapshot: each node's id, +nearest enclosing structural node.

Entities Entity diagram scroll to zoom · drag to pan
UNIONC4LevelSystemContainerComponentPersonRECORDContainerofstringRECORDComponentofstring
data

EdgeOut #

public
universe::EdgeOut

One relationship in the flat snapshot, with its traffic (call count).

Entities Entity diagram scroll to zoom · drag to pan
RECORDEdgeOutsourcestringtostringtrafficnumber
component

Flatten #

private
universe::Flatten

Flattens the software graph into the renderer-facing snapshot: each node's id, level string, and parent id; each relationship's endpoints and traffic. The -boundary the web IDE reads — petgraph indices never cross it.

Parent

Inbound

Outbound

Scenarios

SnapshotIsDeterministic

The snapshot is deterministic and free of engine internals.

  • given the same software graph flattened twice
  • when the snapshots are compared
  • then nodes and edges appear in the same stable order both times
  • but no petgraph index or other engine internal crosses the boundary
Flow Flow — SnapshotIsDeterministic scroll to zoom · drag to pan
FEATURESnapshotIsDeterministicfor FlattenGIVENthe same software graph flattenedtwiceWHENthe snapshots are comparedTHENnodes and edges appear in the samestable order both timesBUTno petgraph index or other engineinternal crosses the boundary
data

FlowDef #

public
universe::FlowDef

One entry-point flow: the entry callable's FQN and simple name, the flow's +boundary the web IDE reads — petgraph indices never cross it.

Parent

Inbound

Scenarios

SnapshotIsDeterministic

The snapshot is deterministic and free of engine internals.

  • given the same software graph flattened twice
  • when the snapshots are compared
  • then nodes and edges appear in the same stable order both times
  • but no petgraph index or other engine internal crosses the boundary
Flow Flow — SnapshotIsDeterministic scroll to zoom · drag to pan
FEATURESnapshotIsDeterministicfor FlattenGIVENthe same software graph flattenedtwiceWHENthe snapshots are comparedTHENnodes and edges appear in the samestable order both timesBUTno petgraph index or other engineinternal crosses the boundary
data

FlowDef #

public
universe::FlowDef

One entry-point flow: the entry callable's FQN and simple name, the flow's palette colour, and its ordered legs. The renderer draws one filament chain per flow and streams its beads in the flow's colour.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDFlowDeffqnstringnamestringcolorstringhopsuniverse::FlowHop[]RECORDFlowHopsourcestringtostringlabelstring
data

FlowHop #

public
universe::FlowHop

One call leg of a flow: the caller and callee as structural node ids (the -same ids the snapshot places), plus the message label shown on the leg.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDFlowHopsourcestringtostringlabelstring
component

FlowTracer #

private
universe::FlowTracer

Traces every entry-point flow: a triggered callable (or a person-owned +same ids the snapshot places), plus the message label shown on the leg.

Entities Entity diagram scroll to zoom · drag to pan
RECORDFlowHopsourcestringtostringlabelstring
component

FlowTracer #

private
universe::FlowTracer

Traces every entry-point flow: a triggered callable (or a person-owned action) starts a flow; its sequence projection is walked call-by-call and each leg's endpoints lift to the nearest placed structural node — the same lift the Adapter applies to relationships, so flows and edges agree. Colours key from the entry's FQN by a stable hash into a fixed palette — the same keying the web IDE paints with — so a flow keeps its hue everywhere it -appears and an unrelated model edit never recolours it.

Parent

Inbound

Outbound

Scenarios

EntryPointsStartFlows

A triggered callable or a person-owned action starts a flow.

  • given a model with trigger-macro callables and person-owned actions
  • when flows are traced
  • then each triggered callable and each person-owned callable yields one flow
  • and entries are ordered by FQN so the set is stable
Flow Flow — EntryPointsStartFlows scroll to zoom · drag to pan
FEATUREEntryPointsStartFlowsfor FlowTracerGIVENa model with trigger-macro callablesand person-owned actionsWHENflows are tracedTHENeach triggered callable and eachperson-owned callable yields one flowANDentries are ordered by FQN so the setis stable
FlowsLiftToStructuralNodes

Flow legs land on the structural nodes the renderer places.

  • given a flow whose calls land on components and callables
  • when its hops are traced
  • then each leg's caller and callee lift to the nearest placed structural node
  • but a leg whose ends lift to the same node, or fail to lift, is dropped
Flow Flow — FlowsLiftToStructuralNodes scroll to zoom · drag to pan
FEATUREFlowsLiftToStructuralNodesfor FlowTracerGIVENa flow whose calls land on componentsand callablesWHENits hops are tracedTHENeach leg's caller and callee lift tothe nearest placed structural nodeBUTa leg whose ends lift to the samenode, or fail to lift, is dropped
FlowsAreDeterministic

Flows are deterministic: same model, same flows, same colours.

  • given the same model traced twice
  • when the flow sets are compared
  • then flows, hops, and colours are identical
  • and a colour keys from its entry's FQN, so an unrelated model edit never recolours a flow
Flow Flow — FlowsAreDeterministic scroll to zoom · drag to pan
FEATUREFlowsAreDeterministicfor FlowTracerGIVENthe same model traced twiceWHENthe flow sets are comparedTHENflows, hops, and colours are identicalANDa colour keys from its entry's FQN, soan unrelated model edit neverrecolours a flow
data

GraphNode #

private
universe::GraphNode

A structural node in the software graph: its stable model FQN, its C4 level, +appears and an unrelated model edit never recolours it.

Parent

Inbound

Outbound

Scenarios

EntryPointsStartFlows

A triggered callable or a person-owned action starts a flow.

  • given a model with trigger-macro callables and person-owned actions
  • when flows are traced
  • then each triggered callable and each person-owned callable yields one flow
  • and entries are ordered by FQN so the set is stable
Flow Flow — EntryPointsStartFlows scroll to zoom · drag to pan
FEATUREEntryPointsStartFlowsfor FlowTracerGIVENa model with trigger-macro callablesand person-owned actionsWHENflows are tracedTHENeach triggered callable and eachperson-owned callable yields one flowANDentries are ordered by FQN so the setis stable
FlowsLiftToStructuralNodes

Flow legs land on the structural nodes the renderer places.

  • given a flow whose calls land on components and callables
  • when its hops are traced
  • then each leg's caller and callee lift to the nearest placed structural node
  • but a leg whose ends lift to the same node, or fail to lift, is dropped
Flow Flow — FlowsLiftToStructuralNodes scroll to zoom · drag to pan
FEATUREFlowsLiftToStructuralNodesfor FlowTracerGIVENa flow whose calls land on componentsand callablesWHENits hops are tracedTHENeach leg's caller and callee lift tothe nearest placed structural nodeBUTa leg whose ends lift to the samenode, or fail to lift, is dropped
FlowsAreDeterministic

Flows are deterministic: same model, same flows, same colours.

  • given the same model traced twice
  • when the flow sets are compared
  • then flows, hops, and colours are identical
  • and a colour keys from its entry's FQN, so an unrelated model edit never recolours a flow
Flow Flow — FlowsAreDeterministic scroll to zoom · drag to pan
FEATUREFlowsAreDeterministicfor FlowTracerGIVENthe same model traced twiceWHENthe flow sets are comparedTHENflows, hops, and colours are identicalANDa colour keys from its entry's FQN, soan unrelated model edit neverrecolours a flow
data

GraphNode #

private
universe::GraphNode

A structural node in the software graph: its stable model FQN, its C4 level, and its place in the containment tree (the enclosing node, empty for a top-level system, and the ids it contains). No position — the renderer -places it.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDGraphNodeidstringleveluniverse::C4Levelparentstringchildrenstring[]UNIONC4LevelSystemContainerComponentPerson
data

NodeOut #

public
universe::NodeOut

One node in the flat snapshot: its id, C4 level as a lowercase string, and the -id of its containment parent (empty for a top-level system).

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeOutidstringlevelstringparentstring
data

Relationship #

private
universe::Relationship

A directed relationship between two structural nodes, weighted by `traffic` — +places it.

Entities Entity diagram scroll to zoom · drag to pan
RECORDGraphNodeidstringleveluniverse::C4Levelparentstringchildrenstring[]UNIONC4LevelSystemContainerComponentPerson
data

NodeOut #

public
universe::NodeOut

One node in the flat snapshot: its id, C4 level as a lowercase string, and the +id of its containment parent (empty for a top-level system).

Entities Entity diagram scroll to zoom · drag to pan
RECORDNodeOutidstringlevelstringparentstring
data

Relationship #

private
universe::Relationship

A directed relationship between two structural nodes, weighted by `traffic` — the number of underlying calls lifted onto the pair. Self-relationships are dropped; the count drives the renderer's flow animation.

Entities Entity diagram scroll to zoom · drag to pan
RECORDRelationshipsourcestringtostringtrafficnumber
data

Snapshot #

public
universe::Snapshot

The flat, serialisable contract the web IDE's `ForceGraph` consumes: nodes and directed weighted edges, with no engine internals (petgraph indices) leaking across the boundary. Positions are not here.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDSnapshotnodesuniverse::NodeOut[]edgesuniverse::EdgeOut[]RECORDNodeOutidstringlevelstringparentstringRECORDEdgeOutsourcestringtostringtrafficnumber
data

SoftwareGraph #

public
universe::SoftwareGraph

The software graph: structural nodes with the containment tree, directed relationship edges weighted by traffic, and the top-level systems (the containment roots, in model-declaration order). The crate's in-memory form, -before flattening to a renderer-facing `Snapshot`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSoftwareGraphnodesuniverse::GraphNode[]relationshipsuniverse::Relationship[]rootsstring[]RECORDGraphNodeidstringleveluniverse::C4Levelparentstringchildrenstring[]RECORDRelationshipsourcestringtostringtrafficnumber
container

Universe #

public
universe::Universe

`crates/pseudoscript-universe`. Maps the resolved C4 model into the software +before flattening to a renderer-facing `Snapshot`.

Inbound

Entities Entity diagram scroll to zoom · drag to pan
RECORDSoftwareGraphnodesuniverse::GraphNode[]relationshipsuniverse::Relationship[]rootsstring[]RECORDGraphNodeidstringleveluniverse::C4Levelparentstringchildrenstring[]RECORDRelationshipsourcestringtostringtrafficnumber
container

Universe #

public
universe::Universe

`crates/pseudoscript-universe`. Maps the resolved C4 model into the software graph the 3D view renders, then flattens it to a determinstic snapshot.

Inbound

Outbound

Scenarios

PositionsAreTheRenderersJob

Layout is the renderer's job, not this crate's.

  • given a software-graph snapshot
  • when the web IDE renders the 3D view
  • then d3-force-3d assigns every node a position in the browser
  • but the crate carries no coordinates — it is pure structure and traffic
Flow Flow — PositionsAreTheRenderersJob scroll to zoom · drag to pan
FEATUREPositionsAreTheRenderersJobfor UniverseGIVENa software-graph snapshotWHENthe web IDE renders the 3D viewTHENd3-force-3d assigns every node aposition in the browserBUTthe crate carries no coordinates — itis pure structure and traffic
Components Component diagram scroll to zoom · drag to pan
PseudoscriptUniverseCOMPONENTAdapterAdapts a resolved model into the softwaregraph: keeps only the structural nodes,…COMPONENTFlowTracerTraces every entry-point flow: a triggeredcallable (or a person-owned action) starts …COMPONENTFlattenFlattens the software graph into therenderer-facing snapshot: each node's id,…CONTAINERDoc`crates/pseudoscript-doc`. Turns a resolvedgraph into a Svelte-rendered,…CONTAINEREmit`crates/pseudoscript-emit`. Projects a viewinto a `Scene` and renders it to SVG; C4…CONTAINERIdeSession`crates/pseudoscript-ide` — the IDEapplication, Rust compiled to a single wasm…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…projectprepareDiagnosticscheckcheckWorkspaceModulesgraphgraphproject
Generated by pds doc.
diff --git a/model/site/search-index.js b/model/site/search-index.js index e7e95843..5adb992d 100644 --- a/model/site/search-index.js +++ b/model/site/search-index.js @@ -1 +1 @@ -window.__PDS_SEARCH__=[{"fqn":"health.html","name":"Architecture Health","kind":"page","summary":"Errors, warnings, and principle lints","text":"","module":"","href":"health.html"},{"fqn":"cli","name":"cli","kind":"module","summary":"","text":"","module":"cli","href":"module/cli.html"},{"fqn":"cli::AddOpts","name":"AddOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-AddOpts"},{"fqn":"cli::Args","name":"Args","kind":"component","summary":"Parses argv with clap-derive into the chosen subcommand and its options, then\ndispatches to the matching command handler.","text":"","module":"cli","href":"module/cli.html#cli-Args"},{"fqn":"cli::CheckCmd","name":"CheckCmd","kind":"component","summary":"`pds check` — parse and statically check one file, print each diagnostic as\n`path:line:col: severity: message`, and exit non-zero on any error-severity\ndiagnostic. Emits no diagram.","text":"","module":"cli","href":"module/cli.html#cli-CheckCmd"},{"fqn":"cli::CheckOpts","name":"CheckOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-CheckOpts"},{"fqn":"cli::Cli","name":"Cli","kind":"container","summary":"`crates/pseudoscript` — the binary crate (`pds`). The composition root and\nonly I/O edge; a thin frontend that wires the pure library crates to disk,\nHTTP, and a filesystem watcher.","text":"","module":"cli","href":"module/cli.html#cli-Cli"},{"fqn":"cli::Command","name":"Command","kind":"data","summary":"The subcommand clap parsed from argv, with its resolved options.","text":"","module":"cli","href":"module/cli.html#cli-Command"},{"fqn":"cli::Deps","name":"Deps","kind":"component","summary":"`pds add`/`install`/`update`/`remove`/`list` — git workspace dependency\nmanagement (§8.3). `add` resolves a git URL into `pds.toml` + `pds.lock` and\nvendors it; `install` restores `pds_modules/` from the lock; `update`\nre-pins; `remove` drops one; `list` discovers every workspace under a root.\nResolution delegates to `project`; fetching is the CLI's I/O.","text":"","module":"cli","href":"module/cli.html#cli-Deps"},{"fqn":"cli::DocCmd","name":"DocCmd","kind":"component","summary":"`pds doc` — the headline command (ADR-017). Load the workspace, check it per\nmodule (reported but non-fatal, like `cargo doc` — the same findings feed the\nsite's health page), project the resolved graph, and render a static doc\nsite. The output format is resolved by precedence — an explicit `--format`\nover the manifest `[doc].format`, else HTML — then a fork renders the SSR\nHTML site (every diagram as server SVG, logo copied) or a flat Markdown site\n(SVG assets, no logo). `--serve` hosts the HTML site over HTTP; `--watch`\nadds a filesystem watcher and browser live reload; both are skipped for\nMarkdown output, which only writes.","text":"","module":"cli","href":"module/cli.html#cli-DocCmd"},{"fqn":"cli::DocOpts","name":"DocOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-DocOpts"},{"fqn":"cli::EvalCmd","name":"EvalCmd","kind":"component","summary":"`pds eval` — read a model from stdin and statically check it, printing each\ndiagnostic as `:line:col: severity: message` and exiting non-zero on\nany error. The fileless path: an agent pipes a snippet to check it without\nwriting a file.","text":"","module":"cli","href":"module/cli.html#cli-EvalCmd"},{"fqn":"cli::FmtCmd","name":"FmtCmd","kind":"component","summary":"`pds fmt` — format to canonical PseudoScript; `--write` overwrites the file in\nplace, otherwise prints to stdout. A parse error is reported and the file is\nleft untouched.","text":"","module":"cli","href":"module/cli.html#cli-FmtCmd"},{"fqn":"cli::FmtOpts","name":"FmtOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-FmtOpts"},{"fqn":"cli::HttpServer","name":"HttpServer","kind":"component","summary":"HTTP host for the generated site (`--serve`/`--watch`): `tiny_http` on\n`127.0.0.1:port`, maps `/` to `index.html`, rejects paths escaping the output\ndir, and on watch injects a live-reload poll and answers `/__livereload` with\nthe current version. Blocks until the process is stopped.","text":"","module":"cli","href":"module/cli.html#cli-HttpServer"},{"fqn":"cli::InitCmd","name":"InitCmd","kind":"component","summary":"`pds init` — bootstrap a workspace: write `pds.toml` and a starter `main.pds`.\nRefuses to overwrite an existing manifest; the starter is written only when\nabsent.","text":"","module":"cli","href":"module/cli.html#cli-InitCmd"},{"fqn":"cli::IoError","name":"IoError","kind":"data","summary":"A filesystem, parse-config, or serving failure surfaced to the CLI exit code.","text":"","module":"cli","href":"module/cli.html#cli-IoError"},{"fqn":"cli::ListOpts","name":"ListOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-ListOpts"},{"fqn":"cli::Loader","name":"Loader","kind":"component","summary":"The CLI loader: resolves the project root and reads its modules through the\n`project` crate (the shared filesystem edge), then parses the cli-specific\n`[doc]` table on top. Root-finding and module-walking are `project`'s job;\nthe manifest's doc config is the CLI's.","text":"","module":"cli","href":"module/cli.html#cli-Loader"},{"fqn":"cli::LspHost","name":"LspHost","kind":"component","summary":"`pds lsp` — boot a Tokio runtime and launch the language server over stdio.\nSpawned as a child process by an editor (`context::Editor.openDocument`).","text":"","module":"cli","href":"module/cli.html#cli-LspHost"},{"fqn":"cli::OutlineCmd","name":"OutlineCmd","kind":"component","summary":"`pds outline` — walk the workspace's modules, build its graph, and print the\nsymbol outline as JSON: each node's `fqn`, `name`, `kind`, `parent`, whether it\nis a triggered flow entry, and its declaration site. The structure tree an\neditor draws. Outlining reads the walked modules straight, skipping the manifest\n`[doc]` parse and dependency resolution: the structure tree never depends on\npresentation config or external modules.","text":"","module":"cli","href":"module/cli.html#cli-OutlineCmd"},{"fqn":"cli::OutlineOpts","name":"OutlineOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-OutlineOpts"},{"fqn":"cli::ReferenceCmd","name":"ReferenceCmd","kind":"component","summary":"`pds lang` (alias `spec`) and `pds skill` — print the bundled, version-pinned\nlanguage reference and the authoring skill to stdout. Fed to an LLM to author\n`.pds`; no workspace needed.","text":"","module":"cli","href":"module/cli.html#cli-ReferenceCmd"},{"fqn":"cli::RemoveOpts","name":"RemoveOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-RemoveOpts"},{"fqn":"cli::SvgCmd","name":"SvgCmd","kind":"component","summary":"`pds svg` — render a single diagram to a self-contained SVG on stdout. With\n`--symbol`, draws that symbol's fitting view; otherwise draws `--view` (paired\nwith `--target`) over the whole workspace. The static counterpart of the IDE\ncanvas. Like `pds outline`, it reads the walked modules straight, skipping the\nmanifest `[doc]` parse and dependency resolution: a diagram never depends on\npresentation config or external modules.","text":"","module":"cli","href":"module/cli.html#cli-SvgCmd"},{"fqn":"cli::SvgOpts","name":"SvgOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-SvgOpts"},{"fqn":"cli::TokensCmd","name":"TokensCmd","kind":"component","summary":"`pds tokens` — print the conformance token stream (`KIND@line:col \"lexeme\"`)\nto stdout, for debugging the lexer.","text":"","module":"cli","href":"module/cli.html#cli-TokensCmd"},{"fqn":"cli::TokensOpts","name":"TokensOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-TokensOpts"},{"fqn":"cli::UpgradeCmd","name":"UpgradeCmd","kind":"component","summary":"`pds upgrade` — download a release and install it over the running binary.","text":"","module":"cli","href":"module/cli.html#cli-UpgradeCmd"},{"fqn":"cli::UpgradeOpts","name":"UpgradeOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-UpgradeOpts"},{"fqn":"cli::Watcher","name":"Watcher","kind":"component","summary":"Filesystem watcher (`--watch`, via `notify`): watches the project root\nrecursively, debounces each save burst, and on a relevant change rebuilds the\nsite and bumps the version the browser's live-reload poll reads. Events under\nthe output dir are ignored so writing the site never re-triggers a build.","text":"","module":"cli","href":"module/cli.html#cli-Watcher"},{"fqn":"cli::Workspace","name":"Workspace","kind":"data","summary":"The loaded project: the `[doc]` config, the resolved output directory\n(`/`, default `target/doc`), every module sorted by FQN, the\ndependency-name-prefixed dependency modules (§8.3; empty without a `pds.lock`),\nand the preferred doc output format. Produced from the nearest `pds.toml`.","text":"","module":"cli","href":"module/cli.html#cli-Workspace"},{"fqn":"context","name":"context","kind":"module","summary":"","text":"","module":"context","href":"module/context.html"},{"fqn":"context::Developer","name":"Developer","kind":"person","summary":"Author of architecture models: edits `.pds` files in an IDE and runs the CLI.","text":"","module":"context","href":"module/context.html#context-Developer"},{"fqn":"context::Editor","name":"Editor","kind":"system","summary":"IDEs that speak the Language Server Protocol (VS Code, Neovim, …). The editor\nspawns `pds lsp` as a child process and drives it over stdio: it streams\ndocument changes to the server and renders the diagnostics it publishes.","text":"","module":"context","href":"module/context.html#context-Editor"},{"fqn":"context::Pseudoscript","name":"Pseudoscript","kind":"system","summary":"The PseudoScript CLI — loads a `.pds` workspace into one resolved graph and\ndocuments it as a static site, or serves the language to editors. Cross-system\ncallers couple to these published faces; the containers stay behind them.","text":"","module":"context","href":"module/context.html#context-Pseudoscript"},{"fqn":"doc","name":"doc","kind":"module","summary":"","text":"","module":"doc","href":"module/doc.html"},{"fqn":"doc::Assets","name":"Assets","kind":"component","summary":"Ships the prebuilt presentation bundles, authored in the `web/` Svelte package and\nembedded at build time (LANG.md §9.3). `style.css`, `client.js`, and\n`universe.js` ship once at the site root; `ssr.js` is build-time only — the\nengine (`Doc::Ssr`) evaluates it and it is never written to the site. The\nuniverse bundle is the only one that carries WebGL; the SSR bundle never\ndoes.","text":"","module":"doc","href":"module/doc.html#doc-Assets"},{"fqn":"doc::Call","name":"Call","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-Call"},{"fqn":"doc::Codec","name":"Codec","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-Codec"},{"fqn":"doc::Crumb","name":"Crumb","kind":"data","summary":"One breadcrumb hop: its label and href; the trailing crumb (the current\npage) carries no href.","text":"","module":"doc","href":"module/doc.html#doc-Crumb"},{"fqn":"doc::DiagnosticInput","name":"DiagnosticInput","kind":"data","summary":"One host-prepared diagnostic, positioned in its module's source: severity\nword (`error`/`warning`), the stable rule code and its principle-article URL\n(empty for plain diagnostics), the message, and the 1-based line/column with\nthe byte span. The host computes line/column once — this crate never sees\nmodule sources.","text":"","module":"doc","href":"module/doc.html#doc-DiagnosticInput"},{"fqn":"doc::Diagram","name":"Diagram","kind":"data","summary":"A diagram figure. Every view — C4, sequence, data, feature — ships as\ndeterministic server-rendered SVG, identical to `pds svg` (the client adds\npan/zoom only); `kind` is the view word (`c4`/`sequence`/`entity`/`flow`)\nthe figure exposes as its `data-diagram` hook. `Empty` marks a view that\nfailed to project.","text":"","module":"doc","href":"module/doc.html#doc-Diagram"},{"fqn":"doc::Diagrams","name":"Diagrams","kind":"component","summary":"The bridge into `emit`: project a view into a `Scene` and render it to the\nsame deterministic SVG `pds svg` emits, under the adaptive palette so the\nfigure follows the site theme. A view that fails to project degrades to an\n`Empty` placeholder rather than aborting the build — the cargo-doc stance\nthat a partial model still documents. The client adds pan/zoom around the\nfigure; it never re-lays-out.","text":"","module":"doc","href":"module/doc.html#doc-Diagrams"},{"fqn":"doc::Doc","name":"Doc","kind":"container","summary":"`crates/pseudoscript-doc`. Turns a resolved graph into a Svelte-rendered,\ncargo-doc-style site that fully represents the system: each node's `///`\ndocs and relationships on its page, every diagram as deterministic\nserver-rendered SVG, the 3D universe with its flows, the architecture-health\nreport, and a static full-text search index. Pure: returns in-memory files,\nthe CLI writes.","text":"","module":"doc","href":"module/doc.html#doc-Doc"},{"fqn":"doc::DocBody","name":"DocBody","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-DocBody"},{"fqn":"doc::DocConfig","name":"DocConfig","kind":"data","summary":"Site presentation, filled by the CLI from the `[doc]` table of `pds.toml`.\n`[doc]` tunes presentation only, never what is documented.","text":"","module":"doc","href":"module/doc.html#doc-DocConfig"},{"fqn":"doc::DocGroup","name":"DocGroup","kind":"data","summary":"One `[[doc.sidebar]]` group of authored Markdown pages: a heading and its\nordered pages, rendered above the auto-generated module tree.","text":"","module":"doc","href":"module/doc.html#doc-DocGroup"},{"fqn":"doc::DocPage","name":"DocPage","kind":"data","summary":"One authored Markdown page: its sidebar title, the source path (relative to\n`pds.toml`) from which the host and this crate derive the same stable slug,\nand the raw Markdown the host has already loaded, rendered to HTML at build\ntime. The crate reads `markdown`; `path` only names the page, never loads it.","text":"","module":"doc","href":"module/doc.html#doc-DocPage"},{"fqn":"doc::Empty","name":"Empty","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-Empty"},{"fqn":"doc::Engine","name":"Engine","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-Engine"},{"fqn":"doc::Escape","name":"Escape","kind":"component","summary":"All user text — node names, `///` docs, tags, the site title — is carried raw in\nthe props and escaped on interpolation by the renderer; this escaper guards the\nRust-owned document shell, where the title and theme become HTML attributes.","text":"","module":"doc","href":"module/doc.html#doc-Escape"},{"fqn":"doc::Health","name":"Health","kind":"component","summary":"Positions the host's diagnostics in the documentation: prepares raw\nper-module findings (line/column from sources), attributes each to the node\nwhose section it belongs on, and builds the health page and the per-section\nbadges. Attribution is positional: the node whose declaration starts\nclosest before the diagnostic's span owns it, a callable lifting to its\nowner; a span no node encloses falls back to the module page.","text":"","module":"doc","href":"module/doc.html#doc-Health"},{"fqn":"doc::HealthEntry","name":"HealthEntry","kind":"data","summary":"One architecture-health finding, attributed to the node whose section it\nbelongs on: the diagnostic fields plus the owning node's FQN and the\n(prefixed) href to its section — the module page when no node encloses the\nspan.","text":"","module":"doc","href":"module/doc.html#doc-HealthEntry"},{"fqn":"doc::HealthPage","name":"HealthPage","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-HealthPage"},{"fqn":"doc::Highlight","name":"Highlight","kind":"component","summary":"Highlights fenced code blocks at build time, so the shipped site needs no\nclient highlighter and one deterministic output serves every theme:\nPseudoScript through the toolchain's own lexer, emitting class-based spans\ncoloured by the site stylesheet. Any other language passes through escaped\nand unhighlighted — an embedded grammar set for common languages is a\ndeliberate future extension (it would bloat the IDE wasm today).","text":"","module":"doc","href":"module/doc.html#doc-Highlight"},{"fqn":"doc::IndexPage","name":"IndexPage","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-IndexPage"},{"fqn":"doc::Markdown","name":"Markdown","kind":"component","summary":"Renders an authored `[[doc.sidebar]]` page's Markdown source into the HTML that\nfills its `Doc` page body (LANG.md §9.3). The host has already loaded the\nsource into the page's `markdown`; this crate does no I/O and renders that\ncontent in memory. The rendered HTML carries through unescaped as trusted\nauthored content.","text":"","module":"doc","href":"module/doc.html#doc-Markdown"},{"fqn":"doc::MarkdownSite","name":"MarkdownSite","kind":"component","summary":"The static Markdown output mode: turns the same per-page props the HTML\nrenderer consumes into flat `.md` files, each diagram a standalone `.svg`\nasset referenced as an image. The universe page renders as text lists\n(nodes by level, edges with traffic, each flow's legs); the health page as\na table with article links. No SSR engine, no shared assets, no logo — the\nengine-free site for wikis and code hosts.","text":"","module":"doc","href":"module/doc.html#doc-MarkdownSite"},{"fqn":"doc::ModuleCard","name":"ModuleCard","kind":"data","summary":"A module card on the index: its FQN, the (prefixed) href to its page, and an\n\"N item(s)\" line.","text":"","module":"doc","href":"module/doc.html#doc-ModuleCard"},{"fqn":"doc::ModulePage","name":"ModulePage","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-ModulePage"},{"fqn":"doc::NavLink","name":"NavLink","kind":"data","summary":"One header navigation link, its href prefixed for the page's depth; `badge`\ncarries the Health page's finding count (empty elsewhere).","text":"","module":"doc","href":"module/doc.html#doc-NavLink"},{"fqn":"doc::NodeHref","name":"NodeHref","kind":"data","summary":"A universe node's documentation link: its id and the (prefixed) href to its\nsection, so clicking a sphere can navigate to the docs.","text":"","module":"doc","href":"module/doc.html#doc-NodeHref"},{"fqn":"doc::NodeSection","name":"NodeSection","kind":"data","summary":"One node's documentation section: head fields, `///` docs, tags, relationship\ngroups, scenario cards, embedded diagrams, and the health findings attributed\nto the node (rendered as inline badges).","text":"","module":"doc","href":"module/doc.html#doc-NodeSection"},{"fqn":"doc::NodeUrl","name":"NodeUrl","kind":"data","summary":"A resolved cross-reference target: the module page it lives on and its in-page\nanchor id. A cross-link uses these to build an `href`; an unresolved FQN has no\nentry and renders as plain text.","text":"","module":"doc","href":"module/doc.html#doc-NodeUrl"},{"fqn":"doc::PageBody","name":"PageBody","kind":"data","summary":"The page body: the landing index, one authored doc page, one module's page,\nthe 3D universe, or the architecture-health report.","text":"","module":"doc","href":"module/doc.html#doc-PageBody"},{"fqn":"doc::PageProps","name":"PageProps","kind":"data","summary":"The serialisable model for one page, handed to the Svelte server renderer.\nEvery derived value (resolved hrefs, anchors, edge labels, counts) is\nprecomputed here so the Svelte components do no graph logic. User text is\ncarried raw — the renderer escapes it on interpolation. `docGroups` carries\nthe authored `[[doc.sidebar]]` navigation shown above the module tree;\n`nav` carries the header links (Overview, Universe, Health with its finding\ncount); `crumbs` is the breadcrumb trail. Only the universe page's props are\nalso embedded in the document, for its 3D island — every other page ships no\npage data.","text":"","module":"doc","href":"module/doc.html#doc-PageProps"},{"fqn":"doc::Pages","name":"Pages","kind":"component","summary":"Projects the resolved graph into per-page `PageProps` — pure data, no markup.\nBuilds the index props (title, context diagram, module cards), each module page's\nnode sections, and the depth-prefixed sidebar tree mirroring the C4 hierarchy.","text":"","module":"doc","href":"module/doc.html#doc-Pages"},{"fqn":"doc::RelGroup","name":"RelGroup","kind":"data","summary":"One relationship group (\"Parent\", \"Inbound\", or \"Outbound\") and its endpoints.","text":"","module":"doc","href":"module/doc.html#doc-RelGroup"},{"fqn":"doc::RelItem","name":"RelItem","kind":"data","summary":"One relationship endpoint: the edge-kind word, whether to draw the outbound\narrow, the endpoint FQN, its resolved href (absent → plain text), and any label.","text":"","module":"doc","href":"module/doc.html#doc-RelItem"},{"fqn":"doc::Relationships","name":"Relationships","kind":"component","summary":"Renders a node's relationships (LANG.md §9.3): its `for`/owner parent, inbound\nedges, and outbound edges, skipping the structural `for`-parent edge kind. Each\nendpoint is a cross-link when its FQN resolves, plain text otherwise.","text":"","module":"doc","href":"module/doc.html#doc-Relationships"},{"fqn":"doc::RenderError","name":"RenderError","kind":"data","summary":"Why server-rendering a page failed. Every variant is a defect in the bundle, the\nengine, or the props codec — never user model data; well-formed props always\nrender.","text":"","module":"doc","href":"module/doc.html#doc-RenderError"},{"fqn":"doc::RenderedPage","name":"RenderedPage","kind":"data","summary":"The server-render result for one page: the `` contents and the\nrendered body markup, dropped into the document shell.","text":"","module":"doc","href":"module/doc.html#doc-RenderedPage"},{"fqn":"doc::ScenarioCard","name":"ScenarioCard","kind":"data","summary":"One BDD scenario card: name, `///` docs, tags, the ordered steps, and the\nfeature's flow figure (LANG.md §9.5).","text":"","module":"doc","href":"module/doc.html#doc-ScenarioCard"},{"fqn":"doc::Scenarios","name":"Scenarios","kind":"component","summary":"Renders the BDD scenario cards on a node's page: each `feature` targeting the node\nbecomes its given/when/then steps and its flow figure as a card (LANG.md §5.2,\n§9.3, §9.5). Empty when the node has no features.","text":"","module":"doc","href":"module/doc.html#doc-Scenarios"},{"fqn":"doc::SearchEntry","name":"SearchEntry","kind":"data","summary":"One record in the static full-text search index: the symbol or page's FQN,\ndisplay name, kind word, one-line summary, plain-text body, declaring\nmodule, and root-relative href. Sorted by href then FQN so the index is\ndeterministic.","text":"","module":"doc","href":"module/doc.html#doc-SearchEntry"},{"fqn":"doc::SearchIndex","name":"SearchIndex","kind":"component","summary":"Builds the static full-text search index the client palette queries: one\nrecord per linkable node, module page, and authored doc page, plus the\nuniverse and health pages. Shipped as a classic-script JS assignment\n(`search-index.js` setting a window global) so it loads under `file://` —\nnever fetched.","text":"","module":"doc","href":"module/doc.html#doc-SearchIndex"},{"fqn":"doc::SectionDiagnostic","name":"SectionDiagnostic","kind":"data","summary":"One inline badge on a node's section: the severity, rule code, article URL,\nmessage, and source line of a finding attributed to that node.","text":"","module":"doc","href":"module/doc.html#doc-SectionDiagnostic"},{"fqn":"doc::Shell","name":"Shell","kind":"component","summary":"Owns the document shell that wraps each server-rendered body — the part Rust\nrenders, not Svelte: doctype, ``, font + stylesheet links,\nthe theme pre-paint script, and the classic deferred scripts. Scripts are\nclassic (never `type=\"module\"`) and shared data ships as JS-global files, so\nthe site works opened from disk (`file://`). Only the universe page embeds\nits props (`window.__DATA__`) — for its 3D island; every other page ships no\npage data and the client only progressively enhances.","text":"","module":"doc","href":"module/doc.html#doc-Shell"},{"fqn":"doc::SidebarDocGroup","name":"SidebarDocGroup","kind":"data","summary":"One `[[doc.sidebar]]` group in the authored-doc navigation: a heading and its\npage links, shown above the module tree.","text":"","module":"doc","href":"module/doc.html#doc-SidebarDocGroup"},{"fqn":"doc::SidebarDocItem","name":"SidebarDocItem","kind":"data","summary":"One authored doc-page link in the sidebar: its title and the page href, already\nprefixed for the page's depth.","text":"","module":"doc","href":"module/doc.html#doc-SidebarDocItem"},{"fqn":"doc::SidebarModule","name":"SidebarModule","kind":"data","summary":"One sidebar entry: a module-page link and its node tree, hrefs already prefixed\nfor the page's depth.","text":"","module":"doc","href":"module/doc.html#doc-SidebarModule"},{"fqn":"doc::SidebarNode","name":"SidebarNode","kind":"data","summary":"One node in the sidebar tree, recursing into its same-module children.","text":"","module":"doc","href":"module/doc.html#doc-SidebarNode"},{"fqn":"doc::Site","name":"Site","kind":"data","summary":"The whole generated site as in-memory files, in deterministic order: the index,\none page per authored doc (`[[doc.sidebar]]`, in declaration order), then one\npage per module sorted by FQN, plus the shared assets. The doc crate does no\nI/O; the CLI writes each file under the configured output directory.","text":"","module":"doc","href":"module/doc.html#doc-Site"},{"fqn":"doc::SiteBuilder","name":"SiteBuilder","kind":"component","summary":"Orchestrates the whole site: build the URL map, project each page's props, server\nrender it through the SSR engine, wrap it in the document shell, and ship the\nshared assets plus the search index. Pure: returns in-memory `Site` files,\nwrites none.","text":"","module":"doc","href":"module/doc.html#doc-SiteBuilder"},{"fqn":"doc::SiteFile","name":"SiteFile","kind":"data","summary":"One generated file: a site-root-relative `/`-separated path (`index.html`,\n`module/banking.core.html`, `style.css`, `client.js`) and its complete contents.","text":"","module":"doc","href":"module/doc.html#doc-SiteFile"},{"fqn":"doc::SiteInfo","name":"SiteInfo","kind":"data","summary":"Site-wide presentation, identical across pages: the title, the\n`light`/`dark`/`system` theme word, the optional logo filename, and the\n`../` prefix to the site root for this page's depth.","text":"","module":"doc","href":"module/doc.html#doc-SiteInfo"},{"fqn":"doc::SiteStats","name":"SiteStats","kind":"data","summary":"The index page's stats strip: how many systems, containers, components,\nflows, and health findings the model carries.","text":"","module":"doc","href":"module/doc.html#doc-SiteStats"},{"fqn":"doc::Ssr","name":"Ssr","kind":"component","summary":"The server-side render boundary: a JSON-string-in / JSON-string-out seam to the\nJavaScript renderer. The native build embeds a `QuickJS` engine that evaluates the\nprebuilt `ssr.js` bundle (`Doc::Assets`) in-process; a wasm host implements the\nsame seam against its own JS engine. A defect here is a build-asset fault, never\nuser model data.","text":"","module":"doc","href":"module/doc.html#doc-Ssr"},{"fqn":"doc::Step","name":"Step","kind":"data","summary":"One scenario step: its keyword (given/when/then/and/but) and prose.","text":"","module":"doc","href":"module/doc.html#doc-Step"},{"fqn":"doc::Svg","name":"Svg","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-Svg"},{"fqn":"doc::Theme","name":"Theme","kind":"data","summary":"Doc-site colour scheme, written as the `data-theme` attribute on the root\n`` to select a CSS variable set. `System` (the default) follows the\nOS `prefers-color-scheme`, overridable by the in-page toggle; `Light` and\n`Dark` pin the scheme.","text":"","module":"doc","href":"module/doc.html#doc-Theme"},{"fqn":"doc::UniversePage","name":"UniversePage","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-UniversePage"},{"fqn":"doc::Urls","name":"Urls","kind":"component","summary":"Maps every node FQN to its page path and anchor, and resolves cross-references to\nmodule-page-relative `href`s. A module page is `module/.html`\n(`::` → `.`); a node is the `#` anchor within it. Only an FQN naming a real\nnode produces a link (LANG.md §9.3).","text":"","module":"doc","href":"module/doc.html#doc-Urls"},{"fqn":"dot","name":"dot","kind":"module","summary":"","text":"","module":"dot","href":"module/dot.html"},{"fqn":"dot::Box2","name":"Box2","kind":"data","summary":"An axis-aligned box: top-left corner and extent.","text":"","module":"dot","href":"module/dot.html#dot-Box2"},{"fqn":"dot::Cluster","name":"Cluster","kind":"data","summary":"A cluster (a `subgraph cluster_*`): its id, optional parent cluster, member\nnode ids, the margin kept outside its members, and the header band reserved on\nthe title side.","text":"","module":"dot","href":"module/dot.html#dot-Cluster"},{"fqn":"dot::ClusterBox","name":"ClusterBox","kind":"data","summary":"A laid-out cluster: its id and bounding box.","text":"","module":"dot","href":"module/dot.html#dot-ClusterBox"},{"fqn":"dot::Clusters","name":"Clusters","kind":"component","summary":"Cluster framing: compute each cluster's bounding box bottom-up so a nested\ncluster's box encloses its children (grown by their margins) and its direct\nmembers, with header room on the title side — `dot`'s recursive `rec_bb`.","text":"","module":"dot","href":"module/dot.html#dot-Clusters"},{"fqn":"dot::Dot","name":"Dot","kind":"container","summary":"`crates/pseudoscript-dot`. Runs the four-pass layered pipeline over a `Graph`\nto produce a `Layout`; also offers the experimental grid placer. The layout\nauthority `emit` drives for C4 diagrams.","text":"","module":"dot","href":"module/dot.html#dot-Dot"},{"fqn":"dot::Edge","name":"Edge","kind":"data","summary":"An input edge from `tail` to `head`, with its minimum rank span, its layout\nweight (higher pulls the endpoints into vertical alignment harder), and an\noptional label size that widens the rank gap to fit.","text":"","module":"dot","href":"module/dot.html#dot-Edge"},{"fqn":"dot::EdgeRoute","name":"EdgeRoute","kind":"data","summary":"A routed edge: the Bézier `spline` and its `polyline` approximation between\n`tail` and `head`, plus where its label sits.","text":"","module":"dot","href":"module/dot.html#dot-EdgeRoute"},{"fqn":"dot::Engine","name":"Engine","kind":"component","summary":"The layered engine: runs the faithful four-pass `dot` pipeline — rank, order,\nposition, splines — then frames the clusters and shifts the whole layout to\nthe origin. Deterministic and panic-free.","text":"","module":"dot","href":"module/dot.html#dot-Engine"},{"fqn":"dot::Graph","name":"Graph","kind":"data","summary":"The input graph the engine lays out: nodes, edges, clusters, the rank and node\nseparations, the rank direction, and any same-rank constraints.","text":"","module":"dot","href":"module/dot.html#dot-Graph"},{"fqn":"dot::Grid","name":"Grid","kind":"component","summary":"The experimental grid placer: an alternative to the layered pipeline that\nsnaps nodes to a grid, honouring drag-to-pin cells and searching for a\nplacement that minimises crossings, distance, and against-flow edges.","text":"","module":"dot","href":"module/dot.html#dot-Grid"},{"fqn":"dot::GridMeta","name":"GridMeta","kind":"data","summary":"Grid metadata carried back when the experimental grid placer ran: the grid\ndimensions, the cell pitch (centre-to-centre), the pixel centre of cell (0,0),\nand the width of the drag-room frame wrapping the grid — the geometry the IDE\nreads to map a drag onto a grid cell, recovering the raw cell from `origin`\nthen subtracting `pad`.","text":"","module":"dot","href":"module/dot.html#dot-GridMeta"},{"fqn":"dot::GridParams","name":"GridParams","kind":"data","summary":"Tunable weights for the experimental grid placer: how strongly it penalises\ncrossings, distance, and against-flow edges, the cell spacing, and how hard it\nsearches.","text":"","module":"dot","href":"module/dot.html#dot-GridParams"},{"fqn":"dot::Layout","name":"Layout","kind":"data","summary":"The layout result: the overall bounding box, the placed nodes, the routed\nedges, the cluster boxes, and — only when the grid placer ran — its grid\nmetadata.","text":"","module":"dot","href":"module/dot.html#dot-Layout"},{"fqn":"dot::LayoutState","name":"LayoutState","kind":"data","summary":"The structure that flows through a pipeline: the (possibly pass-mutated)\ninput graph and its current placement. A pass receives one, returns one, and\nthe framework hands it to the next pass; a re-ranking pass may edit `graph`\nand re-run the base layout.","text":"","module":"dot","href":"module/dot.html#dot-LayoutState"},{"fqn":"dot::Node","name":"Node","kind":"data","summary":"An input node: its id and its rendered size (the placer reserves this box).","text":"","module":"dot","href":"module/dot.html#dot-Node"},{"fqn":"dot::NodePos","name":"NodePos","kind":"data","summary":"A placed node: its id, centre point, and reserved size.","text":"","module":"dot","href":"module/dot.html#dot-NodePos"},{"fqn":"dot::Optimize","name":"Optimize","kind":"component","summary":"The `ShortenLongEdges` pass: a bounded, deterministic post-layout refinement.\nGreedily search for same-rank moves that reduce the sum of squared edge\nlengths (never merging across a cluster boundary), then re-lay-out with the\nimproving moves applied.","text":"","module":"dot","href":"module/dot.html#dot-Optimize"},{"fqn":"dot::Oracle","name":"Oracle","kind":"component","summary":"The test oracle: lays the same graph out with the real `dot` binary and\ncompares, so the port stays faithful rather than approximate. Skipped when\n`dot` is not installed.","text":"","module":"dot","href":"module/dot.html#dot-Oracle"},{"fqn":"dot::Order","name":"Order","kind":"component","summary":"Pass 2 — ordering: order nodes within each rank to minimise edge crossings,\ninserting virtual nodes for long edges so they route through thin lanes.","text":"","module":"dot","href":"module/dot.html#dot-Order"},{"fqn":"dot::Pass","name":"Pass","kind":"data","summary":"One stage of the composable post-layout pipeline: same structure in, same\nstructure out, so passes fold freely. `ShortenLongEdges` is the long-edge\noptimiser; `GridPlacement` wraps the grid placer so it drops into a pipeline.\nNew behaviour is added by writing a pass, not by threading flags through the\nengine.","text":"","module":"dot","href":"module/dot.html#dot-Pass"},{"fqn":"dot::Pin","name":"Pin","kind":"data","summary":"A pin fixing a node to a grid cell: the node's index into `graph.nodes` (the\ncaller resolves the FQN) at a row and column. The IDE's drag-to-pin.","text":"","module":"dot","href":"module/dot.html#dot-Pin"},{"fqn":"dot::Pipeline","name":"Pipeline","kind":"component","summary":"The composable post-layout pipeline: the base layout produces the starting\n`LayoutState`; each `Pass` folds it into the next. A pass adjusts geometry\ndirectly or edits the input graph (e.g. adds same-rank hints) and re-runs the\nbase layout.","text":"","module":"dot","href":"module/dot.html#dot-Pipeline"},{"fqn":"dot::Position","name":"Position","kind":"component","summary":"Pass 3 — positioning: assign x-coordinates by network simplex on an auxiliary\ngraph (aligning nodes and straightening long edges), and y-coordinates per\nrank stacked with `ranksep` plus any label and cluster-header room.","text":"","module":"dot","href":"module/dot.html#dot-Position"},{"fqn":"dot::Pt","name":"Pt","kind":"data","summary":"A point in layout coordinates.","text":"","module":"dot","href":"module/dot.html#dot-Pt"},{"fqn":"dot::Rank","name":"Rank","kind":"component","summary":"Pass 1 — rank assignment: give each node an integer rank by network simplex,\nbanding each cluster onto contiguous ranks and honouring same-rank constraints.","text":"","module":"dot","href":"module/dot.html#dot-Rank"},{"fqn":"dot::RankDir","name":"RankDir","kind":"data","summary":"The rank direction: top-to-bottom (the C4 default) or left-to-right.","text":"","module":"dot","href":"module/dot.html#dot-RankDir"},{"fqn":"dot::SearchMode","name":"SearchMode","kind":"data","summary":"How the experimental grid placer searches for a placement: pick automatically\nby size, always the bounded heuristic, or brute-force exhaustive (tiny graphs\nonly).","text":"","module":"dot","href":"module/dot.html#dot-SearchMode"},{"fqn":"dot::Size","name":"Size","kind":"data","summary":"A width/height extent.","text":"","module":"dot","href":"module/dot.html#dot-Size"},{"fqn":"dot::Splines","name":"Splines","kind":"component","summary":"Pass 4 — splines: route each edge as a piecewise Bézier through its\nvirtual-node corridor, clipped to the endpoint borders, with a label point at\nthe polyline midpoint.","text":"","module":"dot","href":"module/dot.html#dot-Splines"},{"fqn":"emit","name":"emit","kind":"module","summary":"","text":"","module":"emit","href":"module/emit.html"},{"fqn":"emit::BoundaryFrame","name":"BoundaryFrame","kind":"data","summary":"An enclosing frame of a boundary view: the boundary node's FQN (so the canvas\ncan drill into it), title, C4 kind (frame accent), and the cluster rectangle.","text":"","module":"emit","href":"module/emit.html#emit-BoundaryFrame"},{"fqn":"emit::C4EdgeKind","name":"C4EdgeKind","kind":"data","summary":"The relationship a routed edge expresses: a body `call`, a synthesised\n`trigger` from an initiator, or a `from` `provenance` link. Maps from\n`model::EdgeKind`, dropping the structural `for`-parent link.","text":"","module":"emit","href":"module/emit.html#emit-C4EdgeKind"},{"fqn":"emit::C4Layout","name":"C4Layout","kind":"data","summary":"A dot-placed C4 view for the interactive canvas and the static SVG: canvas\nsize, placed node cards, routed edges, the enclosing boundary frames\n(outermost first; empty for a context view), and — only under experimental\ngrid placement — the grid geometry for drag-to-pin.","text":"","module":"emit","href":"module/emit.html#emit-C4Layout"},{"fqn":"emit::C4Scene","name":"C4Scene","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-C4Scene"},{"fqn":"emit::C4Tweaks","name":"C4Tweaks","kind":"data","summary":"Per-diagram C4 layout tweaks (the UI's \"Layout\" toggles): run the long-edge\noptimiser, lay out left-to-right instead of top-to-bottom, scale the spacing,\nand — experimentally — place by brute-force grid search instead of the layered\nengine, with its own cost dials and search mode.","text":"","module":"emit","href":"module/emit.html#emit-C4Tweaks"},{"fqn":"emit::C4View","name":"C4View","kind":"data","summary":"Which C4 view a `C4Scene` is — drives the golden header keyword.","text":"","module":"emit","href":"module/emit.html#emit-C4View"},{"fqn":"emit::Component","name":"Component","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-Component"},{"fqn":"emit::Container","name":"Container","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-Container"},{"fqn":"emit::Data","name":"Data","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-Data"},{"fqn":"emit::DataEntity","name":"DataEntity","kind":"data","summary":"One entity in a `data` ER view: its FQN, label, disclosed form, rows, whether\nit is the focal type, and its laid-out card rectangle.","text":"","module":"emit","href":"module/emit.html#emit-DataEntity"},{"fqn":"emit::DataLink","name":"DataLink","kind":"data","summary":"A field-type reference link between two entities in a data view: the\nreferencing and referenced FQNs and the field driving the reference.","text":"","module":"emit","href":"module/emit.html#emit-DataLink"},{"fqn":"emit::DataScene","name":"DataScene","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-DataScene"},{"fqn":"emit::Edges","name":"Edges","kind":"component","summary":"Builds the routed-edge set for a C4 scene from the graph's edges: maps each\n`model::EdgeKind` to a `C4EdgeKind` (dropping `for`-parent links), lifts each\nendpoint to the in-view node it belongs to, drops self-loops and\nout-of-view edges, then sorts and de-duplicates.","text":"","module":"emit","href":"module/emit.html#emit-Edges"},{"fqn":"emit::Emit","name":"Emit","kind":"container","summary":"`crates/pseudoscript-emit`. Projects a view into a `Scene` and renders it to\nSVG; C4 views are placed by the `dot` layered engine, the sequence/data/feature\nviews by the matching `layout` engine.","text":"","module":"emit","href":"module/emit.html#emit-Emit"},{"fqn":"emit::EmitError","name":"EmitError","kind":"data","summary":"Why projecting a view failed: the target FQN names no node, or names a node of\nthe wrong kind for the requested view.","text":"","module":"emit","href":"module/emit.html#emit-EmitError"},{"fqn":"emit::EntityForm","name":"EntityForm","kind":"data","summary":"The disclosed form of a data entity, driving the card's eyebrow and rows: a\nrecord of typed fields, a discriminated union of variants, or a black box.","text":"","module":"emit","href":"module/emit.html#emit-EntityForm"},{"fqn":"emit::EntityRow","name":"EntityRow","kind":"data","summary":"One row of a data entity: the field or variant name, its rendered type (empty\nfor a union variant), and the FQN of the data type this row targets when it\nreferences one.","text":"","module":"emit","href":"module/emit.html#emit-EntityRow"},{"fqn":"emit::Feature","name":"Feature","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-Feature"},{"fqn":"emit::FeatureScene","name":"FeatureScene","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-FeatureScene"},{"fqn":"emit::FeatureStepNode","name":"FeatureStepNode","kind":"data","summary":"One step box in a `feature` flow view: the step keyword, its prose, and the\nlaid-out box rectangle.","text":"","module":"emit","href":"module/emit.html#emit-FeatureStepNode"},{"fqn":"emit::Frame","name":"Frame","kind":"data","summary":"A nestable frame over a body of sequence items, drawn as an enclosing box\nwith its condition label.","text":"","module":"emit","href":"module/emit.html#emit-Frame"},{"fqn":"emit::FrameItem","name":"FrameItem","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-FrameItem"},{"fqn":"emit::FrameKind","name":"FrameKind","kind":"data","summary":"The kind of a sequence frame: `if`/`else` becomes an `alt` frame, `for`/\n`while` becomes a `loop` frame.","text":"","module":"emit","href":"module/emit.html#emit-FrameKind"},{"fqn":"emit::GridInfo","name":"GridInfo","kind":"data","summary":"The grid the experimental placement used, in absolute canvas coordinates:\ncell `(r, c)` is centred at `origin + (c·cellW, r·cellH)`; `pad` is the\ndrag-room frame, so a pixel maps to its pin cell by recovering the raw cell\nthen subtracting `pad`.","text":"","module":"emit","href":"module/emit.html#emit-GridInfo"},{"fqn":"emit::GridPin","name":"GridPin","kind":"data","summary":"A node the user has pinned to a grid cell (drag-to-pin), identified by FQN;\nthe emit layer resolves it to a `dot` node index for the current view. Honoured\nonly under experimental grid placement.","text":"","module":"emit","href":"module/emit.html#emit-GridPin"},{"fqn":"emit::GridSearch","name":"GridSearch","kind":"data","summary":"Which grid search the experimental grid placer runs — the UI's\nheuristic-vs-brute-force toggle. Mirrors `dot::SearchMode` so the IDE need not\ndepend on `dot`.","text":"","module":"emit","href":"module/emit.html#emit-GridSearch"},{"fqn":"emit::LaidOutEdge","name":"LaidOutEdge","kind":"data","summary":"A routed edge for the canvas/SVG: its endpoints (`source` stands for the wire\n`from`), kind, stacked labels, the engine's polyline (at least two points),\nthe label position at the polyline midpoint when labels exist, and whether it\ndraws dashed (a `from`-provenance edge).","text":"","module":"emit","href":"module/emit.html#emit-LaidOutEdge"},{"fqn":"emit::LaidOutNode","name":"LaidOutNode","kind":"data","summary":"A node card placed by the `dot` engine for the canvas/SVG: its FQN, C4 kind\n(accent and eyebrow), display label, optional `///` summary, and rectangle.","text":"","module":"emit","href":"module/emit.html#emit-LaidOutNode"},{"fqn":"emit::Layout","name":"Layout","kind":"component","summary":"Assigns geometry. Projection stamps each C4 scene with simple row-flow\ncoordinates (`solveC4`) — the panic-proof fallback geometry every scene\ncarries. The real placement runs at render/canvas time: `layoutC4` drives the\n`dot` layered engine (rank/order/position/splines), framing boundary children\nas a cluster, tuned by per-diagram `C4Tweaks` and drag-to-pin cells. The\nsequence/data/feature scenes are placed by the matching `layout` engine.","text":"","module":"emit","href":"module/emit.html#emit-Layout"},{"fqn":"emit::Lifeline","name":"Lifeline","kind":"data","summary":"A sequence lifeline (a participant): its FQN, C4 kind for the head card, the\nnode's `///` summary shown dimmed under the name, and the structural ancestry\npath under a container/component name. No coordinate — the sequence layout\nassigns the lifeline x.","text":"","module":"emit","href":"module/emit.html#emit-Lifeline"},{"fqn":"emit::Message","name":"Message","kind":"data","summary":"A message between two lifelines (or a self-message). `label` is the method\nname, or `Ok`/`Err`/empty for a return; `detail` is the type detail shown after\nit — a call's `(params): ret` signature or a return's concrete type.","text":"","module":"emit","href":"module/emit.html#emit-Message"},{"fqn":"emit::MessageItem","name":"MessageItem","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-MessageItem"},{"fqn":"emit::MessageKind","name":"MessageKind","kind":"data","summary":"The kind of a sequence message: a `call` to another lifeline, a `return` to\nthe caller, or a `self`-message on the owner's own lifeline.","text":"","module":"emit","href":"module/emit.html#emit-MessageKind"},{"fqn":"emit::PlacedNode","name":"PlacedNode","kind":"data","summary":"A node placed in a C4 view: its FQN, C4 kind, display label, optional `///`\nsummary (the card's dimmed description), the boundary it sits inside, and the\nlayout rectangle assigned by the placer.","text":"","module":"emit","href":"module/emit.html#emit-PlacedNode"},{"fqn":"emit::PointI","name":"PointI","kind":"data","summary":"An integer point on the canvas (a rounded layout coordinate).","text":"","module":"emit","href":"module/emit.html#emit-PointI"},{"fqn":"emit::Projector","name":"Projector","kind":"component","summary":"Projects a `View` out of the graph (LANG.md §9): dispatches on the view\nvariant, collecting nodes and edges for a C4 scene or tracing a callable body\nfor a sequence scene, then hands off to the placer. Fails with `EmitError`\nwhen the view's target is missing or the wrong kind.","text":"","module":"emit","href":"module/emit.html#emit-Projector"},{"fqn":"emit::Rect","name":"Rect","kind":"data","summary":"An axis-aligned layout rectangle in renderer coordinates.","text":"","module":"emit","href":"module/emit.html#emit-Rect"},{"fqn":"emit::RoutedEdge","name":"RoutedEdge","kind":"data","summary":"An edge routed between two C4 nodes: its endpoints, kind, and the merged call\nlabels (sorted and de-duplicated; empty for a trigger or provenance edge).\nParallel calls between the same pair collapse into one multi-label edge.\n`source` is the wire field `from`, renamed because `from` is a PseudoScript\nkeyword.","text":"","module":"emit","href":"module/emit.html#emit-RoutedEdge"},{"fqn":"emit::Scene","name":"Scene","kind":"data","summary":"A laid-out diagram: the notation-neutral IR the SVG renderer consumes. A C4\nscene carries placed nodes and routed edges; a sequence scene carries\nlifelines and ordered messages with nested frames. This IR is the generation\nconformance surface (ADR-017): coordinates are carried for the renderer only,\nnever serialised to the golden.","text":"","module":"emit","href":"module/emit.html#emit-Scene"},{"fqn":"emit::SeqItem","name":"SeqItem","kind":"data","summary":"One ordered item in a sequence trace: a message or a nested frame.","text":"","module":"emit","href":"module/emit.html#emit-SeqItem"},{"fqn":"emit::Sequence","name":"Sequence","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-Sequence"},{"fqn":"emit::SequenceScene","name":"SequenceScene","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-SequenceScene"},{"fqn":"emit::SvgRenderer","name":"SvgRenderer","kind":"component","summary":"Renders a laid-out `Scene` to standalone SVG markup — string-building, no\ntemplate engine and no headless browser (LANG.md §9.3, ADR-017). Dispatches\non the scene variant; the layout engine is wrapped so no input panics the\nrender, falling back to the scene's own simple coordinates.","text":"","module":"emit","href":"module/emit.html#emit-SvgRenderer"},{"fqn":"emit::Trace","name":"Trace","kind":"component","summary":"Walks a callable's body trace into ordered sequence items, registering each\nparticipant on first appearance (LANG.md §9.2, §7). A real trigger's\ninitiator leads as the first lifeline with a synthesised inbound call;\nabsent a trigger the owner leads. A `call` is a message to the target; a\ndisclosed callee expands inline; a `self.` call is a self-message; a return\nmarks `Ok`/`Err`; `if`/`else` nests an `alt` frame, `for`/`while` a `loop`\nframe.","text":"","module":"emit","href":"module/emit.html#emit-Trace"},{"fqn":"emit::UnknownNode","name":"UnknownNode","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-UnknownNode"},{"fqn":"emit::View","name":"View","kind":"data","summary":"Which view to project from the graph (LANG.md §9). Context is the C1 whole;\nContainer/Component zoom into one boundary; Sequence traces one entry point;\nData draws a `data` type's entity (ER) view (§9.4); Feature draws a `feature`\nscenario's flow (§9.5).","text":"","module":"emit","href":"module/emit.html#emit-View"},{"fqn":"emit::WrongKind","name":"WrongKind","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-WrongKind"},{"fqn":"format","name":"format","kind":"module","summary":"","text":"","module":"format","href":"module/format.html"},{"fqn":"format::Format","name":"Format","kind":"container","summary":"`crates/pseudoscript-format`. The canonical formatter: parse, then\npretty-print the tree to one canonical form. The string-to-string entry the\nCLI and LSP depend on.","text":"","module":"format","href":"module/format.html#format-Format"},{"fqn":"format::FormatError","name":"FormatError","kind":"data","summary":"Why formatting failed. The only failure is unparseable input: `Parse`\ncarries the rendered error messages (one per diagnostic) for context, and\nthe caller keeps its original text.","text":"","module":"format","href":"module/format.html#format-FormatError"},{"fqn":"format::Formatter","name":"Formatter","kind":"component","summary":"Drives the headline flow: parse the source, short-circuit to\n`FormatError::Parse` if any error diagnostic surfaced, else hand the tree to\nthe printer for canonical text.","text":"","module":"format","href":"module/format.html#format-Formatter"},{"fqn":"format::Parse","name":"Parse","kind":"data","summary":"","text":"","module":"format","href":"module/format.html#format-Parse"},{"fqn":"format::Printer","name":"Printer","kind":"component","summary":"The canonical pretty-printer: walks the AST top-down, appending to a buffer,\nand emits one canonical form. Indentation is a level counter (two spaces\neach); leading trivia is normalised — blank-line runs collapse to at most one\nseparator and `//` / `/* */` comments reproduce at the current indent in\nsource order. Internals are black-boxed per construct; the top-level `print`\nflow is disclosed.","text":"","module":"format","href":"module/format.html#format-Printer"},{"fqn":"format::PrinterState","name":"PrinterState","kind":"data","summary":"The running pretty-printer state: the text buffer being built, the current\nnesting depth (two spaces each), and whether the current line has had its\nindentation written yet so further writes append in place.","text":"","module":"format","href":"module/format.html#format-PrinterState"},{"fqn":"ide","name":"ide","kind":"module","summary":"","text":"","module":"ide","href":"module/ide.html"},{"fqn":"ide::Bootstrap","name":"Bootstrap","kind":"component","summary":"Boots the IDE in a browser tab: load the one wasm bundle (IdeSession), then\nrestore the URL hash's workspace — a share link mounts in memory and needs\nno disk — or fall back to the launcher. File System Access support gates\nonly the disk features (open folder, save, watch): without it those actions\nare disabled with a notice, while share links and the bundled examples\nstill open.","text":"","module":"ide","href":"module/ide.html#ide-Bootstrap"},{"fqn":"ide::BrowserWorkspace","name":"BrowserWorkspace","kind":"data","summary":"The in-browser workspace state the session holds: the open `.pds` modules, the\n`pds.toml` manifest text, and the dependency modules resolved from\n`pds_modules/` as externals (LANG.md §8.3). Held in memory — a decoded\nsample/share link or a local directory loaded through the file-system port.\nEdits never leave the tab.","text":"","module":"ide","href":"module/ide.html#ide-BrowserWorkspace"},{"fqn":"ide::CodeMirrorAdapter","name":"CodeMirrorAdapter","kind":"component","summary":"The editor adapter over CodeMirror 6: the text/cursor model, the completion\nsource, the hover tooltip, the diagnostics gutter, and edit events forwarded\ninto the session. The only place CodeMirror specifics live — it drives the\nsession and applies the typed values it gets back.","text":"","module":"ide","href":"module/ide.html#ide-CodeMirrorAdapter"},{"fqn":"ide::Completion","name":"Completion","kind":"data","summary":"A completion candidate offered as the author types: the inserted label, the\ninteger LSP `CompletionItemKind` the editor maps to an icon, and detail text\n(absent for candidates with nothing to add).","text":"","module":"ide","href":"module/ide.html#ide-Completion"},{"fqn":"ide::DiagramCanvas","name":"DiagramCanvas","kind":"component","summary":"The diagram canvas: draws the **JSON** `Scene` interactively (Svelte Flow\npan/zoom over geometry positioned by `emit`'s layout engine for C4, a\ndepth-collapsible timeline for sequences), and exports the current view as\n**PNG or SVG**, both produced in the browser from the drawn diagram. JSON is\nthe draw format; no diagram image crosses the wasm surface. The editor\nport's diagram seam binds to this.","text":"","module":"ide","href":"module/ide.html#ide-DiagramCanvas"},{"fqn":"ide::Diagrams","name":"Diagrams","kind":"component","summary":"Diagram projection: builds the workspace graph and projects a view to the\nJSON `Scene` via `emit::Projector`; the host's canvas draws it. The wasm\nsurface carries only the JSON scene and layout — SVG and PNG are export\nconcerns of the canvas (PNG rasterised in the browser), and the static SVG\nform is a CLI/doc concern of the `emit` crate, not exposed here.","text":"","module":"ide","href":"module/ide.html#ide-Diagrams"},{"fqn":"ide::DocConfig","name":"DocConfig","kind":"data","summary":"The doc-site build input: the manifest plus each authored page's Markdown,\nloaded by the host. Field detail is the wasm boundary's concern.","text":"","module":"ide","href":"module/ide.html#ide-DocConfig"},{"fqn":"ide::Docs","name":"Docs","kind":"component","summary":"The doc-site builder: renders the whole site in-browser through the same\n`pseudoscript-doc` crate `pds doc` runs, driving SSR through a render\ncallback the host supplies (the browser's JS engine is the SSR engine) — so\nthe IDE writes the exact site the CLI ships, health page included. The site\nbuilds to the opened folder's `target/doc/` only; an in-memory workspace is\ntold to open a folder first (no blob-preview path).","text":"","module":"ide","href":"module/ide.html#ide-Docs"},{"fqn":"ide::FimClient","name":"FimClient","kind":"component","summary":"Provider-agnostic completion client: one `complete` contract over\nOpenAI-compatible HTTP, so one client covers Codestral, OpenRouter, Together,\nOllama, and vLLM. Stateless — the caller hands it the settings snapshot and\nowns cancellation (`GhostText` aborts the in-flight request on the next\nkeystroke; the client honours the abort). Every failure comes back as a\nclassified `ProviderError`, so the caller can surface why a request bailed.","text":"","module":"ide","href":"module/ide.html#ide-FimClient"},{"fqn":"ide::FimPrompt","name":"FimPrompt","kind":"data","summary":"The assembled fill-in-the-middle request: the windowed buffer text before and\nafter the caret, and the cached grammar primer that steers a general model to\nemit valid PseudoScript.","text":"","module":"ide","href":"module/ide.html#ide-FimPrompt"},{"fqn":"ide::FsAccessAdapter","name":"FsAccessAdapter","kind":"component","summary":"The file-system adapter over the browser File System Access API: directory\npicker, recursive walk for `.pds` modules, deriving each module's flat FQN\nfrom its path (LANG.md §8.1, ADR-031), `pds.lock` + `pds_modules/` reads for\ndependency externals, and per-file read/write through handles. The only place\nFS-Access specifics live; it pushes what it reads into the session via\n`mount`.","text":"","module":"ide","href":"module/ide.html#ide-FsAccessAdapter"},{"fqn":"ide::GhostText","name":"GhostText","kind":"component","summary":"Inline ghost-text completion over CodeMirror 6, beside the grammar dropdown:\nstructural candidates stay local and deterministic in `CodeMirrorAdapter`;\nthe remote model supplies only multi-token greyed text. CodeMirror has no\nnative inline-suggestion UI, so this is a custom view plugin rendering a\nwidget decoration at the caret — Tab accepts, Esc dismisses, any edit clears.","text":"","module":"ide","href":"module/ide.html#ide-GhostText"},{"fqn":"ide::GridPin","name":"GridPin","kind":"data","summary":"A node the user has dragged onto a grid cell, identified by FQN. Carried inside\n`LayoutTweaks`; honoured only under experimental grid placement.","text":"","module":"ide","href":"module/ide.html#ide-GridPin"},{"fqn":"ide::IdeSession","name":"IdeSession","kind":"container","summary":"`crates/pseudoscript-ide` — the IDE application, Rust compiled to a single\nwasm. It owns the workspace state and is the whole browser API: the host\npushes modules in (`mount`/`setSource`) and pulls every answer out as a\ntyped value — the session never calls the DOM, CodeMirror, or the File\nSystem Access API. It delegates language intelligence to `lsp_core` and\n`model::Checks`, diagrams to `emit::Projector`, the 3D universe to\n`universe::Adapter`, and the doc site to `doc::SiteBuilder` — each a Rust\nlibrary linked in, never a separate wasm. The one outbound seam is the doc\nbuild's SSR render callback the host supplies. Everything here is Rust.","text":"","module":"ide","href":"module/ide.html#ide-IdeSession"},{"fqn":"ide::LanguageSession","name":"LanguageSession","kind":"component","summary":"The language session: diagnostics, completion, hover, go-to, references,\nrename, outline, folding, and semantic tokens over the held workspace, every\nanswer delegated to the pure toolchain logic (`model::Checks` for diagnostics,\n`lsp_core` for cursor features) with the dependency externals bound. Every\nanswer is a typed value the host applies — the session pushes nothing at the\neditor.","text":"","module":"ide","href":"module/ide.html#ide-LanguageSession"},{"fqn":"ide::Launcher","name":"Launcher","kind":"component","summary":"The project launcher — the first surface. Offers the recents, open-a-folder,\nNew Project, and the bundled examples. Examples and share links mount in\nmemory and need no disk; only the disk actions gate on File System Access\nsupport. Dismissible, so the menus, help, and settings stay reachable\nwithout a project.","text":"","module":"ide","href":"module/ide.html#ide-Launcher"},{"fqn":"ide::LayoutTweaks","name":"LayoutTweaks","kind":"data","summary":"The IDE's per-diagram C4 layout toggles, crossing to JS as a typed object: run\nthe long-edge optimiser, the reading `orientation` (`\"tb\"`/`\"lr\"`), a `spacing`\npreset (`\"compact\"`/`\"comfortable\"`/`\"roomy\"`), and the experimental grid dials\nand pins. Translated to `emit::C4Tweaks` inside the session.","text":"","module":"ide","href":"module/ide.html#ide-LayoutTweaks"},{"fqn":"ide::LlmProvider","name":"LlmProvider","kind":"system","summary":"The author's configured OpenAI-compatible completion provider — hosted\n(OpenAI, Codestral, OpenRouter, Together) or local (Ollama, vLLM). External:\nthe IDE only speaks its HTTP API; transport and HTTP failures surface as\nclassified `ProviderError`s.","text":"","module":"ide","href":"module/ide.html#ide-LlmProvider"},{"fqn":"ide::LlmSettings","name":"LlmSettings","kind":"data","summary":"The author's AI-completion provider settings, persisted in the browser: the\nfeature toggle, the chosen preset (`\"ollama\"`, `\"openai\"`, or `\"custom\"` —\nthe presets pin the endpoint and wire shape so setup is pick-and-go), the\nOpenAI-compatible endpoint, the bring-your-own API key (stored in\nlocalStorage, sent only to the configured endpoint), the model id, and the\nwire shape (`\"fim\"` for a native fill-in-the-middle route, `\"chat\"` for the\nchat-completions fallback).","text":"","module":"ide","href":"module/ide.html#ide-LlmSettings"},{"fqn":"ide::LlmSettingsStore","name":"LlmSettingsStore","kind":"component","summary":"The author's AI-completion settings, persisted to browser localStorage and\nedited through the Settings dialog's \"AI Completion\" tab. Bring-your-own key:\nit never leaves the tab except on requests to the configured endpoint.\nSetup is preset-first: picking a provider applies its pinned endpoint and\nwire shape, so only the Custom preset exposes the raw fields. The store also\ncarries the session's last completion failure (never persisted) so the\nstatus chip and the settings tab can show why ghost text is bailing.","text":"","module":"ide","href":"module/ide.html#ide-LlmSettingsStore"},{"fqn":"ide::LocalInput","name":"LocalInput","kind":"data","summary":"One local-source dependency file the host reads for `dependencyModules`: the\ndependency name (ADR-026), its FQN within the dependency workspace, and its\nsource.","text":"","module":"ide","href":"module/ide.html#ide-LocalInput"},{"fqn":"ide::Occurrence","name":"Occurrence","kind":"data","summary":"One occurrence of a symbol: the module it lies in, its line/column span, the\nsource line text with the match offsets within it, and whether it is the\ndeclaration site.","text":"","module":"ide","href":"module/ide.html#ide-Occurrence"},{"fqn":"ide::OutlineNode","name":"OutlineNode","kind":"data","summary":"One row of the workspace outline: a node's FQN, simple name, C4 kind,\ncontainment parent (absent on roots), whether it is a triggered flow entry,\nits `///` summary (absent when undocumented), and its declaration line/column.","text":"","module":"ide","href":"module/ide.html#ide-OutlineNode"},{"fqn":"ide::PickError","name":"PickError","kind":"data","summary":"Why a folder pick yielded no workspace: the picker failed — the API missing,\nblocked by permission policy, or denied by the embedder. Distinct from a\nuser cancel, which is silent: a cancel is the user's choice, a failure is\nthe product's to explain.","text":"","module":"ide","href":"module/ide.html#ide-PickError"},{"fqn":"ide::ProviderError","name":"ProviderError","kind":"data","summary":"A classified completion-provider failure: `kind` is `\"network\"` (endpoint\nunreachable or CORS-blocked), `\"auth\"` (401/403), `\"notFound\"` (404 route or\nmodel), `\"timeout\"`, or `\"http\"` (any other non-OK status); `message` states\nwhat failed and `hint` names the fix for the configured provider (e.g. the\n`OLLAMA_ORIGINS` command for a CORS-blocked local Ollama).","text":"","module":"ide","href":"module/ide.html#ide-ProviderError"},{"fqn":"ide::References","name":"References","kind":"data","summary":"The find-references result for the symbol under the caret: the symbol's FQN, a\nhuman title, and every occurrence across the workspace.","text":"","module":"ide","href":"module/ide.html#ide-References"},{"fqn":"ide::RenameSelection","name":"RenameSelection","kind":"data","summary":"One occurrence the user chose to rename, keyed by the module FQN and the\n1-based line/column an `ide::Occurrence` reported. The rename rewrites only\nthe selected occurrences, not every match.","text":"","module":"ide","href":"module/ide.html#ide-RenameSelection"},{"fqn":"ide::RenamedSource","name":"RenamedSource","kind":"data","summary":"One module rewritten by a rename: its FQN and new source text.","text":"","module":"ide","href":"module/ide.html#ide-RenamedSource"},{"fqn":"ide::RenderedFile","name":"RenderedFile","kind":"data","summary":"One file of the rendered documentation site: its site-relative path and\ncontents.","text":"","module":"ide","href":"module/ide.html#ide-RenderedFile"},{"fqn":"ide::Samples","name":"Samples","kind":"component","summary":"The bundled example catalogue, discovered at build time from the samples\nfolder (one folder per example: meta.json, the `.pds` modules, `pds.toml`,\ndoc pages). Each entry doubles as a New-project template and as an\nin-memory workspace.","text":"","module":"ide","href":"module/ide.html#ide-Samples"},{"fqn":"ide::Universe","name":"Universe","kind":"component","summary":"The 3D universe: builds the software graph from the held workspace and flattens\nit to a snapshot the `ForceGraph` renders, with the entry-point flows traced\nin Rust. Delegates to the `universe` crate; the wasm surface carries only the\nflat snapshot and flows — positions are the renderer's.","text":"","module":"ide","href":"module/ide.html#ide-Universe"},{"fqn":"ide::UniverseEdge","name":"UniverseEdge","kind":"data","summary":"One directed relationship in the 3D graph, weighted by traffic (call count).\nThe wire field is `from`; `from` is a PseudoScript keyword, so the model\nnames it `source`.","text":"","module":"ide","href":"module/ide.html#ide-UniverseEdge"},{"fqn":"ide::UniverseNode","name":"UniverseNode","kind":"data","summary":"One node in the 3D relationship graph the IDE draws: its FQN, C4 level, and\ncontainment parent (absent on roots). The typed boundary form of a\n`universe::NodeOut`.","text":"","module":"ide","href":"module/ide.html#ide-UniverseNode"},{"fqn":"ide::UniverseSnapshot","name":"UniverseSnapshot","kind":"data","summary":"The 3D-view snapshot the session hands the `ForceGraph`: nodes and directed\nweighted edges, no positions (the renderer lays them out). The typed boundary\nform of a `universe::Snapshot`.","text":"","module":"ide","href":"module/ide.html#ide-UniverseSnapshot"},{"fqn":"ide::VendoredInput","name":"VendoredInput","kind":"data","summary":"One vendored git-dependency file the host reads for `dependencyModules`: its\n`pds_modules/` slug, its FQN within the dependency workspace (the host's\npath→FQN derivation, LANG.md §8.1), and its source.","text":"","module":"ide","href":"module/ide.html#ide-VendoredInput"},{"fqn":"ide::WebIde","name":"WebIde","kind":"container","summary":"`web-ide` — the IDE at `ide.pdscript.dev`: a SvelteKit shell on Cloudflare\nWorkers static assets. Pure glue — it loads the one wasm bundle and binds the\nadapters to the session's ports. It holds no language logic.","text":"","module":"ide","href":"module/ide.html#ide-WebIde"},{"fqn":"ide::Workspace","name":"Workspace","kind":"component","summary":"The in-memory project the session holds: the parsed modules keyed by FQN (an\nopen buffer overlays via `setSource`), the dependency externals, and the\nmemoised resolved workspace + graph — invalidated by any mutation, rebuilt\nonce for the query burst between keystrokes. Edits never leave the tab; an\nexplicit save writes through the host's file handles, not this session.","text":"","module":"ide","href":"module/ide.html#ide-Workspace"},{"fqn":"landing","name":"landing","kind":"module","summary":"","text":"","module":"landing","href":"module/landing.html"},{"fqn":"landing::Landing","name":"Landing","kind":"container","summary":"`web-landing` — the marketing site at `pdscript.dev`. A static Svelte build on\nCloudflare Workers static assets; no backend. It routes a visitor to one of\nthree surfaces and otherwise just tells the model-driven story.","text":"","module":"landing","href":"module/landing.html#landing-Landing"},{"fqn":"landing::Visitor","name":"Visitor","kind":"person","summary":"A prospective user reading the landing page.","text":"","module":"landing","href":"module/landing.html#landing-Visitor"},{"fqn":"layout","name":"layout","kind":"module","summary":"","text":"","module":"layout","href":"module/layout.html"},{"fqn":"layout::Activation","name":"Activation","kind":"data","summary":"An execution-activation bar on a lifeline, spanning a participant's first-to-\nlast involvement; `owner` marks the entry's focus lifeline.","text":"","module":"layout","href":"module/layout.html#layout-Activation"},{"fqn":"layout::Core","name":"Core","kind":"component","summary":"The shared geometry/text core: measures label and title widths, wraps\ndescriptions to a width, and accumulates bounding boxes. Every engine builds\non it, so text sizing and bounds math live in exactly one place.","text":"","module":"layout","href":"module/layout.html#layout-Core"},{"fqn":"layout::Diagram","name":"Diagram","kind":"data","summary":"A structural sequence diagram: the participants (lifelines) and the ordered\nitems — messages and nested fragments — traced down them. The sequence\nengine's input.","text":"","module":"layout","href":"module/layout.html#layout-Diagram"},{"fqn":"layout::Divider","name":"Divider","kind":"data","summary":"A horizontal split between two fragment sections: its y and the following\nsection's guard.","text":"","module":"layout","href":"module/layout.html#layout-Divider"},{"fqn":"layout::FragKind","name":"FragKind","kind":"data","summary":"The kind of a fragment frame: an `alt` (if/else) or a `loop` (for/while).","text":"","module":"layout","href":"module/layout.html#layout-FragKind"},{"fqn":"layout::Fragment","name":"Fragment","kind":"data","summary":"A nestable fragment over a body of items, drawn as an enclosing frame: its\nkind and the labelled sections it splits into (an `alt` has several).","text":"","module":"layout","href":"module/layout.html#layout-Fragment"},{"fqn":"layout::FragmentItem","name":"FragmentItem","kind":"data","summary":"","text":"","module":"layout","href":"module/layout.html#layout-FragmentItem"},{"fqn":"layout::Item","name":"Item","kind":"data","summary":"One ordered item down the lifelines: a message or a nested fragment.","text":"","module":"layout","href":"module/layout.html#layout-Item"},{"fqn":"layout::Layout","name":"Layout","kind":"container","summary":"`crates/pseudoscript-layout`. The geometry/text `Core` and the sequence\nengine, each built on the `Projection` contract — turn a structural input\ninto a positioned output under tunable metrics. The sequence engine is the\nonly one implemented here: C4 placement is delegated to `dot` (the layered\nengine), which `emit` drives directly; a flowchart engine is a planned\nextension point on the same core, not yet built.","text":"","module":"layout","href":"module/layout.html#layout-Layout"},{"fqn":"layout::Message","name":"Message","kind":"data","summary":"A message between two lifelines: its source and target ids (equal for a\nself-message), kind, primary label (method name or return marker), and the\ndimmed detail after it (a call signature or return type). `source` is the\nwire field `from`, renamed because `from` is a PseudoScript keyword.","text":"","module":"layout","href":"module/layout.html#layout-Message"},{"fqn":"layout::MessageItem","name":"MessageItem","kind":"data","summary":"","text":"","module":"layout","href":"module/layout.html#layout-MessageItem"},{"fqn":"layout::Metrics","name":"Metrics","kind":"data","summary":"Tunable spacing and font metrics for the sequence engine — head-card sizing,\nrow advance per message kind, fragment padding. Field detail is the engine's\nconcern; the defaults are the one source of truth consumers start from.","text":"","module":"layout","href":"module/layout.html#layout-Metrics"},{"fqn":"layout::MsgKind","name":"MsgKind","kind":"data","summary":"The kind of a sequence message: a call to another lifeline, a return to the\ncaller, or a self-message on the sender's own lifeline.","text":"","module":"layout","href":"module/layout.html#layout-MsgKind"},{"fqn":"layout::Participant","name":"Participant","kind":"data","summary":"One lifeline: its id (FQN), display label, C4 kind for the head card, optional\nsummary, and the ancestry path shown under the name for container/component\nlifelines.","text":"","module":"layout","href":"module/layout.html#layout-Participant"},{"fqn":"layout::PlacedFragment","name":"PlacedFragment","kind":"data","summary":"A placed fragment frame: its box, the operator-tab label (the first section's\nguard), and the dividers splitting later sections.","text":"","module":"layout","href":"module/layout.html#layout-PlacedFragment"},{"fqn":"layout::PlacedMessage","name":"PlacedMessage","kind":"data","summary":"A placed message: its kind, source/target ids, endpoint x-positions, row y,\ndirection (+1 left-to-right, -1 right-to-left), reading-order step, label, and\ndetail.","text":"","module":"layout","href":"module/layout.html#layout-PlacedMessage"},{"fqn":"layout::PlacedParticipant","name":"PlacedParticipant","kind":"data","summary":"A placed lifeline: its id, label, kind, ancestry path, wrapped summary lines,\nhead-card rectangle, the lifeline's centre x, and the y span of its dashed\nline.","text":"","module":"layout","href":"module/layout.html#layout-PlacedParticipant"},{"fqn":"layout::Point","name":"Point","kind":"data","summary":"A point in renderer coordinates.","text":"","module":"layout","href":"module/layout.html#layout-Point"},{"fqn":"layout::Rect","name":"Rect","kind":"data","summary":"An axis-aligned rectangle: its top-left corner and extent.","text":"","module":"layout","href":"module/layout.html#layout-Rect"},{"fqn":"layout::Section","name":"Section","kind":"data","summary":"One compartment of a fragment: its guard label (shown in the operator tab or\nbeside a divider) over a body of items.","text":"","module":"layout","href":"module/layout.html#layout-Section"},{"fqn":"layout::Sequence","name":"Sequence","kind":"component","summary":"The sequence engine: lays a structural `Diagram` out into a `SequenceLayout` —\nlifeline x-positions in first-appearance order, message rows stacked by\nevaluation order, and fragment frames sized to their bodies. The only engine\nimplemented in this crate; C4 placement is `dot`'s job (`emit` drives it), and\na flowchart engine would follow the same `Projection` contract.","text":"","module":"layout","href":"module/layout.html#layout-Sequence"},{"fqn":"layout::SequenceLayout","name":"SequenceLayout","kind":"data","summary":"A laid-out sequence diagram: the canvas size plus every participant, message,\nactivation bar, and fragment placed at absolute coordinates the renderer draws\nverbatim. The sequence engine's output.","text":"","module":"layout","href":"module/layout.html#layout-SequenceLayout"},{"fqn":"layout::Size","name":"Size","kind":"data","summary":"A width/height extent.","text":"","module":"layout","href":"module/layout.html#layout-Size"},{"fqn":"lsp","name":"lsp","kind":"module","summary":"","text":"","module":"lsp","href":"module/lsp.html"},{"fqn":"lsp::DefTarget","name":"DefTarget","kind":"data","summary":"A go-to-definition target straight from `lsp_core`: the FQN of the module the\ndefinition lives in, and its span within that module's source. The server maps\n`fqn` to a file URI — the target file, not the file the request came from.","text":"","module":"lsp","href":"module/lsp.html#lsp-DefTarget"},{"fqn":"lsp::Lsp","name":"Lsp","kind":"container","summary":"`crates/pseudoscript-lsp`. The stdio language server (tower-lsp): workspace\ndiagnostics on change, and hover, definition, completion, references, rename,\nsemantic tokens, symbols, folding, and formatting — every language answer\ndelegated to `lsp_core`. Owns the transport, the document store, and the\nURI↔FQN mapping, nothing more.","text":"","module":"lsp","href":"module/lsp.html#lsp-Lsp"},{"fqn":"lsp::Occurrence","name":"Occurrence","kind":"data","summary":"One resolved editor location: the file URI a target FQN maps back to, and the\nrange within it. The server's transport-level mapping of a `lsp_core` answer.","text":"","module":"lsp","href":"module/lsp.html#lsp-Occurrence"},{"fqn":"lsp::OpenDocument","name":"OpenDocument","kind":"data","summary":"One open editor buffer: its document URI, current source text, and the\neditor's version counter. The buffer overlays on-disk text until closed.","text":"","module":"lsp","href":"module/lsp.html#lsp-OpenDocument"},{"fqn":"lsp::Server","name":"Server","kind":"component","summary":"The tower-lsp `Backend`: owns the stdio transport, the document store, the\nserver lifecycle, and request routing. Holds no language logic — it locks the\nstore, hands the active text and the resolved workspace to a `lsp_core`\nhandler, and maps the result back to file locations.","text":"","module":"lsp","href":"module/lsp.html#lsp-Server"},{"fqn":"lsp::Store","name":"Store","kind":"component","summary":"The workspace document store: the server's own filesystem edge. Discovers the\nproject root (`pds.toml`, §8.1) by walking up from the opened URI, walks the\ntree for every visible `.pds` file, derives each module's FQN from its path,\nand overlays open buffers on disk text. Caches each parse and memoises the\nresolved `model::Workspace` — built from the local parses with the workspace's\ndirect-dependency externals bound (§8.3) — both invalidated on any edit. The\nexternals are cached separately and reload only on a dependency change.","text":"","module":"lsp","href":"module/lsp.html#lsp-Store"},{"fqn":"lsp_core","name":"lsp_core","kind":"module","summary":"","text":"","module":"lsp_core","href":"module/lsp_core.html"},{"fqn":"lsp_core::Analysis","name":"Analysis","kind":"component","summary":"Document-level analysis: parse-and-check diagnostics, Markdown hover for the\nsymbol under the caret (falling back to an inferred type), go-to-definition,\ninlay hints, and the canonical format edit. Resolution is delegated to\n`model`; this maps the result into LSP shapes.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Analysis"},{"fqn":"lsp_core::Complete","name":"Complete","kind":"component","summary":"Completion: the candidates offered at a byte offset, resolved across the\nworkspace and its externals. A `.`/`::` boundary drives member and path\ncompletion.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Complete"},{"fqn":"lsp_core::CompletionItem","name":"CompletionItem","kind":"data","summary":"One completion candidate: the inserted label, the integer LSP\n`CompletionItemKind`, and detail text.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-CompletionItem"},{"fqn":"lsp_core::Convert","name":"Convert","kind":"component","summary":"Position conversion: the single home for mapping between byte offsets and\nUTF-16 line/character positions, so every handler agrees on coordinates.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Convert"},{"fqn":"lsp_core::DefTarget","name":"DefTarget","kind":"data","summary":"A go-to-definition target: the FQN of the module the definition lives in and\nthe byte span of the definition within that module's source. The consuming\nedge maps `fqn` to a file URI and converts `span` to an editor range against\n*that* file's text — `lsp_core` returns the byte span, not a `Range`, because\nit does not hold the target module's source to convert against.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-DefTarget"},{"fqn":"lsp_core::Diagnostic","name":"Diagnostic","kind":"data","summary":"One diagnostic mapped to LSP shape: its range, severity, message, optional\ncode, and the code's article URL (`codeDescription`, the editor's clickable\nlink — empty when the code carries no article). Converted from the\nparser/checker's byte-span diagnostics; the code and its URL pass through\nunchanged.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Diagnostic"},{"fqn":"lsp_core::Hover","name":"Hover","kind":"data","summary":"Markdown hover content the editor renders in a tooltip.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Hover"},{"fqn":"lsp_core::LspCore","name":"LspCore","kind":"container","summary":"`crates/pseudoscript-lsp-core`. The single home for language intelligence as\ntransport-neutral handlers — the same logic the stdio server and the browser\nwasm both call.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-LspCore"},{"fqn":"lsp_core::Position","name":"Position","kind":"data","summary":"A zero-based caret position: line and UTF-16 character offset within the\nline. This and the shapes below model the standalone `lsp_types` vocabulary\nthe crate returns (pinned to the version tower-lsp re-exports, wasm-safe),\nso the server edge passes values through with no conversion.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Position"},{"fqn":"lsp_core::Range","name":"Range","kind":"data","summary":"A half-open text range between two positions.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Range"},{"fqn":"lsp_core::Refs","name":"Refs","kind":"component","summary":"References and rename: every occurrence of the symbol under the caret across\nthe workspace, the document highlights for it, and the workspace-wide rename\nedits.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Refs"},{"fqn":"lsp_core::Semantic","name":"Semantic","kind":"component","summary":"Semantic tokens: AST-aware highlighting that colours each token by its\ndeclared role, plus the legend the editor binds.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Semantic"},{"fqn":"lsp_core::Symbols","name":"Symbols","kind":"component","summary":"Document and workspace structure: the outline symbols, the foldable ranges,\nand the workspace-wide symbol query.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Symbols"},{"fqn":"lsp_core::TextEdit","name":"TextEdit","kind":"data","summary":"A text edit: replace `range` with `newText`. Formatting and rename return\nthese.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-TextEdit"},{"fqn":"model","name":"model","kind":"module","summary":"","text":"","module":"model","href":"module/model.html"},{"fqn":"model::Alt","name":"Alt","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Alt"},{"fqn":"model::ArchRule","name":"ArchRule","kind":"data","summary":"One architectural-principle lint rule (LANG.md §9 — the C4 facade/boundary\nprinciples). `code` is its stable identifier (`PDS-ARCH-001`); `slug` is the\nfilename of the article documenting it under the published principles base\nURL. Every firing is a `Warning` — a violation advises rather than\ninvalidates — so the rule carries no severity of its own.","text":"","module":"model","href":"module/model.html#model-ArchRule"},{"fqn":"model::Architecture","name":"Architecture","kind":"component","summary":"LANG.md §9 — architectural-principle lints over the resolved graph. Beyond §8.2\nvisibility (which a `public` component still satisfies), these advise on C4\nstructure: a cross-module call SHOULD reach a container/system's published face,\nnot an internal `component` (Facade/Gateway); the module dependency graph SHOULD\nstay acyclic; a cross-system call SHOULD couple to the other system's boundary,\nnot its containers. Each firing is a `Warning` stamped with the rule's `code`\nand `codeDescription` (its article URL); the model stays valid.","text":"","module":"model","href":"module/model.html#model-Architecture"},{"fqn":"model::Branch","name":"Branch","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Branch"},{"fqn":"model::Builder","name":"Builder","kind":"component","summary":"Projects the parsed, resolved workspace into the architecture graph: structural\nnodes plus edges from `for` parents, body calls, triggers, and `from`\nprovenance, with a sequence trace recorded per disclosed body. A pure\nprojection — no I/O — so the emit crate and a future salsa/LSP layer can both\nadopt it.","text":"","module":"model","href":"module/model.html#model-Builder"},{"fqn":"model::Call","name":"Call","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Call"},{"fqn":"model::CaretResolve","name":"CaretResolve","kind":"component","summary":"Caret resolution — the engine every cursor feature shares (`lsp_core` hover,\ndefinition, references, rename; the IDE's symbol actions). Tokenizes the\nactive source, finds the identifier under the offset, and resolves it across\nthe workspace and its externals: a node or data FQN, a `self.`/member access,\nor a local reference. Token-level, so it survives a partial parse.","text":"","module":"model","href":"module/model.html#model-CaretResolve"},{"fqn":"model::Checks","name":"Checks","kind":"component","summary":"Static analysis (LANG.md §2.2, §2.3, §2.4, §3.3, §3.4, §3.5, §4, §5.1, §5.2, §6,\n§7, §8): builds the symbol tables, then runs the well-formedness checks. Every\nentry returns a `syntax::Diagnostic[]`; well-formed input yields an empty one.\nChecks are conservative — each rule fires only when the violation is certain.","text":"","module":"model","href":"module/model.html#model-Checks"},{"fqn":"model::Commit","name":"Commit","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Commit"},{"fqn":"model::Completion","name":"Completion","kind":"component","summary":"Context-aware completion (the model-native producer `lsp_core` maps to LSP\nitems): candidates at a caret offset resolved across the workspace and its\nexternals — members after `.`, a module's public symbols after `::`, the\nbuilt-in macros after `#[`, types in type position, else keywords and symbols.","text":"","module":"model","href":"module/model.html#model-Completion"},{"fqn":"model::ConstantType","name":"ConstantType","kind":"data","summary":"One `constant`'s FQN paired with its declared primitive type name (§3.6,\nADR-039), so inference resolves a `module::NAME` reference to its type.","text":"","module":"model","href":"module/model.html#model-ConstantType"},{"fqn":"model::CrossModule","name":"CrossModule","kind":"component","summary":"§8.2 — cross-module visibility resolution. Walks each module's qualified\nreferences — `for` parents, type annotations (field, parameter, return, and\ngeneric-argument types), feature targets, body call targets, value-position\nunion-variant references, and the member named after a call target's FQN — and\nagainst the global FQN index enforces: a reference from module A to a node in\nmodule B resolves only if that node is `public`. A private target or a dangling\ncross-module FQN is a diagnostic. Same-module references are the single-module\nchecks' business and are skipped here.","text":"","module":"model","href":"module/model.html#model-CrossModule"},{"fqn":"model::DataField","name":"DataField","kind":"data","summary":"One field of a `data` record or union-variant record: its name and rendered\ntype.","text":"","module":"model","href":"module/model.html#model-DataField"},{"fqn":"model::DataShape","name":"DataShape","kind":"data","summary":"The disclosed shape of a `data` node (§3.4, §3.5): a record of fields, a\ndiscriminated union of variants, or an undisclosed black box. Carried on a\n`data` `GraphNode` so the entity (ER) view draws the rows without re-reading\nsource.","text":"","module":"model","href":"module/model.html#model-DataShape"},{"fqn":"model::DataVariant","name":"DataVariant","kind":"data","summary":"One variant of a `data` union (§3.5): its name and, for a record variant, its\nfields.","text":"","module":"model","href":"module/model.html#model-DataVariant"},{"fqn":"model::DepError","name":"DepError","kind":"data","summary":"Why parsing a manifest's `[dependencies]` table or a `pds.lock` failed: the\noffending entry and a human-readable message. Malformed TOML, an unknown key,\nor more than one of tag/rev/branch on one dependency (§8.3).","text":"","module":"model","href":"module/model.html#model-DepError"},{"fqn":"model::DepFile","name":"DepFile","kind":"data","summary":"One dependency module's in-memory form: its FQN *within* the dependency\nworkspace (path relative to that workspace root) and its source. The resolver\nprefixes it with the dependency name.","text":"","module":"model","href":"module/model.html#model-DepFile"},{"fqn":"model::DepSpec","name":"DepSpec","kind":"data","summary":"A `[dependencies]` entry as written in `pds.toml` (§8.3): a git URL with at\nmost one of tag/rev/branch and an in-repo sub-path, or a local sibling path.\nEmpty strings stand for the absent options.","text":"","module":"model","href":"module/model.html#model-DepSpec"},{"fqn":"model::Deps","name":"Deps","kind":"component","summary":"§8.3 — the dependency resolver. Parses a manifest's `[dependencies]` and a\n`pds.lock`, then maps each direct dependency to its dependency-name-prefixed\nmodules — the externals the checker binds for cross-workspace resolution. The\nsingle source of the slug→name→`dep::module` mapping, shared by the native\nloader (`project`) and the WASM bridge (`ide`). Pure: fetching and disk are\nthe caller's job.","text":"","module":"model","href":"module/model.html#model-Deps"},{"fqn":"model::Edge","name":"Edge","kind":"data","summary":"A typed, directed relationship between two graph node FQNs. `source` is the\nwire field `from` — `from` is a PseudoScript keyword, so the model renames\nit. Either endpoint may name a node not present as a `GraphNode` — a\nsynthesised trigger initiator, or a target that does not resolve. `label` is\nthe method name for `Call`, otherwise empty. `span` is the source range that\nproduced the edge — the call site for a `Call` — so an architectural lint can\npoint its diagnostic at the offending call; the empty span when the edge is\nsynthesised.","text":"","module":"model","href":"module/model.html#model-Edge"},{"fqn":"model::EdgeKind","name":"EdgeKind","kind":"data","summary":"What relationship a graph edge expresses (LANG.md §9.1): a `for` parent link,\na body call (label = method), a synthesised trigger initiator edge, or a\n`from` provenance link.","text":"","module":"model","href":"module/model.html#model-EdgeKind"},{"fqn":"model::FeatureCheck","name":"FeatureCheck","kind":"component","summary":"§5.2 / §8.1 — feature checks. A feature's `for` target MUST resolve to a node,\nnot a type or module; a target this single-module model cannot see is left to\ncross-module resolution. Feature names occupy their own module namespace, so a\nrepeated name is a collision (checked once per module).","text":"","module":"model","href":"module/model.html#model-FeatureCheck"},{"fqn":"model::FieldlessVariants","name":"FieldlessVariants","kind":"data","summary":"A union's fieldless variant names, keyed by the union's bare name (§3.5).\nFieldless variants do not hoist a symbol — they are addressed\n`module::Union::Variant` (ADR-032) — so they index under their union.","text":"","module":"model","href":"module/model.html#model-FieldlessVariants"},{"fqn":"model::Folding","name":"Folding","kind":"component","summary":"The foldable regions of a module: every multi-line disclosed declaration and\nstatement block, and doc-comment runs.","text":"","module":"model","href":"module/model.html#model-Folding"},{"fqn":"model::Git","name":"Git","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Git"},{"fqn":"model::Graph","name":"Graph","kind":"data","summary":"The resolved architecture graph: every node and typed edge across all C4\nlevels, plus feature scenarios. The single source every view projects from —\nenough to extract any view without re-reading source. Per-callable sequence\ntraces (`Step[]`) are held alongside, keyed by the owning callable's FQN.","text":"","module":"model","href":"module/model.html#model-Graph"},{"fqn":"model::GraphNode","name":"GraphNode","kind":"data","summary":"One node in the resolved graph — a structural declaration, a `data` type, or a\ncallable. Carries its FQN, simple name, kind, enclosing-node FQN (`for` parent,\nowning node, or empty at top level), declaring module, visibility, name span,\nany trigger macros (callables only), the call signature (callables only), the\ndisclosed shape (`data` only), and lifted `///` documentation.","text":"","module":"model","href":"module/model.html#model-GraphNode"},{"fqn":"model::Inference","name":"Inference","kind":"component","summary":"Local-binding type inference, for inlay hints and hover. Assignments are\nuntyped (`x = expr`); this infers each binding's type from its right-hand side\n— a call's return type, a field access, a `from` expression, or a literal.\nBest-effort: an un-typeable expression yields nothing rather than a guess.","text":"","module":"model","href":"module/model.html#model-Inference"},{"fqn":"model::Local","name":"Local","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Local"},{"fqn":"model::Lock","name":"Lock","kind":"data","summary":"A parsed `pds.lock` (§8.4): the pinned dependency graph. A black box here — its\nshape is the lockfile's concern, not the model's.","text":"","module":"model","href":"module/model.html#model-Lock"},{"fqn":"model::Loop","name":"Loop","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Loop"},{"fqn":"model::MacroTargeting","name":"MacroTargeting","kind":"component","summary":"§2.4 / ADR-015 — macro targeting. Every built-in macro (`onevent`, `schedule`,\n`http`, `manual`) targets callables; on any structural declaration it is a\nwrong-target error, and an unrecognised macro is unknown. An `#[onevent(E)]`\nhandler MUST have exactly one parameter whose type matches the event type.","text":"","module":"model","href":"module/model.html#model-MacroTargeting"},{"fqn":"model::Member","name":"Member","kind":"data","summary":"A member reachable through `.` from a node or `data` owner: its name, kind,\ndefinition span, one-line signature detail (`run(name: string): uuid`), value\ntype (a field's type or a callable's return type), the ordered parameter\ntypes (empty for a field — their count is the call arity, ADR-022), the\n`///` summary (absent for a field — the grammar has no field doc), and\nwhether it is `public` (callables only; gates cross-module member completion,\n§8.2). Powers member completion, arity checks, and go-to-definition.","text":"","module":"model","href":"module/model.html#model-Member"},{"fqn":"model::MemberKind","name":"MemberKind","kind":"data","summary":"What kind of member is reachable through `.` from an owner: a node's callable\n(§5.1) or a `data` record field (§3.4).","text":"","module":"model","href":"module/model.html#model-MemberKind"},{"fqn":"model::Model","name":"Model","kind":"container","summary":"`crates/pseudoscript-model`. AST to one resolved graph; static checks\n(resolution, visibility, Result flow, return coverage); the §8.3 dependency\nresolver; and the LSP analysis primitives (completion, folding, semantic\ntokens, inference). WASM-safe.","text":"","module":"model","href":"module/model.html#model-Model"},{"fqn":"model::ModuleDiagnostics","name":"ModuleDiagnostics","kind":"data","summary":"One workspace module's diagnostics, attributed to its FQN. Every span lies in\nthat module's own source, so a tool with the FQN-to-file mapping publishes\neach list against the right file.","text":"","module":"model","href":"module/model.html#model-ModuleDiagnostics"},{"fqn":"model::ModuleEntry","name":"ModuleEntry","kind":"data","summary":"One module's parsed AST, resolved symbol table, and FQN, as held by a\n`Workspace`.","text":"","module":"model","href":"module/model.html#model-ModuleEntry"},{"fqn":"model::NodeDoc","name":"NodeDoc","kind":"data","summary":"A node's documentation, lifted from its `///` block (LANG.md §2.1): the\nsummary (compact-diagram text), the extended description (tooltip text), and\nits tags (`\n`, including the `#`), in source order.","text":"","module":"model","href":"module/model.html#model-NodeDoc"},{"fqn":"model::NodeKind","name":"NodeKind","kind":"data","summary":"What kind of model element a `GraphNode` is. Adds `Callable` to the structural\nkinds: structural declarations, `data` types (including hoisted union\nvariants), and callables all become nodes.","text":"","module":"model","href":"module/model.html#model-NodeKind"},{"fqn":"model::OnEvent","name":"OnEvent","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-OnEvent"},{"fqn":"model::PackageId","name":"PackageId","kind":"data","summary":"A content-addressable package identity: its source, resolved revision, and\nin-repo path. Drives the `pds_modules/` slug a git package materialises into.","text":"","module":"model","href":"module/model.html#model-PackageId"},{"fqn":"model::ParentKind","name":"ParentKind","kind":"component","summary":"§4 / ADR-010 — C4 parent-kind well-formedness. A `for` parent links a node to\nits enclosing level, and the levels MUST nest: a `container` parents a\n`system`, a `component` parents a `container`. A parent of the wrong kind is a\ndiagnostic (`container `X` parent `Y` is not a system`). A bare parent that\nnames no same-module node is unresolved (§8.1); a qualified parent this\nsingle-module model cannot see is left to cross-module resolution.","text":"","module":"model","href":"module/model.html#model-ParentKind"},{"fqn":"model::Private","name":"Private","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Private"},{"fqn":"model::Public","name":"Public","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Public"},{"fqn":"model::Record","name":"Record","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Record"},{"fqn":"model::ReservedNames","name":"ReservedNames","kind":"component","summary":"§2.3 / ADR-012 — reserved-word identifiers. A declared identifier MUST NOT be a\nreserved word: a keyword, a primitive type name, or `Result`/`Option`. Covers\nevery name a module declares — `data`, node, callable, field, parameter,\nvariant, and feature names — so `data string` or a parameter named `Result` is\na diagnostic.","text":"","module":"model","href":"module/model.html#model-ReservedNames"},{"fqn":"model::Resolution","name":"Resolution","kind":"data","summary":"The outcome of resolving a cross-module reference (LANG.md §8.2): the FQN\nnames a public symbol, a private one reached from another module, or nothing.","text":"","module":"model","href":"module/model.html#model-Resolution"},{"fqn":"model::ResolveHit","name":"ResolveHit","kind":"data","summary":"One resolved caret hit: the clicked identifier's span, the defining module\nand the definition's span there, the resolved graph FQN (a member resolves to\n`owner::member` — the key `emit`'s symbol projection uses), a Markdown title\nline, and the doc summary or signature detail shown under it.","text":"","module":"model","href":"module/model.html#model-ResolveHit"},{"fqn":"model::Resolver","name":"Resolver","kind":"component","summary":"Resolves a module's declarations into a symbol table (LANG.md §8). FQNs are\nfile-derived: a single `.pds` file is one module, named by its `//!` path.\nHolds two namespaces — type names and node names share the symbol table, while\nfeature names live in a separate namespace the `Checks` enforce — plus the\nmember, fieldless-variant, and constant-type indexes. The LSP reuses the\ntable for hover and go-to-definition.","text":"","module":"model","href":"module/model.html#model-Resolver"},{"fqn":"model::ResultFlow","name":"ResultFlow","kind":"component","summary":"§6 — flow-sensitive `Result` / `Option` typestate. Each binding carries a\nstate (`Unknown`, `Ok`/`Err` for a `Result`, `Some`/`None` for an `Option`),\nnarrowed on entering the branches of `if (r.isErr)` / `if (r.isOk)` /\n`if (o.isNone)` / `if (o.isSome)`. Reading `.value` while known-`Err` or\nknown-`None`, or `.error` while known-`Ok`, is a model error. The env is\ncloned per branch so narrowing does not leak; an `if` whose guarded arm\ndiverges narrows the fall-through to the inverse state (`Ok`<->`Err`,\n`Some`<->`None`).","text":"","module":"model","href":"module/model.html#model-ResultFlow"},{"fqn":"model::Return","name":"Return","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Return"},{"fqn":"model::ReturnCoverage","name":"ReturnCoverage","kind":"component","summary":"ADR-016 — return coverage. A disclosed non-void callable MUST return on every\npath. A `return` makes a block diverge; an `if`/`else` diverges only when both\narms do; `for`/`while` bodies and bare expressions never guarantee a return.\nAn explicit `void` and a parse-recovered missing return type (ADR-040) both\nmean void.","text":"","module":"model","href":"module/model.html#model-ReturnCoverage"},{"fqn":"model::Rev","name":"Rev","kind":"data","summary":"A resolved revision selector — at most one of these (§8.3); `Default` is the\nremote's default-branch HEAD.","text":"","module":"model","href":"module/model.html#model-Rev"},{"fqn":"model::Scenario","name":"Scenario","kind":"data","summary":"A `feature` BDD scenario attached to its target node (LANG.md §5.2, §9.3):\nits name, the canonicalised target FQN (as written if it does not resolve),\nthe declaring module's FQN, the span of the feature name (a host's\ngo-to-definition target), lifted `///` documentation, and the ordered\ngiven/when/then steps. Steps are prose, not resolved, so a scenario adds no\nedges; it renders as a card on its target node's doc page.","text":"","module":"model","href":"module/model.html#model-Scenario"},{"fqn":"model::ScenarioStep","name":"ScenarioStep","kind":"data","summary":"One step of a `Scenario` (LANG.md §5.2): a keyword (`given`/`when`/`then`/\n`and`/`but`) and its prose, with the string literal's quotes stripped.","text":"","module":"model","href":"module/model.html#model-ScenarioStep"},{"fqn":"model::SelfCall","name":"SelfCall","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-SelfCall"},{"fqn":"model::Semantic","name":"Semantic","kind":"component","summary":"AST-aware semantic colouring: each identifier classified by its declared role\n(node→namespace, `data`→class, callable→method, parameter, call segment), the\nspans `lsp_core` delta-encodes for the editor.","text":"","module":"model","href":"module/model.html#model-Semantic"},{"fqn":"model::SigParam","name":"SigParam","kind":"data","summary":"One parameter of a callable signature: its name and rendered type.","text":"","module":"model","href":"module/model.html#model-SigParam"},{"fqn":"model::Signature","name":"Signature","kind":"data","summary":"A callable node's signature (§5.1): its ordered parameters and rendered return\ntype. Carried on a callable `GraphNode` so the sequence and symbol views can\nshow the call shape without re-reading source.","text":"","module":"model","href":"module/model.html#model-Signature"},{"fqn":"model::Source","name":"Source","kind":"data","summary":"The resolved source of a dependency (ADR-026): a fetched git repository at a\nrevision and in-repo sub-path, or a local sibling workspace read from disk.","text":"","module":"model","href":"module/model.html#model-Source"},{"fqn":"model::Step","name":"Step","kind":"data","summary":"One step in a callable's ordered sequence trace (LANG.md §7, §9.2). Calls in a\nchained expression are emitted left-to-right; control flow becomes `Alt`/\n`Loop` frames whose bodies are nested step lists, in §7 evaluation order.","text":"","module":"model","href":"module/model.html#model-Step"},{"fqn":"model::Symbol","name":"Symbol","kind":"data","summary":"One declared, addressable node in a module namespace: the bare name, its FQN\n(`module::Ledger`), its declaration kind, whether it is `public` (§8.2), and\nthe span of its name.","text":"","module":"model","href":"module/model.html#model-Symbol"},{"fqn":"model::SymbolKind","name":"SymbolKind","kind":"data","summary":"The lowercase declaration keyword a `Symbol` names. Drives the parent-kind and\nmacro-target diagnostics, which embed it as prose. `Constant` is a top-level\nprimitive value (§3.6, ADR-039).","text":"","module":"model","href":"module/model.html#model-SymbolKind"},{"fqn":"model::SymbolTable","name":"SymbolTable","kind":"data","summary":"One module's resolved symbol table (LANG.md §8): its FQN plus the declared\nnodes, the members reachable through `.`, the fieldless-variant index\n(ADR-032), and the constant-type index (ADR-039). The `Resolver` produces it;\nthe `Workspace` indexes and the `Checks` consume it.","text":"","module":"model","href":"module/model.html#model-SymbolTable"},{"fqn":"model::Tag","name":"Tag","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Tag"},{"fqn":"model::Trigger","name":"Trigger","kind":"data","summary":"A trigger macro on a callable (LANG.md §2.4): the macro that makes the\ncallable a diagram entry point and synthesises an inbound initiator edge. Each\nvariant maps to a synthesised initiator node (`event:`, `scheduler`,\n`client`, `caller`).","text":"","module":"model","href":"module/model.html#model-Trigger"},{"fqn":"model::TypeRefs","name":"TypeRefs","kind":"component","summary":"§3.3 / §8.1 — type-reference resolution. Every named type in a declaration — a\nfield, parameter, or return type, and each generic argument — MUST resolve. A\nbare name that resolves to nothing is reported as unresolved; a name that\nresolves to a declared type or node MUST be written by its full FQN\n(`module::Name`), so an unqualified declared-type annotation is rejected.\nBuilt-in types (the primitives, `Result`, `Option`) stay bare.","text":"","module":"model","href":"module/model.html#model-TypeRefs"},{"fqn":"model::Union","name":"Union","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Union"},{"fqn":"model::VariantCollision","name":"VariantCollision","kind":"component","summary":"§3.5 / ADR-006 — union variant collision. A top-level `data Name` followed by\nan inline variant `| Name { ... }` hoisting the same name is a collision. Bare\nvariants reference existing data and never collide.","text":"","module":"model","href":"module/model.html#model-VariantCollision"},{"fqn":"model::Visibility","name":"Visibility","kind":"data","summary":"Whether a node is `public` (cross-module addressable) or module-private\n(LANG.md §8.2).","text":"","module":"model","href":"module/model.html#model-Visibility"},{"fqn":"model::Workspace","name":"Workspace","kind":"component","summary":"The resolved set of modules keyed by FQN (LANG.md §8). Built once per\nworkspace from `(fqn, parsed module)` pairs; owns the per-module models and a\nglobal FQN-to-`Symbol` index for cross-module resolution.","text":"","module":"model","href":"module/model.html#model-Workspace"},{"fqn":"model::WorkspaceModule","name":"WorkspaceModule","kind":"data","summary":"One `.pds` module of a workspace: its caller-supplied FQN (the loader derives\nit from the file path relative to `pds.toml`, LANG.md §8.1) and its source\ntext. This crate stays pure over in-memory modules; it never touches the\nfilesystem.","text":"","module":"model","href":"module/model.html#model-WorkspaceModule"},{"fqn":"project","name":"project","kind":"module","summary":"","text":"","module":"project","href":"module/project.html"},{"fqn":"project::Deps","name":"Deps","kind":"component","summary":"Resolves a workspace's declared dependencies into modules the checker binds as\nexternals (§8.3): reads `pds.lock` + `pds_modules/`, materialises each direct\ndependency's `.pds` modules under its dependency-name prefix, and resolves a\nlocal path dependency's directory.","text":"","module":"project","href":"module/project.html#project-Deps"},{"fqn":"project::IoError","name":"IoError","kind":"data","summary":"A filesystem failure surfaced to the caller: the path or manifest that could\nnot be read, with a human-readable message.","text":"","module":"project","href":"module/project.html#project-IoError"},{"fqn":"project::Loader","name":"Loader","kind":"component","summary":"Resolves and reads a workspace off disk: finds the root by walking up to the\nnearest `pds.toml`, then walks the tree for visible `.pds` files and loads each\nas a `(fqn, source)` module — mapping its path to a flat module FQN (§8.1) and\nskipping `target/` and `pds_modules/`.","text":"","module":"project","href":"module/project.html#project-Loader"},{"fqn":"project::Project","name":"Project","kind":"container","summary":"`crates/pseudoscript-project`. The disk-facing loader: resolves the workspace\nroot, reads its `.pds` modules, and materialises dependency modules from the\nvendor directory. The only place the native toolchain touches the filesystem\nfor project loading.","text":"","module":"project","href":"module/project.html#project-Project"},{"fqn":"syntax","name":"syntax","kind":"module","summary":"","text":"","module":"syntax","href":"module/syntax.html"},{"fqn":"syntax::Assign","name":"Assign","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Assign"},{"fqn":"syntax::BinOp","name":"BinOp","kind":"data","summary":"A binary operator (§7.5): arithmetic, comparison, equality, and boolean.","text":"","module":"syntax","href":"module/syntax.html#syntax-BinOp"},{"fqn":"syntax::Binary","name":"Binary","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Binary"},{"fqn":"syntax::BlankLines","name":"BlankLines","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-BlankLines"},{"fqn":"syntax::Block","name":"Block","kind":"data","summary":"A `{ ... }` statement block (§7): statements in order, plus the brace span.","text":"","module":"syntax","href":"module/syntax.html#syntax-Block"},{"fqn":"syntax::BlockComment","name":"BlockComment","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-BlockComment"},{"fqn":"syntax::BodyMember","name":"BodyMember","kind":"data","summary":"A member of a disclosed node body: a callable, or — under error recovery —\na nested structural declaration the parser flags as illegal (ADR-011).","text":"","module":"syntax","href":"module/syntax.html#syntax-BodyMember"},{"fqn":"syntax::BoolLit","name":"BoolLit","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-BoolLit"},{"fqn":"syntax::CallableDecl","name":"CallableDecl","kind":"data","summary":"A callable (implicit operation) declared inside a disclosed node (§5.1).\n`returnTy` is required (ADR-040) — a missing return type is a syntax error,\nrecovered as `void`; `body` absent means a black box (`;`).","text":"","module":"syntax","href":"module/syntax.html#syntax-CallableDecl"},{"fqn":"syntax::CallableMember","name":"CallableMember","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-CallableMember"},{"fqn":"syntax::Compose","name":"Compose","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Compose"},{"fqn":"syntax::Constant","name":"Constant","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Constant"},{"fqn":"syntax::ConstantDecl","name":"ConstantDecl","kind":"data","summary":"A `constant NAME = Literal` declaration (§3.6, ADR-039): a top-level primitive\nvalue. `public` lives on the enclosing `Declaration`, mirroring `data`.","text":"","module":"syntax","href":"module/syntax.html#syntax-ConstantDecl"},{"fqn":"syntax::Convert","name":"Convert","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Convert"},{"fqn":"syntax::Data","name":"Data","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Data"},{"fqn":"syntax::DataBody","name":"DataBody","kind":"data","summary":"The three `data` forms. A bare `| Name` variant is an enum case; a\n`| Name { .. }` variant carries an inline record (§3.5, ADR-006).","text":"","module":"syntax","href":"module/syntax.html#syntax-DataBody"},{"fqn":"syntax::DataDecl","name":"DataDecl","kind":"data","summary":"A `data` declaration: a record, a union, or a black box (§3.4, §3.5).","text":"","module":"syntax","href":"module/syntax.html#syntax-DataDecl"},{"fqn":"syntax::DeclItem","name":"DeclItem","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-DeclItem"},{"fqn":"syntax::DeclKind","name":"DeclKind","kind":"data","summary":"The structural payload of a declaration: a node (person/system/container/\ncomponent), a `data` type, or a top-level `constant` (§3.6, ADR-039).","text":"","module":"syntax","href":"module/syntax.html#syntax-DeclKind"},{"fqn":"syntax::DeclMember","name":"DeclMember","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-DeclMember"},{"fqn":"syntax::Declaration","name":"Declaration","kind":"data","summary":"A documented, annotated structural declaration (§4): the shared\n`doc → macros → public` prefix plus the structural payload.","text":"","module":"syntax","href":"module/syntax.html#syntax-Declaration"},{"fqn":"syntax::Diagnostic","name":"Diagnostic","kind":"data","summary":"One message about a span of source. The single diagnostic type every crate\nemits, so a driver collects lexer, parser, and checker output into one\nordered list. `code` is an optional stable identifier (e.g. `E0001`) for\ntooling; the human-facing text is `message`. `codeDescription` is an optional\nURL the code resolves to — an article explaining the rule — which the LSP\nsurfaces as the diagnostic's clickable link. Empty when the code carries no\narticle.","text":"","module":"syntax","href":"module/syntax.html#syntax-Diagnostic"},{"fqn":"syntax::DocBlock","name":"DocBlock","kind":"data","summary":"A `///` doc block split into summary and extended on the first blank `///`\nline (ADR-009): summary feeds compact diagrams, extended feeds tooltips,\ntags carry the `\n` markers.","text":"","module":"syntax","href":"module/syntax.html#syntax-DocBlock"},{"fqn":"syntax::Expr","name":"Expr","kind":"data","summary":"An expression (§7, §10): its form and source span.","text":"","module":"syntax","href":"module/syntax.html#syntax-Expr"},{"fqn":"syntax::ExprKind","name":"ExprKind","kind":"data","summary":"The expression forms (§10). `Marker` is a built-in generic constructor —\n`Ok`/`Err` (`Result`) or `Some`/`None` (`Option`); `From` names a target\ntype and its `source`, whose `FromSource` form is the §7.2 vs §7.4 split;\n`Postfix` is a `.name`/`.name(..)` access chain (ADR-007); `Unary`/`Binary`\nare the §7.5 operator forms. A `Marker` or `From` head is never a binary\noperand (§7.5).","text":"","module":"syntax","href":"module/syntax.html#syntax-ExprKind"},{"fqn":"syntax::ExprStmt","name":"ExprStmt","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-ExprStmt"},{"fqn":"syntax::FeatureDecl","name":"FeatureDecl","kind":"data","summary":"A `feature Name for Path { given* when+ then+ }` BDD scenario (§5.2). Steps\nare prose, not resolved against the model; the strict given→when→then order\nis enforced by the parser. A feature takes no macros and no `public`.","text":"","module":"syntax","href":"module/syntax.html#syntax-FeatureDecl"},{"fqn":"syntax::FeatureItem","name":"FeatureItem","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-FeatureItem"},{"fqn":"syntax::FeatureStep","name":"FeatureStep","kind":"data","summary":"One step line in a feature flow: a step keyword and its prose string (§5.2).","text":"","module":"syntax","href":"module/syntax.html#syntax-FeatureStep"},{"fqn":"syntax::Field","name":"Field","kind":"data","summary":"A record field `name: Type`.","text":"","module":"syntax","href":"module/syntax.html#syntax-Field"},{"fqn":"syntax::For","name":"For","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-For"},{"fqn":"syntax::From","name":"From","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-From"},{"fqn":"syntax::FromSource","name":"FromSource","kind":"data","summary":"The source of a `from` expression (§7.2, §7.4, ADR-035) — the parser\nbranches on the leading token, so the two forms are distinct: a `{`\nopens `Compose`, a set the target `data` record/variant is built from;\nanything else is `Convert`, carrying the target type onto one value.","text":"","module":"syntax","href":"module/syntax.html#syntax-FromSource"},{"fqn":"syntax::If","name":"If","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-If"},{"fqn":"syntax::InnerDoc","name":"InnerDoc","kind":"data","summary":"One `//!` inner-doc line documenting the module (§2.1).","text":"","module":"syntax","href":"module/syntax.html#syntax-InnerDoc"},{"fqn":"syntax::Item","name":"Item","kind":"data","summary":"A top-level item: a documented structural declaration, or a `feature` BDD\nscenario.","text":"","module":"syntax","href":"module/syntax.html#syntax-Item"},{"fqn":"syntax::Lexed","name":"Lexed","kind":"data","summary":"The full result of lexing: the conformance token stream plus interleaved\ntrivia for the formatter.","text":"","module":"syntax","href":"module/syntax.html#syntax-Lexed"},{"fqn":"syntax::Lexer","name":"Lexer","kind":"component","summary":"Hand-written lexer for LANG.md §2. One pass yields the conformance token\nstream (comments discarded, `///`→`Doc`+`Tag`, `//!`→`InnerDoc`) and\nfull-fidelity trivia for the formatter. Infallible: lexical anomalies surface\nas parser diagnostics, never a failed lex.","text":"","module":"syntax","href":"module/syntax.html#syntax-Lexer"},{"fqn":"syntax::LineComment","name":"LineComment","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-LineComment"},{"fqn":"syntax::LineIndex","name":"LineIndex","kind":"component","summary":"Precomputed newline offsets turning a byte offset into a 1-based (line, col)\npair in O(log n). Built once per source and reused for every lookup; column\ncounts bytes from the line start.","text":"","module":"syntax","href":"module/syntax.html#syntax-LineIndex"},{"fqn":"syntax::List","name":"List","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-List"},{"fqn":"syntax::Lit","name":"Lit","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Lit"},{"fqn":"syntax::Literal","name":"Literal","kind":"data","summary":"A literal value (ADR-013). `raw` carries the source text (string literals\nkeep their quotes).","text":"","module":"syntax","href":"module/syntax.html#syntax-Literal"},{"fqn":"syntax::LiteralArg","name":"LiteralArg","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-LiteralArg"},{"fqn":"syntax::Macro","name":"Macro","kind":"data","summary":"A `#[..]` macro (outer attribute) on a callable (§2.4): its name path and\nargument form.","text":"","module":"syntax","href":"module/syntax.html#syntax-Macro"},{"fqn":"syntax::MacroArg","name":"MacroArg","kind":"data","summary":"One argument inside a macro's `( .. )` list (§10 `MetaArg`).","text":"","module":"syntax","href":"module/syntax.html#syntax-MacroArg"},{"fqn":"syntax::MacroArgs","name":"MacroArgs","kind":"data","summary":"The three macro argument forms (§2.4): `#[manual]` word, `#[onevent(Path)]`/\n`#[http(\"..\")]` list, `#[schedule = \"..]` name=value.","text":"","module":"syntax","href":"module/syntax.html#syntax-MacroArgs"},{"fqn":"syntax::Marker","name":"Marker","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Marker"},{"fqn":"syntax::MarkerKind","name":"MarkerKind","kind":"data","summary":"The built-in generic constructor a `Marker` names (§6, ADR-019). The\nvariants mirror the four marker keywords (their names carry the `Kw` prefix\nbecause `Ok`/`Err`/`Some`/`None` are reserved words): `KwOk`/`KwErr` build a\n`Result`, `KwSome`/`KwNone` build an `Option`.","text":"","module":"syntax","href":"module/syntax.html#syntax-MarkerKind"},{"fqn":"syntax::Module","name":"Module","kind":"data","summary":"The typed syntax tree of one module (LANG.md §10): module-level inner docs,\nthen declarations and features in source order. Every node carries a `Span`;\ndeclarations and statements also carry leading trivia so the formatter can\nreproduce layout.","text":"","module":"syntax","href":"module/syntax.html#syntax-Module"},{"fqn":"syntax::NameValue","name":"NameValue","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-NameValue"},{"fqn":"syntax::NestedArg","name":"NestedArg","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-NestedArg"},{"fqn":"syntax::Node","name":"Node","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Node"},{"fqn":"syntax::NodeDecl","name":"NodeDecl","kind":"data","summary":"A `person` / `system` / `container` / `component` declaration. `parent` is\nthe `for ` path, present for container/component. `body` is the\ndisclosed member list, or absent for a black box (`;`).","text":"","module":"syntax","href":"module/syntax.html#syntax-NodeDecl"},{"fqn":"syntax::NodeKind","name":"NodeKind","kind":"data","summary":"The structural keyword class of a node.","text":"","module":"syntax","href":"module/syntax.html#syntax-NodeKind"},{"fqn":"syntax::NumberLit","name":"NumberLit","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-NumberLit"},{"fqn":"syntax::Param","name":"Param","kind":"data","summary":"A callable parameter `name: Type`.","text":"","module":"syntax","href":"module/syntax.html#syntax-Param"},{"fqn":"syntax::Paren","name":"Paren","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Paren"},{"fqn":"syntax::Parsed","name":"Parsed","kind":"data","summary":"Parser output: the tree (always present, recovered on error) plus the\ndiagnostics collected while parsing. Parsing never fails outright.","text":"","module":"syntax","href":"module/syntax.html#syntax-Parsed"},{"fqn":"syntax::Parser","name":"Parser","kind":"component","summary":"Recursive-descent parser for the §10 grammar with error recovery: on\nunexpected input it records a `Diagnostic`, resynchronises to the next\nstatement/declaration boundary, and continues. Always yields a (possibly\npartial) `Module`; never panics.","text":"","module":"syntax","href":"module/syntax.html#syntax-Parser"},{"fqn":"syntax::Path","name":"Path","kind":"data","summary":"A `::`-separated path of identifiers (§2.2, §10 `Path`); never empty.","text":"","module":"syntax","href":"module/syntax.html#syntax-Path"},{"fqn":"syntax::PathArg","name":"PathArg","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-PathArg"},{"fqn":"syntax::PathRef","name":"PathRef","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-PathRef"},{"fqn":"syntax::Postfix","name":"Postfix","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Postfix"},{"fqn":"syntax::PostfixSeg","name":"PostfixSeg","kind":"data","summary":"One `.name` or `.name(args)` step in a postfix chain (ADR-007). `callArgs`\npresent marks a call; absent marks field access.","text":"","module":"syntax","href":"module/syntax.html#syntax-PostfixSeg"},{"fqn":"syntax::Record","name":"Record","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Record"},{"fqn":"syntax::Ref","name":"Ref","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Ref"},{"fqn":"syntax::Reference","name":"Reference","kind":"data","summary":"A reference primary (§10 `Ref`): `self` or an FQN.","text":"","module":"syntax","href":"module/syntax.html#syntax-Reference"},{"fqn":"syntax::Return","name":"Return","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Return"},{"fqn":"syntax::SelfNode","name":"SelfNode","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-SelfNode"},{"fqn":"syntax::Severity","name":"Severity","kind":"data","summary":"Diagnostic severity. `Error` invalidates the input; `Warning`/`Info` advise\nand never block compilation.","text":"","module":"syntax","href":"module/syntax.html#syntax-Severity"},{"fqn":"syntax::Span","name":"Span","kind":"data","summary":"A half-open byte range `[start, end)` into one module's source. Offsets are\nbytes, not characters; columns derived via `LineIndex` count bytes too,\nmatching the conformance token goldens.","text":"","module":"syntax","href":"module/syntax.html#syntax-Span"},{"fqn":"syntax::SpannedTrivia","name":"SpannedTrivia","kind":"data","summary":"A trivia element paired with the source span it occupies.","text":"","module":"syntax","href":"module/syntax.html#syntax-SpannedTrivia"},{"fqn":"syntax::StepKind","name":"StepKind","kind":"data","summary":"The step keyword class of a feature step (§5.2). `And`/`But` continue the\npreceding step's flow phase.","text":"","module":"syntax","href":"module/syntax.html#syntax-StepKind"},{"fqn":"syntax::Stmt","name":"Stmt","kind":"data","summary":"A statement valid inside a callable body (§7), with the leading trivia that\npreceded it.","text":"","module":"syntax","href":"module/syntax.html#syntax-Stmt"},{"fqn":"syntax::StmtKind","name":"StmtKind","kind":"data","summary":"The statement forms (§7).","text":"","module":"syntax","href":"module/syntax.html#syntax-StmtKind"},{"fqn":"syntax::StringLit","name":"StringLit","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-StringLit"},{"fqn":"syntax::Syntax","name":"Syntax","kind":"container","summary":"`crates/pseudoscript-syntax`. The foundation crate: source text to tokens\nand a typed AST, emitting the shared `Diagnostic`. WASM-safe and I/O-free.","text":"","module":"syntax","href":"module/syntax.html#syntax-Syntax"},{"fqn":"syntax::Tag","name":"Tag","kind":"data","summary":"A `\n` tag from a doc block, including the leading `#` (§2.4).","text":"","module":"syntax","href":"module/syntax.html#syntax-Tag"},{"fqn":"syntax::Token","name":"Token","kind":"data","summary":"A lexical token: its kind, source span, and rendered lexeme (LANG.md §2).","text":"For most tokens `text` is the raw source slice. For `Doc`/`InnerDoc` it is\nthe doc text with the marker and surrounding whitespace stripped; for `Tag`\nit includes the leading `#`.","module":"syntax","href":"module/syntax.html#syntax-Token"},{"fqn":"syntax::TokenKind","name":"TokenKind","kind":"data","summary":"Every lexical token class (LANG.md §2). The `name` rendering (e.g.\n`KW_SYSTEM`) is the conformance golden's `KIND`. Primitive type names and\n`Result` are NOT keywords — they lex as `Ident` and are classified in type\nposition by the model crate.","text":"","module":"syntax","href":"module/syntax.html#syntax-TokenKind"},{"fqn":"syntax::Trivia","name":"Trivia","kind":"data","summary":"Non-token source between tokens, preserved for the formatter. Doc comments,\ntags, macros, and modifiers are first-class tokens/AST data, not trivia —\nonly discarded comments and blank-line gaps live here.","text":"","module":"syntax","href":"module/syntax.html#syntax-Trivia"},{"fqn":"syntax::Type","name":"Type","kind":"data","summary":"A type expression: a named base with optional generic arguments and an\noptional trailing `[]` array suffix (§3.3, ADR-008 — no optionality marker).","text":"","module":"syntax","href":"module/syntax.html#syntax-Type"},{"fqn":"syntax::Unary","name":"Unary","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Unary"},{"fqn":"syntax::UnaryOp","name":"UnaryOp","kind":"data","summary":"A unary operator (§7.5): boolean `!` or numeric `-`.","text":"","module":"syntax","href":"module/syntax.html#syntax-UnaryOp"},{"fqn":"syntax::Union","name":"Union","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Union"},{"fqn":"syntax::Variant","name":"Variant","kind":"data","summary":"One union variant: its name and an optional inline record body.","text":"","module":"syntax","href":"module/syntax.html#syntax-Variant"},{"fqn":"syntax::While","name":"While","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-While"},{"fqn":"universe","name":"universe","kind":"module","summary":"","text":"","module":"universe","href":"module/universe.html"},{"fqn":"universe::Adapter","name":"Adapter","kind":"component","summary":"Adapts a resolved model into the software graph: keeps only the structural\nnodes, hooks each to its structural parent for the containment tree, and lifts\nevery call to the structural level — tallying directed traffic per\ncaller→callee pair so the edge carries direction.","text":"","module":"universe","href":"module/universe.html#universe-Adapter"},{"fqn":"universe::C4Level","name":"C4Level","kind":"data","summary":"The C4 abstraction level a node sits at. Only these four enter the graph;\ndata and callables do not — a relationship through them is lifted to the\nnearest enclosing structural node.","text":"","module":"universe","href":"module/universe.html#universe-C4Level"},{"fqn":"universe::EdgeOut","name":"EdgeOut","kind":"data","summary":"One relationship in the flat snapshot, with its traffic (call count).","text":"","module":"universe","href":"module/universe.html#universe-EdgeOut"},{"fqn":"universe::Flatten","name":"Flatten","kind":"component","summary":"Flattens the software graph into the renderer-facing snapshot: each node's id,\nlevel string, and parent id; each relationship's endpoints and traffic. The\nboundary the web IDE reads — petgraph indices never cross it.","text":"","module":"universe","href":"module/universe.html#universe-Flatten"},{"fqn":"universe::FlowDef","name":"FlowDef","kind":"data","summary":"One entry-point flow: the entry callable's FQN and simple name, the flow's\npalette colour, and its ordered legs. The renderer draws one filament chain\nper flow and streams its beads in the flow's colour.","text":"","module":"universe","href":"module/universe.html#universe-FlowDef"},{"fqn":"universe::FlowHop","name":"FlowHop","kind":"data","summary":"One call leg of a flow: the caller and callee as structural node ids (the\nsame ids the snapshot places), plus the message label shown on the leg.","text":"","module":"universe","href":"module/universe.html#universe-FlowHop"},{"fqn":"universe::FlowTracer","name":"FlowTracer","kind":"component","summary":"Traces every entry-point flow: a triggered callable (or a person-owned\naction) starts a flow; its sequence projection is walked call-by-call and\neach leg's endpoints lift to the nearest placed structural node — the same\nlift the Adapter applies to relationships, so flows and edges agree. Colours\nkey from the entry's FQN by a stable hash into a fixed palette — the same\nkeying the web IDE paints with — so a flow keeps its hue everywhere it\nappears and an unrelated model edit never recolours it.","text":"","module":"universe","href":"module/universe.html#universe-FlowTracer"},{"fqn":"universe::GraphNode","name":"GraphNode","kind":"data","summary":"A structural node in the software graph: its stable model FQN, its C4 level,\nand its place in the containment tree (the enclosing node, empty for a\ntop-level system, and the ids it contains). No position — the renderer\nplaces it.","text":"","module":"universe","href":"module/universe.html#universe-GraphNode"},{"fqn":"universe::NodeOut","name":"NodeOut","kind":"data","summary":"One node in the flat snapshot: its id, C4 level as a lowercase string, and the\nid of its containment parent (empty for a top-level system).","text":"","module":"universe","href":"module/universe.html#universe-NodeOut"},{"fqn":"universe::Relationship","name":"Relationship","kind":"data","summary":"A directed relationship between two structural nodes, weighted by `traffic` —\nthe number of underlying calls lifted onto the pair. Self-relationships are\ndropped; the count drives the renderer's flow animation.","text":"","module":"universe","href":"module/universe.html#universe-Relationship"},{"fqn":"universe::Snapshot","name":"Snapshot","kind":"data","summary":"The flat, serialisable contract the web IDE's `ForceGraph` consumes: nodes\nand directed weighted edges, with no engine internals (petgraph indices)\nleaking across the boundary. Positions are not here.","text":"","module":"universe","href":"module/universe.html#universe-Snapshot"},{"fqn":"universe::SoftwareGraph","name":"SoftwareGraph","kind":"data","summary":"The software graph: structural nodes with the containment tree, directed\nrelationship edges weighted by traffic, and the top-level systems (the\ncontainment roots, in model-declaration order). The crate's in-memory form,\nbefore flattening to a renderer-facing `Snapshot`.","text":"","module":"universe","href":"module/universe.html#universe-SoftwareGraph"},{"fqn":"universe::Universe","name":"Universe","kind":"container","summary":"`crates/pseudoscript-universe`. Maps the resolved C4 model into the software\ngraph the 3D view renders, then flattens it to a determinstic snapshot.","text":"","module":"universe","href":"module/universe.html#universe-Universe"},{"fqn":"universe.html","name":"3D Universe","kind":"page","summary":"The model in 3D — structure and flows","text":"","module":"","href":"universe.html"}]; \ No newline at end of file +window.__PDS_SEARCH__=[{"fqn":"health.html","name":"Architecture Health","kind":"page","summary":"Errors, warnings, and principle lints","text":"","module":"","href":"health.html"},{"fqn":"cli","name":"cli","kind":"module","summary":"","text":"","module":"cli","href":"module/cli.html"},{"fqn":"cli::AddOpts","name":"AddOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-AddOpts"},{"fqn":"cli::Args","name":"Args","kind":"component","summary":"Parses argv with clap-derive into the chosen subcommand and its options, then\ndispatches to the matching command handler.","text":"","module":"cli","href":"module/cli.html#cli-Args"},{"fqn":"cli::CheckCmd","name":"CheckCmd","kind":"component","summary":"`pds check` — parse and statically check one file, print each diagnostic as\n`path:line:col: severity: message`, and exit non-zero on any error-severity\ndiagnostic. Emits no diagram.","text":"","module":"cli","href":"module/cli.html#cli-CheckCmd"},{"fqn":"cli::CheckOpts","name":"CheckOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-CheckOpts"},{"fqn":"cli::Cli","name":"Cli","kind":"container","summary":"`crates/pseudoscript` — the binary crate (`pds`). The composition root and\nonly I/O edge; a thin frontend that wires the pure library crates to disk,\nHTTP, and a filesystem watcher.","text":"","module":"cli","href":"module/cli.html#cli-Cli"},{"fqn":"cli::Command","name":"Command","kind":"data","summary":"The subcommand clap parsed from argv, with its resolved options.","text":"","module":"cli","href":"module/cli.html#cli-Command"},{"fqn":"cli::Deps","name":"Deps","kind":"component","summary":"`pds add`/`install`/`update`/`remove`/`list` — git workspace dependency\nmanagement (§8.3). `add` resolves a git URL into `pds.toml` + `pds.lock` and\nvendors it; `install` restores `pds_modules/` from the lock; `update`\nre-pins; `remove` drops one; `list` discovers every workspace under a root.\nResolution delegates to `project`; fetching is the CLI's I/O.","text":"","module":"cli","href":"module/cli.html#cli-Deps"},{"fqn":"cli::DocCmd","name":"DocCmd","kind":"component","summary":"`pds doc` — the headline command (ADR-017). Load the workspace, check it per\nmodule (reported but non-fatal, like `cargo doc` — the same findings feed the\nsite's health page), project the resolved graph, and render a static doc\nsite. The output format is resolved by precedence — an explicit `--format`\nover the manifest `[doc].format`, else HTML — then a fork renders the SSR\nHTML site (every diagram as server SVG, logo copied) or a flat Markdown site\n(SVG assets, no logo). `--serve` hosts the HTML site over HTTP; `--watch`\nadds a filesystem watcher and browser live reload; both are skipped for\nMarkdown output, which only writes.","text":"","module":"cli","href":"module/cli.html#cli-DocCmd"},{"fqn":"cli::DocOpts","name":"DocOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-DocOpts"},{"fqn":"cli::EvalCmd","name":"EvalCmd","kind":"component","summary":"`pds eval` — read a model from stdin and statically check it, printing each\ndiagnostic as `:line:col: severity: message` and exiting non-zero on\nany error. The fileless path: an agent pipes a snippet to check it without\nwriting a file.","text":"","module":"cli","href":"module/cli.html#cli-EvalCmd"},{"fqn":"cli::FmtCmd","name":"FmtCmd","kind":"component","summary":"`pds fmt` — format to canonical PseudoScript; `--write` overwrites the file in\nplace, otherwise prints to stdout. A parse error is reported and the file is\nleft untouched.","text":"","module":"cli","href":"module/cli.html#cli-FmtCmd"},{"fqn":"cli::FmtOpts","name":"FmtOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-FmtOpts"},{"fqn":"cli::HttpServer","name":"HttpServer","kind":"component","summary":"HTTP host for the generated site (`--serve`/`--watch`): `tiny_http` on\n`127.0.0.1:port`, maps `/` to `index.html`, rejects paths escaping the output\ndir, and on watch injects a live-reload poll and answers `/__livereload` with\nthe current version. Blocks until the process is stopped.","text":"","module":"cli","href":"module/cli.html#cli-HttpServer"},{"fqn":"cli::InitCmd","name":"InitCmd","kind":"component","summary":"`pds init` — bootstrap a workspace: write `pds.toml` and a starter `main.pds`.\nRefuses to overwrite an existing manifest; the starter is written only when\nabsent.","text":"","module":"cli","href":"module/cli.html#cli-InitCmd"},{"fqn":"cli::IoError","name":"IoError","kind":"data","summary":"A filesystem, parse-config, or serving failure surfaced to the CLI exit code.","text":"","module":"cli","href":"module/cli.html#cli-IoError"},{"fqn":"cli::ListOpts","name":"ListOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-ListOpts"},{"fqn":"cli::Loader","name":"Loader","kind":"component","summary":"The CLI loader: resolves the project root and reads its modules through the\n`project` crate (the shared filesystem edge), then parses the cli-specific\n`[doc]` table on top. Root-finding and module-walking are `project`'s job;\nthe manifest's doc config is the CLI's.","text":"","module":"cli","href":"module/cli.html#cli-Loader"},{"fqn":"cli::LspHost","name":"LspHost","kind":"component","summary":"`pds lsp` — boot a Tokio runtime and launch the language server over stdio.\nSpawned as a child process by an editor (`context::Editor.openDocument`).","text":"","module":"cli","href":"module/cli.html#cli-LspHost"},{"fqn":"cli::OutlineCmd","name":"OutlineCmd","kind":"component","summary":"`pds outline` — walk the workspace's modules, build its graph, and print the\nsymbol outline as JSON: each node's `fqn`, `name`, `kind`, `parent`, whether it\nis a triggered flow entry, and its declaration site. The structure tree an\neditor draws. Outlining reads the walked modules straight, skipping the manifest\n`[doc]` parse and dependency resolution: the structure tree never depends on\npresentation config or external modules.","text":"","module":"cli","href":"module/cli.html#cli-OutlineCmd"},{"fqn":"cli::OutlineOpts","name":"OutlineOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-OutlineOpts"},{"fqn":"cli::ReferenceCmd","name":"ReferenceCmd","kind":"component","summary":"`pds lang` (alias `spec`) and `pds skill` — print the bundled, version-pinned\nlanguage reference and the authoring skill to stdout. Fed to an LLM to author\n`.pds`; no workspace needed.","text":"","module":"cli","href":"module/cli.html#cli-ReferenceCmd"},{"fqn":"cli::RemoveOpts","name":"RemoveOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-RemoveOpts"},{"fqn":"cli::SvgCmd","name":"SvgCmd","kind":"component","summary":"`pds svg` — render a single diagram to a self-contained SVG on stdout. With\n`--symbol`, draws that symbol's fitting view; otherwise draws `--view` (paired\nwith `--target`) over the whole workspace. The static counterpart of the IDE\ncanvas. Like `pds outline`, it reads the walked modules straight, skipping the\nmanifest `[doc]` parse and dependency resolution: a diagram never depends on\npresentation config or external modules.","text":"","module":"cli","href":"module/cli.html#cli-SvgCmd"},{"fqn":"cli::SvgOpts","name":"SvgOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-SvgOpts"},{"fqn":"cli::TokensCmd","name":"TokensCmd","kind":"component","summary":"`pds tokens` — print the conformance token stream (`KIND@line:col \"lexeme\"`)\nto stdout, for debugging the lexer.","text":"","module":"cli","href":"module/cli.html#cli-TokensCmd"},{"fqn":"cli::TokensOpts","name":"TokensOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-TokensOpts"},{"fqn":"cli::UpgradeCmd","name":"UpgradeCmd","kind":"component","summary":"`pds upgrade` — download a release and install it over the running binary.","text":"","module":"cli","href":"module/cli.html#cli-UpgradeCmd"},{"fqn":"cli::UpgradeOpts","name":"UpgradeOpts","kind":"data","summary":"","text":"","module":"cli","href":"module/cli.html#cli-UpgradeOpts"},{"fqn":"cli::Watcher","name":"Watcher","kind":"component","summary":"Filesystem watcher (`--watch`, via `notify`): watches the project root\nrecursively, debounces each save burst, and on a relevant change rebuilds the\nsite and bumps the version the browser's live-reload poll reads. Events under\nthe output dir are ignored so writing the site never re-triggers a build.","text":"","module":"cli","href":"module/cli.html#cli-Watcher"},{"fqn":"cli::Workspace","name":"Workspace","kind":"data","summary":"The loaded project: the `[doc]` config, the resolved output directory\n(`/`, default `target/doc`), every module sorted by FQN, the\ndependency-name-prefixed dependency modules (§8.3; empty without a `pds.lock`),\nand the preferred doc output format. Produced from the nearest `pds.toml`.","text":"","module":"cli","href":"module/cli.html#cli-Workspace"},{"fqn":"context","name":"context","kind":"module","summary":"","text":"","module":"context","href":"module/context.html"},{"fqn":"context::Developer","name":"Developer","kind":"person","summary":"Author of architecture models: edits `.pds` files in an IDE and runs the CLI.","text":"","module":"context","href":"module/context.html#context-Developer"},{"fqn":"context::Editor","name":"Editor","kind":"system","summary":"IDEs that speak the Language Server Protocol (VS Code, Neovim, …). The editor\nspawns `pds lsp` as a child process and drives it over stdio: it streams\ndocument changes to the server and renders the diagnostics it publishes.","text":"","module":"context","href":"module/context.html#context-Editor"},{"fqn":"context::Pseudoscript","name":"Pseudoscript","kind":"system","summary":"The PseudoScript CLI — loads a `.pds` workspace into one resolved graph and\ndocuments it as a static site, or serves the language to editors. Cross-system\ncallers couple to these published faces; the containers stay behind them.","text":"","module":"context","href":"module/context.html#context-Pseudoscript"},{"fqn":"doc","name":"doc","kind":"module","summary":"","text":"","module":"doc","href":"module/doc.html"},{"fqn":"doc::Assets","name":"Assets","kind":"component","summary":"Ships the prebuilt presentation bundles, authored in the `web/` Svelte package and\nembedded at build time (LANG.md §9.3). `style.css`, `client.js`, and\n`universe.js` ship once at the site root; `ssr.js` is build-time only — the\nengine (`Doc::Ssr`) evaluates it and it is never written to the site. The\nuniverse bundle is the only one that carries WebGL; the SSR bundle never\ndoes.","text":"","module":"doc","href":"module/doc.html#doc-Assets"},{"fqn":"doc::Call","name":"Call","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-Call"},{"fqn":"doc::Codec","name":"Codec","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-Codec"},{"fqn":"doc::Crumb","name":"Crumb","kind":"data","summary":"One breadcrumb hop: its label and href; the trailing crumb (the current\npage) carries no href.","text":"","module":"doc","href":"module/doc.html#doc-Crumb"},{"fqn":"doc::DiagnosticInput","name":"DiagnosticInput","kind":"data","summary":"One host-prepared diagnostic, positioned in its module's source: severity\nword (`error`/`warning`), the stable rule code and its principle-article URL\n(empty for plain diagnostics), the message, and the 1-based line/column with\nthe byte span. The host computes line/column once — this crate never sees\nmodule sources.","text":"","module":"doc","href":"module/doc.html#doc-DiagnosticInput"},{"fqn":"doc::Diagram","name":"Diagram","kind":"data","summary":"A diagram figure. Every view — C4, sequence, data, feature — ships as\ndeterministic server-rendered SVG, identical to `pds svg` (the client adds\npan/zoom only); `kind` is the view word (`c4`/`sequence`/`entity`/`flow`)\nthe figure exposes as its `data-diagram` hook. `Empty` marks a view that\nfailed to project.","text":"","module":"doc","href":"module/doc.html#doc-Diagram"},{"fqn":"doc::Diagrams","name":"Diagrams","kind":"component","summary":"The bridge into `emit`: project a view into a `Scene` and render it to the\nsame deterministic SVG `pds svg` emits, under the adaptive palette so the\nfigure follows the site theme. A view that fails to project degrades to an\n`Empty` placeholder rather than aborting the build — the cargo-doc stance\nthat a partial model still documents. The client adds pan/zoom around the\nfigure; it never re-lays-out.","text":"","module":"doc","href":"module/doc.html#doc-Diagrams"},{"fqn":"doc::Doc","name":"Doc","kind":"container","summary":"`crates/pseudoscript-doc`. Turns a resolved graph into a Svelte-rendered,\ncargo-doc-style site that fully represents the system: each node's `///`\ndocs and relationships on its page, every diagram as deterministic\nserver-rendered SVG, the 3D universe with its flows, the architecture-health\nreport, and a static full-text search index. Pure: returns in-memory files,\nthe CLI writes.","text":"","module":"doc","href":"module/doc.html#doc-Doc"},{"fqn":"doc::DocBody","name":"DocBody","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-DocBody"},{"fqn":"doc::DocConfig","name":"DocConfig","kind":"data","summary":"Site presentation, filled by the CLI from the `[doc]` table of `pds.toml`.\n`[doc]` tunes presentation only, never what is documented.","text":"","module":"doc","href":"module/doc.html#doc-DocConfig"},{"fqn":"doc::DocGroup","name":"DocGroup","kind":"data","summary":"One `[[doc.sidebar]]` group of authored Markdown pages: a heading and its\nordered pages, rendered above the auto-generated module tree.","text":"","module":"doc","href":"module/doc.html#doc-DocGroup"},{"fqn":"doc::DocPage","name":"DocPage","kind":"data","summary":"One authored Markdown page: its sidebar title, the source path (relative to\n`pds.toml`) from which the host and this crate derive the same stable slug,\nand the raw Markdown the host has already loaded, rendered to HTML at build\ntime. The crate reads `markdown`; `path` only names the page, never loads it.","text":"","module":"doc","href":"module/doc.html#doc-DocPage"},{"fqn":"doc::Empty","name":"Empty","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-Empty"},{"fqn":"doc::Engine","name":"Engine","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-Engine"},{"fqn":"doc::Escape","name":"Escape","kind":"component","summary":"All user text — node names, `///` docs, tags, the site title — is carried raw in\nthe props and escaped on interpolation by the renderer; this escaper guards the\nRust-owned document shell, where the title and theme become HTML attributes.","text":"","module":"doc","href":"module/doc.html#doc-Escape"},{"fqn":"doc::Health","name":"Health","kind":"component","summary":"Positions the host's diagnostics in the documentation: prepares raw\nper-module findings (line/column from sources), attributes each to the node\nwhose section it belongs on, and builds the health page and the per-section\nbadges. Attribution is positional: the node whose declaration starts\nclosest before the diagnostic's span owns it, a callable lifting to its\nowner; a span no node encloses falls back to the module page.","text":"","module":"doc","href":"module/doc.html#doc-Health"},{"fqn":"doc::HealthEntry","name":"HealthEntry","kind":"data","summary":"One architecture-health finding, attributed to the node whose section it\nbelongs on: the diagnostic fields plus the owning node's FQN and the\n(prefixed) href to its section — the module page when no node encloses the\nspan.","text":"","module":"doc","href":"module/doc.html#doc-HealthEntry"},{"fqn":"doc::HealthPage","name":"HealthPage","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-HealthPage"},{"fqn":"doc::Highlight","name":"Highlight","kind":"component","summary":"Highlights fenced code blocks at build time, so the shipped site needs no\nclient highlighter and one deterministic output serves every theme:\nPseudoScript through the toolchain's own lexer, emitting class-based spans\ncoloured by the site stylesheet. Any other language passes through escaped\nand unhighlighted — an embedded grammar set for common languages is a\ndeliberate future extension (it would bloat the IDE wasm today).","text":"","module":"doc","href":"module/doc.html#doc-Highlight"},{"fqn":"doc::IndexPage","name":"IndexPage","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-IndexPage"},{"fqn":"doc::Markdown","name":"Markdown","kind":"component","summary":"Renders an authored `[[doc.sidebar]]` page's Markdown source into the HTML that\nfills its `Doc` page body (LANG.md §9.3). The host has already loaded the\nsource into the page's `markdown`; this crate does no I/O and renders that\ncontent in memory. The rendered HTML carries through unescaped as trusted\nauthored content.","text":"","module":"doc","href":"module/doc.html#doc-Markdown"},{"fqn":"doc::MarkdownSite","name":"MarkdownSite","kind":"component","summary":"The static Markdown output mode: turns the same per-page props the HTML\nrenderer consumes into flat `.md` files, each diagram a standalone `.svg`\nasset referenced as an image. The universe page renders as text lists\n(nodes by level, edges with traffic, each flow's legs); the health page as\na table with article links. No SSR engine, no shared assets, no logo — the\nengine-free site for wikis and code hosts.","text":"","module":"doc","href":"module/doc.html#doc-MarkdownSite"},{"fqn":"doc::ModuleCard","name":"ModuleCard","kind":"data","summary":"A module card on the index: its FQN, the (prefixed) href to its page, and an\n\"N item(s)\" line.","text":"","module":"doc","href":"module/doc.html#doc-ModuleCard"},{"fqn":"doc::ModulePage","name":"ModulePage","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-ModulePage"},{"fqn":"doc::NavLink","name":"NavLink","kind":"data","summary":"One header navigation link, its href prefixed for the page's depth; `badge`\ncarries the Health page's finding count (empty elsewhere).","text":"","module":"doc","href":"module/doc.html#doc-NavLink"},{"fqn":"doc::NodeHref","name":"NodeHref","kind":"data","summary":"A universe node's documentation link: its id and the (prefixed) href to its\nsection, so clicking a sphere can navigate to the docs.","text":"","module":"doc","href":"module/doc.html#doc-NodeHref"},{"fqn":"doc::NodeSection","name":"NodeSection","kind":"data","summary":"One node's documentation section: head fields, `///` docs, tags, relationship\ngroups, scenario cards, embedded diagrams, and the health findings attributed\nto the node (rendered as inline badges).","text":"","module":"doc","href":"module/doc.html#doc-NodeSection"},{"fqn":"doc::NodeUrl","name":"NodeUrl","kind":"data","summary":"A resolved cross-reference target: the module page it lives on and its in-page\nanchor id. A cross-link uses these to build an `href`; an unresolved FQN has no\nentry and renders as plain text.","text":"","module":"doc","href":"module/doc.html#doc-NodeUrl"},{"fqn":"doc::PageBody","name":"PageBody","kind":"data","summary":"The page body: the landing index, one authored doc page, one module's page,\nthe 3D universe, or the architecture-health report.","text":"","module":"doc","href":"module/doc.html#doc-PageBody"},{"fqn":"doc::PageProps","name":"PageProps","kind":"data","summary":"The serialisable model for one page, handed to the Svelte server renderer.\nEvery derived value (resolved hrefs, anchors, edge labels, counts) is\nprecomputed here so the Svelte components do no graph logic. User text is\ncarried raw — the renderer escapes it on interpolation. `docGroups` carries\nthe authored `[[doc.sidebar]]` navigation shown above the module tree;\n`nav` carries the header links (Overview, Universe, Health with its finding\ncount); `crumbs` is the breadcrumb trail. Only the universe page's props are\nalso embedded in the document, for its 3D island — every other page ships no\npage data.","text":"","module":"doc","href":"module/doc.html#doc-PageProps"},{"fqn":"doc::Pages","name":"Pages","kind":"component","summary":"Projects the resolved graph into per-page `PageProps` — pure data, no markup.\nBuilds the index props (title, context diagram, module cards), each module page's\nnode sections, and the depth-prefixed sidebar tree mirroring the C4 hierarchy.","text":"","module":"doc","href":"module/doc.html#doc-Pages"},{"fqn":"doc::RelGroup","name":"RelGroup","kind":"data","summary":"One relationship group (\"Parent\", \"Inbound\", or \"Outbound\") and its endpoints.","text":"","module":"doc","href":"module/doc.html#doc-RelGroup"},{"fqn":"doc::RelItem","name":"RelItem","kind":"data","summary":"One relationship endpoint: the edge-kind word, whether to draw the outbound\narrow, the endpoint FQN, its resolved href (absent → plain text), and any label.","text":"","module":"doc","href":"module/doc.html#doc-RelItem"},{"fqn":"doc::Relationships","name":"Relationships","kind":"component","summary":"Renders a node's relationships (LANG.md §9.3): its `for`/owner parent, inbound\nedges, and outbound edges, skipping the structural `for`-parent edge kind. Each\nendpoint is a cross-link when its FQN resolves, plain text otherwise.","text":"","module":"doc","href":"module/doc.html#doc-Relationships"},{"fqn":"doc::RenderError","name":"RenderError","kind":"data","summary":"Why server-rendering a page failed. Every variant is a defect in the bundle, the\nengine, or the props codec — never user model data; well-formed props always\nrender.","text":"","module":"doc","href":"module/doc.html#doc-RenderError"},{"fqn":"doc::RenderedPage","name":"RenderedPage","kind":"data","summary":"The server-render result for one page: the `` contents and the\nrendered body markup, dropped into the document shell.","text":"","module":"doc","href":"module/doc.html#doc-RenderedPage"},{"fqn":"doc::ScenarioCard","name":"ScenarioCard","kind":"data","summary":"One BDD scenario card: name, `///` docs, tags, the ordered steps, and the\nfeature's flow figure (LANG.md §9.5).","text":"","module":"doc","href":"module/doc.html#doc-ScenarioCard"},{"fqn":"doc::Scenarios","name":"Scenarios","kind":"component","summary":"Renders the BDD scenario cards on a node's page: each `feature` targeting the node\nbecomes its given/when/then steps and its flow figure as a card (LANG.md §5.2,\n§9.3, §9.5). Empty when the node has no features.","text":"","module":"doc","href":"module/doc.html#doc-Scenarios"},{"fqn":"doc::SearchEntry","name":"SearchEntry","kind":"data","summary":"One record in the static full-text search index: the symbol or page's FQN,\ndisplay name, kind word, one-line summary, plain-text body, declaring\nmodule, and root-relative href. Sorted by href then FQN so the index is\ndeterministic.","text":"","module":"doc","href":"module/doc.html#doc-SearchEntry"},{"fqn":"doc::SearchIndex","name":"SearchIndex","kind":"component","summary":"Builds the static full-text search index the client palette queries: one\nrecord per linkable node, module page, and authored doc page, plus the\nuniverse and health pages. Shipped as a classic-script JS assignment\n(`search-index.js` setting a window global) so it loads under `file://` —\nnever fetched.","text":"","module":"doc","href":"module/doc.html#doc-SearchIndex"},{"fqn":"doc::SectionDiagnostic","name":"SectionDiagnostic","kind":"data","summary":"One inline badge on a node's section: the severity, rule code, article URL,\nmessage, and source line of a finding attributed to that node.","text":"","module":"doc","href":"module/doc.html#doc-SectionDiagnostic"},{"fqn":"doc::Shell","name":"Shell","kind":"component","summary":"Owns the document shell that wraps each server-rendered body — the part Rust\nrenders, not Svelte: doctype, ``, font + stylesheet links,\nthe theme pre-paint script, and the classic deferred scripts. Scripts are\nclassic (never `type=\"module\"`) and shared data ships as JS-global files, so\nthe site works opened from disk (`file://`). Only the universe page embeds\nits props (`window.__DATA__`) — for its 3D island; every other page ships no\npage data and the client only progressively enhances.","text":"","module":"doc","href":"module/doc.html#doc-Shell"},{"fqn":"doc::SidebarDocGroup","name":"SidebarDocGroup","kind":"data","summary":"One `[[doc.sidebar]]` group in the authored-doc navigation: a heading and its\npage links, shown above the module tree.","text":"","module":"doc","href":"module/doc.html#doc-SidebarDocGroup"},{"fqn":"doc::SidebarDocItem","name":"SidebarDocItem","kind":"data","summary":"One authored doc-page link in the sidebar: its title and the page href, already\nprefixed for the page's depth.","text":"","module":"doc","href":"module/doc.html#doc-SidebarDocItem"},{"fqn":"doc::SidebarModule","name":"SidebarModule","kind":"data","summary":"One sidebar entry: a module-page link and its node tree, hrefs already prefixed\nfor the page's depth.","text":"","module":"doc","href":"module/doc.html#doc-SidebarModule"},{"fqn":"doc::SidebarNode","name":"SidebarNode","kind":"data","summary":"One node in the sidebar tree, recursing into its same-module children.","text":"","module":"doc","href":"module/doc.html#doc-SidebarNode"},{"fqn":"doc::Site","name":"Site","kind":"data","summary":"The whole generated site as in-memory files, in deterministic order: the index,\none page per authored doc (`[[doc.sidebar]]`, in declaration order), then one\npage per module sorted by FQN, plus the shared assets. The doc crate does no\nI/O; the CLI writes each file under the configured output directory.","text":"","module":"doc","href":"module/doc.html#doc-Site"},{"fqn":"doc::SiteBuilder","name":"SiteBuilder","kind":"component","summary":"Orchestrates the whole site: build the URL map, project each page's props, server\nrender it through the SSR engine, wrap it in the document shell, and ship the\nshared assets plus the search index. Pure: returns in-memory `Site` files,\nwrites none.","text":"","module":"doc","href":"module/doc.html#doc-SiteBuilder"},{"fqn":"doc::SiteFile","name":"SiteFile","kind":"data","summary":"One generated file: a site-root-relative `/`-separated path (`index.html`,\n`module/banking.core.html`, `style.css`, `client.js`) and its complete contents.","text":"","module":"doc","href":"module/doc.html#doc-SiteFile"},{"fqn":"doc::SiteInfo","name":"SiteInfo","kind":"data","summary":"Site-wide presentation, identical across pages: the title, the\n`light`/`dark`/`system` theme word, the optional logo filename, and the\n`../` prefix to the site root for this page's depth.","text":"","module":"doc","href":"module/doc.html#doc-SiteInfo"},{"fqn":"doc::SiteStats","name":"SiteStats","kind":"data","summary":"The index page's stats strip: how many systems, containers, components,\nflows, and health findings the model carries.","text":"","module":"doc","href":"module/doc.html#doc-SiteStats"},{"fqn":"doc::Ssr","name":"Ssr","kind":"component","summary":"The server-side render boundary: a JSON-string-in / JSON-string-out seam to the\nJavaScript renderer. The native build embeds a `QuickJS` engine that evaluates the\nprebuilt `ssr.js` bundle (`Doc::Assets`) in-process; a wasm host implements the\nsame seam against its own JS engine. A defect here is a build-asset fault, never\nuser model data.","text":"","module":"doc","href":"module/doc.html#doc-Ssr"},{"fqn":"doc::Step","name":"Step","kind":"data","summary":"One scenario step: its keyword (given/when/then/and/but) and prose.","text":"","module":"doc","href":"module/doc.html#doc-Step"},{"fqn":"doc::Svg","name":"Svg","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-Svg"},{"fqn":"doc::Theme","name":"Theme","kind":"data","summary":"Doc-site colour scheme, written as the `data-theme` attribute on the root\n`` to select a CSS variable set. `System` (the default) follows the\nOS `prefers-color-scheme`, overridable by the in-page toggle; `Light` and\n`Dark` pin the scheme.","text":"","module":"doc","href":"module/doc.html#doc-Theme"},{"fqn":"doc::UniversePage","name":"UniversePage","kind":"data","summary":"","text":"","module":"doc","href":"module/doc.html#doc-UniversePage"},{"fqn":"doc::Urls","name":"Urls","kind":"component","summary":"Maps every node FQN to its page path and anchor, and resolves cross-references to\nmodule-page-relative `href`s. A module page is `module/.html`\n(`::` → `.`); a node is the `#` anchor within it. Only an FQN naming a real\nnode produces a link (LANG.md §9.3).","text":"","module":"doc","href":"module/doc.html#doc-Urls"},{"fqn":"dot","name":"dot","kind":"module","summary":"","text":"","module":"dot","href":"module/dot.html"},{"fqn":"dot::Box2","name":"Box2","kind":"data","summary":"An axis-aligned box: top-left corner and extent.","text":"","module":"dot","href":"module/dot.html#dot-Box2"},{"fqn":"dot::Cluster","name":"Cluster","kind":"data","summary":"A cluster (a `subgraph cluster_*`): its id, optional parent cluster, member\nnode ids, the margin kept outside its members, and the header band reserved on\nthe title side.","text":"","module":"dot","href":"module/dot.html#dot-Cluster"},{"fqn":"dot::ClusterBox","name":"ClusterBox","kind":"data","summary":"A laid-out cluster: its id and bounding box.","text":"","module":"dot","href":"module/dot.html#dot-ClusterBox"},{"fqn":"dot::Clusters","name":"Clusters","kind":"component","summary":"Cluster framing: compute each cluster's bounding box bottom-up so a nested\ncluster's box encloses its children (grown by their margins) and its direct\nmembers, with header room on the title side — `dot`'s recursive `rec_bb`.","text":"","module":"dot","href":"module/dot.html#dot-Clusters"},{"fqn":"dot::Dot","name":"Dot","kind":"container","summary":"`crates/pseudoscript-dot`. Runs the four-pass layered pipeline over a `Graph`\nto produce a `Layout`; also offers the experimental grid placer. The layout\nauthority `emit` drives for C4 diagrams.","text":"","module":"dot","href":"module/dot.html#dot-Dot"},{"fqn":"dot::Edge","name":"Edge","kind":"data","summary":"An input edge from `tail` to `head`, with its minimum rank span, its layout\nweight (higher pulls the endpoints into vertical alignment harder), and an\noptional label size that widens the rank gap to fit.","text":"","module":"dot","href":"module/dot.html#dot-Edge"},{"fqn":"dot::EdgeRoute","name":"EdgeRoute","kind":"data","summary":"A routed edge: the Bézier `spline` and its `polyline` approximation between\n`tail` and `head`, plus where its label sits.","text":"","module":"dot","href":"module/dot.html#dot-EdgeRoute"},{"fqn":"dot::Engine","name":"Engine","kind":"component","summary":"The layered engine: runs the faithful four-pass `dot` pipeline — rank, order,\nposition, splines — then frames the clusters and shifts the whole layout to\nthe origin. Deterministic and panic-free.","text":"","module":"dot","href":"module/dot.html#dot-Engine"},{"fqn":"dot::Graph","name":"Graph","kind":"data","summary":"The input graph the engine lays out: nodes, edges, clusters, the rank and node\nseparations, the rank direction, and any same-rank constraints.","text":"","module":"dot","href":"module/dot.html#dot-Graph"},{"fqn":"dot::Grid","name":"Grid","kind":"component","summary":"The experimental grid placer: an alternative to the layered pipeline that\nsnaps nodes to a grid, honouring drag-to-pin cells and searching for a\nplacement that minimises crossings, distance, and against-flow edges.","text":"","module":"dot","href":"module/dot.html#dot-Grid"},{"fqn":"dot::GridMeta","name":"GridMeta","kind":"data","summary":"Grid metadata carried back when the experimental grid placer ran: the grid\ndimensions, the cell pitch (centre-to-centre), the pixel centre of cell (0,0),\nand the width of the drag-room frame wrapping the grid — the geometry the IDE\nreads to map a drag onto a grid cell, recovering the raw cell from `origin`\nthen subtracting `pad`.","text":"","module":"dot","href":"module/dot.html#dot-GridMeta"},{"fqn":"dot::GridParams","name":"GridParams","kind":"data","summary":"Tunable weights for the experimental grid placer: how strongly it penalises\ncrossings, distance, and against-flow edges, the cell spacing, and how hard it\nsearches.","text":"","module":"dot","href":"module/dot.html#dot-GridParams"},{"fqn":"dot::Layout","name":"Layout","kind":"data","summary":"The layout result: the overall bounding box, the placed nodes, the routed\nedges, the cluster boxes, and — only when the grid placer ran — its grid\nmetadata.","text":"","module":"dot","href":"module/dot.html#dot-Layout"},{"fqn":"dot::LayoutState","name":"LayoutState","kind":"data","summary":"The structure that flows through a pipeline: the (possibly pass-mutated)\ninput graph and its current placement. A pass receives one, returns one, and\nthe framework hands it to the next pass; a re-ranking pass may edit `graph`\nand re-run the base layout.","text":"","module":"dot","href":"module/dot.html#dot-LayoutState"},{"fqn":"dot::Node","name":"Node","kind":"data","summary":"An input node: its id and its rendered size (the placer reserves this box).","text":"","module":"dot","href":"module/dot.html#dot-Node"},{"fqn":"dot::NodePos","name":"NodePos","kind":"data","summary":"A placed node: its id, centre point, and reserved size.","text":"","module":"dot","href":"module/dot.html#dot-NodePos"},{"fqn":"dot::Optimize","name":"Optimize","kind":"component","summary":"The `ShortenLongEdges` pass: a bounded, deterministic post-layout refinement.\nGreedily search for same-rank moves that reduce the sum of squared edge\nlengths (never merging across a cluster boundary), then re-lay-out with the\nimproving moves applied.","text":"","module":"dot","href":"module/dot.html#dot-Optimize"},{"fqn":"dot::Oracle","name":"Oracle","kind":"component","summary":"The test oracle: lays the same graph out with the real `dot` binary and\ncompares, so the port stays faithful rather than approximate. Skipped when\n`dot` is not installed.","text":"","module":"dot","href":"module/dot.html#dot-Oracle"},{"fqn":"dot::Order","name":"Order","kind":"component","summary":"Pass 2 — ordering: order nodes within each rank to minimise edge crossings,\ninserting virtual nodes for long edges so they route through thin lanes.","text":"","module":"dot","href":"module/dot.html#dot-Order"},{"fqn":"dot::Pass","name":"Pass","kind":"data","summary":"One stage of the composable post-layout pipeline: same structure in, same\nstructure out, so passes fold freely. `ShortenLongEdges` is the long-edge\noptimiser; `GridPlacement` wraps the grid placer so it drops into a pipeline.\nNew behaviour is added by writing a pass, not by threading flags through the\nengine.","text":"","module":"dot","href":"module/dot.html#dot-Pass"},{"fqn":"dot::Pin","name":"Pin","kind":"data","summary":"A pin fixing a node to a grid cell: the node's index into `graph.nodes` (the\ncaller resolves the FQN) at a row and column. The IDE's drag-to-pin.","text":"","module":"dot","href":"module/dot.html#dot-Pin"},{"fqn":"dot::Pipeline","name":"Pipeline","kind":"component","summary":"The composable post-layout pipeline: the base layout produces the starting\n`LayoutState`; each `Pass` folds it into the next. A pass adjusts geometry\ndirectly or edits the input graph (e.g. adds same-rank hints) and re-runs the\nbase layout.","text":"","module":"dot","href":"module/dot.html#dot-Pipeline"},{"fqn":"dot::Position","name":"Position","kind":"component","summary":"Pass 3 — positioning: assign x-coordinates by network simplex on an auxiliary\ngraph (aligning nodes and straightening long edges), and y-coordinates per\nrank stacked with `ranksep` plus any label and cluster-header room.","text":"","module":"dot","href":"module/dot.html#dot-Position"},{"fqn":"dot::Pt","name":"Pt","kind":"data","summary":"A point in layout coordinates.","text":"","module":"dot","href":"module/dot.html#dot-Pt"},{"fqn":"dot::Rank","name":"Rank","kind":"component","summary":"Pass 1 — rank assignment: give each node an integer rank by network simplex,\nbanding each cluster onto contiguous ranks and honouring same-rank constraints.","text":"","module":"dot","href":"module/dot.html#dot-Rank"},{"fqn":"dot::RankDir","name":"RankDir","kind":"data","summary":"The rank direction: top-to-bottom (the C4 default) or left-to-right.","text":"","module":"dot","href":"module/dot.html#dot-RankDir"},{"fqn":"dot::SearchMode","name":"SearchMode","kind":"data","summary":"How the experimental grid placer searches for a placement: pick automatically\nby size, always the bounded heuristic, or brute-force exhaustive (tiny graphs\nonly).","text":"","module":"dot","href":"module/dot.html#dot-SearchMode"},{"fqn":"dot::Size","name":"Size","kind":"data","summary":"A width/height extent.","text":"","module":"dot","href":"module/dot.html#dot-Size"},{"fqn":"dot::Splines","name":"Splines","kind":"component","summary":"Pass 4 — splines: route each edge as a piecewise Bézier through its\nvirtual-node corridor, clipped to the endpoint borders, with a label point at\nthe polyline midpoint.","text":"","module":"dot","href":"module/dot.html#dot-Splines"},{"fqn":"emit","name":"emit","kind":"module","summary":"","text":"","module":"emit","href":"module/emit.html"},{"fqn":"emit::BoundaryFrame","name":"BoundaryFrame","kind":"data","summary":"An enclosing frame of a boundary view: the boundary node's FQN (so the canvas\ncan drill into it), title, C4 kind (frame accent), and the cluster rectangle.","text":"","module":"emit","href":"module/emit.html#emit-BoundaryFrame"},{"fqn":"emit::C4EdgeKind","name":"C4EdgeKind","kind":"data","summary":"The relationship a routed edge expresses: a body `call`, a synthesised\n`trigger` from an initiator, or a `from` `provenance` link. Maps from\n`model::EdgeKind`, dropping the structural `for`-parent link.","text":"","module":"emit","href":"module/emit.html#emit-C4EdgeKind"},{"fqn":"emit::C4Layout","name":"C4Layout","kind":"data","summary":"A dot-placed C4 view for the interactive canvas and the static SVG: canvas\nsize, placed node cards, routed edges, the enclosing boundary frames\n(outermost first; empty for a context view), and — only under experimental\ngrid placement — the grid geometry for drag-to-pin.","text":"","module":"emit","href":"module/emit.html#emit-C4Layout"},{"fqn":"emit::C4Scene","name":"C4Scene","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-C4Scene"},{"fqn":"emit::C4Tweaks","name":"C4Tweaks","kind":"data","summary":"Per-diagram C4 layout tweaks (the UI's \"Layout\" toggles): run the long-edge\noptimiser, lay out left-to-right instead of top-to-bottom, scale the spacing,\nand — experimentally — place by brute-force grid search instead of the layered\nengine, with its own cost dials and search mode.","text":"","module":"emit","href":"module/emit.html#emit-C4Tweaks"},{"fqn":"emit::C4View","name":"C4View","kind":"data","summary":"Which C4 view a `C4Scene` is — drives the golden header keyword.","text":"","module":"emit","href":"module/emit.html#emit-C4View"},{"fqn":"emit::Component","name":"Component","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-Component"},{"fqn":"emit::Container","name":"Container","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-Container"},{"fqn":"emit::Data","name":"Data","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-Data"},{"fqn":"emit::DataEntity","name":"DataEntity","kind":"data","summary":"One entity in a `data` ER view: its FQN, label, disclosed form, rows, whether\nit is the focal type, and its laid-out card rectangle.","text":"","module":"emit","href":"module/emit.html#emit-DataEntity"},{"fqn":"emit::DataLink","name":"DataLink","kind":"data","summary":"A field-type reference link between two entities in a data view: the\nreferencing and referenced FQNs and the field driving the reference.","text":"","module":"emit","href":"module/emit.html#emit-DataLink"},{"fqn":"emit::DataScene","name":"DataScene","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-DataScene"},{"fqn":"emit::Edges","name":"Edges","kind":"component","summary":"Builds the routed-edge set for a C4 scene from the graph's edges: maps each\n`model::EdgeKind` to a `C4EdgeKind` (dropping `for`-parent links), lifts each\nendpoint to the in-view node it belongs to, drops self-loops and\nout-of-view edges, then sorts and de-duplicates.","text":"","module":"emit","href":"module/emit.html#emit-Edges"},{"fqn":"emit::Emit","name":"Emit","kind":"container","summary":"`crates/pseudoscript-emit`. Projects a view into a `Scene` and renders it to\nSVG; C4 views are placed by the `dot` layered engine, the sequence/data/feature\nviews by the matching `layout` engine.","text":"","module":"emit","href":"module/emit.html#emit-Emit"},{"fqn":"emit::EmitError","name":"EmitError","kind":"data","summary":"Why projecting a view failed: the target FQN names no node, or names a node of\nthe wrong kind for the requested view.","text":"","module":"emit","href":"module/emit.html#emit-EmitError"},{"fqn":"emit::EntityForm","name":"EntityForm","kind":"data","summary":"The disclosed form of a data entity, driving the card's eyebrow and rows: a\nrecord of typed fields, a discriminated union of variants, or a black box.","text":"","module":"emit","href":"module/emit.html#emit-EntityForm"},{"fqn":"emit::EntityRow","name":"EntityRow","kind":"data","summary":"One row of a data entity: the field or variant name, its rendered type (empty\nfor a union variant), and the FQN of the data type this row targets when it\nreferences one.","text":"","module":"emit","href":"module/emit.html#emit-EntityRow"},{"fqn":"emit::Feature","name":"Feature","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-Feature"},{"fqn":"emit::FeatureScene","name":"FeatureScene","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-FeatureScene"},{"fqn":"emit::FeatureStepNode","name":"FeatureStepNode","kind":"data","summary":"One step box in a `feature` flow view: the step keyword, its prose, and the\nlaid-out box rectangle.","text":"","module":"emit","href":"module/emit.html#emit-FeatureStepNode"},{"fqn":"emit::Frame","name":"Frame","kind":"data","summary":"A nestable frame over a body of sequence items, drawn as an enclosing box\nwith its condition label.","text":"","module":"emit","href":"module/emit.html#emit-Frame"},{"fqn":"emit::FrameItem","name":"FrameItem","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-FrameItem"},{"fqn":"emit::FrameKind","name":"FrameKind","kind":"data","summary":"The kind of a sequence frame: `if`/`else` becomes an `alt` frame, `for`/\n`while` becomes a `loop` frame.","text":"","module":"emit","href":"module/emit.html#emit-FrameKind"},{"fqn":"emit::GridInfo","name":"GridInfo","kind":"data","summary":"The grid the experimental placement used, in absolute canvas coordinates:\ncell `(r, c)` is centred at `origin + (c·cellW, r·cellH)`; `pad` is the\ndrag-room frame, so a pixel maps to its pin cell by recovering the raw cell\nthen subtracting `pad`.","text":"","module":"emit","href":"module/emit.html#emit-GridInfo"},{"fqn":"emit::GridPin","name":"GridPin","kind":"data","summary":"A node the user has pinned to a grid cell (drag-to-pin), identified by FQN;\nthe emit layer resolves it to a `dot` node index for the current view. Honoured\nonly under experimental grid placement.","text":"","module":"emit","href":"module/emit.html#emit-GridPin"},{"fqn":"emit::GridSearch","name":"GridSearch","kind":"data","summary":"Which grid search the experimental grid placer runs — the UI's\nheuristic-vs-brute-force toggle. Mirrors `dot::SearchMode` so the IDE need not\ndepend on `dot`.","text":"","module":"emit","href":"module/emit.html#emit-GridSearch"},{"fqn":"emit::LaidOutEdge","name":"LaidOutEdge","kind":"data","summary":"A routed edge for the canvas/SVG: its endpoints (`source` stands for the wire\n`from`), kind, stacked labels, the engine's polyline (at least two points),\nthe label position at the polyline midpoint when labels exist, and whether it\ndraws dashed (a `from`-provenance edge).","text":"","module":"emit","href":"module/emit.html#emit-LaidOutEdge"},{"fqn":"emit::LaidOutNode","name":"LaidOutNode","kind":"data","summary":"A node card placed by the `dot` engine for the canvas/SVG: its FQN, C4 kind\n(accent and eyebrow), display label, optional `///` summary, and rectangle.","text":"","module":"emit","href":"module/emit.html#emit-LaidOutNode"},{"fqn":"emit::Layout","name":"Layout","kind":"component","summary":"Assigns geometry. Projection stamps each C4 scene with simple row-flow\ncoordinates (`solveC4`) — the panic-proof fallback geometry every scene\ncarries. The real placement runs at render/canvas time: `layoutC4` drives the\n`dot` layered engine (rank/order/position/splines), framing boundary children\nas a cluster, tuned by per-diagram `C4Tweaks` and drag-to-pin cells. The\nsequence/data/feature scenes are placed by the matching `layout` engine.","text":"","module":"emit","href":"module/emit.html#emit-Layout"},{"fqn":"emit::Lifeline","name":"Lifeline","kind":"data","summary":"A sequence lifeline (a participant): its FQN, C4 kind for the head card, the\nnode's `///` summary shown dimmed under the name, and the structural ancestry\npath under a container/component name. No coordinate — the sequence layout\nassigns the lifeline x.","text":"","module":"emit","href":"module/emit.html#emit-Lifeline"},{"fqn":"emit::Message","name":"Message","kind":"data","summary":"A message between two lifelines (or a self-message). `label` is the method\nname, or `Ok`/`Err`/empty for a return; `detail` is the type detail shown after\nit — a call's `(params): ret` signature or a return's concrete type.","text":"","module":"emit","href":"module/emit.html#emit-Message"},{"fqn":"emit::MessageItem","name":"MessageItem","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-MessageItem"},{"fqn":"emit::MessageKind","name":"MessageKind","kind":"data","summary":"The kind of a sequence message: a `call` to another lifeline, a `return` to\nthe caller, or a `self`-message on the owner's own lifeline.","text":"","module":"emit","href":"module/emit.html#emit-MessageKind"},{"fqn":"emit::PlacedNode","name":"PlacedNode","kind":"data","summary":"A node placed in a C4 view: its FQN, C4 kind, display label, optional `///`\nsummary (the card's dimmed description), the boundary it sits inside, and the\nlayout rectangle assigned by the placer.","text":"","module":"emit","href":"module/emit.html#emit-PlacedNode"},{"fqn":"emit::PointI","name":"PointI","kind":"data","summary":"An integer point on the canvas (a rounded layout coordinate).","text":"","module":"emit","href":"module/emit.html#emit-PointI"},{"fqn":"emit::Projector","name":"Projector","kind":"component","summary":"Projects a `View` out of the graph (LANG.md §9): dispatches on the view\nvariant, collecting nodes and edges for a C4 scene or tracing a callable body\nfor a sequence scene, then hands off to the placer. Fails with `EmitError`\nwhen the view's target is missing or the wrong kind.","text":"","module":"emit","href":"module/emit.html#emit-Projector"},{"fqn":"emit::Rect","name":"Rect","kind":"data","summary":"An axis-aligned layout rectangle in renderer coordinates.","text":"","module":"emit","href":"module/emit.html#emit-Rect"},{"fqn":"emit::RoutedEdge","name":"RoutedEdge","kind":"data","summary":"An edge routed between two C4 nodes: its endpoints, kind, and the merged call\nlabels (sorted and de-duplicated; empty for a trigger or provenance edge).\nParallel calls between the same pair collapse into one multi-label edge.\n`source` is the wire field `from`, renamed because `from` is a PseudoScript\nkeyword.","text":"","module":"emit","href":"module/emit.html#emit-RoutedEdge"},{"fqn":"emit::Scene","name":"Scene","kind":"data","summary":"A laid-out diagram: the notation-neutral IR the SVG renderer consumes. A C4\nscene carries placed nodes and routed edges; a sequence scene carries\nlifelines and ordered messages with nested frames. This IR is the generation\nconformance surface (ADR-017): coordinates are carried for the renderer only,\nnever serialised to the golden.","text":"","module":"emit","href":"module/emit.html#emit-Scene"},{"fqn":"emit::SeqItem","name":"SeqItem","kind":"data","summary":"One ordered item in a sequence trace: a message or a nested frame.","text":"","module":"emit","href":"module/emit.html#emit-SeqItem"},{"fqn":"emit::Sequence","name":"Sequence","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-Sequence"},{"fqn":"emit::SequenceScene","name":"SequenceScene","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-SequenceScene"},{"fqn":"emit::SvgRenderer","name":"SvgRenderer","kind":"component","summary":"Renders a laid-out `Scene` to standalone SVG markup — string-building, no\ntemplate engine and no headless browser (LANG.md §9.3, ADR-017). Dispatches\non the scene variant; the layout engine is wrapped so no input panics the\nrender, falling back to the scene's own simple coordinates.","text":"","module":"emit","href":"module/emit.html#emit-SvgRenderer"},{"fqn":"emit::Trace","name":"Trace","kind":"component","summary":"Walks a callable's body trace into ordered sequence items, registering each\nparticipant on first appearance (LANG.md §9.2, §7). A real trigger's\ninitiator leads as the first lifeline with a synthesised inbound call;\nabsent a trigger the owner leads. A `call` is a message to the target; a\ndisclosed callee expands inline; a same-node call is a self-message that\nexpands its disclosed body inline too; a return\nmarks `Ok`/`Err`; `if`/`else` nests an `alt` frame, `for`/`while` a `loop`\nframe.","text":"","module":"emit","href":"module/emit.html#emit-Trace"},{"fqn":"emit::UnknownNode","name":"UnknownNode","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-UnknownNode"},{"fqn":"emit::View","name":"View","kind":"data","summary":"Which view to project from the graph (LANG.md §9). Context is the C1 whole;\nContainer/Component zoom into one boundary; Sequence traces one entry point;\nData draws a `data` type's entity (ER) view (§9.4); Feature draws a `feature`\nscenario's flow (§9.5).","text":"","module":"emit","href":"module/emit.html#emit-View"},{"fqn":"emit::WrongKind","name":"WrongKind","kind":"data","summary":"","text":"","module":"emit","href":"module/emit.html#emit-WrongKind"},{"fqn":"format","name":"format","kind":"module","summary":"","text":"","module":"format","href":"module/format.html"},{"fqn":"format::Format","name":"Format","kind":"container","summary":"`crates/pseudoscript-format`. The canonical formatter: parse, then\npretty-print the tree to one canonical form. The string-to-string entry the\nCLI and LSP depend on.","text":"","module":"format","href":"module/format.html#format-Format"},{"fqn":"format::FormatError","name":"FormatError","kind":"data","summary":"Why formatting failed. The only failure is unparseable input: `Parse`\ncarries the rendered error messages (one per diagnostic) for context, and\nthe caller keeps its original text.","text":"","module":"format","href":"module/format.html#format-FormatError"},{"fqn":"format::Formatter","name":"Formatter","kind":"component","summary":"Drives the headline flow: parse the source, short-circuit to\n`FormatError::Parse` if any error diagnostic surfaced, else hand the tree to\nthe printer for canonical text.","text":"","module":"format","href":"module/format.html#format-Formatter"},{"fqn":"format::Parse","name":"Parse","kind":"data","summary":"","text":"","module":"format","href":"module/format.html#format-Parse"},{"fqn":"format::Printer","name":"Printer","kind":"component","summary":"The canonical pretty-printer: walks the AST top-down, appending to a buffer,\nand emits one canonical form. Indentation is a level counter (two spaces\neach); leading trivia is normalised — blank-line runs collapse to at most one\nseparator and `//` / `/* */` comments reproduce at the current indent in\nsource order. Internals are black-boxed per construct; the top-level `print`\nflow is disclosed.","text":"","module":"format","href":"module/format.html#format-Printer"},{"fqn":"format::PrinterState","name":"PrinterState","kind":"data","summary":"The running pretty-printer state: the text buffer being built, the current\nnesting depth (two spaces each), and whether the current line has had its\nindentation written yet so further writes append in place.","text":"","module":"format","href":"module/format.html#format-PrinterState"},{"fqn":"ide","name":"ide","kind":"module","summary":"","text":"","module":"ide","href":"module/ide.html"},{"fqn":"ide::Bootstrap","name":"Bootstrap","kind":"component","summary":"Boots the IDE in a browser tab: load the one wasm bundle (IdeSession), then\nrestore the URL hash's workspace — a share link mounts in memory and needs\nno disk — or fall back to the launcher. File System Access support gates\nonly the disk features (open folder, save, watch): without it those actions\nare disabled with a notice, while share links and the bundled examples\nstill open.","text":"","module":"ide","href":"module/ide.html#ide-Bootstrap"},{"fqn":"ide::BrowserWorkspace","name":"BrowserWorkspace","kind":"data","summary":"The in-browser workspace state the session holds: the open `.pds` modules, the\n`pds.toml` manifest text, and the dependency modules resolved from\n`pds_modules/` as externals (LANG.md §8.3). Held in memory — a decoded\nsample/share link or a local directory loaded through the file-system port.\nEdits never leave the tab.","text":"","module":"ide","href":"module/ide.html#ide-BrowserWorkspace"},{"fqn":"ide::CodeMirrorAdapter","name":"CodeMirrorAdapter","kind":"component","summary":"The editor adapter over CodeMirror 6: the text/cursor model, the completion\nsource, the hover tooltip, the diagnostics gutter, and edit events forwarded\ninto the session. The only place CodeMirror specifics live — it drives the\nsession and applies the typed values it gets back.","text":"","module":"ide","href":"module/ide.html#ide-CodeMirrorAdapter"},{"fqn":"ide::Completion","name":"Completion","kind":"data","summary":"A completion candidate offered as the author types: the inserted label, the\ninteger LSP `CompletionItemKind` the editor maps to an icon, and detail text\n(absent for candidates with nothing to add).","text":"","module":"ide","href":"module/ide.html#ide-Completion"},{"fqn":"ide::DiagramCanvas","name":"DiagramCanvas","kind":"component","summary":"The diagram canvas: draws the **JSON** `Scene` interactively (Svelte Flow\npan/zoom over geometry positioned by `emit`'s layout engine for C4, a\ndepth-collapsible timeline for sequences), and exports the current view as\n**PNG or SVG**, both produced in the browser from the drawn diagram. JSON is\nthe draw format; no diagram image crosses the wasm surface. The editor\nport's diagram seam binds to this.","text":"","module":"ide","href":"module/ide.html#ide-DiagramCanvas"},{"fqn":"ide::Diagrams","name":"Diagrams","kind":"component","summary":"Diagram projection: builds the workspace graph and projects a view to the\nJSON `Scene` via `emit::Projector`; the host's canvas draws it. The wasm\nsurface carries only the JSON scene and layout — SVG and PNG are export\nconcerns of the canvas (PNG rasterised in the browser), and the static SVG\nform is a CLI/doc concern of the `emit` crate, not exposed here.","text":"","module":"ide","href":"module/ide.html#ide-Diagrams"},{"fqn":"ide::DocConfig","name":"DocConfig","kind":"data","summary":"The doc-site build input: the manifest plus each authored page's Markdown,\nloaded by the host. Field detail is the wasm boundary's concern.","text":"","module":"ide","href":"module/ide.html#ide-DocConfig"},{"fqn":"ide::Docs","name":"Docs","kind":"component","summary":"The doc-site builder: renders the whole site in-browser through the same\n`pseudoscript-doc` crate `pds doc` runs, driving SSR through a render\ncallback the host supplies (the browser's JS engine is the SSR engine) — so\nthe IDE writes the exact site the CLI ships, health page included. The site\nbuilds to the opened folder's `target/doc/` only; an in-memory workspace is\ntold to open a folder first (no blob-preview path).","text":"","module":"ide","href":"module/ide.html#ide-Docs"},{"fqn":"ide::FimClient","name":"FimClient","kind":"component","summary":"Provider-agnostic completion client: one `complete` contract over\nOpenAI-compatible HTTP, so one client covers Codestral, OpenRouter, Together,\nOllama, and vLLM. Stateless — the caller hands it the settings snapshot and\nowns cancellation (`GhostText` aborts the in-flight request on the next\nkeystroke; the client honours the abort). Every failure comes back as a\nclassified `ProviderError`, so the caller can surface why a request bailed.","text":"","module":"ide","href":"module/ide.html#ide-FimClient"},{"fqn":"ide::FimPrompt","name":"FimPrompt","kind":"data","summary":"The assembled fill-in-the-middle request: the windowed buffer text before and\nafter the caret, and the cached grammar primer that steers a general model to\nemit valid PseudoScript.","text":"","module":"ide","href":"module/ide.html#ide-FimPrompt"},{"fqn":"ide::FsAccessAdapter","name":"FsAccessAdapter","kind":"component","summary":"The file-system adapter over the browser File System Access API: directory\npicker, recursive walk for `.pds` modules, deriving each module's flat FQN\nfrom its path (LANG.md §8.1, ADR-031), `pds.lock` + `pds_modules/` reads for\ndependency externals, and per-file read/write through handles. The only place\nFS-Access specifics live; it pushes what it reads into the session via\n`mount`.","text":"","module":"ide","href":"module/ide.html#ide-FsAccessAdapter"},{"fqn":"ide::GhostText","name":"GhostText","kind":"component","summary":"Inline ghost-text completion over CodeMirror 6, beside the grammar dropdown:\nstructural candidates stay local and deterministic in `CodeMirrorAdapter`;\nthe remote model supplies only multi-token greyed text. CodeMirror has no\nnative inline-suggestion UI, so this is a custom view plugin rendering a\nwidget decoration at the caret — Tab accepts, Esc dismisses, any edit clears.","text":"","module":"ide","href":"module/ide.html#ide-GhostText"},{"fqn":"ide::GridPin","name":"GridPin","kind":"data","summary":"A node the user has dragged onto a grid cell, identified by FQN. Carried inside\n`LayoutTweaks`; honoured only under experimental grid placement.","text":"","module":"ide","href":"module/ide.html#ide-GridPin"},{"fqn":"ide::IdeSession","name":"IdeSession","kind":"container","summary":"`crates/pseudoscript-ide` — the IDE application, Rust compiled to a single\nwasm. It owns the workspace state and is the whole browser API: the host\npushes modules in (`mount`/`setSource`) and pulls every answer out as a\ntyped value — the session never calls the DOM, CodeMirror, or the File\nSystem Access API. It delegates language intelligence to `lsp_core` and\n`model::Checks`, diagrams to `emit::Projector`, the 3D universe to\n`universe::Adapter`, and the doc site to `doc::SiteBuilder` — each a Rust\nlibrary linked in, never a separate wasm. The one outbound seam is the doc\nbuild's SSR render callback the host supplies. Everything here is Rust.","text":"","module":"ide","href":"module/ide.html#ide-IdeSession"},{"fqn":"ide::LanguageSession","name":"LanguageSession","kind":"component","summary":"The language session: diagnostics, completion, hover, go-to, references,\nrename, outline, folding, and semantic tokens over the held workspace, every\nanswer delegated to the pure toolchain logic (`model::Checks` for diagnostics,\n`lsp_core` for cursor features) with the dependency externals bound. Every\nanswer is a typed value the host applies — the session pushes nothing at the\neditor.","text":"","module":"ide","href":"module/ide.html#ide-LanguageSession"},{"fqn":"ide::Launcher","name":"Launcher","kind":"component","summary":"The project launcher — the first surface. Offers the recents, open-a-folder,\nNew Project, and the bundled examples. Examples and share links mount in\nmemory and need no disk; only the disk actions gate on File System Access\nsupport. Dismissible, so the menus, help, and settings stay reachable\nwithout a project.","text":"","module":"ide","href":"module/ide.html#ide-Launcher"},{"fqn":"ide::LayoutTweaks","name":"LayoutTweaks","kind":"data","summary":"The IDE's per-diagram C4 layout toggles, crossing to JS as a typed object: run\nthe long-edge optimiser, the reading `orientation` (`\"tb\"`/`\"lr\"`), a `spacing`\npreset (`\"compact\"`/`\"comfortable\"`/`\"roomy\"`), and the experimental grid dials\nand pins. Translated to `emit::C4Tweaks` inside the session.","text":"","module":"ide","href":"module/ide.html#ide-LayoutTweaks"},{"fqn":"ide::LlmProvider","name":"LlmProvider","kind":"system","summary":"The author's configured OpenAI-compatible completion provider — hosted\n(OpenAI, Codestral, OpenRouter, Together) or local (Ollama, vLLM). External:\nthe IDE only speaks its HTTP API; transport and HTTP failures surface as\nclassified `ProviderError`s.","text":"","module":"ide","href":"module/ide.html#ide-LlmProvider"},{"fqn":"ide::LlmSettings","name":"LlmSettings","kind":"data","summary":"The author's AI-completion provider settings, persisted in the browser: the\nfeature toggle, the chosen preset (`\"ollama\"`, `\"openai\"`, or `\"custom\"` —\nthe presets pin the endpoint and wire shape so setup is pick-and-go), the\nOpenAI-compatible endpoint, the bring-your-own API key (stored in\nlocalStorage, sent only to the configured endpoint), the model id, and the\nwire shape (`\"fim\"` for a native fill-in-the-middle route, `\"chat\"` for the\nchat-completions fallback).","text":"","module":"ide","href":"module/ide.html#ide-LlmSettings"},{"fqn":"ide::LlmSettingsStore","name":"LlmSettingsStore","kind":"component","summary":"The author's AI-completion settings, persisted to browser localStorage and\nedited through the Settings dialog's \"AI Completion\" tab. Bring-your-own key:\nit never leaves the tab except on requests to the configured endpoint.\nSetup is preset-first: picking a provider applies its pinned endpoint and\nwire shape, so only the Custom preset exposes the raw fields. The store also\ncarries the session's last completion failure (never persisted) so the\nstatus chip and the settings tab can show why ghost text is bailing.","text":"","module":"ide","href":"module/ide.html#ide-LlmSettingsStore"},{"fqn":"ide::LocalInput","name":"LocalInput","kind":"data","summary":"One local-source dependency file the host reads for `dependencyModules`: the\ndependency name (ADR-026), its FQN within the dependency workspace, and its\nsource.","text":"","module":"ide","href":"module/ide.html#ide-LocalInput"},{"fqn":"ide::Occurrence","name":"Occurrence","kind":"data","summary":"One occurrence of a symbol: the module it lies in, its line/column span, the\nsource line text with the match offsets within it, and whether it is the\ndeclaration site.","text":"","module":"ide","href":"module/ide.html#ide-Occurrence"},{"fqn":"ide::OutlineNode","name":"OutlineNode","kind":"data","summary":"One row of the workspace outline: a node's FQN, simple name, C4 kind,\ncontainment parent (absent on roots), whether it is a triggered flow entry,\nits `///` summary (absent when undocumented), and its declaration line/column.","text":"","module":"ide","href":"module/ide.html#ide-OutlineNode"},{"fqn":"ide::PickError","name":"PickError","kind":"data","summary":"Why a folder pick yielded no workspace: the picker failed — the API missing,\nblocked by permission policy, or denied by the embedder. Distinct from a\nuser cancel, which is silent: a cancel is the user's choice, a failure is\nthe product's to explain.","text":"","module":"ide","href":"module/ide.html#ide-PickError"},{"fqn":"ide::ProviderError","name":"ProviderError","kind":"data","summary":"A classified completion-provider failure: `kind` is `\"network\"` (endpoint\nunreachable or CORS-blocked), `\"auth\"` (401/403), `\"notFound\"` (404 route or\nmodel), `\"timeout\"`, or `\"http\"` (any other non-OK status); `message` states\nwhat failed and `hint` names the fix for the configured provider (e.g. the\n`OLLAMA_ORIGINS` command for a CORS-blocked local Ollama).","text":"","module":"ide","href":"module/ide.html#ide-ProviderError"},{"fqn":"ide::References","name":"References","kind":"data","summary":"The find-references result for the symbol under the caret: the symbol's FQN, a\nhuman title, and every occurrence across the workspace.","text":"","module":"ide","href":"module/ide.html#ide-References"},{"fqn":"ide::RenameSelection","name":"RenameSelection","kind":"data","summary":"One occurrence the user chose to rename, keyed by the module FQN and the\n1-based line/column an `ide::Occurrence` reported. The rename rewrites only\nthe selected occurrences, not every match.","text":"","module":"ide","href":"module/ide.html#ide-RenameSelection"},{"fqn":"ide::RenamedSource","name":"RenamedSource","kind":"data","summary":"One module rewritten by a rename: its FQN and new source text.","text":"","module":"ide","href":"module/ide.html#ide-RenamedSource"},{"fqn":"ide::RenderedFile","name":"RenderedFile","kind":"data","summary":"One file of the rendered documentation site: its site-relative path and\ncontents.","text":"","module":"ide","href":"module/ide.html#ide-RenderedFile"},{"fqn":"ide::Samples","name":"Samples","kind":"component","summary":"The bundled example catalogue, discovered at build time from the samples\nfolder (one folder per example: meta.json, the `.pds` modules, `pds.toml`,\ndoc pages). Each entry doubles as a New-project template and as an\nin-memory workspace.","text":"","module":"ide","href":"module/ide.html#ide-Samples"},{"fqn":"ide::Universe","name":"Universe","kind":"component","summary":"The 3D universe: builds the software graph from the held workspace and flattens\nit to a snapshot the `ForceGraph` renders, with the entry-point flows traced\nin Rust. Delegates to the `universe` crate; the wasm surface carries only the\nflat snapshot and flows — positions are the renderer's.","text":"","module":"ide","href":"module/ide.html#ide-Universe"},{"fqn":"ide::UniverseEdge","name":"UniverseEdge","kind":"data","summary":"One directed relationship in the 3D graph, weighted by traffic (call count).\nThe wire field is `from`; `from` is a PseudoScript keyword, so the model\nnames it `source`.","text":"","module":"ide","href":"module/ide.html#ide-UniverseEdge"},{"fqn":"ide::UniverseNode","name":"UniverseNode","kind":"data","summary":"One node in the 3D relationship graph the IDE draws: its FQN, C4 level, and\ncontainment parent (absent on roots). The typed boundary form of a\n`universe::NodeOut`.","text":"","module":"ide","href":"module/ide.html#ide-UniverseNode"},{"fqn":"ide::UniverseSnapshot","name":"UniverseSnapshot","kind":"data","summary":"The 3D-view snapshot the session hands the `ForceGraph`: nodes and directed\nweighted edges, no positions (the renderer lays them out). The typed boundary\nform of a `universe::Snapshot`.","text":"","module":"ide","href":"module/ide.html#ide-UniverseSnapshot"},{"fqn":"ide::VendoredInput","name":"VendoredInput","kind":"data","summary":"One vendored git-dependency file the host reads for `dependencyModules`: its\n`pds_modules/` slug, its FQN within the dependency workspace (the host's\npath→FQN derivation, LANG.md §8.1), and its source.","text":"","module":"ide","href":"module/ide.html#ide-VendoredInput"},{"fqn":"ide::WebIde","name":"WebIde","kind":"container","summary":"`web-ide` — the IDE at `ide.pdscript.dev`: a SvelteKit shell on Cloudflare\nWorkers static assets. Pure glue — it loads the one wasm bundle and binds the\nadapters to the session's ports. It holds no language logic.","text":"","module":"ide","href":"module/ide.html#ide-WebIde"},{"fqn":"ide::Workspace","name":"Workspace","kind":"component","summary":"The in-memory project the session holds: the parsed modules keyed by FQN (an\nopen buffer overlays via `setSource`), the dependency externals, and the\nmemoised resolved workspace + graph — invalidated by any mutation, rebuilt\nonce for the query burst between keystrokes. Edits never leave the tab; an\nexplicit save writes through the host's file handles, not this session.","text":"","module":"ide","href":"module/ide.html#ide-Workspace"},{"fqn":"landing","name":"landing","kind":"module","summary":"","text":"","module":"landing","href":"module/landing.html"},{"fqn":"landing::Landing","name":"Landing","kind":"container","summary":"`web-landing` — the marketing site at `pdscript.dev`. A static Svelte build on\nCloudflare Workers static assets; no backend. It routes a visitor to one of\nthree surfaces and otherwise just tells the model-driven story.","text":"","module":"landing","href":"module/landing.html#landing-Landing"},{"fqn":"landing::Visitor","name":"Visitor","kind":"person","summary":"A prospective user reading the landing page.","text":"","module":"landing","href":"module/landing.html#landing-Visitor"},{"fqn":"layout","name":"layout","kind":"module","summary":"","text":"","module":"layout","href":"module/layout.html"},{"fqn":"layout::Activation","name":"Activation","kind":"data","summary":"An execution-activation bar on a lifeline, spanning a participant's first-to-\nlast involvement; `owner` marks the entry's focus lifeline.","text":"","module":"layout","href":"module/layout.html#layout-Activation"},{"fqn":"layout::Core","name":"Core","kind":"component","summary":"The shared geometry/text core: measures label and title widths, wraps\ndescriptions to a width, and accumulates bounding boxes. Every engine builds\non it, so text sizing and bounds math live in exactly one place.","text":"","module":"layout","href":"module/layout.html#layout-Core"},{"fqn":"layout::Diagram","name":"Diagram","kind":"data","summary":"A structural sequence diagram: the participants (lifelines) and the ordered\nitems — messages and nested fragments — traced down them. The sequence\nengine's input.","text":"","module":"layout","href":"module/layout.html#layout-Diagram"},{"fqn":"layout::Divider","name":"Divider","kind":"data","summary":"A horizontal split between two fragment sections: its y and the following\nsection's guard.","text":"","module":"layout","href":"module/layout.html#layout-Divider"},{"fqn":"layout::FragKind","name":"FragKind","kind":"data","summary":"The kind of a fragment frame: an `alt` (if/else) or a `loop` (for/while).","text":"","module":"layout","href":"module/layout.html#layout-FragKind"},{"fqn":"layout::Fragment","name":"Fragment","kind":"data","summary":"A nestable fragment over a body of items, drawn as an enclosing frame: its\nkind and the labelled sections it splits into (an `alt` has several).","text":"","module":"layout","href":"module/layout.html#layout-Fragment"},{"fqn":"layout::FragmentItem","name":"FragmentItem","kind":"data","summary":"","text":"","module":"layout","href":"module/layout.html#layout-FragmentItem"},{"fqn":"layout::Item","name":"Item","kind":"data","summary":"One ordered item down the lifelines: a message or a nested fragment.","text":"","module":"layout","href":"module/layout.html#layout-Item"},{"fqn":"layout::Layout","name":"Layout","kind":"container","summary":"`crates/pseudoscript-layout`. The geometry/text `Core` and the sequence\nengine, each built on the `Projection` contract — turn a structural input\ninto a positioned output under tunable metrics. The sequence engine is the\nonly one implemented here: C4 placement is delegated to `dot` (the layered\nengine), which `emit` drives directly; a flowchart engine is a planned\nextension point on the same core, not yet built.","text":"","module":"layout","href":"module/layout.html#layout-Layout"},{"fqn":"layout::Message","name":"Message","kind":"data","summary":"A message between two lifelines: its source and target ids (equal for a\nself-message), kind, primary label (method name or return marker), and the\ndimmed detail after it (a call signature or return type). `source` is the\nwire field `from`, renamed because `from` is a PseudoScript keyword.","text":"","module":"layout","href":"module/layout.html#layout-Message"},{"fqn":"layout::MessageItem","name":"MessageItem","kind":"data","summary":"","text":"","module":"layout","href":"module/layout.html#layout-MessageItem"},{"fqn":"layout::Metrics","name":"Metrics","kind":"data","summary":"Tunable spacing and font metrics for the sequence engine — head-card sizing,\nrow advance per message kind, fragment padding. Field detail is the engine's\nconcern; the defaults are the one source of truth consumers start from.","text":"","module":"layout","href":"module/layout.html#layout-Metrics"},{"fqn":"layout::MsgKind","name":"MsgKind","kind":"data","summary":"The kind of a sequence message: a call to another lifeline, a return to the\ncaller, or a self-message on the sender's own lifeline.","text":"","module":"layout","href":"module/layout.html#layout-MsgKind"},{"fqn":"layout::Participant","name":"Participant","kind":"data","summary":"One lifeline: its id (FQN), display label, C4 kind for the head card, optional\nsummary, and the ancestry path shown under the name for container/component\nlifelines.","text":"","module":"layout","href":"module/layout.html#layout-Participant"},{"fqn":"layout::PlacedFragment","name":"PlacedFragment","kind":"data","summary":"A placed fragment frame: its box, the operator-tab label (the first section's\nguard), and the dividers splitting later sections.","text":"","module":"layout","href":"module/layout.html#layout-PlacedFragment"},{"fqn":"layout::PlacedMessage","name":"PlacedMessage","kind":"data","summary":"A placed message: its kind, source/target ids, endpoint x-positions, row y,\ndirection (+1 left-to-right, -1 right-to-left), reading-order step, label, and\ndetail.","text":"","module":"layout","href":"module/layout.html#layout-PlacedMessage"},{"fqn":"layout::PlacedParticipant","name":"PlacedParticipant","kind":"data","summary":"A placed lifeline: its id, label, kind, ancestry path, wrapped summary lines,\nhead-card rectangle, the lifeline's centre x, and the y span of its dashed\nline.","text":"","module":"layout","href":"module/layout.html#layout-PlacedParticipant"},{"fqn":"layout::Point","name":"Point","kind":"data","summary":"A point in renderer coordinates.","text":"","module":"layout","href":"module/layout.html#layout-Point"},{"fqn":"layout::Rect","name":"Rect","kind":"data","summary":"An axis-aligned rectangle: its top-left corner and extent.","text":"","module":"layout","href":"module/layout.html#layout-Rect"},{"fqn":"layout::Section","name":"Section","kind":"data","summary":"One compartment of a fragment: its guard label (shown in the operator tab or\nbeside a divider) over a body of items.","text":"","module":"layout","href":"module/layout.html#layout-Section"},{"fqn":"layout::Sequence","name":"Sequence","kind":"component","summary":"The sequence engine: lays a structural `Diagram` out into a `SequenceLayout` —\nlifeline x-positions in first-appearance order, message rows stacked by\nevaluation order, and fragment frames sized to their bodies. The only engine\nimplemented in this crate; C4 placement is `dot`'s job (`emit` drives it), and\na flowchart engine would follow the same `Projection` contract.","text":"","module":"layout","href":"module/layout.html#layout-Sequence"},{"fqn":"layout::SequenceLayout","name":"SequenceLayout","kind":"data","summary":"A laid-out sequence diagram: the canvas size plus every participant, message,\nactivation bar, and fragment placed at absolute coordinates the renderer draws\nverbatim. The sequence engine's output.","text":"","module":"layout","href":"module/layout.html#layout-SequenceLayout"},{"fqn":"layout::Size","name":"Size","kind":"data","summary":"A width/height extent.","text":"","module":"layout","href":"module/layout.html#layout-Size"},{"fqn":"lsp","name":"lsp","kind":"module","summary":"","text":"","module":"lsp","href":"module/lsp.html"},{"fqn":"lsp::DefTarget","name":"DefTarget","kind":"data","summary":"A go-to-definition target straight from `lsp_core`: the FQN of the module the\ndefinition lives in, and its span within that module's source. The server maps\n`fqn` to a file URI — the target file, not the file the request came from.","text":"","module":"lsp","href":"module/lsp.html#lsp-DefTarget"},{"fqn":"lsp::Lsp","name":"Lsp","kind":"container","summary":"`crates/pseudoscript-lsp`. The stdio language server (tower-lsp): workspace\ndiagnostics on change, and hover, definition, completion, references, rename,\nsemantic tokens, symbols, folding, and formatting — every language answer\ndelegated to `lsp_core`. Owns the transport, the document store, and the\nURI↔FQN mapping, nothing more.","text":"","module":"lsp","href":"module/lsp.html#lsp-Lsp"},{"fqn":"lsp::Occurrence","name":"Occurrence","kind":"data","summary":"One resolved editor location: the file URI a target FQN maps back to, and the\nrange within it. The server's transport-level mapping of a `lsp_core` answer.","text":"","module":"lsp","href":"module/lsp.html#lsp-Occurrence"},{"fqn":"lsp::OpenDocument","name":"OpenDocument","kind":"data","summary":"One open editor buffer: its document URI, current source text, and the\neditor's version counter. The buffer overlays on-disk text until closed.","text":"","module":"lsp","href":"module/lsp.html#lsp-OpenDocument"},{"fqn":"lsp::Server","name":"Server","kind":"component","summary":"The tower-lsp `Backend`: owns the stdio transport, the document store, the\nserver lifecycle, and request routing. Holds no language logic — it locks the\nstore, hands the active text and the resolved workspace to a `lsp_core`\nhandler, and maps the result back to file locations.","text":"","module":"lsp","href":"module/lsp.html#lsp-Server"},{"fqn":"lsp::Store","name":"Store","kind":"component","summary":"The workspace document store: the server's own filesystem edge. Discovers the\nproject root (`pds.toml`, §8.1) by walking up from the opened URI, walks the\ntree for every visible `.pds` file, derives each module's FQN from its path,\nand overlays open buffers on disk text. Caches each parse and memoises the\nresolved `model::Workspace` — built from the local parses with the workspace's\ndirect-dependency externals bound (§8.3) — both invalidated on any edit. The\nexternals are cached separately and reload only on a dependency change.","text":"","module":"lsp","href":"module/lsp.html#lsp-Store"},{"fqn":"lsp_core","name":"lsp_core","kind":"module","summary":"","text":"","module":"lsp_core","href":"module/lsp_core.html"},{"fqn":"lsp_core::Analysis","name":"Analysis","kind":"component","summary":"Document-level analysis: parse-and-check diagnostics, Markdown hover for the\nsymbol under the caret (falling back to an inferred type), go-to-definition,\ninlay hints, and the canonical format edit. Resolution is delegated to\n`model`; this maps the result into LSP shapes.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Analysis"},{"fqn":"lsp_core::Complete","name":"Complete","kind":"component","summary":"Completion: the candidates offered at a byte offset, resolved across the\nworkspace and its externals. A `.`/`::` boundary drives member and path\ncompletion.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Complete"},{"fqn":"lsp_core::CompletionItem","name":"CompletionItem","kind":"data","summary":"One completion candidate: the inserted label, the integer LSP\n`CompletionItemKind`, and detail text.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-CompletionItem"},{"fqn":"lsp_core::Convert","name":"Convert","kind":"component","summary":"Position conversion: the single home for mapping between byte offsets and\nUTF-16 line/character positions, so every handler agrees on coordinates.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Convert"},{"fqn":"lsp_core::DefTarget","name":"DefTarget","kind":"data","summary":"A go-to-definition target: the FQN of the module the definition lives in and\nthe byte span of the definition within that module's source. The consuming\nedge maps `fqn` to a file URI and converts `span` to an editor range against\n*that* file's text — `lsp_core` returns the byte span, not a `Range`, because\nit does not hold the target module's source to convert against.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-DefTarget"},{"fqn":"lsp_core::Diagnostic","name":"Diagnostic","kind":"data","summary":"One diagnostic mapped to LSP shape: its range, severity, message, optional\ncode, and the code's article URL (`codeDescription`, the editor's clickable\nlink — empty when the code carries no article). Converted from the\nparser/checker's byte-span diagnostics; the code and its URL pass through\nunchanged.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Diagnostic"},{"fqn":"lsp_core::Hover","name":"Hover","kind":"data","summary":"Markdown hover content the editor renders in a tooltip.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Hover"},{"fqn":"lsp_core::LspCore","name":"LspCore","kind":"container","summary":"`crates/pseudoscript-lsp-core`. The single home for language intelligence as\ntransport-neutral handlers — the same logic the stdio server and the browser\nwasm both call.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-LspCore"},{"fqn":"lsp_core::Position","name":"Position","kind":"data","summary":"A zero-based caret position: line and UTF-16 character offset within the\nline. This and the shapes below model the standalone `lsp_types` vocabulary\nthe crate returns (pinned to the version tower-lsp re-exports, wasm-safe),\nso the server edge passes values through with no conversion.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Position"},{"fqn":"lsp_core::Range","name":"Range","kind":"data","summary":"A half-open text range between two positions.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Range"},{"fqn":"lsp_core::Refs","name":"Refs","kind":"component","summary":"References and rename: every occurrence of the symbol under the caret across\nthe workspace, the document highlights for it, and the workspace-wide rename\nedits.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Refs"},{"fqn":"lsp_core::Semantic","name":"Semantic","kind":"component","summary":"Semantic tokens: AST-aware highlighting that colours each token by its\ndeclared role, plus the legend the editor binds.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Semantic"},{"fqn":"lsp_core::Symbols","name":"Symbols","kind":"component","summary":"Document and workspace structure: the outline symbols, the foldable ranges,\nand the workspace-wide symbol query.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-Symbols"},{"fqn":"lsp_core::TextEdit","name":"TextEdit","kind":"data","summary":"A text edit: replace `range` with `newText`. Formatting and rename return\nthese.","text":"","module":"lsp_core","href":"module/lsp_core.html#lsp-core-TextEdit"},{"fqn":"model","name":"model","kind":"module","summary":"","text":"","module":"model","href":"module/model.html"},{"fqn":"model::Alt","name":"Alt","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Alt"},{"fqn":"model::ArchRule","name":"ArchRule","kind":"data","summary":"One architectural-principle lint rule (LANG.md §9 — the C4 facade/boundary\nprinciples). `code` is its stable identifier (`PDS-ARCH-001`); `slug` is the\nfilename of the article documenting it under the published principles base\nURL. Every firing is a `Warning` — a violation advises rather than\ninvalidates — so the rule carries no severity of its own.","text":"","module":"model","href":"module/model.html#model-ArchRule"},{"fqn":"model::Architecture","name":"Architecture","kind":"component","summary":"LANG.md §9 — architectural-principle lints over the resolved graph. Beyond §8.2\nvisibility (which a `public` component still satisfies), these advise on C4\nstructure: a cross-module call SHOULD reach a container/system's published face,\nnot an internal `component` (Facade/Gateway); the module dependency graph SHOULD\nstay acyclic; a cross-system call SHOULD couple to the other system's boundary,\nnot its containers. Each firing is a `Warning` stamped with the rule's `code`\nand `codeDescription` (its article URL); the model stays valid.","text":"","module":"model","href":"module/model.html#model-Architecture"},{"fqn":"model::Branch","name":"Branch","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Branch"},{"fqn":"model::Builder","name":"Builder","kind":"component","summary":"Projects the parsed, resolved workspace into the architecture graph: structural\nnodes plus edges from `for` parents, body calls, triggers, and `from`\nprovenance, with a sequence trace recorded per disclosed body. A pure\nprojection — no I/O — so the emit crate and a future salsa/LSP layer can both\nadopt it.","text":"","module":"model","href":"module/model.html#model-Builder"},{"fqn":"model::Call","name":"Call","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Call"},{"fqn":"model::CaretResolve","name":"CaretResolve","kind":"component","summary":"Caret resolution — the engine every cursor feature shares (`lsp_core` hover,\ndefinition, references, rename; the IDE's symbol actions). Tokenizes the\nactive source, finds the identifier under the offset, and resolves it across\nthe workspace and its externals: a node or data FQN, a same-node call or member access,\nor a local reference. Token-level, so it survives a partial parse.","text":"","module":"model","href":"module/model.html#model-CaretResolve"},{"fqn":"model::Checks","name":"Checks","kind":"component","summary":"Static analysis (LANG.md §2.2, §2.3, §2.4, §3.3, §3.4, §3.5, §4, §5.1, §5.2, §6,\n§7, §8): builds the symbol tables, then runs the well-formedness checks. Every\nentry returns a `syntax::Diagnostic[]`; well-formed input yields an empty one.\nChecks are conservative — each rule fires only when the violation is certain.","text":"","module":"model","href":"module/model.html#model-Checks"},{"fqn":"model::Commit","name":"Commit","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Commit"},{"fqn":"model::Completion","name":"Completion","kind":"component","summary":"Context-aware completion (the model-native producer `lsp_core` maps to LSP\nitems): candidates at a caret offset resolved across the workspace and its\nexternals — members after `.`, a module's public symbols after `::`, the\nbuilt-in macros after `#[`, types in type position, else keywords and symbols.","text":"","module":"model","href":"module/model.html#model-Completion"},{"fqn":"model::ConstantType","name":"ConstantType","kind":"data","summary":"One `constant`'s FQN paired with its declared primitive type name (§3.6,\nADR-039), so inference resolves a `module::NAME` reference to its type.","text":"","module":"model","href":"module/model.html#model-ConstantType"},{"fqn":"model::CrossModule","name":"CrossModule","kind":"component","summary":"§8.2 — cross-module visibility resolution. Walks each module's qualified\nreferences — `for` parents, type annotations (field, parameter, return, and\ngeneric-argument types), feature targets, body call targets, value-position\nunion-variant references, and the member named after a call target's FQN — and\nagainst the global FQN index enforces: a reference from module A to a node in\nmodule B resolves only if that node is `public`. A private target or a dangling\ncross-module FQN is a diagnostic. Same-module references are the single-module\nchecks' business and are skipped here.","text":"","module":"model","href":"module/model.html#model-CrossModule"},{"fqn":"model::DataField","name":"DataField","kind":"data","summary":"One field of a `data` record or union-variant record: its name and rendered\ntype.","text":"","module":"model","href":"module/model.html#model-DataField"},{"fqn":"model::DataShape","name":"DataShape","kind":"data","summary":"The disclosed shape of a `data` node (§3.4, §3.5): a record of fields, a\ndiscriminated union of variants, or an undisclosed black box. Carried on a\n`data` `GraphNode` so the entity (ER) view draws the rows without re-reading\nsource.","text":"","module":"model","href":"module/model.html#model-DataShape"},{"fqn":"model::DataVariant","name":"DataVariant","kind":"data","summary":"One variant of a `data` union (§3.5): its name and, for a record variant, its\nfields.","text":"","module":"model","href":"module/model.html#model-DataVariant"},{"fqn":"model::DepError","name":"DepError","kind":"data","summary":"Why parsing a manifest's `[dependencies]` table or a `pds.lock` failed: the\noffending entry and a human-readable message. Malformed TOML, an unknown key,\nor more than one of tag/rev/branch on one dependency (§8.3).","text":"","module":"model","href":"module/model.html#model-DepError"},{"fqn":"model::DepFile","name":"DepFile","kind":"data","summary":"One dependency module's in-memory form: its FQN *within* the dependency\nworkspace (path relative to that workspace root) and its source. The resolver\nprefixes it with the dependency name.","text":"","module":"model","href":"module/model.html#model-DepFile"},{"fqn":"model::DepSpec","name":"DepSpec","kind":"data","summary":"A `[dependencies]` entry as written in `pds.toml` (§8.3): a git URL with at\nmost one of tag/rev/branch and an in-repo sub-path, or a local sibling path.\nEmpty strings stand for the absent options.","text":"","module":"model","href":"module/model.html#model-DepSpec"},{"fqn":"model::Deps","name":"Deps","kind":"component","summary":"§8.3 — the dependency resolver. Parses a manifest's `[dependencies]` and a\n`pds.lock`, then maps each direct dependency to its dependency-name-prefixed\nmodules — the externals the checker binds for cross-workspace resolution. The\nsingle source of the slug→name→`dep::module` mapping, shared by the native\nloader (`project`) and the WASM bridge (`ide`). Pure: fetching and disk are\nthe caller's job.","text":"","module":"model","href":"module/model.html#model-Deps"},{"fqn":"model::Edge","name":"Edge","kind":"data","summary":"A typed, directed relationship between two graph node FQNs. `source` is the\nwire field `from` — `from` is a PseudoScript keyword, so the model renames\nit. Either endpoint may name a node not present as a `GraphNode` — a\nsynthesised trigger initiator, or a target that does not resolve. `label` is\nthe method name for `Call`, otherwise empty. `span` is the source range that\nproduced the edge — the call site for a `Call` — so an architectural lint can\npoint its diagnostic at the offending call; the empty span when the edge is\nsynthesised.","text":"","module":"model","href":"module/model.html#model-Edge"},{"fqn":"model::EdgeKind","name":"EdgeKind","kind":"data","summary":"What relationship a graph edge expresses (LANG.md §9.1): a `for` parent link,\na body call (label = method), a synthesised trigger initiator edge, or a\n`from` provenance link.","text":"","module":"model","href":"module/model.html#model-EdgeKind"},{"fqn":"model::FeatureCheck","name":"FeatureCheck","kind":"component","summary":"§5.2 / §8.1 — feature checks. A feature's `for` target MUST resolve to a node,\nnot a type or module; a target this single-module model cannot see is left to\ncross-module resolution. Feature names occupy their own module namespace, so a\nrepeated name is a collision (checked once per module).","text":"","module":"model","href":"module/model.html#model-FeatureCheck"},{"fqn":"model::FieldlessVariants","name":"FieldlessVariants","kind":"data","summary":"A union's fieldless variant names, keyed by the union's bare name (§3.5).\nFieldless variants do not hoist a symbol — they are addressed\n`module::Union::Variant` (ADR-032) — so they index under their union.","text":"","module":"model","href":"module/model.html#model-FieldlessVariants"},{"fqn":"model::Folding","name":"Folding","kind":"component","summary":"The foldable regions of a module: every multi-line disclosed declaration and\nstatement block, and doc-comment runs.","text":"","module":"model","href":"module/model.html#model-Folding"},{"fqn":"model::Git","name":"Git","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Git"},{"fqn":"model::Graph","name":"Graph","kind":"data","summary":"The resolved architecture graph: every node and typed edge across all C4\nlevels, plus feature scenarios. The single source every view projects from —\nenough to extract any view without re-reading source. Per-callable sequence\ntraces (`Step[]`) are held alongside, keyed by the owning callable's FQN.","text":"","module":"model","href":"module/model.html#model-Graph"},{"fqn":"model::GraphNode","name":"GraphNode","kind":"data","summary":"One node in the resolved graph — a structural declaration, a `data` type, or a\ncallable. Carries its FQN, simple name, kind, enclosing-node FQN (`for` parent,\nowning node, or empty at top level), declaring module, visibility, name span,\nany trigger macros (callables only), the call signature (callables only), the\ndisclosed shape (`data` only), and lifted `///` documentation.","text":"","module":"model","href":"module/model.html#model-GraphNode"},{"fqn":"model::Inference","name":"Inference","kind":"component","summary":"Local-binding type inference, for inlay hints and hover. Assignments are\nuntyped (`x = expr`); this infers each binding's type from its right-hand side\n— a call's return type, a field access, a `from` expression, or a literal.\nBest-effort: an un-typeable expression yields nothing rather than a guess.","text":"","module":"model","href":"module/model.html#model-Inference"},{"fqn":"model::Local","name":"Local","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Local"},{"fqn":"model::Lock","name":"Lock","kind":"data","summary":"A parsed `pds.lock` (§8.4): the pinned dependency graph. A black box here — its\nshape is the lockfile's concern, not the model's.","text":"","module":"model","href":"module/model.html#model-Lock"},{"fqn":"model::Loop","name":"Loop","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Loop"},{"fqn":"model::MacroTargeting","name":"MacroTargeting","kind":"component","summary":"§2.4 / ADR-015 — macro targeting. Every built-in macro (`onevent`, `schedule`,\n`http`, `manual`) targets callables; on any structural declaration it is a\nwrong-target error, and an unrecognised macro is unknown. An `#[onevent(E)]`\nhandler MUST have exactly one parameter whose type matches the event type.","text":"","module":"model","href":"module/model.html#model-MacroTargeting"},{"fqn":"model::Member","name":"Member","kind":"data","summary":"A member reachable through `.` from a node or `data` owner: its name, kind,\ndefinition span, one-line signature detail (`run(name: string): uuid`), value\ntype (a field's type or a callable's return type), the ordered parameter\ntypes (empty for a field — their count is the call arity, ADR-022), the\n`///` summary (absent for a field — the grammar has no field doc), and\nwhether it is `public` (callables only; gates cross-module member completion,\n§8.2). Powers member completion, arity checks, and go-to-definition.","text":"","module":"model","href":"module/model.html#model-Member"},{"fqn":"model::MemberKind","name":"MemberKind","kind":"data","summary":"What kind of member is reachable through `.` from an owner: a node's callable\n(§5.1) or a `data` record field (§3.4).","text":"","module":"model","href":"module/model.html#model-MemberKind"},{"fqn":"model::Model","name":"Model","kind":"container","summary":"`crates/pseudoscript-model`. AST to one resolved graph; static checks\n(resolution, visibility, Result flow, return coverage); the §8.3 dependency\nresolver; and the LSP analysis primitives (completion, folding, semantic\ntokens, inference). WASM-safe.","text":"","module":"model","href":"module/model.html#model-Model"},{"fqn":"model::ModuleDiagnostics","name":"ModuleDiagnostics","kind":"data","summary":"One workspace module's diagnostics, attributed to its FQN. Every span lies in\nthat module's own source, so a tool with the FQN-to-file mapping publishes\neach list against the right file.","text":"","module":"model","href":"module/model.html#model-ModuleDiagnostics"},{"fqn":"model::ModuleEntry","name":"ModuleEntry","kind":"data","summary":"One module's parsed AST, resolved symbol table, and FQN, as held by a\n`Workspace`.","text":"","module":"model","href":"module/model.html#model-ModuleEntry"},{"fqn":"model::NodeDoc","name":"NodeDoc","kind":"data","summary":"A node's documentation, lifted from its `///` block (LANG.md §2.1): the\nsummary (compact-diagram text), the extended description (tooltip text), and\nits tags (`\n`, including the `#`), in source order.","text":"","module":"model","href":"module/model.html#model-NodeDoc"},{"fqn":"model::NodeKind","name":"NodeKind","kind":"data","summary":"What kind of model element a `GraphNode` is. Adds `Callable` to the structural\nkinds: structural declarations, `data` types (including hoisted union\nvariants), and callables all become nodes.","text":"","module":"model","href":"module/model.html#model-NodeKind"},{"fqn":"model::OnEvent","name":"OnEvent","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-OnEvent"},{"fqn":"model::PackageId","name":"PackageId","kind":"data","summary":"A content-addressable package identity: its source, resolved revision, and\nin-repo path. Drives the `pds_modules/` slug a git package materialises into.","text":"","module":"model","href":"module/model.html#model-PackageId"},{"fqn":"model::ParentKind","name":"ParentKind","kind":"component","summary":"§4 / ADR-010 — C4 parent-kind well-formedness. A `for` parent links a node to\nits enclosing level, and the levels MUST nest: a `container` parents a\n`system`, a `component` parents a `container`. A parent of the wrong kind is a\ndiagnostic (`container `X` parent `Y` is not a system`). A bare parent that\nnames no same-module node is unresolved (§8.1); a qualified parent this\nsingle-module model cannot see is left to cross-module resolution.","text":"","module":"model","href":"module/model.html#model-ParentKind"},{"fqn":"model::Private","name":"Private","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Private"},{"fqn":"model::Public","name":"Public","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Public"},{"fqn":"model::Record","name":"Record","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Record"},{"fqn":"model::ReservedNames","name":"ReservedNames","kind":"component","summary":"§2.3 / ADR-012 — reserved-word identifiers. A declared identifier MUST NOT be a\nreserved word: a keyword, a primitive type name, or `Result`/`Option`. Covers\nevery name a module declares — `data`, node, callable, field, parameter,\nvariant, and feature names — so `data string` or a parameter named `Result` is\na diagnostic.","text":"","module":"model","href":"module/model.html#model-ReservedNames"},{"fqn":"model::Resolution","name":"Resolution","kind":"data","summary":"The outcome of resolving a cross-module reference (LANG.md §8.2): the FQN\nnames a public symbol, a private one reached from another module, or nothing.","text":"","module":"model","href":"module/model.html#model-Resolution"},{"fqn":"model::ResolveHit","name":"ResolveHit","kind":"data","summary":"One resolved caret hit: the clicked identifier's span, the defining module\nand the definition's span there, the resolved graph FQN (a member resolves to\n`owner::member` — the key `emit`'s symbol projection uses), a Markdown title\nline, and the doc summary or signature detail shown under it.","text":"","module":"model","href":"module/model.html#model-ResolveHit"},{"fqn":"model::Resolver","name":"Resolver","kind":"component","summary":"Resolves a module's declarations into a symbol table (LANG.md §8). FQNs are\nfile-derived: a single `.pds` file is one module, named by its `//!` path.\nHolds two namespaces — type names and node names share the symbol table, while\nfeature names live in a separate namespace the `Checks` enforce — plus the\nmember, fieldless-variant, and constant-type indexes. The LSP reuses the\ntable for hover and go-to-definition.","text":"","module":"model","href":"module/model.html#model-Resolver"},{"fqn":"model::ResultFlow","name":"ResultFlow","kind":"component","summary":"§6 — flow-sensitive `Result` / `Option` typestate. Each binding carries a\nstate (`Unknown`, `Ok`/`Err` for a `Result`, `Some`/`None` for an `Option`),\nnarrowed on entering the branches of `if (r.isErr)` / `if (r.isOk)` /\n`if (o.isNone)` / `if (o.isSome)`. Reading `.value` while known-`Err` or\nknown-`None`, or `.error` while known-`Ok`, is a model error. The env is\ncloned per branch so narrowing does not leak; an `if` whose guarded arm\ndiverges narrows the fall-through to the inverse state (`Ok`<->`Err`,\n`Some`<->`None`).","text":"","module":"model","href":"module/model.html#model-ResultFlow"},{"fqn":"model::Return","name":"Return","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Return"},{"fqn":"model::ReturnCoverage","name":"ReturnCoverage","kind":"component","summary":"ADR-016 — return coverage. A disclosed non-void callable MUST return on every\npath. A `return` makes a block diverge; an `if`/`else` diverges only when both\narms do; `for`/`while` bodies and bare expressions never guarantee a return.\nAn explicit `void` and a parse-recovered missing return type (ADR-040) both\nmean void.","text":"","module":"model","href":"module/model.html#model-ReturnCoverage"},{"fqn":"model::Rev","name":"Rev","kind":"data","summary":"A resolved revision selector — at most one of these (§8.3); `Default` is the\nremote's default-branch HEAD.","text":"","module":"model","href":"module/model.html#model-Rev"},{"fqn":"model::Scenario","name":"Scenario","kind":"data","summary":"A `feature` BDD scenario attached to its target node (LANG.md §5.2, §9.3):\nits name, the canonicalised target FQN (as written if it does not resolve),\nthe declaring module's FQN, the span of the feature name (a host's\ngo-to-definition target), lifted `///` documentation, and the ordered\ngiven/when/then steps. Steps are prose, not resolved, so a scenario adds no\nedges; it renders as a card on its target node's doc page.","text":"","module":"model","href":"module/model.html#model-Scenario"},{"fqn":"model::ScenarioStep","name":"ScenarioStep","kind":"data","summary":"One step of a `Scenario` (LANG.md §5.2): a keyword (`given`/`when`/`then`/\n`and`/`but`) and its prose, with the string literal's quotes stripped.","text":"","module":"model","href":"module/model.html#model-ScenarioStep"},{"fqn":"model::SelfCall","name":"SelfCall","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-SelfCall"},{"fqn":"model::Semantic","name":"Semantic","kind":"component","summary":"AST-aware semantic colouring: each identifier classified by its declared role\n(node→namespace, `data`→class, callable→method, parameter, call segment), the\nspans `lsp_core` delta-encodes for the editor.","text":"","module":"model","href":"module/model.html#model-Semantic"},{"fqn":"model::SigParam","name":"SigParam","kind":"data","summary":"One parameter of a callable signature: its name and rendered type.","text":"","module":"model","href":"module/model.html#model-SigParam"},{"fqn":"model::Signature","name":"Signature","kind":"data","summary":"A callable node's signature (§5.1): its ordered parameters and rendered return\ntype. Carried on a callable `GraphNode` so the sequence and symbol views can\nshow the call shape without re-reading source.","text":"","module":"model","href":"module/model.html#model-Signature"},{"fqn":"model::Source","name":"Source","kind":"data","summary":"The resolved source of a dependency (ADR-026): a fetched git repository at a\nrevision and in-repo sub-path, or a local sibling workspace read from disk.","text":"","module":"model","href":"module/model.html#model-Source"},{"fqn":"model::Step","name":"Step","kind":"data","summary":"One step in a callable's ordered sequence trace (LANG.md §7, §9.2). Calls in a\nchained expression are emitted left-to-right; control flow becomes `Alt`/\n`Loop` frames whose bodies are nested step lists, in §7 evaluation order.","text":"","module":"model","href":"module/model.html#model-Step"},{"fqn":"model::Symbol","name":"Symbol","kind":"data","summary":"One declared, addressable node in a module namespace: the bare name, its FQN\n(`module::Ledger`), its declaration kind, whether it is `public` (§8.2), and\nthe span of its name.","text":"","module":"model","href":"module/model.html#model-Symbol"},{"fqn":"model::SymbolKind","name":"SymbolKind","kind":"data","summary":"The lowercase declaration keyword a `Symbol` names. Drives the parent-kind and\nmacro-target diagnostics, which embed it as prose. `Constant` is a top-level\nprimitive value (§3.6, ADR-039).","text":"","module":"model","href":"module/model.html#model-SymbolKind"},{"fqn":"model::SymbolTable","name":"SymbolTable","kind":"data","summary":"One module's resolved symbol table (LANG.md §8): its FQN plus the declared\nnodes, the members reachable through `.`, the fieldless-variant index\n(ADR-032), and the constant-type index (ADR-039). The `Resolver` produces it;\nthe `Workspace` indexes and the `Checks` consume it.","text":"","module":"model","href":"module/model.html#model-SymbolTable"},{"fqn":"model::Tag","name":"Tag","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Tag"},{"fqn":"model::Trigger","name":"Trigger","kind":"data","summary":"A trigger macro on a callable (LANG.md §2.4): the macro that makes the\ncallable a diagram entry point and synthesises an inbound initiator edge. Each\nvariant maps to a synthesised initiator node (`event:`, `scheduler`,\n`client`, `caller`).","text":"","module":"model","href":"module/model.html#model-Trigger"},{"fqn":"model::TypeRefs","name":"TypeRefs","kind":"component","summary":"§3.3 / §8.1 — type-reference resolution. Every named type in a declaration — a\nfield, parameter, or return type, and each generic argument — MUST resolve. A\nbare name that resolves to nothing is reported as unresolved; a name that\nresolves to a declared type or node MUST be written by its full FQN\n(`module::Name`), so an unqualified declared-type annotation is rejected.\nBuilt-in types (the primitives, `Result`, `Option`) stay bare.","text":"","module":"model","href":"module/model.html#model-TypeRefs"},{"fqn":"model::Union","name":"Union","kind":"data","summary":"","text":"","module":"model","href":"module/model.html#model-Union"},{"fqn":"model::VariantCollision","name":"VariantCollision","kind":"component","summary":"§3.5 / ADR-006 — union variant collision. A top-level `data Name` followed by\nan inline variant `| Name { ... }` hoisting the same name is a collision. Bare\nvariants reference existing data and never collide.","text":"","module":"model","href":"module/model.html#model-VariantCollision"},{"fqn":"model::Visibility","name":"Visibility","kind":"data","summary":"Whether a node is `public` (cross-module addressable) or module-private\n(LANG.md §8.2).","text":"","module":"model","href":"module/model.html#model-Visibility"},{"fqn":"model::Workspace","name":"Workspace","kind":"component","summary":"The resolved set of modules keyed by FQN (LANG.md §8). Built once per\nworkspace from `(fqn, parsed module)` pairs; owns the per-module models and a\nglobal FQN-to-`Symbol` index for cross-module resolution.","text":"","module":"model","href":"module/model.html#model-Workspace"},{"fqn":"model::WorkspaceModule","name":"WorkspaceModule","kind":"data","summary":"One `.pds` module of a workspace: its caller-supplied FQN (the loader derives\nit from the file path relative to `pds.toml`, LANG.md §8.1) and its source\ntext. This crate stays pure over in-memory modules; it never touches the\nfilesystem.","text":"","module":"model","href":"module/model.html#model-WorkspaceModule"},{"fqn":"project","name":"project","kind":"module","summary":"","text":"","module":"project","href":"module/project.html"},{"fqn":"project::Deps","name":"Deps","kind":"component","summary":"Resolves a workspace's declared dependencies into modules the checker binds as\nexternals (§8.3): reads `pds.lock` + `pds_modules/`, materialises each direct\ndependency's `.pds` modules under its dependency-name prefix, and resolves a\nlocal path dependency's directory.","text":"","module":"project","href":"module/project.html#project-Deps"},{"fqn":"project::IoError","name":"IoError","kind":"data","summary":"A filesystem failure surfaced to the caller: the path or manifest that could\nnot be read, with a human-readable message.","text":"","module":"project","href":"module/project.html#project-IoError"},{"fqn":"project::Loader","name":"Loader","kind":"component","summary":"Resolves and reads a workspace off disk: finds the root by walking up to the\nnearest `pds.toml`, then walks the tree for visible `.pds` files and loads each\nas a `(fqn, source)` module — mapping its path to a flat module FQN (§8.1) and\nskipping `target/` and `pds_modules/`.","text":"","module":"project","href":"module/project.html#project-Loader"},{"fqn":"project::Project","name":"Project","kind":"container","summary":"`crates/pseudoscript-project`. The disk-facing loader: resolves the workspace\nroot, reads its `.pds` modules, and materialises dependency modules from the\nvendor directory. The only place the native toolchain touches the filesystem\nfor project loading.","text":"","module":"project","href":"module/project.html#project-Project"},{"fqn":"syntax","name":"syntax","kind":"module","summary":"","text":"","module":"syntax","href":"module/syntax.html"},{"fqn":"syntax::Assign","name":"Assign","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Assign"},{"fqn":"syntax::BinOp","name":"BinOp","kind":"data","summary":"A binary operator (§7.5): arithmetic, comparison, equality, and boolean.","text":"","module":"syntax","href":"module/syntax.html#syntax-BinOp"},{"fqn":"syntax::Binary","name":"Binary","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Binary"},{"fqn":"syntax::BlankLines","name":"BlankLines","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-BlankLines"},{"fqn":"syntax::Block","name":"Block","kind":"data","summary":"A `{ ... }` statement block (§7): statements in order, plus the brace span.","text":"","module":"syntax","href":"module/syntax.html#syntax-Block"},{"fqn":"syntax::BlockComment","name":"BlockComment","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-BlockComment"},{"fqn":"syntax::BodyMember","name":"BodyMember","kind":"data","summary":"A member of a disclosed node body: a callable, or — under error recovery —\na nested structural declaration the parser flags as illegal (ADR-011).","text":"","module":"syntax","href":"module/syntax.html#syntax-BodyMember"},{"fqn":"syntax::BoolLit","name":"BoolLit","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-BoolLit"},{"fqn":"syntax::CallableDecl","name":"CallableDecl","kind":"data","summary":"A callable (implicit operation) declared inside a disclosed node (§5.1).\n`returnTy` is required (ADR-040) — a missing return type is a syntax error,\nrecovered as `void`; `body` absent means a black box (`;`).","text":"","module":"syntax","href":"module/syntax.html#syntax-CallableDecl"},{"fqn":"syntax::CallableMember","name":"CallableMember","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-CallableMember"},{"fqn":"syntax::Compose","name":"Compose","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Compose"},{"fqn":"syntax::Constant","name":"Constant","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Constant"},{"fqn":"syntax::ConstantDecl","name":"ConstantDecl","kind":"data","summary":"A `constant NAME = Literal` declaration (§3.6, ADR-039): a top-level primitive\nvalue. `public` lives on the enclosing `Declaration`, mirroring `data`.","text":"","module":"syntax","href":"module/syntax.html#syntax-ConstantDecl"},{"fqn":"syntax::Convert","name":"Convert","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Convert"},{"fqn":"syntax::Data","name":"Data","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Data"},{"fqn":"syntax::DataBody","name":"DataBody","kind":"data","summary":"The three `data` forms. A bare `| Name` variant is an enum case; a\n`| Name { .. }` variant carries an inline record (§3.5, ADR-006).","text":"","module":"syntax","href":"module/syntax.html#syntax-DataBody"},{"fqn":"syntax::DataDecl","name":"DataDecl","kind":"data","summary":"A `data` declaration: a record, a union, or a black box (§3.4, §3.5).","text":"","module":"syntax","href":"module/syntax.html#syntax-DataDecl"},{"fqn":"syntax::DeclItem","name":"DeclItem","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-DeclItem"},{"fqn":"syntax::DeclKind","name":"DeclKind","kind":"data","summary":"The structural payload of a declaration: a node (person/system/container/\ncomponent), a `data` type, or a top-level `constant` (§3.6, ADR-039).","text":"","module":"syntax","href":"module/syntax.html#syntax-DeclKind"},{"fqn":"syntax::DeclMember","name":"DeclMember","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-DeclMember"},{"fqn":"syntax::Declaration","name":"Declaration","kind":"data","summary":"A documented, annotated structural declaration (§4): the shared\n`doc → macros → public` prefix plus the structural payload.","text":"","module":"syntax","href":"module/syntax.html#syntax-Declaration"},{"fqn":"syntax::Diagnostic","name":"Diagnostic","kind":"data","summary":"One message about a span of source. The single diagnostic type every crate\nemits, so a driver collects lexer, parser, and checker output into one\nordered list. `code` is an optional stable identifier (e.g. `E0001`) for\ntooling; the human-facing text is `message`. `codeDescription` is an optional\nURL the code resolves to — an article explaining the rule — which the LSP\nsurfaces as the diagnostic's clickable link. Empty when the code carries no\narticle.","text":"","module":"syntax","href":"module/syntax.html#syntax-Diagnostic"},{"fqn":"syntax::DocBlock","name":"DocBlock","kind":"data","summary":"A `///` doc block split into summary and extended on the first blank `///`\nline (ADR-009): summary feeds compact diagrams, extended feeds tooltips,\ntags carry the `\n` markers.","text":"","module":"syntax","href":"module/syntax.html#syntax-DocBlock"},{"fqn":"syntax::Expr","name":"Expr","kind":"data","summary":"An expression (§7, §10): its form and source span.","text":"","module":"syntax","href":"module/syntax.html#syntax-Expr"},{"fqn":"syntax::ExprKind","name":"ExprKind","kind":"data","summary":"The expression forms (§10). `Marker` is a built-in generic constructor —\n`Ok`/`Err` (`Result`) or `Some`/`None` (`Option`); `From` names a target\ntype and its `source`, whose `FromSource` form is the §7.2 vs §7.4 split;\n`Postfix` is a `.name`/`.name(..)` access chain (ADR-007); `OwnCall` is a\nbare same-node call `Name(args)` (§5.1, ADR-041); `Unary`/`Binary` are the\n§7.5 operator forms. A `Marker` or `From` head is never a binary operand (§7.5).","text":"","module":"syntax","href":"module/syntax.html#syntax-ExprKind"},{"fqn":"syntax::ExprStmt","name":"ExprStmt","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-ExprStmt"},{"fqn":"syntax::FeatureDecl","name":"FeatureDecl","kind":"data","summary":"A `feature Name for Path { given* when+ then+ }` BDD scenario (§5.2). Steps\nare prose, not resolved against the model; the strict given→when→then order\nis enforced by the parser. A feature takes no macros and no `public`.","text":"","module":"syntax","href":"module/syntax.html#syntax-FeatureDecl"},{"fqn":"syntax::FeatureItem","name":"FeatureItem","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-FeatureItem"},{"fqn":"syntax::FeatureStep","name":"FeatureStep","kind":"data","summary":"One step line in a feature flow: a step keyword and its prose string (§5.2).","text":"","module":"syntax","href":"module/syntax.html#syntax-FeatureStep"},{"fqn":"syntax::Field","name":"Field","kind":"data","summary":"A record field `name: Type`.","text":"","module":"syntax","href":"module/syntax.html#syntax-Field"},{"fqn":"syntax::For","name":"For","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-For"},{"fqn":"syntax::From","name":"From","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-From"},{"fqn":"syntax::FromSource","name":"FromSource","kind":"data","summary":"The source of a `from` expression (§7.2, §7.4, ADR-035) — the parser\nbranches on the leading token, so the two forms are distinct: a `{`\nopens `Compose`, a set the target `data` record/variant is built from;\nanything else is `Convert`, carrying the target type onto one value.","text":"","module":"syntax","href":"module/syntax.html#syntax-FromSource"},{"fqn":"syntax::If","name":"If","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-If"},{"fqn":"syntax::InnerDoc","name":"InnerDoc","kind":"data","summary":"One `//!` inner-doc line documenting the module (§2.1).","text":"","module":"syntax","href":"module/syntax.html#syntax-InnerDoc"},{"fqn":"syntax::Item","name":"Item","kind":"data","summary":"A top-level item: a documented structural declaration, or a `feature` BDD\nscenario.","text":"","module":"syntax","href":"module/syntax.html#syntax-Item"},{"fqn":"syntax::Lexed","name":"Lexed","kind":"data","summary":"The full result of lexing: the conformance token stream plus interleaved\ntrivia for the formatter.","text":"","module":"syntax","href":"module/syntax.html#syntax-Lexed"},{"fqn":"syntax::Lexer","name":"Lexer","kind":"component","summary":"Hand-written lexer for LANG.md §2. One pass yields the conformance token\nstream (comments discarded, `///`→`Doc`+`Tag`, `//!`→`InnerDoc`) and\nfull-fidelity trivia for the formatter. Infallible: lexical anomalies surface\nas parser diagnostics, never a failed lex.","text":"","module":"syntax","href":"module/syntax.html#syntax-Lexer"},{"fqn":"syntax::LineComment","name":"LineComment","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-LineComment"},{"fqn":"syntax::LineIndex","name":"LineIndex","kind":"component","summary":"Precomputed newline offsets turning a byte offset into a 1-based (line, col)\npair in O(log n). Built once per source and reused for every lookup; column\ncounts bytes from the line start.","text":"","module":"syntax","href":"module/syntax.html#syntax-LineIndex"},{"fqn":"syntax::List","name":"List","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-List"},{"fqn":"syntax::Lit","name":"Lit","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Lit"},{"fqn":"syntax::Literal","name":"Literal","kind":"data","summary":"A literal value (ADR-013). `raw` carries the source text (string literals\nkeep their quotes).","text":"","module":"syntax","href":"module/syntax.html#syntax-Literal"},{"fqn":"syntax::LiteralArg","name":"LiteralArg","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-LiteralArg"},{"fqn":"syntax::Macro","name":"Macro","kind":"data","summary":"A `#[..]` macro (outer attribute) on a callable (§2.4): its name path and\nargument form.","text":"","module":"syntax","href":"module/syntax.html#syntax-Macro"},{"fqn":"syntax::MacroArg","name":"MacroArg","kind":"data","summary":"One argument inside a macro's `( .. )` list (§10 `MetaArg`).","text":"","module":"syntax","href":"module/syntax.html#syntax-MacroArg"},{"fqn":"syntax::MacroArgs","name":"MacroArgs","kind":"data","summary":"The three macro argument forms (§2.4): `#[manual]` word, `#[onevent(Path)]`/\n`#[http(\"..\")]` list, `#[schedule = \"..]` name=value.","text":"","module":"syntax","href":"module/syntax.html#syntax-MacroArgs"},{"fqn":"syntax::Marker","name":"Marker","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Marker"},{"fqn":"syntax::MarkerKind","name":"MarkerKind","kind":"data","summary":"The built-in generic constructor a `Marker` names (§6, ADR-019). The\nvariants mirror the four marker keywords (their names carry the `Kw` prefix\nbecause `Ok`/`Err`/`Some`/`None` are reserved words): `KwOk`/`KwErr` build a\n`Result`, `KwSome`/`KwNone` build an `Option`.","text":"","module":"syntax","href":"module/syntax.html#syntax-MarkerKind"},{"fqn":"syntax::Module","name":"Module","kind":"data","summary":"The typed syntax tree of one module (LANG.md §10): module-level inner docs,\nthen declarations and features in source order. Every node carries a `Span`;\ndeclarations and statements also carry leading trivia so the formatter can\nreproduce layout.","text":"","module":"syntax","href":"module/syntax.html#syntax-Module"},{"fqn":"syntax::NameValue","name":"NameValue","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-NameValue"},{"fqn":"syntax::NestedArg","name":"NestedArg","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-NestedArg"},{"fqn":"syntax::Node","name":"Node","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Node"},{"fqn":"syntax::NodeDecl","name":"NodeDecl","kind":"data","summary":"A `person` / `system` / `container` / `component` declaration. `parent` is\nthe `for ` path, present for container/component. `body` is the\ndisclosed member list, or absent for a black box (`;`).","text":"","module":"syntax","href":"module/syntax.html#syntax-NodeDecl"},{"fqn":"syntax::NodeKind","name":"NodeKind","kind":"data","summary":"The structural keyword class of a node.","text":"","module":"syntax","href":"module/syntax.html#syntax-NodeKind"},{"fqn":"syntax::NumberLit","name":"NumberLit","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-NumberLit"},{"fqn":"syntax::OwnCall","name":"OwnCall","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-OwnCall"},{"fqn":"syntax::Param","name":"Param","kind":"data","summary":"A callable parameter `name: Type`.","text":"","module":"syntax","href":"module/syntax.html#syntax-Param"},{"fqn":"syntax::Paren","name":"Paren","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Paren"},{"fqn":"syntax::Parsed","name":"Parsed","kind":"data","summary":"Parser output: the tree (always present, recovered on error) plus the\ndiagnostics collected while parsing. Parsing never fails outright.","text":"","module":"syntax","href":"module/syntax.html#syntax-Parsed"},{"fqn":"syntax::Parser","name":"Parser","kind":"component","summary":"Recursive-descent parser for the §10 grammar with error recovery: on\nunexpected input it records a `Diagnostic`, resynchronises to the next\nstatement/declaration boundary, and continues. Always yields a (possibly\npartial) `Module`; never panics.","text":"","module":"syntax","href":"module/syntax.html#syntax-Parser"},{"fqn":"syntax::Path","name":"Path","kind":"data","summary":"A `::`-separated path of identifiers (§2.2, §10 `Path`); never empty.","text":"","module":"syntax","href":"module/syntax.html#syntax-Path"},{"fqn":"syntax::PathArg","name":"PathArg","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-PathArg"},{"fqn":"syntax::PathRef","name":"PathRef","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-PathRef"},{"fqn":"syntax::Postfix","name":"Postfix","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Postfix"},{"fqn":"syntax::PostfixSeg","name":"PostfixSeg","kind":"data","summary":"One `.name` or `.name(args)` step in a postfix chain (ADR-007). `callArgs`\npresent marks a call; absent marks field access.","text":"","module":"syntax","href":"module/syntax.html#syntax-PostfixSeg"},{"fqn":"syntax::Record","name":"Record","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Record"},{"fqn":"syntax::Ref","name":"Ref","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Ref"},{"fqn":"syntax::Reference","name":"Reference","kind":"data","summary":"A reference primary (§10 `Ref`): an FQN. `self` was dropped (ADR-041); a\nsame-node call is the bare `OwnCall` primary, not a reference.","text":"","module":"syntax","href":"module/syntax.html#syntax-Reference"},{"fqn":"syntax::Return","name":"Return","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Return"},{"fqn":"syntax::Severity","name":"Severity","kind":"data","summary":"Diagnostic severity. `Error` invalidates the input; `Warning`/`Info` advise\nand never block compilation.","text":"","module":"syntax","href":"module/syntax.html#syntax-Severity"},{"fqn":"syntax::Span","name":"Span","kind":"data","summary":"A half-open byte range `[start, end)` into one module's source. Offsets are\nbytes, not characters; columns derived via `LineIndex` count bytes too,\nmatching the conformance token goldens.","text":"","module":"syntax","href":"module/syntax.html#syntax-Span"},{"fqn":"syntax::SpannedTrivia","name":"SpannedTrivia","kind":"data","summary":"A trivia element paired with the source span it occupies.","text":"","module":"syntax","href":"module/syntax.html#syntax-SpannedTrivia"},{"fqn":"syntax::StepKind","name":"StepKind","kind":"data","summary":"The step keyword class of a feature step (§5.2). `And`/`But` continue the\npreceding step's flow phase.","text":"","module":"syntax","href":"module/syntax.html#syntax-StepKind"},{"fqn":"syntax::Stmt","name":"Stmt","kind":"data","summary":"A statement valid inside a callable body (§7), with the leading trivia that\npreceded it.","text":"","module":"syntax","href":"module/syntax.html#syntax-Stmt"},{"fqn":"syntax::StmtKind","name":"StmtKind","kind":"data","summary":"The statement forms (§7).","text":"","module":"syntax","href":"module/syntax.html#syntax-StmtKind"},{"fqn":"syntax::StringLit","name":"StringLit","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-StringLit"},{"fqn":"syntax::Syntax","name":"Syntax","kind":"container","summary":"`crates/pseudoscript-syntax`. The foundation crate: source text to tokens\nand a typed AST, emitting the shared `Diagnostic`. WASM-safe and I/O-free.","text":"","module":"syntax","href":"module/syntax.html#syntax-Syntax"},{"fqn":"syntax::Tag","name":"Tag","kind":"data","summary":"A `\n` tag from a doc block, including the leading `#` (§2.4).","text":"","module":"syntax","href":"module/syntax.html#syntax-Tag"},{"fqn":"syntax::Token","name":"Token","kind":"data","summary":"A lexical token: its kind, source span, and rendered lexeme (LANG.md §2).","text":"For most tokens `text` is the raw source slice. For `Doc`/`InnerDoc` it is\nthe doc text with the marker and surrounding whitespace stripped; for `Tag`\nit includes the leading `#`.","module":"syntax","href":"module/syntax.html#syntax-Token"},{"fqn":"syntax::TokenKind","name":"TokenKind","kind":"data","summary":"Every lexical token class (LANG.md §2). The `name` rendering (e.g.\n`KW_SYSTEM`) is the conformance golden's `KIND`. Primitive type names and\n`Result` are NOT keywords — they lex as `Ident` and are classified in type\nposition by the model crate.","text":"","module":"syntax","href":"module/syntax.html#syntax-TokenKind"},{"fqn":"syntax::Trivia","name":"Trivia","kind":"data","summary":"Non-token source between tokens, preserved for the formatter. Doc comments,\ntags, macros, and modifiers are first-class tokens/AST data, not trivia —\nonly discarded comments and blank-line gaps live here.","text":"","module":"syntax","href":"module/syntax.html#syntax-Trivia"},{"fqn":"syntax::Type","name":"Type","kind":"data","summary":"A type expression: a named base with optional generic arguments and an\noptional trailing `[]` array suffix (§3.3, ADR-008 — no optionality marker).","text":"","module":"syntax","href":"module/syntax.html#syntax-Type"},{"fqn":"syntax::Unary","name":"Unary","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Unary"},{"fqn":"syntax::UnaryOp","name":"UnaryOp","kind":"data","summary":"A unary operator (§7.5): boolean `!` or numeric `-`.","text":"","module":"syntax","href":"module/syntax.html#syntax-UnaryOp"},{"fqn":"syntax::Union","name":"Union","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-Union"},{"fqn":"syntax::Variant","name":"Variant","kind":"data","summary":"One union variant: its name and an optional inline record body.","text":"","module":"syntax","href":"module/syntax.html#syntax-Variant"},{"fqn":"syntax::While","name":"While","kind":"data","summary":"","text":"","module":"syntax","href":"module/syntax.html#syntax-While"},{"fqn":"universe","name":"universe","kind":"module","summary":"","text":"","module":"universe","href":"module/universe.html"},{"fqn":"universe::Adapter","name":"Adapter","kind":"component","summary":"Adapts a resolved model into the software graph: keeps only the structural\nnodes, hooks each to its structural parent for the containment tree, and lifts\nevery call to the structural level — tallying directed traffic per\ncaller→callee pair so the edge carries direction.","text":"","module":"universe","href":"module/universe.html#universe-Adapter"},{"fqn":"universe::C4Level","name":"C4Level","kind":"data","summary":"The C4 abstraction level a node sits at. Only these four enter the graph;\ndata and callables do not — a relationship through them is lifted to the\nnearest enclosing structural node.","text":"","module":"universe","href":"module/universe.html#universe-C4Level"},{"fqn":"universe::EdgeOut","name":"EdgeOut","kind":"data","summary":"One relationship in the flat snapshot, with its traffic (call count).","text":"","module":"universe","href":"module/universe.html#universe-EdgeOut"},{"fqn":"universe::Flatten","name":"Flatten","kind":"component","summary":"Flattens the software graph into the renderer-facing snapshot: each node's id,\nlevel string, and parent id; each relationship's endpoints and traffic. The\nboundary the web IDE reads — petgraph indices never cross it.","text":"","module":"universe","href":"module/universe.html#universe-Flatten"},{"fqn":"universe::FlowDef","name":"FlowDef","kind":"data","summary":"One entry-point flow: the entry callable's FQN and simple name, the flow's\npalette colour, and its ordered legs. The renderer draws one filament chain\nper flow and streams its beads in the flow's colour.","text":"","module":"universe","href":"module/universe.html#universe-FlowDef"},{"fqn":"universe::FlowHop","name":"FlowHop","kind":"data","summary":"One call leg of a flow: the caller and callee as structural node ids (the\nsame ids the snapshot places), plus the message label shown on the leg.","text":"","module":"universe","href":"module/universe.html#universe-FlowHop"},{"fqn":"universe::FlowTracer","name":"FlowTracer","kind":"component","summary":"Traces every entry-point flow: a triggered callable (or a person-owned\naction) starts a flow; its sequence projection is walked call-by-call and\neach leg's endpoints lift to the nearest placed structural node — the same\nlift the Adapter applies to relationships, so flows and edges agree. Colours\nkey from the entry's FQN by a stable hash into a fixed palette — the same\nkeying the web IDE paints with — so a flow keeps its hue everywhere it\nappears and an unrelated model edit never recolours it.","text":"","module":"universe","href":"module/universe.html#universe-FlowTracer"},{"fqn":"universe::GraphNode","name":"GraphNode","kind":"data","summary":"A structural node in the software graph: its stable model FQN, its C4 level,\nand its place in the containment tree (the enclosing node, empty for a\ntop-level system, and the ids it contains). No position — the renderer\nplaces it.","text":"","module":"universe","href":"module/universe.html#universe-GraphNode"},{"fqn":"universe::NodeOut","name":"NodeOut","kind":"data","summary":"One node in the flat snapshot: its id, C4 level as a lowercase string, and the\nid of its containment parent (empty for a top-level system).","text":"","module":"universe","href":"module/universe.html#universe-NodeOut"},{"fqn":"universe::Relationship","name":"Relationship","kind":"data","summary":"A directed relationship between two structural nodes, weighted by `traffic` —\nthe number of underlying calls lifted onto the pair. Self-relationships are\ndropped; the count drives the renderer's flow animation.","text":"","module":"universe","href":"module/universe.html#universe-Relationship"},{"fqn":"universe::Snapshot","name":"Snapshot","kind":"data","summary":"The flat, serialisable contract the web IDE's `ForceGraph` consumes: nodes\nand directed weighted edges, with no engine internals (petgraph indices)\nleaking across the boundary. Positions are not here.","text":"","module":"universe","href":"module/universe.html#universe-Snapshot"},{"fqn":"universe::SoftwareGraph","name":"SoftwareGraph","kind":"data","summary":"The software graph: structural nodes with the containment tree, directed\nrelationship edges weighted by traffic, and the top-level systems (the\ncontainment roots, in model-declaration order). The crate's in-memory form,\nbefore flattening to a renderer-facing `Snapshot`.","text":"","module":"universe","href":"module/universe.html#universe-SoftwareGraph"},{"fqn":"universe::Universe","name":"Universe","kind":"container","summary":"`crates/pseudoscript-universe`. Maps the resolved C4 model into the software\ngraph the 3D view renders, then flattens it to a determinstic snapshot.","text":"","module":"universe","href":"module/universe.html#universe-Universe"},{"fqn":"universe.html","name":"3D Universe","kind":"page","summary":"The model in 3D — structure and flows","text":"","module":"","href":"universe.html"}]; \ No newline at end of file diff --git a/model/site/universe.html b/model/site/universe.html index 6c3b8ab9..a304150f 100644 --- a/model/site/universe.html +++ b/model/site/universe.html @@ -11,9 +11,9 @@ -
PseudoScript
Model

Universe

The whole model as a 3D scene — drag to orbit, scroll to zoom, click a - node to open its docs.

Systems

Flows

  • dispatch 0 hops
  • run 3 hops
  • runAll 1 hop
  • add 0 hops
  • install 0 hops
  • list 0 hops
  • remove 0 hops
  • update 0 hops
  • runAll 1 hop
  • serve 2 hops
  • run 5 hops
  • run 6 hops
  • serve 0 hops
  • run 0 hops
  • run 9 hops
  • lang 0 hops
  • skill 0 hops
  • run 9 hops
  • run 3 hops
  • run 0 hops
  • editModel 9 hops
  • renderDocs 14 hops
  • installCli 1 hop
  • tryInBrowser 4 hops
Generated by pds doc.
- +
PseudoScript
Model

Universe

The whole model as a 3D scene — drag to orbit, scroll to zoom, click a + node to open its docs.

Systems

Flows

  • dispatch 0 hops
  • run 22 hops
  • runAll 1 hop
  • add 0 hops
  • install 0 hops
  • list 0 hops
  • remove 0 hops
  • update 0 hops
  • runAll 1 hop
  • serve 54 hops
  • run 10 hops
  • run 6 hops
  • serve 0 hops
  • run 0 hops
  • run 9 hops
  • lang 0 hops
  • skill 0 hops
  • run 9 hops
  • run 3 hops
  • run 0 hops
  • editModel 11 hops
  • renderDocs 55 hops
  • installCli 1 hop
  • tryInBrowser 4 hops
Generated by pds doc.
+ diff --git a/model/syntax.pds b/model/syntax.pds index 682aa753..7b587e26 100644 --- a/model/syntax.pds +++ b/model/syntax.pds @@ -179,13 +179,14 @@ public data Expr { kind: syntax::ExprKind, span: syntax::Span } /// The expression forms (§10). `Marker` is a built-in generic constructor — /// `Ok`/`Err` (`Result`) or `Some`/`None` (`Option`); `From` names a target /// type and its `source`, whose `FromSource` form is the §7.2 vs §7.4 split; -/// `Postfix` is a `.name`/`.name(..)` access chain (ADR-007); `Unary`/`Binary` -/// are the §7.5 operator forms. A `Marker` or `From` head is never a binary -/// operand (§7.5). +/// `Postfix` is a `.name`/`.name(..)` access chain (ADR-007); `OwnCall` is a +/// bare same-node call `Name(args)` (§5.1, ADR-041); `Unary`/`Binary` are the +/// §7.5 operator forms. A `Marker` or `From` head is never a binary operand (§7.5). public data ExprKind = | Marker { kind: syntax::MarkerKind, payload: syntax::Expr } | From { ty: syntax::Type, source: syntax::FromSource } | Postfix { base: syntax::Expr, segments: syntax::PostfixSeg[] } + | OwnCall { name: string, args: syntax::Expr[] } | Ref { target: syntax::Reference } | Lit { value: syntax::Literal } | Unary { op: syntax::UnaryOp, opSpan: syntax::Span, expr: syntax::Expr } @@ -235,9 +236,9 @@ public data MarkerKind = /// present marks a call; absent marks field access. public data PostfixSeg { name: string, callArgs: syntax::Expr[], span: syntax::Span } -/// A reference primary (§10 `Ref`): `self` or an FQN. +/// A reference primary (§10 `Ref`): an FQN. `self` was dropped (ADR-041); a +/// same-node call is the bare `OwnCall` primary, not a reference. public data Reference = - | SelfNode { span: syntax::Span } | PathRef { path: syntax::Path } /// A literal value (ADR-013). `raw` carries the source text (string literals @@ -310,7 +311,7 @@ public container Syntax for context::Pseudoscript { component Lexer for syntax::Syntax { /// The conformance token stream (LANG.md §2). tokenize(text: string): syntax::Token[] { - lexed = Lexed from self.lex(text) + lexed = Lexed from lex(text) return lexed.tokens } @@ -344,9 +345,9 @@ component Lexer for syntax::Syntax { /// The conformance rendering: one `KIND@line:col "lexeme"` line per token, /// line/col resolved via `LineIndex`, interior `\` and `"` escaped. public renderTokens(text: string): string { - tokens = Token[] from self.tokenize(text) + tokens = Token[] from tokenize(text) syntax::LineIndex.build(text) - return self.renderStream(tokens) + return renderStream(tokens) } /// Formats a token stream into the conformance text, one @@ -377,8 +378,8 @@ component Parser for syntax::Syntax { /// the trivia stream. public parse(text: string): syntax::Parsed { lexed = Lexed from syntax::Lexer.lex(text) - ast = Module from self.parseModule(lexed) - diagnostics = Diagnostic[] from self.diagnostics() + ast = Module from parseModule(lexed) + diagnostics = Diagnostic[] from diagnostics() return Parsed from { ast, diagnostics } } @@ -453,9 +454,10 @@ component Parser for syntax::Syntax { /// so `Result from ..` is told apart from a comparison `a < b`. atFromHead(): bool; - /// A primary: a literal, `self`, a `( group )`, or a path reference. Markers - /// and `from` heads never reach here — `parseExpr` dispatches them first — so - /// a `<` after a path here is the less-than operator (§7.5). + /// A primary: a literal, a bare same-node call `Name(args)`, a `( group )`, or + /// a path reference. Markers and `from` heads never reach here — `parseExpr` + /// dispatches them first — so a `<` after a path here is the less-than + /// operator (§7.5). parsePrimary(): syntax::Expr; /// A run of `Doc`/`Tag` tokens into a `DocBlock`, splitting summary from diff --git a/model/universe.pds b/model/universe.pds index ffcfbabd..19f2978a 100644 --- a/model/universe.pds +++ b/model/universe.pds @@ -99,9 +99,9 @@ component Adapter for universe::Universe { /// Adapt an already-resolved model: place the structural nodes, wire /// containment, then lift and tally call traffic into directed edges. public fromModel(graph: model::Graph): universe::SoftwareGraph { - nodes = GraphNode[] from self.placeStructural(graph) - rooted = SoftwareGraph from self.wireContainment(graph, nodes) - return self.tallyTraffic(graph, rooted) + nodes = GraphNode[] from placeStructural(graph) + rooted = SoftwareGraph from wireContainment(graph, nodes) + return tallyTraffic(graph, rooted) } /// Each model node whose kind is structural (system/container/component/person) @@ -137,8 +137,8 @@ component Adapter for universe::Universe { component FlowTracer for universe::Universe { /// Every flow, one per entry point in FQN order, coloured by its FQN key. public flows(graph: model::Graph): universe::FlowDef[] { - entries = model::GraphNode[] from self.entryPoints(graph) - return self.traceAll(graph, entries) + entries = model::GraphNode[] from entryPoints(graph) + return traceAll(graph, entries) } /// The flow entry points: every callable carrying a trigger macro, plus every @@ -153,12 +153,12 @@ component FlowTracer for universe::Universe { /// hops, and carry the flow's colour. A projection failure yields a flow with /// no hops rather than aborting — a partial model still animates. trace(graph: model::Graph, entry: model::GraphNode, color: string): universe::FlowDef { - scene = Result from emit::Emit.project(graph, self.sequenceView(entry)) + scene = Result from emit::Emit.project(graph, sequenceView(entry)) if (scene.isErr) { - return self.emptyFlow(entry, color) + return emptyFlow(entry, color) } - hops = universe::FlowHop[] from self.walkMessages(graph, scene.value) - return self.flowOf(entry, color, hops) + hops = universe::FlowHop[] from walkMessages(graph, scene.value) + return flowOf(entry, color, hops) } /// Assemble the flow from the entry's FQN and simple name, its colour, and @@ -191,8 +191,8 @@ component Flatten for universe::Universe { /// Flatten a graph to a `Snapshot`: map each node and relationship to its flat /// `out` form. public snapshot(graph: universe::SoftwareGraph): universe::Snapshot { - nodes = NodeOut[] from self.nodesOf(graph) - edges = EdgeOut[] from self.edgesOf(graph) + nodes = NodeOut[] from nodesOf(graph) + edges = EdgeOut[] from edgesOf(graph) return Snapshot from { nodes, edges } } diff --git a/web-ide/src/lib/bundled/LANG.md b/web-ide/src/lib/bundled/LANG.md index 10f53ac8..71f84ee1 100644 --- a/web-ide/src/lib/bundled/LANG.md +++ b/web-ide/src/lib/bundled/LANG.md @@ -123,7 +123,7 @@ Option // optional value: Some(T) | None ### 3.3 Type expressions A named type (`BankingInfo`), generic (`Result`, `Option`), or array (`T[]`). `[]` is the only type suffix; an absent value is modeled with `Option` (§6). -Every named type — a field, parameter, or return type, and each generic argument — MUST resolve to a primitive (§3.1), `Result`/`Option` (§3.2), or a declared type or node (§3.4, §3.5, §4); an unresolved type MUST be rejected (ADR-022). A reference to a declared type or node MUST be its FQN (§8.1), including one in the same module; only primitives, `Result`/`Option`, and `self` are bare. +Every named type — a field, parameter, or return type, and each generic argument — MUST resolve to a primitive (§3.1), `Result`/`Option` (§3.2), or a declared type or node (§3.4, §3.5, §4); an unresolved type MUST be rejected (ADR-022). A reference to a declared type or node MUST be its FQN (§8.1), including one in the same module; only primitives and `Result`/`Option` are bare. ### 3.4 Data declarations A `data` type models any payload — DTOs, entities, messages alike. It MAY stay a **black box** with `;` (fields not yet disclosed). @@ -224,8 +224,8 @@ A function-shaped declaration is a callable. - All calls are request/response. A call to a resolvable callable MUST pass one argument per declared parameter, and each inferable argument MUST match its parameter's type; a wrong arity or argument type MUST be rejected (ADR-022, ADR-023). - Every callable MUST declare a return type; a callable without one MUST be rejected (ADR-040). `void` declares that no value is returned. A disclosed non-`void` callable MUST return a value on every path. - A `return` operand whose type is determinable — a literal, an `Ok`/`Err`/`Some`/`None` marker (§6), a `from` (§7.2), a typed binding, or a call to a resolvable callable — MUST match the declared return type; a mismatch MUST be rejected. A union variant satisfies its union type (§3.5). A bare reference resolving to a `data` record or a node is not a value and MUST be rejected (§7.2). -- A bare name in a body MUST resolve to a parameter, a binding, or a `for` binding; it MUST NOT resolve to a node or union variant (ADR-030) — those are referenced by FQN (§8.1). An unresolved bare name MUST be rejected (ADR-022). -- A same-node callable is invoked via `self.Name(args)` (`self` = the enclosing node); this also covers recursion. +- A bare name read as a value MUST resolve to a parameter, a binding, or a `for` binding; it MUST NOT resolve to a node or union variant (ADR-030) — those are referenced by FQN (§8.1). An unresolved bare name MUST be rejected (ADR-022). +- A same-node callable is invoked by a bare call `Name(args)` — a sibling, or the enclosing callable itself for recursion (ADR-041). A bare name in call position MUST resolve to a callable on the enclosing node; one matching no callable on the node MUST be rejected (ADR-022). - A callable's name and its parameter names MUST NOT be reserved words (§2.3) — `container`, `component`, `data`, and `for` are reserved. - A call statement MAY ignore its `Result` (the call still renders as a message). - A black-box callable shows in C4 as a capability; a call to it in a sequence diagram is a single message with no expansion. @@ -402,7 +402,7 @@ Each path segment becomes an FQN segment, which MUST be an identifier (§2.2). A A module has four distinct namespaces: **type names** (`data` declarations and hoisted record variants, §3.5), **node names** (`system`/`container`/`component`/`person`), **feature names** (§5.2), and **value names** (`constant`, §3.6). A name MUST be unique within its namespace; the four do not collide — a `data`, a `container`, a `feature`, and a `constant` MAY share a name. Callable and parameter names are scoped to their owner, not the module. -Every reference to a node, type, union variant, or constant MUST be its FQN, including a reference to one declared in the same module (ADR-030). A bare leaf name MUST NOT resolve to a node, type, variant, or constant; it resolves only to a parameter, a binding, or a `for` binding (§7). `self` and member access (§7.1) are unaffected, as are the primitives (§3.1) and `Result`/`Option` (§3.2). Within `banking/core.pds`, a sibling node is addressed `banking::core::Other`, never `Other`. An FQN names a node by its module path and name only; the system→container→component nesting (§4) is carried by `for`, not the name. A structural drill — a node addressed through its C4 ancestry, `Container::Component` or `module::System::Container::Component` — is not an FQN and MUST NOT resolve (ADR-036). +Every reference to a node, type, union variant, or constant MUST be its FQN, including a reference to one declared in the same module (ADR-030). A bare leaf name read as a value MUST NOT resolve to a node, type, variant, or constant; it resolves only to a parameter, a binding, or a `for` binding (§7). A bare name in call position resolves to a callable on the enclosing node (§5.1, ADR-041). Member access (§7.1) is unaffected, as are the primitives (§3.1) and `Result`/`Option` (§3.2). Within `banking/core.pds`, a sibling node is addressed `banking::core::Other`, never `Other`. An FQN names a node by its module path and name only; the system→container→component nesting (§4) is carried by `for`, not the name. A structural drill — a node addressed through its C4 ancestry, `Container::Component` or `module::System::Container::Component` — is not an FQN and MUST NOT resolve (ADR-036). An FQN's first segment is a **root**. The file-derived module paths above are the local roots; a `[dependencies]` entry (§8.3) adds one root per declared dependency. @@ -453,7 +453,7 @@ From disclosed callables per §7. A **triggered** callable (one bearing a trigge A call to a **disclosed** callee expands inline: the callee becomes the active lifeline, its body traces in place, and each of its `return`s is a return message to its caller's lifeline. A call to a **black-box** callable renders as a single message with no expansion (§5.1). A callee already in flight on the call path (direct or mutual recursion) MUST NOT re-expand; it renders as a single message. -In a chained expression, each call is its own message, emitted left-to-right; field accesses between calls are local. A `self.` call renders as a self-message. +In a chained expression, each call is its own message, emitted left-to-right; field accesses between calls are local. A same-node call (`Name(args)`, §5.1) renders as a self-message and expands its callee's body inline, exactly as a direct call to a disclosed callee does (ADR-041); recursion is stack-guarded as above. A method on a local value or chain intermediate renders as a leaf self-message — it names no node callable and has no body to follow. Each lifeline head card shows the participant's C4 kind and name. A `container` or `component` participant SHOULD also show its `for` ancestry (enclosing node names, outermost first) dimmed beneath the name. Every declared participant SHOULD show its `///` summary, as on a C4 card (§9.1). A synthesised initiator carries neither. @@ -572,11 +572,12 @@ AddExpr = MulExpr { ( "+" | "-" ) MulExpr } ; MulExpr = UnaryExpr { ( "*" | "/" | "%" ) UnaryExpr } ; UnaryExpr = ( "!" | "-" ) UnaryExpr | Postfix ; Postfix = Primary { "." Ident [ "(" [ Args ] ")" ] } ; // field access / call, chained -Primary = Ref | Literal | "(" Expr ")" ; +Primary = Call | Ref | Literal | "(" Expr ")" ; +Call = Ident "(" [ Args ] ")" ; // same-node callable (§5.1) Marker = ( "Ok" | "Err" | "Some" ) [ "(" Expr ")" ] | "None" ; // built-in generic constructors FromExpr = Type "from" ( "{" [ Expr { "," Expr } ] "}" | Expr ) ; // brace source set, or a single value; "[]" target composes an array Args = Expr { "," Expr } ; -Ref = "self" | Ident | Path ; // self or an FQN +Ref = Ident | Path ; // a local name or an FQN Path = Ident { "::" Ident } ; Literal = String | Number | Bool ; diff --git a/web-ide/src/lib/components/RenameDialog.test.ts b/web-ide/src/lib/components/RenameDialog.test.ts index d7b70be6..5a23838e 100644 --- a/web-ide/src/lib/components/RenameDialog.test.ts +++ b/web-ide/src/lib/components/RenameDialog.test.ts @@ -8,7 +8,7 @@ import RenameDialog from "./RenameDialog.svelte"; const occurrences = [ { fqn: "orders", line: 3, col: 10, text: "public Place(): void", match_start: 7, match_end: 12, decl: true }, - { fqn: "orders", line: 9, col: 4, text: "self.Place()", match_start: 5, match_end: 10, decl: false }, + { fqn: "orders", line: 9, col: 4, text: "Place()", match_start: 0, match_end: 5, decl: false }, ] as never; describe("RenameDialog", () => { diff --git a/web-ide/src/lib/fim-context.ts b/web-ide/src/lib/fim-context.ts index 30f79404..8d1dd9fe 100644 --- a/web-ide/src/lib/fim-context.ts +++ b/web-ide/src/lib/fim-context.ts @@ -30,7 +30,7 @@ const GRAMMAR_PRIMER = `// PseudoScript (.pds) — a C4 architecture-modeling la // statements x = Type from expr x = Type from { partA, partB } // if (expr) { … } else { … } for (x in xs) { … } while (expr) { … } // return expr Ok(x) Err(e) Some(x) None -// calls module::Node.method(args) self.method(args) — references are flat FQNs +// calls module::Node.method(args) Name(args) — references are flat FQNs; a bare call is same-node // triggers #[http("POST /path")] #[onevent(Event)] #[schedule = "cron"] #[manual] // behaviour feature Name for module::Node { given "…" when "…" then "…" and "…" but "…" } // Example: diff --git a/web-ide/src/lib/pds-ide-wasm/pseudoscript_ide_bg.wasm b/web-ide/src/lib/pds-ide-wasm/pseudoscript_ide_bg.wasm index 43f9a2e8c91f1cc756b0c27225bba580981e3b4d..b661abd8fd0688784dbbd5cce55ef37cce1d7a91 100644 GIT binary patch delta 476427 zcmbq+349er^8a+d`@NZDavvlx? zgES~8$RQ{$LC~Nghk!)o2!a>|5e1b?2#Sgd^8Z%P%u5j6Zgq}L z%1P{ny^~nQ;>O{4;-7M(Cmw%5xskD*E7z|N5fGSiN3Zbgv3k4L#>rnzqAQ1F~P|=GF zUl46WK2!|_eL7SROwa*vy`4q1=t^^SJe1U)xq>&XR$ik?v1cNN31cJ!) zC>(V=@<4#2fTeQu<^^<$kNLbl8Vl8P0*W8mEGOVa1AmY!-0KBg+{cvwqMS1V6O&Z9 z;^Q2h1h~Tdan$p8P?Kg6r6%;xiyFv6CkhXxA?;67SOBf5g5O($DrvGVPm`T-?x$u1 zh}{JZk1U!Y=N|MN@hY(lns>&4KEqJ+7>lj03~{a&Uj zNjwSTV~J44A`!+sfC~UBK2I29hcdi8EPD)l!XdfbAz-Al&zGS@Bsd_7a9HsMQgeJ< z#Tec$Ku!o{v_iBV_!pr$W3g1b1%6e9WAU*bN?7&zuBL^-a-a$icIDo%5@t;CGT@8a zg@I_FpVpl#eu<=@3UvBVj0zE-7pv>{E8Nc%u0|p}fI)$8Zhe)~G>%SGEI(?do`V`3 zwN)=gSO&unn)regQ9Qt-!VvXERICedj{oRikb46W5D`SFX%)Fe1O z2>c!osEkn~#wmj_>xtBy28?^ zJV0^9Yvrf4$RYeO=B1%Q!-QMJF+FZwm$t>rJd9gy(>qy1((|mx()06kbG`l+EfinN zmWsa-{sFAqn3w5+rfOj`YfXA-K2Zd*3@xz-iH84}m7Y;zU7T@=2hdtm5Weku+uDj~YB`)Q~$y47}y`!M6-m-iu^3%)4Xwox=u?MzONi>YJI()>%U`jgm(q znGGrp8gkQZBkmYAddMxKlns%rh9!60GI01!BZk~Mc+_a+ZEIy_9@}W`%*^ifbR?%i zwOj8PHfYF*+XjxjX~b=VM=8~jl+y}F4!>!%vN+NZ*4yv++u)JP1gmRS?$vWnD;a*r z-6KXT|MDd@=wig+zbj9NQXAylarfw9Lq-f%HlH@zk%Mm?JaX`eTL43a^>SA3xxa;T z8#F@Epur;t4#K2H4H-RHsf;u%9W@v;1r7#|zGLX%5u=n97SC>7$_G3d6zBY?AE!|u36ITcQAkU4U&o%^gcGdnA9 zyP7p{;NW{k4<0!JU=JL9)6K&M540;xu(oEmU^A@WvUAumD?2AIzAmIU=xEgFn?{aS z+J#PrnPRfYa^DtpZs=|Qw(ur(y7sI#Lwio!9XX^;R4w%b^#|=e^?h}NS{IoWe#d`A zov5wX-qW7fp4O&nleJ0OG|ke4_KY?~tJe0bA7~r3P1+9aW9<`di?&t!RNJn7sKvKw zJGENvBdtc;EdTrC@H3QAi7Zv$*Paj03_q`}ROfgf^KWthn5jJ$eko)FGYd60Xp_~C zgLRP))fJJA;WxtjgPVgjYE5Kra7OT%;8eagxJ!FFu5ML-)V`Jf*-c;2K2%qQH-%ph zO;R_hE7dJ(ZD332U*Xl^dD{9=b!bYYMx7ejt%=CA$j5Z6gm$ei$6|99$KtuC@M zvMRDV@@C|%$UBj_k$I69Bg?&Yktym^!Jo8u!XHMCXb%MiMm(mjR@a2Si^RWIe+`}p z9aSF>+ugjVJrkK9*`l5dEr~3ROvBt3g+K8Bpw7o^KaD&QUJ+autc^Syu8n*VnHHWF z{v`5DcxPlsq&6})JRRwU;om}^Mz%$M3hj?f41XCJt3IqgqCToF@_Z0Fdz0FJlX^&d z4$HR|;q&VBc%(e?ari)F6Xv=JbFGVP2-SvXsxuM$I{aB=sehq1#wnfUAo>JqPLEWE zzX?CcPm|#QL5@d7a;0q>t6D z{E#+Veb)hLS7crIjQ~w!y+-{U(&nI#XM*do#`Dxq)Lq(-SR5kL-_%NNv9?8hH9S{+ zQLT-uR(MQkulAKTAC*2--^I$mC0BlnItv|5R(A(0)g{`i+ER^(XF+gwWMklzGwjPD z8fpQkFw+Jx}I$b;&n$S!TE`nl|DFIsMoM=WH$ zrtX$m2gAFx*Af3wI|wSTiM)cj)1pvUTOwP+kA#e?_u6`k($u1Fm?VqhB_2J z5quv&RHqAWIU~mhj^{?P8Fy05KwM_lesTJQ8uF@*imm_1eRqES;AA(!d zZT_R7W!fRI77g-RxW@mG_J;PnXH(!obWCX?)II86^(*yj^&52zJEXmVoUz&y>XG0t z!6p9X{(b6W>QCA+{C7nA4r~9T_PzF#c33;E9o4?pKEmYQ#Hd@;Z{m?z{;wexz6~!A zd>eUK`$l^a#BngNNuA?=B{C-Rdid$^O8=wUFOgp(<3Pt_BVR|V!e0SrHoHCs$#x`s zKwYjKjyxWDB=`yz=i$g(SiBXXPXp!Q)uA`l8ug(1wzd*Huu7X8ITo%7Jg%+KPDIwA zkK$$FE&eC8cfj3GsE5==-iJeLp{Y*|%np3#`6yhWseBg;zcP8?I%{p?%h((%rO91v zw)IexTDHL&U|f#hmy8FI(>i((zd5lUz8?=O`U>lo*az$@t4+bf$bGF~`So?G5r}50 zp@`u%GR<09DXdT`Z0>VYrq>ARV^k%A2zMi1JHia+o*HiOVoxx7Hh?((+hMDH(b?=x z>(-*iY@zjVQ7>6P)7n#XE^?#Al-sR%pYMe1uXT${*$(R;E!MF*>-?7YA-=q2HR2Dq zx_}+9HnlFW4z*g+M%E=DIdD^*NO_Dv3CHLyduWQ0V-#Wh8eXPTy8~$b##tZ8-vVoX zo3DZT32m3*_o8;!I}0+uT|Z#qWV^Wx1D2b)_+8QdZ2TUTzl9w(#p~3FkpT<@j0}^H z2J$Ean5ktkj%)x_pIvBr%VLE_tDag|g;o!QCYk#r)(G+t*5-I3r5Tzz?zoG3pOIot zO{6$d^X*iooU%`@GU&o@j@vJ>_GrhMfV`+gWod~O(=gn8nX-D7HnSHg%U-1VC2Hp^ z(TvizSd2}jv>4x(+DnxEZ))dQy^H+TL!DBLH<_tKIVjib>4wgNWj4|cZxL5Op|s+L zbz^a{b+XejxtfNR+ND2`I<(8*oHXxB>Fc|e1`l{+ZC|`A>a}WGM;greomwnm;m53!tXi@;;=b$cDd{BB)C zw18Q}1y-p0FmT7;y5EA|PrDDR$7IBan8)P;Sl3=~1zT*rd_kiY2|RnTJj-16Y_KRc zd19@W)Lo!*NjaJv34ERgS_v6x^|X?X4An@l&j3wruxTo}Ax)*Ao`C`R=opvOXGBqK zlVO3|JKEkS$q|uqhH}qn(}OzJ13lXS1OMvT3covg=H@xXJJTKrwdYW6o35>tUX8lc zsj45d$AJ41WCxeOL`{M0h$^f(;%cG;5N;HYDw(U8~BX`cP22A3pt6o+0$=I zOrLEuHPvBGj>oLyWra#|#H@Yrh@!t1ky10}O3f@MV(KW#DG zOP0~6F@DeQ(+zY{E`L||$xDF*ReNaMU{UZg2ApFZ?z4=&Xua6?TwwRBzO7lExM>K> zu!^q8K*o7jBr@(C?YADiBDoRG!e7K&#graefMRV8#YO(&D=q{8KVE^u=jL=_L3PnG$SOh6j-&2_NQ)I?1p z8@sbJYsy}ZxWfj}=QuY7dFC_kiv}RinBnWGC1FY-tHt%Raxu+hOp`^EX`0C{{dlp# zes%qHp#8xCB;)@6*WxyZ+^$oNM&`amiUYvoiBtdx9%oN+^IyA0h#-=Y#lWf=H{6`# z5QrXQL>moDf~VEg5;d2+a8rb(PXv{+G)cmOF)%5VC2;6$>#8u*#d};_sSlH z1hK9dmepY#2-hGyNOCbeAfBLE9)y;#TDjPW=;I)0kzqh$s+_=qR%uNicCgKtE+qsZ z-KQo}q0>_JW!CG%hx-mv8>?uFE+7SyYNDhzOVpy&)I=&3xSpR#$(o6FF8dmdurwaBlj1|N5dDa6P{{2YjTkGp#zeW6=$QDPsk zcZj}jLBG=q%o-+lH!M{^XJah?-A&m)tX6k7W7k+$-rbeGVNJNZH2E`MR5t=dc4<>lw9yp*l1X>VHK;*-}-B46sAUCICL}lZ|`C!zw_a2 z>&}TeY=O1=o^PUBWgZe;zVys?A7h2{Tw+=_~Tb=8qLFoKQpq2-N`@eHiK(K3h-vcUHY)%7v96ua0Co5LFJsMma?bxaumAg4 zODbrr(^>4fi9{l2;xe@XR=Q0htlTo`|1wA2ddVWTc-#8$f1Ky+ryH(cy47yVA47Wj z`h~2WQ*xk1{y616ru{?p;&cre%FI=tTk)ycssF%EWX}2guwtf}l?e0`)`F>Bw0oiN zK%4OnjTZB6;^;ze9=poYrj1Jf#up=fAi0Qp=_hEU=-*hAr?qhlR4TxaUGVX=v)zIS z72qcb;{L|Uf95Z4L4Av4{hK8ZJ(J3Sm&zF}t<}$VL@edGo2>rRd&s;3>-^b%YyI^0 zNc}o}sm!}k)|rB)H;FHN)ypxwSiDu~qaL@H)Pojz&j{t)K&U+d@1HGf7tX6kL!!m5MQ)1= zD$i`uq+yG8)<=t5&^R}+4NC^T3d`6AYu(a9t9D5z#8Q^J&|J2ZX0>iyaBctt{8byIfOn-q7%Wgorv1s;<3+OFnvSCX3&z`Xbnti6ss_gfr|* zeyoD6LzbDauRwM2>-Uo8K~{{!vY9og44&CZZBB%7@HJYPx~(k)am=m9y93WhB?TzS-z6is8YoA?s0h z()1=rfx2JoF}%fmFN=1h3cFdfwbS8Q6xOn6Q^Ky-43+Q>2)>}+4}51`_(qFH74Ioy zOFgxu8)ui9pS`vQun_F}8$K~>pq9aQThG7oa8}Ta_QLQ%vq>+U`t5NsH$c|XfZA_Q zgalZk$eng9*?Q#7!X`Koup(YaXGgE8lyFS7J7HrLTnh?~Wb3^*o5pi7^Hyci=BTmH zU-pVDF9&>40(vGZi?%^{Oeu>-5pF{mL%17Z0m5_2qJ;>iqgq>p$Gm0HB82-879(7X zFbm;wl(#@wfiN3khq7op1Y=Qb{q-%CC0k{0<@@ELC0kFvRoDiat(;c52Ma@X8C9R} zM~m^4*53!_%}NccwLzLbym(wdZeW1jle_w?{~Gg*`l zvJ_B-v0itTkrS}~x;(#`%wOg)m0lyGfe7!G_%DuFoEnYu#8Rx8%X3)JdUJVx97kfH zJO)DsM0+1PxA?U9=Xjz$8dGGxC)$LEU8R2rPe8}-rxxj@_r9}sKS`~n))^jaSfnja4UD6^m!7$s25)u@Z#Ks|TG&}rfC zFdT3&3>|f(&11l-R8$>egy4|GxEBkWpvIkkPG=&*SuD^;Q*erHLx{8S<6vi~nb`+0 zdoR5UXqDs&n3w+qn3MEs33IW8xv_*9L=z1;G|>QN8{&}luN8%7(b*Z)DJkg#bP0Lj zp*BVQm_M3I;cibfgTmwfXkgOH9^GK1y&cN)vu<_+E_;G+|@0mVcX7OI<1?b7jvc5 zGn3#%G+62(X+crF)Klq1vr9e8oTyRiS%oN}NXlq1v9sRe{m~4wIVAmTE#@IxtH(Tf z;)qhLD5XjhBz~ksoKo3H9d?U!B))bNK_qs$35g{GDkAWoO(c=2?*=&_l?PI83*HZy zN*ARS5kv_uLXb)n>L8|sXB&a;FOtlrfALaiivgoC*p7Irc?r(O#KlA~hRt`8Xa+HF z9-$5rCE8OXvm-VT+G2=O8sN}w5e<>S9moIb1{C=%{ast@6Ae{XrJeUv02TRTLmtqaEy$}g_j3CX+V}z}V zwFTIDXu)VF(T7`$*LLl>&mVKtkwbp8an%v*g!-%i^<3$3D=ei|>)_r>pa@%s&+vo( ze4_EhOuA=WyeZpybe)da)OCg^nwUvZWHz5__dqXc< zsS4c}i97eR+;f6trJ(ycvf;ouEURI|D~ozyj$=b(DYl#eA7aQJTFBWC$zW(Lem9-v zTJOGVbfl|ihj^KOfz8+8_G*Wj!R<8;GlP_Icw^>yFe5fv-!%puMDBJN9#MM}4C0O! zx#b>0e35m}`c|cC7iBp~5fI5T3L%J>BD5*11a~B8O1Q_(5=C9)TRYYl0K`-4^W(=s zCj0E&6+3IGXScJ{o43P$5=M>Z+KF*0(BVJBcW8#T>dP1l{g)0V(gaJe`Ie;HD3MjW) z=E`UdqB0lSEGp>0Oi~H&i=asfzYIa+5`GZ^Ur7gkAwtdGzw%39X2eBt3Gaj;Oxkah z23aKsL9`gt#n4vA_d3O)6&3?f8c0UV95qazB&b(N_YqYReT@ zfB+99KpI(V-j9;9B0;i+o@#Fs#7cEOS7OxpT#0dv_&p&ph{MCyzt-7;A|o@0(jcLP zKp<hLnz^teq)5@<_%6jXWS;-ZRkj#t@x@0C2Ts-Lm1VZc>LX#O8~` zqCPa{DI}?ct60( zmL{C~h~x>wbj+2sR%8UN{S zm`xlIHFSO*S6-*IQIxI>)8nU{4Vm`SIyXVv={_VZ?VW6#A)j266$GF~ z1gN!RV;h`MBAYIkQa;TZwh2Zs>yb?@WSV|=%6MRNi>`#~n6sz!a|xtBI#19C`07Tt zU=Rvy*&fx)t%}Xr=xf2|^YOcX^I1OXtBsXclZSNYn#TD-tSVYBXVEZ@Zb?w|!=Qq| zXsm?(zPS8nR+Nex`1*ZAqrOF-pI8f(x&pzJ#c+*e?X4+9kD)DeElgWkpDkoWym<>b z8c_PhE$N6Ym+AdmT1BaGTW3zwnG5?&LbE+9Yru!?(Bi2N3%xjg`mD;W)WOPa=iv9m zHX5ewwhZgitZ%rGOSU+j`~WG`i4|`?q~7iH+QLoFJAdj5(YGSwWSSkU1p{m!z;Zog~W< zeADRq>_p(M7{D3#@SWH>uq_g7$HyX3P6??|*)|T_218a07+%be-+&D!;5FMew80Fh zy^VFS*4AE})v=TthGMiXf!3}VXOUX27)?vW`K^Mn)&`@kPBB{2R;NHagq;QSON`eH z=xAj$bJzo;2dq(_tjU3;!)s1tWvvz3A2>!uIw;Y|{NB3jvV06 zoXwvVyex(t8TuR!pHiOUPCV}mxP@77e{msu%i>@5W@D`@zU+w}rheIv)mqku3P;PbDshsk80i? znu^BzaPRIh$HQ<2JV8RDFZ{a6RVek@Xf52^x!~&n3b8SRASUw|60oCibJHAH`nmoI zgX7qCt9)<9`Ghypo^{6=hHu? z0$E{@E75l4!E=H3!v{-RZT82!5{ra3o4e{M6XZ?qNgHe$dEM%Js4M%<8h>aU8fSca zb_Do_{S7-fIQK8#jzR9WZ=;lpJw@7NCLMl*WPO%3@JN0DUKkj>oAt%ve}W+f9BIZV z-ppEXq#x419qEAI_H`Xd3Z~Wj+QK+wJHr4J%xbFRfy+#gkMzj}Q|PN96`=*ymqXS$ zA(sps8nzKjWg=KlE&eo=CgJU>CtctRxT#ms3DOP{`?Wdo<$W z+#hq+ZiKmXJF2Pn>A7*TP;rvpuGz6fa=)tX&i$}x7nI; zA{$6}{ed98#m&d?tCizQjh1|%!=o~S3oDRMkc#dQwWc4mdRnHG{--0RsNRIY%Hqj<2>dm zc2^8E3Y$OW5S97#wf8ehX}mqJm_SZ+!t6>z#f0qOd1Z6aP~Y*-4eK7c0db6l5KA6{`ukVVDC z^r~@z7|2;Ed_Vgf(@kU}G1X1r0@AE-6Xa$%?)VXLzmMhQkogp#jm8O?%%|Kw`f@`T zi+rqq2XHTx2->$cy3MnZSm!2mB;IxtK_p&7$A@!R4%;oR^0QllAED4x^;)sY&&~!K zzxT72DK-^W0!eb)L1~)+E52R|9h~EtIq~Ns3KX?2N?RlzLqZvll`I|ri}siYHq>lD+J!OSI8(3tx{RxRRGUynLs%0SzB>hg#0K`nj^8n zJvtHyYuyBau-r`$2us}rfv~V#e4E2^ftA)FHWYZ67Gh_CxT-_!(JOVcMPf8?y;=F7 zb5NxT&qqSeUaqd2kgMw^ZT~7V3X6|V<#gYi_IKj!d0E5!#D>GkQBDFXWJy~r*P4~dz6~UdPQHAu~ z!cbY;-w&U8dZ&-5?3!*M0BCJ6o0~rYdCpngYaVeiNw=NfxCvO$%+K8fj1uO@OktwF9u*SKtu*ka+seX<3M{xCujGew{W3erTos)Mu z=}GAsgQ*kp)8S4q%@wK4h}&DQ={yE-54SkwHnlam4G2Gg~>scmn`3 zZi*qbBe>c{#s*&un@AB~>$6V*YeCB&*`g5^=UlT8vJo`hh8^>DRT#D%QJ2bc&W7n0 z0-Q{@K#u`iZ8`!@)?N5FmvGn^Vb6s%mXYZd#{(l*bWLM<^2!aP-G|!^1UJ$RA)efu zPtxscvN;`r3v)|*Hq312MhrL7+K%j(SGIVHOvO|Fpe-->}<*Ze!|p zkDH)wcen}acI#=~R-xM@79l%x9_-A}J;fD`SZ3TM4bzXSB_IIgLFz{eI!G8JwJ1(I zQ5-~2zMRFdMHJxz2W(;6dpYdAQrq^JOR+v0X^VKLVHrL15y1qVKu)fEJ|q9859w*6v6+&}oynp6^Ep~RTGVP4vx&}j%qFfdhr z1d$Tn4*`s`eGx=U_?-yU5c!1pw80|K*C3GV`}8<#fn3ItN9*i*wwArPcM zszvod6vh1ya!1>_)yO3x^ouolteN3(>B0oVB|E5srUXCiWD&||E%TBuZWO^8$3tb6 z=zwe<=$FrDu|m-|pEY5H;?8_lz>>w}e3!?v#W(p3mRIphgRILNvs5y;;+zOCcXAa# zm%)0?Ife`@Fuag6Lf=7ukoF|8Dl;QDo9yBGB$8v$@ul||#9&k(BWfD6++;`Dm#V&5 z^BigRovNSvy=G524K#bxNz(8T^BYHMrO?q!R48JH`A^EYCnNX^#X%#2S z+_iRY269(X?pT?Nn?g5=OG3YStcH46NYTADVo4J=?B<1Vp76u)1hFt3W040|GYX7o zb93CR?}-6T21}_vBZOCeGrw2l54~h<+nwD<#|*!@YNLGHimN{Ax!O(5r&ReYF~(rU zY`%EefKaItn+!IOEfjZ0+0@K+bXtbnq**kS?wD}nK_)X%5M#sHx~hpWmd@BoF|UAK zhT!`Gc23iU0i0yf?O6E1$eV9~if6Y;1ahUcF(pIa?N`XgV~j5fSw4bOg{)C<`v_9@ zcWxK4rtBPK4s6OU4xNk`9rcqDeTrDzl=bt@Q+tA&o~AvjJqY^P818TKS|wM|@HYNxe{n zS^)NiqF)Pk2m7>YZ3~vd*sEfDOKd>1MW7Yyhtz;pteTCfYTBA@_F(QtXZq!yDufj4dIv z78vLHOM;iO$Jq|?WGQ=89Gc|`iTq9s7a^igCzjp$nCs|EBGP^gOU8C?BsX{i9fEU! z{hkw64$~vwmx!62SbOwx|79#&9O}g2Tp&(%V!4;n(xZX%(iAc5b?yUDyNDh(lSCjJ ziQO4V68As6Kk|%@8CcUf;^xi_ugk^bo!N9YyQ+B?))z02#64Zv$@J>)UC6VIbkk0W z$If9e-BE?#(oQR1CR3u|JoYZQ>cDwyNNc>~qAL(p!(l6$A}to+4rwbR8zPERdT2QQ zhsG^I>n33#~sb zp1**Vqf6sLw$=9o;il^Ng={Zt{4807mNK9`8`A-#*i7mAm0pG0Z<2(k7b}X( zhC~2(Wn)$+Qc*xsn@Dj8{c(vDyjjetiIkjdBITi}CsLtePpzjf@QwbRcWElz;-n2O z6*c#L-xzR9cjQz+1w~HY1(5Ut+F-{N)xB60batQ@E5lT;x`=%M9*N60{_@MDh6;km6{L9SGG;$^My(Tx`sJiCI0)U18mRc|Wo$X#<^BOrIQ@Qj zc|9XF?kyRqO>dSZHF9)bXLBB6$9~U9ClW>Fq)OZ4f*y%F;hsQB7E;OZIHWZv2s+rD zM^_o%(PmJVhs;VZHe#}(LOHNC_~YLnRu%mzY&7s91s#hmy&3L_#DU&8yhCR8VI5PT zbOu3ENzov=lLt|$Pak$^Y=%6v`^}k9#XS0FArkm=0H_I#gLI~C8^!WI%(!L-P%HHU zawE&C!aJ_N;9U_V&JriCWL>*ppWv;PZqYRKHs~KK|i2YY%tCJJRtjfQJ8LTl@24W2y^Ld19?CH^D3iK$x;}+46 zi0k{a9c*S*>9yF1SY6fd>mXZ@e)D=3BZ(=Rd2v0^5G%Vb{l0lsCGWsSqqBl`y%qXV4 z-G_4~+#MZh+0vs+?2;Q9xT&Qlm`FAyMS_+jO)3&nr%1Cm^R_oL-1vwQH{c6#Gk9x=`)_A$J;0LKeH-Lgomh`- zr;l=6!;KXuZijKBPGk;obuVf)eh4d)?j7K|%jhcr(20w12*Dkw{VY_vL}Hnw2yANv zUl|*PAB|sr*(Ho)6(ZO;ob?3G z(?_tU8ZRUlDQ>P+=ya3>A2ixwVDfPqt{TCz(4uw(!}WL7ZzIqi=q|XEJ;B})i|$0P zv&Fl2viFdxxQp#X+3=BUX^?b4h^1ulz-X2wx{U&7ed0J8u4Xe{+d zqIxu2fmV;+&3XX~o9||1%9Q$O+TU1e8c`e01RndqAwPFe)#-1nH;W(e3|&pdbmGC?CGL$-q8J%N%~Pj5cg2|gCG07(7bi-cP&Cm8 z&a}X{eT#MKaOVy zsuteQIz|wFIS%v_U-l%97J24a3kRgf>8|kjQ^?3SCnqxIPmnd{Br>K?L`I1@cCy=K zTLm&o&0~og3RJ%$bNYL*IM7y%S%ywar8)_2TN%GZ%Y)hns}as3dugDJqVGiZ5B7_A zeUL!_Zta~Q9N>er93|)Ar3#zhFY_RZQQyEni zG0S2ZG$x)+xnqVBV~$-b8#I~B@-Lv_rLLsOc^+HsrrqAxN&v~X*2ctS8badPp5WLu zB0ib5Y2jukM%k8Vm~Ld^dK!ijXq!I$+p5~h>@G$de+IUfP&9+|#0-5*)pb)?3s!8a zl_3KjU0|SXYAg*Zr*wrMfJa;K@##mF%p84>ctx;I;MT7N>*bqFx~lm28P;8lp2{Y& zJyrf`r04%4u6c&tTVMP*`&QiiEW6stdHY!i?mBVrbT*LvRJCI|yMVJbRZX5}zc8mp z<5^&t)#AKa?7TEN2$3uKvz(BrstL28gR`fr{Igka51U$b)jT%Ehw#wL>~f?>?PSPF=ru6lSWi+bV}EqH1?ATKfb z&{!CR3P(6NqZ{GGYnW_^5&6VBY#w9vZV#|LgWjEV9o!@uBVE`a-2`d)#Mll_DyWFJguC7~hM}0HCP~?CD90|9FM?M zPdEAPFL~`xM4-k=SxCic-VyOCwsG)T1Zo7_XYe`&4k9WY387giz0o3xP5~^M4mA~l zifnmFpDs1fbaJ;zxA(LpQYzD_Z`(lu0KuBq(;J71x(AL60NZEi@rVSFUK7IS8DE+( z(#hN>Q>4#;hA~TMwqc`jsi%@5YywwogeJU@Y_F6soxkXQ333KE2>7y437<(d!*D<6 z_38siQ?Yh1}_fy#xaRt2^(Ak@NqAKE&}MFExJI_ zO?n6WAf}U3mZasqXd{VPFNK#9_PB;sux8ka6!P$h(W;>dXcm@NrQR7!#piob3(pQw zORlCmES6#qliUNJ$4Lh1Btn$47MtTIP*I9`TX+>DG4?dx2-b+BW%E(fPf|ME!(L~QjR1SIONBf>=6(i!l~Tp52*?UW4me>3 zV`NuIv6&xfa%cH7{-=)qjQ`!alNSYP`{)YF1<8&O*jSpF=qqU|q!;jH8?>E;b|-@G z2BC)JWAsMOgA#Z5Py@)H`#|v^07!}qFnmZqpI8G3246{jM|>=g!IDp0PZs@!;1{Yv zoGvF#UV_-`G|+YjeRhz_W;*LPofufd6$X9L%RVi27*>YyR9h-VWsfj00|#Xi|L4xS)B;FQSLCNnsU(bvKVDsV8cgV=Zi$tfqeV;V*>Jz@^yR7Dzt!Q;?fU@@cZMTfx} zK{{5=SuMGw0Js(C!-l^TiJOQ%6V@wy`po694q&jvT@nh)v8rSYLv$>zY9y*iPfsH* zXiGu@G5AhHa&)w5VqAhIY{^cTl!&50zSszpm+UssB{K5FW3TZh;?-rmpet4!KpWW8 z{04{yyAsw0TdrA1$7S;&THId94qzvS!6b4y;$eD*9n(bLr93ZARGH_9cD%|q_ilPe zaga$n4=#>1+;urq?iZuGGi3IMX5DbgH`4uJI+YAU3DJh!Rmf6oBf1{X=>%}Li{rRN zGVS@qglIpyA&Nmq_IP*xA&N1ThA2*TP&_Pw;?X3WWw(EZ;T&kUe}rPZO?l!q-bExY z<^H&#rjSxVo2OI?vaqT>ZBPp?e_e4t0F@-Y6O3jHjk!ULP z5~x;Dopb=H2M|V*e4ZqQGkkI{g**^9Z)d$U6@CClN)eJ-Mry zMoQe|b5@;{*;B2QwiNBrg$?91~1TZ4}iZJCVB(r;A1;3`j+6 z6iuSxFd-84sWj@3yXMaJ_r$2uKONc;%b7IMIu1<-B8@(2XN%h)@)3+K=*R4spAt9{)TZJ0DA*m1{B)`NSMn~u< zpGiaUkvO18P= z>MHQ&s;huTs;gky)6~_3K8~-E(u851AVh?Uguap|F-ZdMa4VAwV1fF?D(1 zkXmXZBY;~U>{N1ZH)t%xig`8-6{fd3gdx32hy_T`_V61;+8T^T6i`B~*-nEH+ z%UI(qsFRV_%0z}so&bGd2t&{dIg$Sc%flT(mp52BK9eQhdK0%(vqkVN7Nt)>hFdEN z&Q2jB5BoKbIPWcasW9j*=BEZjm*eJTjF`2Yk-x;|<+vn)AINe!e&O5fs}}ScfgH#K z^3KDDGc9oezR=SE7W-M5Xum>Ubo5^VfBXI7Un|(1dG;>qcnZLT=5=-%`gE`8vXYHp zFNg&z(X38vT8Xh=5c^h2cZ=LrtUH-b>1Hk%h5i674o!xyf&qH77`KX*0Qi-wSd%20 zCZs;eR3Kd(T7~<)%_6)S7fTyNuhoBAW72B&7u5J_H7kZmJNX^f4M6mLhm}O$4btWV z-qc?a6W?La6axnySj0kPfx)J0qrf9k0OB@lWUgF}ers3(5O~iT+%nA;Yu2!r)6f`y z+6&coq8jc}Xw}B7l@AoeT0&UW^0lzg1E)adHS$E)gQZ>6nzHFphS4brJx|L%Ll4``>b)xZmta*TJEZi& zQ)%_-W9>PH`>}S>=R?*^UVM^w7d!!BIvt9ahYF5>sFZl(n0$skB^!d17Paz2)~#J- zo3ZkPW~*RRk7dilAZ6tkc6=4$~c z=WGOJVif;rqnMvSFapP)u*?ClJ%FZR!?Fn%A02Tcb`EV|ZE^9ApcT;QHFE8NAe784 z%m4F0X`>7;rk7(&XgOAYG&_#vk%_)Iiqd1a zGDFcH5O3~e1!n^F?M?voq)7e@?uH+T*LT62f9z)fP>5-tv5Q(Rk)(yk-v7k_>aIT; z;QU>3fSY!?19U*&2Y0bP>7NmF2`mxK07<<+$0j^g4E>z-&s^>UOW^iSI?>>u4b>{7 zPZghhPM(NWckO03Fm_bbe8HNh@1njEKvG}FXNky{EGPCN`Lzb&Pk|$eBos&n`JjwM zlcKNk=8AR~XQqqmzQm64kr;>jboRMe@TJ^3cYMj(@K1tb%NOu9EZoCV(s%w5&=>E) zCcjCH-NQO$e~JnQ!U$KR#nEVagJ1_Vez}1OCU$d9&taCD*whaCSk;+2+;Yrfv zJtC!}FHKxBf#;?Nxe^HnncoL@28FPx>)plQC-BR0tGQ(ozY;-C1^+7ob0Y67Dl2#% z;u|aY#Ts02^PnUl$c{3xdOB}u*XoU+Vj?fl=zTL0w|_M7D_TwA=b!|go-6teg1hIU zDO^X!swuo3?pP}(@osi8jd|BIyg*!J@f#7xz-`4RR>R^EllkB5%1&P`pO$@{^E4m$ zC;2%-ox%s4R@eXltvl$a+fev7_@F_GD=rGP|D&pp3Euy-{1bybdcn6+as_<`j1LfD zcqYru*+=#%@>Q1C;O6u2ZJNsSla|%pjvWAgU-J?1is(r1*$sNjL0q54Z$^MAyIAyL zRj?%Wbsh9vW4ELfAzO5N7Js<$59-At_z0(5S??L$JUh(OB%j`mfCTZ`Hn`%@CoE17 zaO5~&U3a^v8|iIrk94kRF@vWg4j9i8!)Ndoh&zCOGlQE2+db|`=nghJ{S7ZND2DEc zPoq9}8ZIq`#f<|rpSWg_Cl#ITD)VF}QBA{ckO#7Qe3Z9HJ3VXhC~t$IY4Z4MlKAvj z!4%%Z1@-p?=C{{Z%;**BYS&3n*)`ul-CI!g>^IEEAb4l(!%e;X?n{PPydS>PbzvXJm&P#NAX18 zNvS?@@_>}=j~!&~HM?qse8F>FeU*RS5D1G04ze)DX;5z_P9gXLnRxFYT;Ugps}C{x zc^mUF@z^2uS9YEF<`CPAg4TywuK3FlmMWD*Zrc5y2!I47RQd%xUO!lq!%VXqwRGTF zMWADx!H3z04ZF*32yVmf#Nxvkeftr1L+GjRvFj%$Jm4rxMi0Y|CgwU_Iv!moUaDi` z|GY8~JM$>5hn&82*T>^0yD2fwA#O9!J`SbzUEB)Fk8)u3z2-CD9}yE*d9ytk`tGWm zzGIxU>p|Z`rN@r@J!?W<%CKT_oEXtkZtcK}vjjAe8>@mz19PuOTb>4U6)krY+x6caD zw?Qh<=pfFMb(DH#X}0+o-L=r?5@jyAm7!Gp?Kn0@`CX#Um;il-2*JtYEQ>DF=zB{6 z+ui-SpP*gY-!Brs{DemWiOQwNSrdG&muwS%4#l62Qy8}0W+X5zfBpktUj3QTY4YQr zp{Y0w)A|>dj_nDDIv^Q-58|?4SdMn=7)S#T#1PvxL#a#5+~k6RkxmGRV-&d3QhWcI6i?q{$0dZAw#bSE8;E2yNbI`vGdO8 zV8tofLG39xxY8F>aJlTogMcv(&?b*Y%(^w=2FA0prc<8{`(KI-y+VvJI)r&}veRf}C- z-b1y~%W%*DaBY0NBm9mA`*1aTxA@J+@8jFvt-8<8+cJL2BmNcO&#>Rb#X&wQY5#Ui z;iO{D{}_;;5bp>1Ahu4l3GpY{Jn?pj55+mYILs%oc~x(O`E?Ar=_-F6xgV&gbGNuw zTQiTW60f`gycGLQ8F*HQ|-jwWIhDVdh58z-z5&}d_u-NX${CQ@wYx;sms9k zMauMbVnPbfX8pzd6fRJ|TPn{&PyJK*#mIaimA~GIZr!1TtR+>0?1J2c(Ttp`$L|)4 z()kT4?)Q8qPEL?*yToT{yy`zSxs4y&Dt2e^9R9;ru`3hdk6T4=O8>M~49Vbk^W#qW z&rbO-PWi7}MLVj0Vyn0;6ZJlE>V4|e+p$&roXH>HJDvQ`ocvu|s}^PPNrcGmIlR3- zeS@u})7jo*&e@uZ8DIXs4%U*_;`s#7ysLbcAy<(IJK;vc!#oaa@| z$>onzk8SdJi%WrA2m)xk_FG#op-6tnNS|kK*Dy@WO&VVriQtsuA?q8?CaUR-5G%0_ zb{J+(9xuQ!)p=OmdE!VO9@Wei%k%j>1h+Kit5Mdp34tK`HsKdRI81B8=@IRFP54!) z(!}5sn@A}EQyugpTNY!*8briqgAWd_02)k>zFqWzm=I&4d_-Uhvh)W-;>Rez;nJT>KO4z0bhYsk3v2JUvdM7z|u)$iNl2)AH)$un(~Vp!vhN% z&mo4xEWKf~=_u2tqo+2C%}x2&>24jIab=0$M9F*2K#6rCtvMgV=8LDB^ER0_9ed19 zWWthvB+vjMSAE(XiY}m2i+M{vXQSv`%+FUVF&#*%DBjF$5MzsZ7icFdi?NFHs=_Tm z)2P3>B|Mks!R3qYUSPy#`g7uBOTGzJHnifcsmd>{c`Pka1&3JrR2|o!t7>x=I2RQr zx8a5LeaJHLZX3QHeLU5czd%*mo$XZ7X&5?`JST2BoBxa|e{Ihnr7B-_;4Ne?*;EA| z_{IqN9eDcL1*5LUJS_ZRR#>AKJ@4{6}%ONYz&!8-xFgx^Db#CH-boD zZy-)t1y#YT9~PTB^DFZs9epn3R-M>&E-%hq=K(|E3!(IQJuAUbz})L1dL9J&JTc)s zetnKh4|J&p>l#3mfI_x;&WH5-u4?A_kf;CyZ>Wftt~U8?NUbpWC5_M)*UPv9PseR4 z-GtLsNHR=GFw_)uhs2&IR&?i`*el|v?p!+SUjTVNPh52Y{!;5E(cwa{z=u_XE`&A& zsYgya(#DHWg`mU%lmz7mUyJe{fVWBUJn@;f*?B7VAvKaJqYi{(H?m+W{aF|Y}TnenziL>lrfE_%JKw3iap?*edr;Ze)8ZUd}VJwi{(!98fhSD zyx>*=7;uYZJI`PRBym>oP=NgfP2``nP z_ALDp)I)!Lk<>f-ds|dC4EEMw)DIJbUw@>k-CywX5zU8ODd#-#O5P&)IOz;b-z(N! z$w}Wkc_qKszYG|F3-SZ~__bG^_Cn_cJm1Cj>gi8-J2_8y(@Yn0o*OZ%N(YUe+Y=9x zN{|ivoBmc+tE+e}V{eIGSMx0ad$_O|Ge09khmmWX$F@n*gW==i!fW_B^=qOSZD>s< zT*F7Pxx&+*|5Y3RDW+hU8xZJ^i{btG`4GCV^yjVG?)(~A()Aq#4&x_1tE&0th*E~v zQ4kP(w7HB@u(yB~$t)SV78}bn(e_&2qe}vzW;LNhc0(F?xkL`JX|0=YCiW7%VuyTR zbS?ioU}%0FkM&&dH_pOpv^LIiRPdIzk5f;hrKwytl5Vp*AZn}UE!?seZdrSy1(k^j z*KxAezl@+It$cI0W^<~E8PvGRJ}BV{fg zc*HPlKz?uz9|05@1F)^uRdpV~e`2|Z2x;<<6GM3)4UtDT$nu6xTyg`?XY0l7H^3HS zw@N2i!ldKq<#4`|Om#pkzk%mq{@ZWhE%=7Lf)C`KdCk}2+<{=@Dsk69-p>x2ih~1r z*Ng)JDQcYOp$;XBt~c`U`Lx}l?M?h@=x&eR#2-Qsxfu(;N5pUDBRw$liwT4H1%IGb zLD?Yrg67{2;&-9Jmccwtgm2?F*zx}2sX_e0|3kxR|7#mIgkK|8-Nw8Bj}5EP@CxGA zE6b!NGd&SB5#FJ^7$s*7l_h^4%JJziamg^r)gy=T3!rSjK8)Yxoy62^D|uRuxNtbn zWUp3TKb-SGnEqUiT;H%bvdo)Nb>C=?7v4Rpp1PY?_~KM5Us2#T(yUC>%|&WeA_cFH z1}V~8>TBY25e>@7FFjHA2Y)e#y#EsAxTWu{HE4`W`vxg;8K?*0^b}qA*LQ=rz)nqZ z@Lt|T&dHuJl>7Q>@N;dD!p@|`kVPMFNJdHhP^Z^x3_%T}=7OeNi!*xEFcYFBfJY5b zUCHGbMi07D#ydHD9hK9!+2ZmpD34o zJ0MzZM_VDfiYn6w3h8C_Y)9J59y7Lja0DUcM-K4QeJO5Y4&m$H@INLOCN3?-9L>oq&;Amk zA0GmO`2{&0NDqtRh(NLnmEf%^hHnGKN5tZ7{3huzl|3xR@tszB--(Zlk`*u+HKiW{ z97Ki!)n-0ytz?jfK13Tj)gq@y1m0*8jnftzCxTYdFe;H3mfSwvKU`ym@P%JU(4d)0 zf2YV}dWPa&27R4>7k%B>hDJFJ!Mgz!LAuf`gOUY7jrWIr&bS;)(r2&Xekc;~osjdQZ=KToCUf2L$*%)aYCNYe{?nI7F(c=3B&*dE;R5}Q3>?tKl3WvGBT=`cqsM;@3$C_xxOOU6l3t3@l z6isziRO79&KdIas#m`zqQ#Y!@M%UwK#QvOzpSZhVxjFb5!q3wF;!+wuhUiinI%4vg zLC6jV;yIa1c50quPwV*EJBHD7l@^%B{c_6(iC0U=5_BAXvhiRS+!BGrOp0R)gj&Ev z$R9#>k7pU$=1wH*2OTa2MsV!9`BTzH4hc!W%Jm=I5Vbo zQKfl&XmK1UQ+mb2zPi+(0O=3zrdeI!UW-_PN4m{l--iRw;$a1p$foS*aS01Tq@VFlt^oNl(FVbBkl0(Cx(7Gyzn{#{5 zHpCqQ#86hJewcaw12^vg8KyY1MFI#fDv01qO+)KVMgf}~E+oax22>U+8p_4m?D_zT zm^cu_?;mmyM4;I%uyiKyISMR=^?+b)9jF0MNm%f5=%l}3nX2h7Zdfp7Gu^xx?1e3r z?TxJu4dECKZW!!l4&~P}uh2e077*45+sEuM4+NlmN7pK@f->_S32%2{8Oe;2 zN?4^PAtXzg3tZ#8g{07*pqmNsDpXwMz`7iB-edHV`S{;fI|yc5OL4 zy{1+g2GkXsDk&8&R;P3E0Gnsx%QGG66jTOFA11nxRs|%4)xecDRw02V1fi6~gc~_` zj)af(;m^ZXMn%L#9HS;?!;~Bjtl(sc_9)z$xGBN?Pd2uygkZTAL`9isF19(0z}jdb z4_f!-zA>}9SnOyg3_32x&J}jbcbFL>|8ien?R5W zKmNjSvV4(43g;@L)%Y`Jg^i zV%e~}!b&4&R}IE4s$x1=YaX~dfEaho%p4|mLeek>QLrZVo7tvjeh=#pg(d=TDX+vT z>x~-yDsTc25T{xJfp?_^1+fKafZ6<^+dZ+4GzDDXd!#YI%e(8u7J9dWt5=xm30W718pMgQZR#;!h`?~5zCo?qudUDL7%tt3tBJ>io*mn zhkpm+WfBlih2qbHcv=TgX)o9i(5B_6@}u}^87j*!k)N`RQH@J>DjMBSGLztRw3$h6 zy5lFhf>-R>lL7c-Fh~fMnkO3Fwq;z?fV>AR4tQ{Ei{{o(+{#)CXn<7Q?s35aKM^4B z?8;?Q0vZ}X>p-hc4yZzXhxqXMO zih(7Wfn^LZhAB%k1FINd3{#e81{xS(3{zHT2Hs1^8=*chbno6fd_fuTk5WfR&bbGhqI&WDawqVTogJ#-|wvH!nbh{1X+C}@2K`5N_{N*-C zX$CLfv9;v#=J?;Q`sMeV*iG(<`+??VTbgHO#ndUrUJg>Mn@KTftk6JArqDq1yAPQwyC7{gsU_;cV;FLfB>N7= z!rfE$JgPvmFQ|oo047LXw+<+(GOyk27Ik7`~lJ~Ia}_)Re4$0IoZ{?+91Z=TGiQ?Z1bVodCqEF1D{!WfZF`yssPiKDqc$xE(~n z=)>+1s(+of(7gtq#)WP?|9e1MM?TGssr+11zYw|s`z&&60Merux#P2#>P9{_FD!CL zAujxgds1eJY+K@{M^Ivg`ST<05t8cJ`m%!h9<}v78q^m?eVBwYv-VNwvu`jR7rTwp zP#9(=k`R5&jTAyo4L7+>wg)z$y$>-6W2f6*H?r4&^mhz;D1G5$?h>=KwzRDo{J2{H zu6oSlZpU^q@5lfeoj zSyK*^EAOB^Gy4hGI*rW^lKs%|XyFv}C}_c~e8P>}k-}Q5%qj%q6lw>@yBkVnF}Pk! zaK-tV8Mef2U+^=a)ZPCxK6oP_`N(p&&T&>J_jv^ttIk?|*B|c(!Jk64WV1PPqdUyJ_^Fsgy!ok^EFfy2 zY5TP(@L&3w7<3@&08{^sn`>Hs?o$80+vixeQhKoY5K+yB4Orix$IvRn!#yx;=)w1f zAn)^+LO19f)yC}eg`49%XZHKT{k^SVxcU1RZV`TO_`*Fg6?MY~iMnfpdk~@;n%t=Q zX@l!`{u_2poQmPfad&H(j9yh0aDL3oaeF^1|&E~N$-3M&N$97B` zU}W^O>D!G~cbhxq=5IF||B$jW)3_08DKbPEdMh*WE9ujfUqR(c;?q#t_iJd6NYro> z^xXNzJu9Ph48LFbrn%smo7{GY`gOD0#XPdfJsiLLG>Hk#=*=mJ4>lV&3$T%Elrz>0 z`&O)Cf_(q@);%~kJsQt6Zou;0Z;N|Wb5-lNKy4#k@r)*Sn6o(vSnf;p;oV!^x7yR} z5_BcYU;1^*6*)tzgODlA!i_`m@k7s1~oag&!OM|ik$^r`ZJfFU0V(@Ao+2P*me2~0Stg7^4Sjs_=VwV5n zmM6)Jgy}@oI{lxdmlFrmu}tu1cL}lI7*< zb*Cgqr>Pn&;*jY)om|aRCsa~T)M4|nrlIy>`|$pN!?&htx{hHvvEYV z>KLT{p<3M=Oj5Ek;0A$SbALf@&FSVSp~LzVLGXGw1>Ym9qNYA>U4-A!6kwv!U7<)JRPE~%er(< zPDpc3hLE#&pcvK-!HwyxzbNfI_oYkaH|K$Le4|ZS)kXEkwzs1TVAWvmuTk9gcGswd zd^TpMd9h=K5~xQT*<^kGicR6Y~yGLQTThj8^}WLKLWh_zUgp4qxq~x})y$ z?&^6wr}B1p)fJy#yQ{0Jcjm?Vkim!ZT}b~)lH6#GKhsk0+k0Ta;bEK}>Z&2XrmAK7 z_H?KN2)ZHWx2aOf|jsRj-0R|FExm7?^Nx zUsZAR)RaC_HL!6`D&#xSE_OlFjwf>~g+@qvkBLNMe&g=cShEpol90*ir!L>4`?vH1 zRKGCG`eA?kBI)j@s+~4VQq76x1Xv!ZdP|h)zrQ+pj|vv-FBQDGzdA6MDhK%I`fKZ& zhk*V_$n4W!9r@b|+M0*@t0MZ*?ypAmO4lMiPuJpN9Lv+8PS`7#*gAU+Py+$B+5ti% zZyg|e`y&HD%9_mj0ji5EKB)K)mBoV}Bbpaa+XGYu9_tWGfRn7s6Eci%UY+9(0GfVb zb{s(Xm_r7taV6GFY|WN7{Cy zmHxssdNa$sbVvi)XG+MtJQ%ODkO>gYGU(7xHPu7ZLogCuIYg}vua-5Pywz88F|=gO zp=ye|ztj&+glJ7<8WnS9;_}vN-oY$j7GkL87TL{{2NFR`3qVAsn70m-S=o4);u}KM z!&HqNoRRx;M{eryYa0O7<%L8`JUl|L=IfAPU7ny04iT0 zj`10Ihe`~s;FA{5j)v&2hstzNPmSClm5_xh;Q2iSodJ1-uwW$2!;pnhStBp1g3uA! zM_*Kx7l-;aF5$D`S}{+YgoMC0L#CO3eyjk!%k@w@wspjs`D4RX=Dc3v>;yROSfOIG zg}%b(hC4XOF~?Mi6&>!YaqWlH90X+#h8JJ9Ok1STNch`?`3@tbS^Q$N#F;2n5K?6- zP=-1Qba@>VEJDFz#Fi$=&$7>W_$pnvD5G#k7OvQ9;pl%VizgkZYSVGArMpY%#BZ90 z_A%awu8qT24BsoINCWTCKtXJ8z+nB&qxyH?kZJ*hbhRL3kSq2B-Gp~~`p04$qBt$U z#IFDzgdLCu{^*1aM@BQ{l5olKITJ-G8^=M4@E{jmDDFhgb$+8&A?xZl3$SLzO_FrNs7*q@=RR$Pp%cRhB zY$8q+rRb$Jg=LX6hC=q9Q5YB+6b{gIY`Sb3L;qD-!O);|fTp%IT&ZXI7Da)fEsFy{ z0fqvs7DM?i0v63)fC1F{FM>m=6%0kSg{&7^pd$JPPW;+C932Gqw-&jGu|N&@+7^T) z6ysS!xu9KS^{%01j$4_y~{t{w@f;Re)h> zT!ob&-ioqw15Jb$*qV<*z*fBR7+@>N4gnO#>O+O*(SG5!iChp{Ae)zogRsLwpCMPi z85@bbYO)@`u(NDr#Ex8|DTFUXW*!GEjw+ zTBt~}WuvT2k}B{EePlB>se3w!`c@>9@m$K8*>~iSKNz3pFwh}H<-<%9pHMuJl^Uue z@L(P=q8uLV+@o0*T96}S+!$E~6bgbt<|7;5nl6Cn$SUrAp%{q^JAimpks2Gu5{!*? zV?BTyDoU_h@o+F?G#P*aUMZ0UNfsJ-jhLMRgrfMx!J~O4r7${qp%xluzUF}t_bB*p z3Aq!wkpxdbq9{7UAIGQLryE_Lt`f{sv%S^{Nr#XE6CTCKLKPQusmb!4ycnowv~VKk z6gvi0yGRwOSRRA=Br2xggg9Pzg5p{fA3F|c_(nOlcsaM@@`nL+xUic@Xp#x&3L72B zLP2Gz?~F>aSe`kEQi3lSsEm?>!VUz@%1VAGVl!Y}6;c=0mlV#!!a_?__@x3B4!7L1 zK;|ic3G|^cX2~r>#`6tC*+ee81BB*l1u`!50c;Uewa_i(;MmYNOeRTgiqSwYb8J9_ z=CNVa99sdFg^p#*@SyO_Dwt`HDiWe;09fV8_&_B1d`CdvSZ(t#SxLq);f@!h0ok1> zTpY@2^p;a78si|I00Dtz5rR#FcG6x0pF9kXs~ub)7dFb^t}ztXBjX-WGME6&W-tK| zWdbF+un7o$zys!1k)M*O0zRj5vP~c&$H9pM?#e2owk@Z362YG3U+ja)tHQpH=W8T@ zX9UI~Oy__Qa1?S{h3f$7fnvigCoAKGxudyiuo$Ib-1`R&OWK&A0gIEh9$jiV!%z+Y ztsOR{03N+rb1S*>&)d?*ZEe;bt?(jl(m6(bq7#jGUI-ST3P(NHe+8iAS6vL<&W!j^ zpk}tW_&$4&#*VzV+}P!Q8(rl3SU=72X7UND?D)*aAO5R5P7f$$L&zFeROpeC#CU@cYEc_WR^1 zs*vI3r%KqoGG6@zG3fKBsnNJnYWB?5c$T7Pwv$g+C$xxv!g_2gIs-!c&1TFQ>S*_G zj@jA;k4n69h8l-BIQHsd2A_vR>YR-(TwcwSyROmf?AcCIT50;&1T-j{~F-c*nDlK+$uMu@H^KHll9sp zb!0}B-S&zMFQ=deQslq5#f-aHSA>HhK60Mw+I(H=*z3|?rs!O=^E}Afq_+diRF@-||#oJOXtKOzj1#0~{6H zd;tdXmT9~I;`Y1D4;LuB;+nj5GK8h@7JJ-<>N7~(23>?jvnYA_MXIOUX4%t|eRqmn zibTtK$Km4%#vY+%Pn+eJs6o)5*l~%v7$Tl2m#PV<;{8k25x6Mr`UjB#9rp)y6Vg8W z1LWO{P2bB@44-2zgXHG3>mcS`b|qE?E_AO{XW?q{n5)zV zr-TABNY0grY4HR0Ip&CKRR4-SL6icFx%V1%=An%l&{&-c02U|#%Yl9!x$OtADuTZs>7|@BD0}R zoy99Q$p50ERwHIb=A@~Lk9J-=RbAwCLszUdJ+6}cS(v6&$nocAhHwMeej21Y*f9o8 zS1$rq$)9JaCoxgUN3X~90kF$wstUQxzQgWl20ouE;WDrvQ^j&y#Ztr zIzPv^sxV8wXjNd=K3U`;qV5Kf@IHKlh<5*ZgE~HIRi;+j;Ww(u(3W`dMs)_%kzzNg zZTOVW!aO#a0kc%Km!UXz!7SCPKLv*_PLYwj!3@w943yy^umj_deL8p$1nU?Q*~L`; z2^87#%xSl)vQ|(SbM_Vw8Ls==_)=3j8%OCT(`7b@?gn$%Y(*8Y3A5FWs`vCJ>VV}@ zbqiW(_@Y-EK}0?aQwLBY;5pAB_X{Hjh&`*<6-CXfi`+_c(ybWYXXct)Ro}fRbiIEo z7V>l0H+zImf-#)wb-SuD``xC7XXXvmyZ&?=Zd5jyw{BB6iWV1?$wZ4QdCBd-hagJy zw_?=kf_~r3KqJbmy+h5+*#MRwcnS5k)9zHU0{~kb;dE3Uv;e0?pK=g}f#0TeroS;z z<^mKm^teRT>4iI0cR0!8)EtPZF33WT zQW{yH1ALl`aGNk!#ani?)I2;_m05>~V4e2VyAo^EJE&+j3}&gJBQB)K1nOAd%vJ4& zw9vx}<;^R1BWc-V`EO;9GzWE{Uxsz`E>k1uKEY_6N zkqT*9kr`R`DXx%6>jL2cL|+hw^Q;X%AB0DKLD&GXP8EzHVVQ}a6L~V?!4dZkp?C?R z_#O&>Ly8p59$A%ORthV#Cq@gaE~2?AjFh81bC=+V0}eNuGg|6HZOnvYUjegKiDP>! zDJ|#2c{&cuhH2!{WKwo*P+kvlQkswxgC+=wbD zkp{eRq2K;eoO{O6$*4{wR{yQq@Yqqhx+q?wK>xrwr~6kOOyhr}dm=iFQruabl2PSg{AfpHR4t%f ztjx)Cb$cHQjrd=X0w;n3&VrWUEU@5|1^`63in0yhtYTiA3m*fNoAVH-%+{s4d}JZ9 zJeo}zDaJS@Mv6gfb0+#%QCNcsrG&H4ziJA6T|_9A%EkE%a@qjkV#x;#H3uIZZtawq zQ;lv@fUv&&n2SQ3wABP>!naDOEE5cos+5aBh)oe04 z7Y3nh9f-rzmBtk?YzD)TqoUb3^k@4qp7ybzd6|pDL$h$y%0^Lb39O=n(_|54qjF&Xn0q?Jv#5`Rw2n2|O0hZlq$)~D zK$rY3T-qj(fRY&CoDHu|f@^5YoVHAt9FZ1!V$l-SFuh(ae0>4%F1nP)xojd^p%ux) zF;pM|#cQl`dm;!|kV3cuLAVhJHzQnakh92-;u1grLloW{0tV<8EeR0N^u0&-Y!-gz z#~?hl*k;A>{}mBvwjYQ$t7 zLM@`K;EWuhp_Dny{R@-}6vl~Vh}kHI%1%rSCXli0j0R{g?;fz!73ol z;X2BwnX+EgoX46;W+=JCV-)Bdun|iTV^EYrftrvE0Xva^l|nIF0DV;(gQpl8xyAq_ z6d=IjN=O65kQ_Ov7)7h4Ek+K}UW<{_G&?nN{I(;fHdv~EGIHETfzP0j5kfXAh0C7U zHDM8*;#4ddjGhlzVTA|licMJ{u#prH(v9HSl#LXmfWVqFfG`nb%3*!Dcpxk=e8Pgj zqHl$j9)MU*8I)-aACA@UJP*;neP#pVS8n}8#W+7W*aw8b$8a9 ztLLc>*-Vr7G8WFmZSpSjmwC|Md%(21OC7wAm`{&DXURNeSX9HToxW`R4X?if(I-$D zrWse>1wp{gX8v936OhDf?pAF}QdL8U=hx##FAN8`kKYa5nJ3K~cgyKy=iTZ?~9iJ%6HqHW7sj?$anm^a85dhN8dI0!I({6zphR<0G zR2&&`+%aS3t4cHWUX}eHJG|r1|FOeY_mEN7bIyiL^k1|k06sopvKOG4`_<{;&xwI+ z%sN`~|1D^UMb1)_h9Hv0^Jt@N&+)h--Ls)G15hcds2r~Ww^{2ws zUkB%Co+kciN*+|lLV!^Fpt>7srp9|n#h~KQ%pAW^9pb#5yl0^r;=rlm z`bBD&GuwRd2*&ib>Gvq~b>B3}c_{*pKGOA65_WI01J1kU){bO>qaaTCL-5%_hiL-OLC1bgYyK`aWBa2 z0~2jtTmqu^uK9Y2`n~hGS&*MyX-;`k-BJ3bCx<@z)uDb5ga?r?P53D_(x$ZLaS)zd znUal^GoDgs?KLI2{wcMO!a{A6R9#J@yA-{&t&fb5d0WB?^{8ue!nf{2b~leopE;?74J(bHtl;FwA8;hTI|U5dY5~L52fMG=6mCVMtVPb>h=)uoHPH*>0JF z@cwKQe^Fi54MKkqWXvh(!X_o0hl;$*4IB<>c|FFv7>7HTS@5E&JOuI(sExXQBlw$} z`CwP@ds`M&`ks1iW61wU$Zx_|JRrMZJbHvC+Ya=T_RY>0Ro^VzwZEJGFDX-sMJ>dG z)1K;rDVm#CF*HI!6?#E@K((PsqVpza5p1pzY1Q%^pc8l>!FqlQv1=}MMDQ@t6Q=rQ z2%=sxPhO&<=7g73xA4Nc<)O&y=Ej%R@7mOfdn7O)7<1%d1{x?nge>#Nm(}5Uiz&l^ z7V}{RS?09Y)CBX)a)rkSO!0?VbmQ7<1tft@X7mcxqsrFG8ep+{IGr5vr5o3LP|CmPOk$(%D;9s+v?aFRp}~ zx5+GcN7}K?C5Ntp&4D{D#~k@8DAi(f$E&JGetM{o-zL|*3W0NKMNRvQnp5zh7p)+J zi6_C8GAjAfYE|z7k57FA!s12d^*05p+rOm_Du<93>+(I9 z4taoV86 z@4llRP;iL*hrdIU_94^ZAGmFL)lB{e6ipv8t=GYYUeYXIr#^?_>4HX8RvwA0!j>Z5 z5-Ba>Miy?_HC4U-j*?1Z~UP6hqPOQwa2+ zHQg`-o{?T1-Q3l~5&86c=Ck+J4bCg(ybsijpq98PU$2V$)MZw6ZDv(7_Ey!j_ssF@ zad#k9#f)l;{S;c~0ZeoE-gMok&~$yk-1VtyN0>hMsXC<93Q#rw^LIqGrU@S?Z5Di{TE~ND z0pp$jg`3xn_ual^S6S!A47aXW>rS4}7_J#UW=M*s5o4x)1}=G*dHOTlu52~V=c=N3 z-Afxow9e_(A7lcVUP^ZRTpi;?*5AI$?&{bg`ODn$1?*7pD9;8QryejDY=Crnk-2k& zdJUnIzEs!qN+XAxB%O?gp{_aAZ2M9&Rc=)0Ftt!p3z>?y=*(>!C3WdWbv9FrkczjI z$>8yg&t6|)D_CTX`bwRR&vRd?;mlNuOvN#5!5*$&rkdifB~!nzRXtP7B(;nU;2l`= z#n<3$7n$zgNT#vh;C|$BQ?N;W;M{4x+5{3d)ePCJ-f9JUp#8--PiRq{cHkvH_N|&% zA@TEY^rO{q$BA?~SAw1|GH-v2<3s)2EvlQSC4GQ4izIolPoV%2Sgko{vQr$Yycn!==|@E0$i9Iee?S&317$ z_Dmh@oGVPz*32#zr@Pn+6j8d^&C7>&^MCAS$@i)gpL~V7N#stRb?UMIKv0EB#(b|% zbAB{Wd=JJL+rjtHOlUIhHdP}7X@k>XpKYqLCoc^!@Ksv&Zv0v;njhi>pd#`TtSTcP zb4Ipt(!Mj7Z&O#dhT|t>#EHp=vA*!O?T@OvJoBXdwbbp5oM2)D)m_%c_oU)89}6L{EI?m%-0-=z*un6TT#A!?(!{Z~~lnXAm$9imBp z`VMvbFxxX;Y27icDb$rOJw*|il?t$D(^CQVY{#`hHuh{=5HP-@TigEiHq&;h`-}NJ z5gh6AKm@?^X{Y^nsWE(-2V{o3#{6mKmR(@D8_nap)Y0wi@lBvg66g3e_KMc=zYJlG zMt7?-(nEcEw>sE9LgxC8+47@meP=|&55b-7^lR=ab>{{>GLPfJ=v{x>bTiP=Z0Glm zJ{4>EIY(oP%r_2ntY(@XE?%R1AUWREQ&f9e=E*rjbcLWiHnt!Kg6KkjqogF8JiU)o zabh%6%8X+Kj(EVmMajNd`ZASRd-tV(VPKt)0~V@S&I-Ar<*&}GK43?GtvrMgs?JjHC*e5Qp1LBMjHx+ zU{4W+IV!BpEEvspwTR3htg;WnK2V|GEedj=68j+Rj5eBd?AbQD1`U1OMxXF6 z8sZZk7gcJSxX!E8Jw(ReN@n5UTc#BlJ3sGKT&E{a@Kr47(AuNqkS zfH|mISL9)=Z7|Uo=V~*)THgnx-CeCa;M1Y4?uuMv+Uh8CQQ{`KE^Dh#%wB;ZVn=x2 ze9%_+Xbwf%VH^(_zn!jt-oOd%^cbf)b2?&eEo4)3VOF-+(^LC!Rt)1XMcvSDhGW18`(H{kFfl%gayx_&xY>G&TNB~8Notn;=GM}fHspgQF z-meq#6i|p8gXT1ho{1qu7My%B%#vW3$@wweE3Ly}B|XsLAbdZHgZ?y`ALIHM=kes> z9dx~h?$qWk`b~V6)!^yG8_btA`nr-C4}BGa`p`wFQq|&zKNBzTbk*f0b{ zvl^b=NB<5AI=S6}seneW9-w8Pn-hEJECQOY z1>zni`%d>-FbN^QrI0)ua=}Pq9->S7;^iXV z+fnZ;xb~16F3K3wVaTu)>>W~JGkchxcnI9a^FAacf5)vY#ZYVN9h{rQpSAk}q63Qs%tf1PppGwF_tvwH2XHHSUNQg^2>Iq4YyLQg_UTco{mDTt$e~ zOGi${9U7K5#J{}rj?t^9ETsrv;|1}w45WkXDsn2&d z&7p%$j+4s~GlUP_k`LkkXkoA@^D|eaIpq*to+tNJ^7yG^5{KwcPT2hE5PcFpOEG)p zSV}mDrk7IcD(m<|b#Eg9rb~?mbKka-j8v7nk&=N(Rel)UZsIJPo zV1B5qbW-FPgE3>5i@LMo{eu6W7%p z!n5z40NS142By=2HDnw@R%HhugJVt` zqsO-wYRH@r1P3|EnOOon$1yMMub;=JdwGAozcbz}>92Y7`D=gO2TYv|0MvS_=|4cz z`2WlS`V{0^$n0A1@G3QmbvPS~QXQYi>~Kgcc> zE-Dd6)l%y$5`m5qK!y=O1$>5(PL)Q!PR<^rKZWOz zcGa(w-3Mztj=I5IKSbYc-Wa1tdEbf`y~-o>HSof4*Ae=7e7>`v(PP1~O*0F|>T#Xm zS`ZIeh~9{g*?=w)wpn@>#Ea2*yxuA$Cd;3ZK-4FBfX>LsC!#4C7T~_c> zMpT}y_=00}MOF}PZazkz)z1bRSqyIS)@KBvF!^CdQ04hSg^i}mv3j)iC3nlQJgu60 zkJatlq`l^4Dq7-V`!n;mWA*;&W?LPnYnltoBWysxAt{AOZVW6GCN07JAiEIg!{W6% z?6@0D@;DtA2X+O1pfL&cu(ZbH*5h>h&UU*+jG#n~Yzub?0&JI8WQy<=plDid`17=b1Mp4t%R$sUt=LJLPu2R{Nfiib|H zQ8}O`Lisgti&Pt@GKcqQq+Z~)gvMsmuj&B&#yv$pd?3Mwk}}sU-k~Xg`WBjUsoMcg z2L7|11TO!SP!gaKDvgMJU$CnPU7>9aX`yTlRNE7NE#sV+ZRuf*0)W&}5l0z{FRVTs zY6iNJUlScT$i^@vj2Yw2Hv1On(H-c`1%knRlFLA|jnCOZVFx+${nAO%h^a5o9TPYV zLEB0I!LHz(ROqJ;qkh2o7Aq>Iqu0C-7lNQOwk zDW6CIKJ6bL%%D&$DN!b1XSo`y=!%A75p!vY9_XBIo-ENN(1FEOn01bi4K8?o1Vg9Q z6}U)lD^JDTw^M`y8Wz04|;nb=MH>Rn#^LkW9S?tNmcM% zS3e1a6KqC|4fkvY)C|plqIY#GSa-JV8@42FUH}lAkz|m2_*7sVwtxyWjq@8RJog*S zCAL&t*>Mo~LevGmgBlSa|KLve1ViWuqy^8!@JbPT6;A@PDdp3$mFl*5JJ@n5sH9(9 z9tXj%0c?v?g7qoe2Q|0k5g8nnTa22G12Q9k+yX5i6Uc7I1Xl|NgBF1RrE$zGrh%P} zM7YTz#CP$y$$`pqhXd}x^(;O#p2Ek%2l6Dg0H8nyg*XMERMjocbhYkoWwAVxHF*oAQBh&VjDWJiuQUO+C4 z^V(vmLCypF^o!$89D2{(;B%1+F?h}lvjW`b3acuh<{!?2{`e^|Oa(SJSB_<2*jS%D zAUwPSpBR9eV_4Q2U+bYlo?UBv&lzjYHCGqwez4yyNUtrdSy@}8kziWoLX=&h zVt*8(TQC=xSvU1I7HAPC2&V}wMc(!g;l!d;016DUUnZX(OiM1H8+x17D zE{_Yh#+w8j$}_)@=pG5gL})u3u-nLlLgXJZ2;&~J1+Y?I4jDkLGYKQm8V0K}ZJZud zlt~;TSRDYMYzAP9?TOa3F4l*(i(ulYIF~VToJ$f(lrWbS>jM%bxhZ-G!{rn`#15uJ$dv^IHoU7_Lt-JnqWxVs`;ea?Fu(*~ zafyWKS-K_~rj240A4)PK_E`<=KcFk6cBNYqLEbM9^Nocoz93|6^dp0aib)@WRRY5e zYNN=C3Xwu%KZ~kFihkqFM1cd;p*aB*g-9OAGWc5p(cpDJNH21jSp8qzfCYFCW?32yPylzI#)w zAlIC97^Dy3`g9mgAzYUZlLou~^5@L9({S=`GF7MR+dFOl5o#bWQAiJU=i2U}kpFUG zlt33?_xz2LY~DRxj}6cK30c>enlto8lzrxdRCwG1s4O|vEIvaw!F=uBGa*Dvnm5n1 z0#f?9^NQTE-mGXF7Y6{NNod#@! zGhCmT2%H{;+li3>%Wq=pU}))MoiyjUVT-9fPt#v+vuSYCc|ga_h7A^NLLEJuhK0ra(Ho!z`VGr4T>})}M4i+}z>2FKq7cFDYA6sw955 z#jLq-?;ZZAR&_RaUj%`5P*a# z4_E+ao2EbLC!s=j%jLyoCV81I@<>fRQ#4BtGsTzd$-tLDw`s~7Syjc7N=+sT48U_` zo55Fr_`tI)G?DC8yg!XJYZ!2q4_MP19CDhv*}ARy{S|<#&5O_a*_ex!a5Lv>eRdY~(;O&+nOz%;DzXBl zFjIYv4z!vG2?vmvdaLeZ&c9UWm|L#VS2;JCaX0E~0E*W{q_K=Rg@ zcGu!+>RB`VS_lXpH4j~@FUKc34W0VJoIVX0@n~|{G~A0I_Py!)*3JM0bl*s0s3+be zm0$(>+&FXn^|wJ?5OQvp@+&@FtWi4Yfc;^~1b!O3Zx*}-!wd?c%41D)>nC?f- zpzHMs#Tk`3Qki+^dOf$u9ztl@g5gKrGoxqf{_QzG(D~%!@$kXM1iAgCfQQ{M3ufw) z1JN6QA7mR)>(Alu26k@_=`xfLy1EDA!C${Vl?hU*%v`2vrmnVFcaRx%gWkWgjvU=y zP;YbC+6$NZ!UbHD$(seqO_TZL zg2J*aA-}+yG|qto;u34dxk_{IY(XaGH{)mP@PEKQ;#fK_em7%ZThr?1mQ^7+z{A>` zGx0F9JdkmS>3EC&k_cHar^Sdm-YO#^3KpanqZ8RXL~!?bQ$o)&uP(;g-C`y@qq~@! z9>k*BW*VN+&^Vp@EUuFpO!sH8>Kn}3$Mli-)c;A(#%Ian5OBc*^uwU#^OKS<^*h&G z@C3RciC5#|r+A6J)-lD4beW0G({0S)MG$Z`n1#=4D%&-sKb_4fFR)e>0yF0s(3SrU#BwH?IrR_~{LBAwIx(TM;K9%wi^%-k^Q=aj9Z z?**^ue%VX6Vr)4W>Bv_wlfi)g_zLLkBD3}t-K_(*1*}xDl>jH;`r;Ouk3Zt-hw6pg zjN7h+rh=5+2mLTB^_0H0zhrrzfhLxWstkc8sQ{jg^cSWAxYzURe@u-x_8K;|$*c6p z>=%*2&xdNoid7K5KWw(I(no{5jd>M(=ReGOuj;c3=Cl8K{z81IXp?+|n45ncz}BmMCRuj-^5ah9!dYhY?85e2R25}+T__>1=l!S!rTy9(WR0tkJSupGpf^fLDy?ZwJccb5Lr zmvKP^ALKY=JZBn@^h(8XE&2xmg4_>Ns;cbXo$lSCM|m}->PRn!zRf<$Yds8SZ+P~W z9{Fzqo_+)VptJeI@J`?VZ`Xd>vug*FK}vN^F7eV`Bo3SBa}SGYnM+Dqw_q8oNqok#w&H7y3hP{ zjMs1Ai|pnyc9W|U^LjXjkWb6dG>S!)y~SL@XI>{nT|v3!z06t1da+pYrRLtrr7#>B zV#3fV$iRfMJ$$U!8{JuVtaoM`=?4y@sLS7u%l6>cH`g+HC z!JP09eOu}BbQd`4Itk5Pr^gJ~ab0SJJpmTT`0zv=I@Axtbs|5DLrLx+o6_0(*c3Bk zoxV4x;o6|Isjt&z$szyL$2wk8PEGf`uWvngeJUO9R7>E0J0%105L%cHX@r)x2(6Ql zsr>*~nCr~S4UX>!)<(av&n%z8blbTu=GEQkB;Mw|WV^?FwL$((3ESXCbOq3(FX zri|v{aV6aZ$UQvcr#i#XymW}>feX_irY&s|S}h^7@^!WzU!2I8hF0)KksO&vonY4%^0`KGy^2xCY|oBFN;S|M{)?=5u`~q+V0Mz+tY* z-1mhpuWXRq6m>x<15)q(F$h@Zltp$W-~2+4b-N{VDzQDnRbWnj8y*#_d^=@Cat@o` zN7oTjYs~PC;BaP`mp1A{!>e~nRMuB|D4II_E8Q);)J9$P6~?#AEcptjuP@BIU+G6N z%*5AvXe60a1y8NGbf%SIJd!l;eyxuc$LTQWV+Wv~lxlLLZSt^h^g1xtMTG^H5MU~*SE;LDIKDA$_`t! zW0PLmg%nAMPyrx|7kL;KZD)=LasE8UtTAdUq(n`o?^b<$QL2o;kiTY`ySM69;aSs( zujb6}^qHxly!oBJrgXlL(RSV2%=keBJFotr$6{W~e$)rI ze%%vC46K9~KT?Z|ykcs9)KgJx(~o*QnjiC%J_Da8f5I{JTl2S{^uevra#!1OSGMe- zOsDO7nr-R=P{%eu>kAz`g2%0taGsSWUhwVZH>3y4(0V)AoI20c5 zXc3wfYP=@98@LyOS*7NJcH6$N`D>=Y#N&SSuVH{E%;cT!*M z8I=_3qs}z-jo7u0RNnXA6GVJ7QhPJ< z`BUh9fe+tE+KZbV+B-Uh#m9PH=hFJAsnLR5;9U%cl5;$-&UKzo7H4~o#jQyjTgwWKF5}f%i2SlLGT`nOB}%S>_32 z@^QHb#ss=a6`o~GXkBf~;{0P7lhZ5F4j8DdRo+miv@wG-f!hh`q#4=P+YhxQ+IojN z`DgOPgc~+I@adYjJA0*r5a#&m(<9=9H>E40i)3&Zku#$mBAT`$mIs!J<{imAR!oFspaW+mQ7haW6MycK@g=%zkli0N5=Qdd?{c zQrL$=f2oAbz>Z#b)Ot=w?`vGE9o5OZ+c{xvxbWe%d##IJGikf+@ibS9_-l~Pu{a^ zgQ<06*tuZ>f#|I@-b&n|J=4|ORk8gSZqeNO@o0$vZllDQH@bP}glF2{1NQN5ESLcb z)HNW6>&;t;3a?}GOXk$>-r&S1yb@}HQPLJ#p)7YHhPJB%yvp^NXgW^{5rsLzh3Sxt zJ{^+Lr$YX6vfY7~1L|l(ZH?oXesd3N+Evb;u+mag8p0;o$RcY@-yYs2;rY@5^LP*M zJZGh;?&+O2bXgwWAi$F%kveL%+8^Th3fJ%O`I{eEMu;#OivpS9#+>3vG-S@cDjU2u^Hw%|3m-E~O3W!aNSHw}sE{>n$isEk1vfILAnq z_w%j^j&J4AOYyh=4eNGC^1=PQtKCZe4z@pUbU_@)Kr8UL@H8AJoHI`t&Fb$L4emhEHZw`T|*1d zGbg^{wFRef`72)c1V|<1Q#`kzd%fZ2YchX!bqDl!2Ux`yD52WULk*om89eiWZg}*s z*?u%mJ9M^}H5%GjGKd_gU}1>%-4F_hIAEAz+X15~>`CN$y;vBlK(~qJSan<~=AmsU zeGGuJKb-5#K`XtZ4x+Oj=|4WaR7C&7(7Zw=)a{4L5eFZlCR#o|&?(EtCzpC@2$_bJ zUS$zfIQt<4Ew$eGX!FBLFUDbm`7Vq?;R~C4T%l<&#dg??%7^_-&7>G~aAZQC-q6ry zbV05=M67QxB0jLeeAzNSsuRhC!nOcnN^KJ0g4P`udRAx`@zt;a5}>2{FlGXpNf!192YBZ30v1`}4+x#4 za)fltL(7U1ASh&rWW7DcA(H@&M{!e#iDBn33mTx%rq`?9$z5oKgy9Es0J%s?h17d2 z8h-4M=ylU$#c0kv{i-)K0dy-x{Y9J*SkQAq0-t5e|a5kdYH1>5npiL#K)2)6M5DMbOt}c|+A~1YA z|22=E6K;JCqW4ASsn@&{5;FotE*{}HcuPpLF?^8K2yk|}*vg9yHw>0NOERfR7pTx2{5{-42)-Lq1)RC=?Y{WL>oMI81w-k z#?=#Jp%^TE2oDT#CT*)EHtdmTh)c)NBmeqTSJFh39;AaRhfx9!VM*q=f+5UIm1`bC zR=OOue4&_*wL6)A&A8QG%*Sd5k7V!3#LWdcSK5io%^C1G^&^PE87WYRu)YNf%q53; zc4t|`yb+^!!hc`1O?|u#-sps!wE~P?`OuL3 zYaD!kynI2t3Mq`OkC!n|1^CWNR0IB6>MDs=F@&1U-NU@6`CO+|lgeApY-mt&oIBhb zSB)^LgSm(#RG=?XZEM8rG=CfJ9iFNqNC>i)q7&@)K_k4AjzNh^c9uokphwb5wQVIY zR)zh8@71BFXb3+m>f=%whKgEB(?dZCJBljl-nS#X!2>bc@@Qp!ypnaNhJsQlAQ1p; zPN0A$WMl#kbIwTb>;%eJM%&iM+oC)&N_Exs@#<7{gfzO*u0Gz5zc>WcUR5uEZU%2# zHX-d)+b)&}#G~yP&v_KM$4WrH;e#^{rBCX=<~zy5M|pLsty}>`mV!}$^gABH1p?7` zwRI+Cz8Zsrc9SVO!s|j^sJz+c#N)j7E>tJ3JkIM3{mA=|^A2?0OMZNuw?jD>njW3A zTPMFi(c4!QUMm+lR!L&kgSRK@onMwDQ$v3+r<#r)L73gB|0l%9DrK!*futxWG2X;LZ3}jQ#9T z025m~6y;GTob?7RgTJCZzI7rq=b>;#g4P%zNhQ4VARU2EbMQw+(J-}+Q72d&J4;aj zje1UyG@x5$g1YdIk1a5&L9~5OUdY1!D+&uJBUfPlYme~G6o2qYR?7S#MVq4uT&$AK zpuGZc+6PZ0G%{5yG}ZBf)PJkW%o@?XRE>h7aWFhMV>Tlee5>Lq5TXy@OFmhqQ%n`^ zLze^Z5rWoyn+O&QFrT)2ej#CrD3~U&tTkE4p~XTjPzDwYFfzniaOG%;n+rU#hWNBq zcOLHd@NyQAE->THqcoQ|n+h9$VYoG(_RBDFAWI1FV?L=V&%1t_IMkvl@ruktg-&_P z4bB&ui9ERnY>`D+aeo|)5WhJjPAs3X;G9FBoS%+yw^!tS3=aduCWocWKiCAoMF3RT zhA$T6z>f)WX(-Dqc@+wqFDJdcR#~tEV#hG3M(x9>sFJ&BfI@h}|F`x9Wg zqMDZ%_%5-T1_cx|92_Ug4{@%JmQTZOWDgqV;YHzC0zN$Dn3h6a@GiJ7W!V_|N$LYG zo58q_d?!Qc4!#C`uc5gxBuQL>=m!QN?>_Cw4PmDi#(_Lc1_}jB0L{_mey~!?!9S#T zbE&sCvDR!oD6h=SdL&$yg|iG81ZB=26t0M_0w(neg$9KH0)IIIqQXPO1Da#Cn8ruK z?V_(|=Hj9Wa?v_KaG5j{ef z?coK$!7S9qDxmYE0T)FaY?pvZGCW*F0e$Kl%WjBADCr6ebd&~z=`_GC1B#G+{JYKJ zUlZ)WwhzoLakNLVrJOjff%nIJwxIHKh$vKE7WI&c$umy%b~^6v26OspUN^{OPdmfw zZ&sb=m8X8UI=%V#_>A9=XZ+rg{yo5qKEo@sWyhqd*lTY_I=s@}78hIxlxCn|GRC0i-cc zob9!lJHabf2$=;FyhGhD8_e$~fFqJYwl{yA;2q|^)iSR8xnA7et<1P{alNq1IJMqw zUDy64@K#6}?K=nn0S1Q3?FroRq0)k%@Vv7rxvUma`yg9{%*t{T&!F?$s1j?M>ouyle{+0CWAIB zo;}ZN<%FAnD-}pM?jmY>lE*# z;_VA$8sY`CT2g-9{bueIZ!Am;dS2p{7c;_66Z~Dn-eZ9&xDe>_lo@cLcW4=Rh~MUz zbK(DE?KO2<@-OgyO#@s`n}%=zhCxdc6Q1$GtWGIw7O6L?e3?Q z&X&e8HBe}-(!=;*4$ge18P+C7L*o;^^j z9VbCTz$B1-4d_DDv|8j0#8x>jCJoeHL_yEXTCyiU3?~w15R~L-anH+I_3#@`D2;K@ zP*kM>FKgv0$-0_Zb={&c9?}ex0)R;P0yh=~#O{}&Qz#I1UeWf$LIa40PSc3DFn9&0 zE>@T**s$n@UiuF@~D?AWL*eG&~*ZUAMT$yzdI0AntcBRL>-pt6I zEgHV1_3$p;YoVbb3Sh8mFT5qR)oR2BWE*M5Nj#uuAN)2noKwWIx3!1Er_iB|#iM!m ziKt;wm7>}^(B*w2X1$}8f*%2i5*w=rVISOB>|Y#gi2 zy{%LI#{C~URTXt6O!)8m;}wrhlmqH95z6#2V!=dgw9iGcNzm|qE?P{2?cy9UYm!!{ zoiu9A1$Bb8w%-xzXZ*4}mQ0^wd6SoPDu(bbk?d(f{^c$1ohBt|(-!vzNiNwlXN2jU zGe}esS~}W#Txbub7gQbsF%J~Gb_0|_2NfpVw0P=}(>Ov6QOql92;!Gc<}mQ9E7%vbG-;}q-3j2R z?(8JX8G?*7C1k8m9`Q?dB11*cJgaZ`9Klx5WBjm8+&yH>OPT?*VVp@2pg;p@lK5k$ z!pwS(*fSL($1g>}RILfWL8G7ufA!we`oijH>3iA|tocsUv1ueZ+53mxx6M z;`luVM|}Lkn|9dIBt9bMjx5tuf+XJKm5(?m`76D!kT^O`OGW!PrfHdIqs(-z?&hwT6YhDk&O0>ICkrPc8w?I8A?U@UVl z&eHspOLzPs7g(FhmY%J3qdNo05R;~X{(uv~Z344qYg>ROJ@d3oG3I@k;^&KYA8PmV zMB|`&9l)ROYjkS>3Q&~)&hxYy!ZlZ`(%KH=51Cq&b#(w8^>k<5nczD_QV4km>*Cf@ ziIV^_SSlWoW4AMGt~T|rU5qumSX{LEK%=08vY+YbpxICRYJ>3~-qy)p*}*>GZkv!k z(CvGn{j=YR8}l^#+Jlt&T3_Nq5FQ!_S0V_lDf6{q5r2j^a>#!L^&!2^TA;mBrbrg< zwtjyW2|6)B^b3(BHaHOSe~!pspbf$fYW0z}|F&AP7i#lv%Q~@8t3|EDli$F!BDiqo zB2XA}0<9NmeH5JI8$Q-*;c@+AtpOf&7Hfze8u)NAm>VQ_EddEJNAy^#wQNggeGJxt z^sXd*iDWoXsn7mVn1yysiVWLt5YZYmndD4SV5a~Ixu(T?tF;ygjD32wwivT8X^qwp zk3(xT_~!-ceWtzYLUQ$bSWxAQW*f8%>YrZWU8X$_*UBEtw8~`jgAidpFhkTpIH0>| znRd^;BV8o=P$0i063-Yx{8N(%>^GDBKBW*h4J6+v&0}YY=ufozC5KSSreLk{9k^Ti z}pIaXMK$Xub-{QL4_ zR><qCKPqoIWfSC+F1E~m51PVby zjzV54=4!2^7`h$w={B)@yHqWN@6h@*6h{V zV#!4B!{W>ri}%49BVT;CPiu)sg|E9SrMVH{3lVE31nAPt(j_PWhPVjZG+zEU6-e z@*1)#yCO0kkTNJ>+UB_LotPFTj&*P+P=H$yL!>}hcLQ99!%^Kq8i!SOg1pt1ioNAH zMXHX@;t8U4M>i7(Iz|)|-8;HV<^Wo-cK3l)fpRsMh(BEA`MQ~GXQt>51sBEVR~ypq z;MLVeWT8mxAW5u9+J%$NIEkyha3YXqf?Vn7(lfG6!I^VXflwS@$}LD4XB4#o8AGcL zI?@pWG>*Z-ZO?+5QG&!}A$6(fqFs~It_kG6N%owfEof3|2r5oYlCk$1C>r=gYU15a z?&JofIw%F9ERiROuJVh5p-_J|Kvr}Ti41juR8?)Iv(W@83D_rIM=e`JT=EEj9Pr6N zuXU08n^GwRe#j?)0gQJ7m~0y$0-|^eh!A(pDB*w}Xhd8#gJ?*z&<(QgIjK~4PF9Q> zW=BkAv@r@Dk#k!KBOPid&# zJ}n{aDp)$zrIEi(N<$RLR6W&cHtCnS1LP_v0k0pRAqv#l(};b6wt-J-Fnwd=6Je}Q zxEkCE3Bw_IW;hF_{*p_VEqsTy3$=(>H%{Ww%yRstjY;NtwCX~(CAN}^okyQzV_JdRwX(3y1684BSIYGf|;PcC5DN0^XfeM29J$sB}V8EONXK+C$E+z;nKa7>mh*o;II0Ysz&zzB#b2-?~}fkpB|pWXs4jCD`|`WF1>l*D|I%FIN@ zbgQ{y#GBfq61eBOYEdC^6v*LMxGOpaxs;s`hLuvUynW0t*Sz`EMB<&{f#6=&qZ z+uB@B66QAma|;m-QGA_7LJPT)4^07K9~U>`{c5*dTLIB25t0-nR#TTajw zdB-4;TpXBxOzY%?z{LH7*0fO(3E<4zC4dR01P~)H`13r;1gkp<>0YrDgpMH{obUtK z#E--eKWJ^^_mKM{BJYu{8nmNO8bh4*k!bm&_8!QOzQ>g^fv6MO+c3@zOgahKx|ta# zuKlD1v>PM}6`!8cnwF72iMkG>lTA_?IC*uSSL)7*>nGbkQR*~AeIJPjPHS($#&+*% zX=2Q*{#RwNUj>BW|3+l1?_}pQa@( zBAt46(d9Pn_T`ppEjMNyoMA0DgfPVoOI8BnD_U-YocchzMF?z8hChxTK2s?R3C$_t zb?LK|Jz|+lKTck`6hKTR=NH@=9gAZF5Aw=oOUWbM2TQNKP!u2&u!d0MM93{Y45D|jp4>u|ih8OQg=}Y+b^Z}xaCL|al2@D7i7y^dG7zu`MF#yBHfEH_lp>iC7VPjx$ zyaYp_f1)1k#8w(wTz^Qx7!RiC?>}JDl%#thSq+7@*ht5PcQq(w@Iq2}MwCBZ>&5{r z+TeR)8*+W%K!_Uzp2b~6TTAF;6*zjgOVvAI4Fyv5Zg{}9_g;AA5pQ-}kxV)i7~Ylw7~!}-e4*k(t^Si`9qs2@o|Euo608a06E_m@^Mk>cZ5|5lS>g3qB65c#PP$$Q7#$6PN3t`Sv2Uu3ldm7U)=4 z4^Y1o>Z3Qxh`{&;`m>b2X6S>JCc~s*8o^dEg3)^j`x{3cy?Pi#6*#>p1WKg{mnlQ~ z#GqZ`{-%hGs(N|xXjQ#<4$*mP@W0O)$z6)W!PIaku&=`inlZyh8m)MjG7mUt$jV(H z1tV3RfwM!37MDv34oHBeQaB8k5CfJa2u1%8y^$#?Ql&A*>}b{xR5mJ3N5Z1CAqYkv;Ltz@_UM|t zO&kKtpq`f;kx>MZ9PG;|w8l8KsQWmX9Y%;sljw4cOd~TU;`$_2$Iw+xEb@gVik3C> z2!)9!Yv^qmX_K*B#i|mXz-BXd9ya;DsRHV48L;!t^+nj{7O$n3j3h#z<`F?_!oVZ$ ztEJy>S?Yv~ZngDP-_pYQQH(`MWKggjauu^Iby8~UrOSlOq9S9sSf$7+$Yc#cw{fwk zww^(EA4vHu&7!rEfVHqxZ+tFaKj#%9y^R2m@p8*2)eP5V5AhbR%3vVmK+#J;8P^zl7oaQWS@Zgk_#O|aFD~a zGKmY9;;*~SH?1<*bel6?@s3mOitrWFAJ)m|L@UoH;9;&)gaElH+dxHw?Il;v=slZZR#g}xkPhiN<^qCrHZN}0Af zhiRmf^?}V$sPfL=AiE9nMKH-CcC zCgltBh89btVkuMu8ZTR<@(g-a!Fm-h#y8cYi@dKv@9PBL?`f(RPuz?Jp6P7ok80?A z5S&KTJm??6_N)_XGrbB9+v?49QfH2Argx4T2g5X4`H7HNz$6BEUhy6fYID6>+-cp6 za1T1i3Feke`yktG*<7EdTo-4X>zz^61NY0SX5X)OLCV!ae;QE}ySLCwfXaKjg`Vj? zNj7NEMV%C@TIl6)0-tE1*M`$_>H~WJ2ICk>zq->9+5taIw1oNJg(w3OYaxH;OH;WoA^(=xxx0ZTZhTN2x2y;GQ z`;Q3;tp>~{)Oq$|*xFLBT4b#>qt_4EuS>Vm?^o7~KCSdg&=s=Q7~kcqC%(PoB+`nh>mekX#f*AJ!IeK#`_`L<)h7$-snhXaUtdBL=^q zcPgyRrBR@(Jn>L(P{Mg)c5e{Rivy4L(U&P2ExfTJydMC(P*ms#X;H2s9_ABNk8w>TQ)83nh7nvkZVKO5W`+B=1lNShWawC&s+2KV~Wsk^{;sx>L;_ zg4vdeDi2uK{lOGm_>9fL6kU~Qz6;#@n*OB{bB8w~;th1VBSe+K*EI8r+CwZ2S|Gah7l)d_knh~zKCru&@As(5eS3usNNqSwxgIqree8U1UQ0R^E_*|e5 z3&aVbzZfQws0W@NgG86fdKR+tCSz~S5w|AmrI0E$MPG;1k5iC2Q9L+RZ%jJ1WZ*hI zO$Gx=#+UP^$_jT))w|K#;_@xIAi+atkZAm#eB1LqU0y$&BHtoTj+2bo#EGtFYz;Ig;` z4bD0J)_cp1FIi8=6(&HXxE)JJy^@DQCrr+O!WUAXB%z02qDwep%}T_8l6#QmBvuZT8%c7hK?BGD-{NJ8U*1tcRxZ6@sEV9KfDVErS6U=J zI5`nRkB55AJHEncj!EK-F+!>tZrZs+8w31{e6n#TAD3-dAErw%Dk=1P_UQmJpwI|J zlEu^5eL@d$PYgPM)dMtwAFKCsaBIZr3P}s(Dz1w7%@VU zKdM4g0a-5coC8dO5!fiO(Abois5BL`fFC};(_k$DMi7#~w^K0h?$GFd;=VYBP!>S$Fw((O=GjWMUo z35<#IwG|SYbTyvqbEV$ox4T~eg!&RBXIIF8o{2x)wTNR z+k0MoyXtO-RJOb6_2jhYlLl}bQ0jURfzR^`LLywrn%cH^4IGfvkKD)D&e9l zzX`}wl?ar;w@^vk$vy%+Cn)GNkYJweYRq^QG3p!rqo-l!*}hBPUqrG5RnITXD(cJNj) zC7QL>VO8VsP8FTL&M1<6=1AC8JCl9%B;~I5=*#E5&(C?bBfkYrh zp(5CD9-}CP?f~VSkly_T$`KI=DFN`;a*)}XY=K~ES08?d>NA}+fU5reJjC8{cHNux zI$<|xcrb|oh+1z3wOSzF*bJF(=%^#jz7RCfCd8|X_a-IC&ccS1V%(yNAn7AG!DYPg z74*OJ@rsZJUO`+!-(a^33 zx7ebm)c<=hgJQM7jBo9ZYatUXKHQ>brA$?@f`6f%RTq0As)uouelMC^KrT=h&`i!q zyPN1G&6xM9LZ_>-%Rx-ASu^Sw6*6ox9)#xw7MVH4a&bA0v4u6^Z1SKK;Gi1s7G|3` zT*AxeuI{Xa0^*&mdRWp5-FijKR5iAIXn}64_;{Q;Tbav`wkOX8K+1WIq$FB3va*{L@R2UcdZAa(EeqW8|fNL{o*k9-|sd3kyvlJ1+k zAY!R9|E>OhXF~^AHvYDEz8mTqkk*u;$&~!*!q0}#DqtHYW-CkI5?glb+3F{6iOak7 zZCzH4f|pE+ab`4dm6Wht!7rnPF?o!gF(1EBVskKK+E`>%GxpTf!{gQwNCWc& zPah@K-$P=>G5s4n-u(`IK2qQ5B&DeKJ+x0SUHxAF9+|yQfstJ-W_wWAcc*l^zM|J@ z^bj`C7xnI_tK=Ddi;864W&JHY>iw!86^(w;aqaxyf7C;GOOmeZQk!L16C)Fdwk{q8T>S=7Vx^{|i z=`291VlQbzaN!;THbBZDRl%Bfn}Q@*D~raY*YINo*AsjXA#0(k81`>yn=$quH2N!J z8xn_4LA*2>eytc#fd?Wcmt-WwcFt-jBZTT^eKFtxZdMJCg>FWkEML1>Jv@qqv5a`2 z2Vg!hH(+%kJwylep576nO&A-9BHO}PE!5%+XN{ufqbX^WNX+2JQvz+n0pO^W$Tihi zP>-ydA{Ker&H^6$qIfFt!`589Lyw*cXDtHltUM2U!f>)a#X}k zM4~@~BN*ubzKvkDF`F@wtU|@r--Ip>xBESK1UhjfQ4xb*7C94bgpi04agsu`Ud0$nnrbX8Jb4;N#CYQI zDJa2Ff=9E)HvOgI9EY$1ynupp$Sz$y{$t#9Zey=?D0eyi>SjOABeW_%G)BW z@kAQS=#@owL=my_zi9o{7* zOEQp#^3{7ujR>Q-gt9rHDyK2Qgdiqd?22c_b3*$?)KqA{Oj4fM29R#VORK0d52k5- zp=+~;$1I9o79)!1UjV?O7y$sUIhxr)2#A3RtZmpAAk9Fb6T|Xt0&Ac1e(-&e+$5$} zH$E}fBXto-5<~q*;6tx22ZAjK(hWc&@tZ4@Jm*EobE;GBHq88=<*5 zFFIe*P6yImTV9qK#1eux zBbg9@O9w6~XbJB@Fzxlu4a~R-{a23kc7y^A_z40P?_BUhq;HOePMYqR8Tke7m4VFz ziJA{?#BVyj6Ctyq;@m85U-&^?!C8a?-cY|==-+)VOEO7CGSHttO*hhv9*RBIKPn;pN%Vop^e&$zhiQazpJYV=W0Oj(|6DR#_5??|o9jU>kkeW*= zCsMw2q~_Tr*QK*5aYrfT@y-h)=GS8Le-gb)v$s8`;^s*ua#v_&{ZGu^o9L`VRh?6@t?A+AKm347m}1=+!7Twx;u&O8LUj@ zgSZ2V2rgRt*zc8W?+TbtlBTIhlr*3-P;|abRvd(DolKUTCZ+5YTl5y|+t}ymhl(JZ zwzdlH`6M!Ei^ZGs;Hv4wn+Di%~`Ah$s_xs_}D6} zM38N#y2^+nRauaEYfz05qq(~pYlBB>b@nVCZ&zp6l@4NX4Ymi5hibA6JYK8GhT)yF z7Mp;_B3i!4G1xN__!X(G7RKgeKtL~CYKqk zF<<0_IjP&bNc?Fq+~6o)Z^&xm@o7W$8XouD$6z!N=z1T6^fezbqvgxxjTl)C)M`vG zMX$!}CLTSSFtRRN&oNfW$0+U{+C3~SXtr-vEFwtW1f;pj+g6^l`$Wg$am_CksS^}nDi=JOa(0y}x ztpNQIVq|Od=7cC{jU{wKB(`B`O-{&z0)DJgPnkxHhOq$#D8_Y%kvka&9CQ}p#@uPh z8Lb#ArXxqnREp+^oHndOWYO=$&u!S2Vkev?_jVFn3LG*xx4;(4hYSA0$lI{QRPW?4@{f7Jqb835VN0TnfPqyldJ(!o~Kv^q-s9J zx;8KwWFTeZ0Q@vE$sMr-5_|0gtgwu2c7o2s4R(U~=v9}M(rp#O91RaIZ~1G=+LTv1K3I>dShW+cydYG@O9vYm)LWPwt)h&i=zXv3O^0FUIttMYvUF6 z02bxwSAa;q7KdJ8k7-}aa#det_gJ6wdX=@r>~!nQs+NR~6ahS(g>)6t3BFVwaUnW3=o-LccKq~?d(c4sq2PNo4>(w2rc)6I;9TU1-Z0ydG#p+kt zL>w@!Ut`ZG%GAKh*V#})w6))4&1l_$_6C&xV#kJccR|d4lkLSPy@!Hl#`2qy%RUa) zboPH=(^<17wZJ28J*Ov#*5;ducrc zw>*q;LNE;@2IF`6HF-ag)AJB|CxyNAt}q2Hv{h1MkHqlk3eeDUiTM&3cq^4JYL8jqFlhK-en zPvkiEFfzN01H1!b+c<2$eDUUZ)*FxW;~8!h7SBy!uj6rQf;^G#pGdk;du|M<0kjb*h@yV=ExyO&6U0EI9K+0<6PO0{{z+@wd8&v-|hWCHe3Ef zS?Bl4o)3(lFQ(6z6ZPwSb1oOiIzL<>KR>rX7J2+5 z`T6@F$rf&YB>VZ$LRoU@LOB_?7Rt}tE|Q&}w}=f#)s;S$AQ0=hsnGwIQK zLUdTk9<=2AfgLLuR}sj2vm*^fMMl)l7cLsTyM>~I#xtJzUJF>rDf+pHk5U=5oI zWYGLGLMvwjOV(m71FgiYD?}^ujz`%0hM4_IwDQV2pp~-%XeCuVx1Rk;2;s&sJy8tW zfHQQRn6`mErssW*Q*w{Ex`92EluLTjJf~zpz4IsmVDqNTW`4J?_y2O;vAH&oZh}mDsV*75&$1|I74@Le^k++GJ zP-opEmTY3B!dLA9+bP+_)#BJD9NM>k>w*^7wG#v zkj3paw8>{Fc7e{fSQolgz3*{msI%On{9#tXV-H%PK_A)50szyp7jf-*rz}kul}5O5 zul#Ku7(lX&e2d-QG~yA&otrmk{{2Y0bJvF-p+`rQCmAr{p+ygU949X~a z-vZ^_K0bnwe7oU0`S!2ik#D0lPPZf$ofCqMd^_k6d&UL~mVUXzEGxVaE|)}`U2NxF z!1Bx0zX!`7CRjjFR6fc!{S81+(fA9hv|a@f~@ zWWA93&yQ?Jk`yB9#tNJ~9_bioY{1WO__^et0532{{CNVB4Cr1@vUIvW9+8KL_}9R$ zwLA%uV~*Hy5{K0Sk@6GhkU?VdPax{&h^;@d)NokC(wTs;x!Xj+PpobDwvcFd51wMp z_(qZdQhdAFr&v~D>YG!n3dsr)cm&tCroj|i29q{<2k(MF`e~e}sbA}0@@cTtZ=9vE zxP=K150U8MU{sf%Vat^5;+g+I*Y$(Q`wvTqU#L;EH*g^t2xEZ*H(ko2#OG85cW$0# z#Sz#Ynp?awBf*L2vk=3`S7qyv5CLCul0wTmJSb<%7IXvm%gOj#uu7DYS?HKe5iLZH z$Pv@ef}mI^(tc+B@tF8CYaTw$m1fCJr-_OeK+@g%ncat%_x%D2W}z7O3;MrMG&(20 zSat4BU--|NT2)pN+Gp9pnnN)cup4M{r@{v((s;cli{0c@Qy3uTP* zm^)aE=F#tb`Y4a&97Lzw>7!ehRl3_5eAzl|CX21t<>~uF@5netQOk*gvkt#SH$Y?tQx8wCfu6g`N>d;1eyZT>yPhg3PI?=9tf-Ss`Xl6=y*#l#x3Fg6!0**_gC|Pr z-wytyg*IpZcZ0W@x!d5=?S9-1J(jf#+#Nq!O@!h{b@pG#u#(%wf5YcVw{M3Ega$EHhK$vT9~H>P9wGxo5b{YQYVs2R zMnycB4E&N7^l%(>N!1=C0uVzP*WZ=mD9F;GkRp{CS**du0E>rWtwNy>MXS=70)b>$ zs`tb0KK<5#AW`@`A*c_9xG9;gdOu9NOgfM+Ek3UtB=Wn7 z*DIN6%R5idu;pX{?Irn@8#EB`El$Hn4iafOPUOhIQ>1nwr8Zq9C(XEh8X0nv5?pDB zm@5uz(3Rv+Ni!^^FZ6)@x&s|mA)ujq;UI0yb|lqSDB2G!UyIjr;2LyN3?nuK$*8C_ z@)L0=s8xxDk$Mbi!Uxokj*?ytUUZ~vKyRT)r#4It8RR`ZjTG_yHpMUf?&&Tws@lA& z#4BARFeE7~rv9Ws#|KElZknP*p`IF~y#nS31X64*hSE?i9A5*!+YCWKrMpX87W`<0 z&fprb5I{Jh+qA>Qa06 z6)~}@shtW}jz65FXjD(<74C8^>5iDfegP~7)WZM=RuDjy=EBt4h8D=RL$<-of#60? z5~hK_>Fh2Ju5j1NIW{a97C|u%AtB|u@;)}m*J;jSkwp_3l9CaOESDz|lbNbe>*Pfr zT+|_$t{BXqs}8j$#qrnGq&OymG(hMnfSHC;9zBPw5J-R}J8Rkvk@!wa1`r^iqIK*e zzgUuTnGHd%=RgG*t~?uP?Gsgml=)uXrwIL`xe3T9&V`Ox^;7Ex{J*5G*EldN#~Lt} zi1Af$^oE)ScM;fK`84tvgDjC8rO^@d?m8%I{~8d=y0`@Mhcnv8vlUNmM-u(Yazxg0 zz`u=x$3mYe!qgZOH||w?`b7)I>)FDFxr}?@K`fTJ`L}qC2;-UXCte=Lg@R-Y4~Nxb z0H%_;!J~14MwH~u@i5Y0cR4GSGx2?949N#_O7gN{L}@8TdJhD{Us{qU;|_wIC3$8N zWUBxM7C1;S6Hi(cn3(0`Wo68Byz~h;6D6~BEEqbt+o$p}q}b9Y`FI&LusD^I{T#kX z76qx?gWoq(G0viIp7X(wgjAYh3BEVW(`VbvN-p^17pU9pJ*#B3hVfA8?rA&~k2}5( z886J%H z8LKy)lf8F;Kmy>?5JSUILhzfiV8Xi-DC$uzA zF0yObYgbtsiJf-Bhr}j3LEZSwPEa?N+X?E%!q9HKXtt9iW@T|N8e5jdA1_9`-Z+SF zKti9y15u??D)MKG{RUhCt_snbFR>zB?%!E9*Dm z%jWS>$d8oy8im|{H_$knuXfgY*BOopr(^v1kD%J6+@1W`3WBM-y%RO=<>iWoxcW;( zwOA{}m2Mn7VMVnfmh-rs$Uq`@w)pT~J_;hwDpmMH5Gf9;!VmC8xB!bRG(^{`xWMs* z7*>@(kKj_5s`An)_*!;Ume`2%7TDHpT#?zLS~Wf&JmvS*ctY5Ix>8-nWtvo-$H(pm z-bDmcI}B48g<%rqs`DDYLpZa@D-w5g(9MDf=|&+AfDNJi_Pf1@#Ng^YuY_F+QQFK> zoZ@RC?7W|&NOleW0m2s?sDV`*Lpw@(vWCG!Of?O3uhj%{IwIm~@q4h=n$e>`ES>L; z6M40uID~4Z7H=f))&PWLyrRS6LM=?JG~!MTw5!cw@zIh{X_C07F8>t2&(;MhZ5fEI z#~0&OU~_%+!8VbWsyFy&Vr$zb(t{1`-xFe$!Cz1c#xL6)BWg9|4=anr=!V#g$Heyy zQC)%H_whVDrrd`uyhxn6kEh`g)(Eq6LbPwhH@gOd#t=_D#YZMbP>eiiFB{e$4!Y4a zWK;khf8?b0h*ldZQrq(en2%2Fd0q9QCT6zhhB(`vkI>#hgo%;j*v`HdL-ULZo!!iOOD4wG*$Ovr67KrUDUU!A+I9TrNd*xIjMQ z?kA|&a9=0RPgtenneQ0UTh zS$;Tuhk`Gg4{@Or=Q$s!fQ8u}=oYgP>>nZw$>fOIG|A2iehoMaBpdLx)4L8zM+m@C zHCn*6&XQ`By+$n{y69~$#0f_&)OV1jAfAc#jF@NDPBe~QOFY<_zpQ?sik+PS?gDYP zGp`jlPF_9>^8kz1F>vWdx=3xzztp}V9dh93#{8g5*&;UI4>oX%7}J8U#G~;8{Aqn8 z$O`XrvG@Tjku9P`Oa6kLHMS+624=ZpD?VQxt_ts@@RV4n^=Sv-jurFnNjh^yrw4d> zac^s$(TuhMMvM(ZBwh48SoD|_GlVs;wwQ`OY&aWmuwg=2FT?82oYuUw z-Kg+hc1K~Tms|6OP;HNSC7O;p09$wm@>p^7H(nWUBQHuM{>$KEbP{*C$Pv=hBeH52 zOY%^ZL+>}}y7y~E6zuZG;;QswT>H2;-7G=G=A#bQbNM5{J9L1N=&xy60& zMpNMja-)eDShm%hd(WkkmkgM$+SttMKnKJ_Tjf^?`EryLda+M>Cm;)%ArA0E5R z)PLIY*Mq6R;K%rQ71Trg6X@01PxmJo!Axf+-^J zdHx{q+K405P2gV!(gD$mz{oc|w|~UN*%yBv`Y<_~Iq3ppp99(76zm#) z{ewea)ikqV=psvpWQ+Iu@c|I_dHeHwA};LgQ_E2b9fQ<#r)b?DSB%Ik&|QEBvR+4) zdSR!S(Vr*Lb9H~7M$e=Dc`14-1I+vs>sfsOFW*4+2*xFzzx4C=&QRCkDnkWByZHV9 z-Wy#k_98D!jnsb8Y^>9ZX5()m&C$==4jAu>=x)(5x=ck2-vAy*Uwro>PbwkvA~2FL zUpQ7rub!}7boMor0oe`|iG7JbN=19V#8c=w;w9dkp8H=yBN+J~FL8<-nWl!(R(^A! zL=!EWhS84RI}qD)kLdgdPZWJ_xuXf`3~Cw{hgZ?fW%-S_-1J%MtAth{>c&B3&M%=I zDxUia;jM|C!x|N)#Oxbx((V=3ku3i6isXwrHJ8{5^-;CUnuif<^TMkVLs^+tPmjII zYn8cx#YSEWIC0@MPFIn!*Lmqe1&x{-@Z;RgL3#-0>@a*^yKt#+Xbc@LBlEFh$D&>ZRz!n_$y# zoWYOTOynhp#XEsk#n{fc1$13<&#}9&={;iQv%H$T-;d}CQ<6gxF2%cNQa5>E zWp;z)0e5>f^u&oby76KJz(CwkJ_O9BnEEz9tdX4;6EoiC<;0v}5H!FDXnaJRSn@Vc z5~GImq2U*{0*C6@%}{cc7=ita8Tr7QuKO8=Ie_=zB@A8UwY57?LBed`S zl-i<1KSvf0!W4@VlDXjN2|FX(YZFLtwJ_Zh!$yMLUL@9xbH4}KC5`aJfh};x_2>8o7EQqipiW#wGK+|OJwW7j4IxZfe!`GQgRNS#SIYHIv@r|;x~Tba>Qx$iv+U9 zBK-1BcX_gbFyuRmj*FPE^qCtOs#O?P@1dXNTc1@lKXXEwOrKq$&k*o{+Bk#XK1WWl zh9b>n6>V??N*5Go0Npw#p zeX@eygwZD%lw3ziPRX*A+)7EEl4U5FPf1ySX-XcVWH`M|r{qaWx+z(zXzRI$@d92z z1nvS9!mZmuC}Sjkv$V?s*95b)EHVVYsjF#4i_8xxGTABuo}A{&u4NGwfefA+vWukJ zMRLrESw>}|%`$dNCCxH)j|I)$7gVGWaI!NcXs~1|`?=8t#FwsA4Rk z7jk;ybBcbsO1=rM4%t>5eX>zjNp0a8OvTs|tN|{kim{uLk@OaxpV%G2!iY-}I+Wa_ zC`bBitpDREgliiJI0g9W#q?9ek&uZSMx}3qA2@;Qpu>A5c;b2mYc|fjwm# z=mmu^MH@@;n;-{pkzeqe`T?$5F$R5y7ZSE)H*dT{Nr@Cd zz$?Z$>#c~K0bDv*)S1ESgfG3+-4q~Cz9in70eR3Iv3drW&pG1A42VDH1nSM?hcxB9 zNc;fY&y>K>4|oa1OqLQ`Kjclp?nKVx&*Us!)7QsZ6i3u2)d=9W0(v?T$2Bzn2soZQ zF;TBG6L5{JbJKm3uO zz;Idmup`rOAp6EL$`Kze;g6Cp6lM%;jHS(?A0lQcPcMUWR3nuTIK7ZFltjEzpA_yZ zNfd`@zm%7a-aO+XC=uddAyv#!H|L9qOZkJ3O@rkN37X(*Lqe-4qeyuD>F(REy0vc} za2p$TSz_4@bQ9+`JGG5c5X{zH1`>O|=(Y?DU_iXH4D`ezk^BjNGbc9#+$t4A!Qa&$ zAN#YUrvS43nbn=LHr$!)huSh9wDjD4=b@GIUUDX*IE?{Bp5NkobIYP8`Tz?SJfg|_ z%1l&meLv@`!tXQGX^KxIEa#OP?nmdzIfaOUTXuqW{jdYp8xp&Zu@fYa7k0vj#PkDV z#BzS`qi8KH9X$hgZ8e`UB&{@MU}W~V()`GP=~J+SX=#w{CfezY*V8hPP6?((^a>uY zZk~b5nt)2hBWRXx?7RD`SB>qY%0#Y>#dM zaf+FQWZ;rWT`39q>MQvo^-o3ow31h&sY)wXWH1=i;QWZ83dup zp&10BS)mzsfKXOLoz$|qWyP#ddH))6*~syPhYVV-qf*wumIBkuMKgwCf!G6U5#S|T zqW@c#SXMi1?z8t#JNB`wu)C|vN&Y@BUkZsEAgoatb*)(PJpk5=`|S0@HM<9c1hzk zyfq#Z*YKC*uEmPaR1>SK^Hpjmeg<4FzepCX)^a_w@H4l8YX9cbH`em|BQdrN zieXQ>Vue6sLiZ1uQ7}s270E&qK1cc7ox$Cw7{f*H&n17h_;X%dDjrqQ zQ7x7bL8cKT*E2u-?Q>q%Co45>fEPXr34ezAx*Q5MtDB0Fn(HujXjoAd9xt!snXteh zF}U1+zGSb7?p7(VFTnR}l{C-)6T*`>fm@p}wYn1v)k9D=gl|2M4xbMb8BiuTJw2lD zGOP-T5=#d9ujfZpH8(@F`GO}rEtjH1fWV8eM3K`V5ujYle)YdVgH|mP4dQ#T;|pH1 zosIDRd+cXTAhte$UlAnN4Y@d<+{8OpC7ehbyx{f?UIc5Tp+q5)EGsT-0`CY1md!kY zP~H=pVGBN8%-qbYKUawIyhfc+^d?cB7dI-0U<8RGEN^lNP>CY!6NAnk8^U)$g4T|0 zw*`u$MdIBpd=%lrD<0O1T|Ir zlDEFYZb%Y~zJwSW^7}94a&~T$;;O7|oE#QAY?GOTwn=H(f^E=l&JhXQfit#?Zrf3E zv>3ack1PRUm-iYYWiLc!Sc~{UlCnCc+@{tJ&}Idq-45QM8^GkRT;16Q5(QifhFSAx z+eerG9(?JiVp}g-P*xx zH2nU{kj;PEPEe4Y3wDAeZhzPb(jDBg6Fww{idS}We-0LfzmnbQkcR!(eYf>^@|xRw zY(|Mi@FkD;Izk!2V8v9514b_IG`fwtqJ%&mAagHW$IX4HwjCa3lMN4644lu+#Yxc& z$FKy;^v}&v5LuhGvvQMg_Y7Hdh6t z3y)J|WFiBi!on)bBcnmj!gLv=7pZOS68NMPatc>2GSZPzNP^G~<{>1?5YR9jCf0>j zrum{tAxTG4!(F@yJMuBs#=(!pm|alkOcUyE-ZxVM=6k%rw^%RcYROPHm`4!6wAns_ zrtOB74S4X&-H@8wf(_REwD8cPdwNXb}nUL9`6WRDOKgL5bD+0X0H zq0whQulhi6V3F7Y{!n6(Miz{#xF`%qp_wxo+^XPARanb4k zq^T0fCzhcUy`Ob}*NNW}z*+$s$xtT)b%4uILF?=kza8Kc=-c7n@RCh~tP3QxX)&bx zhHa@W5tjBI9^(M&u_VGCV;2%8i(-VOB^zO2{%Nmah<*|EEiaQP$4NsfTz39q<{&=V zX|EedqA!UK-|~vqAf5>6KfSv2Ew51KcZ?Y_g3$guygQxLq7)UAH4&O_dXSf-YP#VW zE@j<>I3elIJIHG{D+>0|1NiU2ZuWQEr#8^hrI( z3;0fo`iFUD%_;IU-3*cz-71cw=palNkIB>K&@o=M7{D%(P~izEeBbdmtTSqL$nstM9lzINoI^33g&{#lnP`<3IGxHx zkRqM@p+^=W$sm>^BwHF{pePx_pEgA3aZRUPP@+&-?w+FOwa+-aL-J{9;l^p}7i5_B z89w%V-XZelC+F#!L0A%djLV;ho8LqHaN!e?dYpGiXoUvQdzz!os$cGeZK`*gm~fnD z5kI==IImb&BFC#i6lx#%D}o39s-PtRRb&wYu&0q5ui_89ym^RyNNO`VJ3$(g+J;3m zu2lsc>zyESQ5Xl`q91rtY1wQDn_F15?5$P(*&lfIY)RZ<4bgfjXYQl2!EIx%4Ox+W zY`6JQE`shqO4@tMk8%Tl@gtvnJBH|ff>#GYJ?jKd$Rs`$Egv-zLA=?%nRmv_Lx4v) zWI_xjsJH?_F^RV5s3vD);(X21I`t&aEM{`C7CwM<*ZaPB;v|3YSwaUzN%wU7{PkBc z$5r9~jtxZgPrSmqpF&ZIKe|V0K0tgPYNAo z>OX`91|?>$0YWj=d_hDCbR)57?Ob~Czb5xh+IY=>_*~qs+wm;#9Win_NMUTAKG;g- zMa$jXpNO@_%uO_5xs4NXslz1^_cO0r^=SSJMELB@f5A)G1m_g(l2t0?{CKVfHlgzX z45%-PHah;q0>R|`%zgFkwrJae>jGZ)Ri))^wKjbvS~I1@sOb*;#dkmR1ZgCI*A_Oi zS&y(^c;{jgEmV_7OGC3Q@y0Jap{t2mHWe-*^I${^G7d0m0}Dgsp1nZ{O@Xh3$s+y~ z4oERCdqIdFyQPEENZo+;3 zu8=T*Zcf|4Z5AEM`Zo&>}-^gORr^KUVc#8QbNSjv>onON%ld7eqt zf>1$t?);s?e}U)RNA<Q`xf zgc=i*pOW7w_#ne3>0+hP%``FUSDskgoZdTBPD8;(vOT@ABKf@{vSAiOruP3;}6Kl3Phjl zQXX{wBW?+DwDb!)Fj~C%2x1r6)~O#n;wG<$eUG@wyrI(+~nP|tgWoz za9gTi(semagbyrJB>%7Yh+~Rg~wn z@-{fk%)OMUS(&+tnR${j!|Y7e%p5rpnK3exBwJ^l$x(D&0yKBJkzq{RZiOtu?+ini z$#tT*;%*dOupV9~IOU61$Ne(UP~mDt#r;8w6+w~&)iBj*kcMd_wWCM6F;rIF`=jg_ zlNuC7WRV%`bdxNwvC~a4#d|s3qS(k~z0(jW3v&IXh~|iGHb=y{+;htz$R!v#7Z^Mx z%c1xqiu-BDLUl+6LsBwe3?u*e!5hU1mpe0AI*%x6QIh;XFifdepyChnc~K}zcbATNitL?S@b#Cqxuhe1Q{7#o(D{Ct?#?Vs zt-3tgg8S9h{Vce^ujDO)SIo9=pl*6pVFL-}qu#r&xe=H7(IjW9Re_1-_+Jspo| zkDH=7b@#ZxM0}n~5$+w)OMj-R1T+Bz-nuw0`wEYAmo9$3Cv004W7YYe9TE+~rXTCk z*_;Zr_@@Hz{!@XS|5PA6%ANkVeYpRh3XJ%t0^9zn0Q3GsADaAAfuUY^M(e+UWSD8_ z+!MMr!*M^11Sq^6$c7cSe?!ym^toCP^ly0G<-*SQOp{&(YtM^H(e4u3m2>2=@KCfn z+v)!lrVlcV81_AGX#oy^9?(InlBjKE1H3io8U`0{>t#yy&MyXN=acGF!kqO$0wJMX-{ zX+Th@o;-C`U_M-boYul!ISW?{NDplvOsjFzoohf(e}qM%$eZrMVEHXCs>8-Y5U=7m zh$ggfm&wslA3*EL+I>W8WY!vX+I6pB(-BksQZi z+8*?bbSmL0K}V(m4mgd`hd-U%eqHbHli&P?Z;(&c=yr;YU{wvq z@IiNA_{BC9s~&Kd%z@txG+vyX?Thx%XChW~kXjDdEhi$e#7#JMmw4sDTY3SUh3b`zQth7X4rE z6}!vcaf=6Axf32c1*$m>22F5ZAarZ4JcuMy%~M4&d_{kd-<$)d5Vnt`F`-m48wjU- z7YyYydi6--qEAa#VjZ}*I54^LsxtsBG0owm{b7A^`*sFk5#Q49^6{qdw-VpRxm)qw zE+6ja@a`5_@$R>9fGmr5_rjxOg8K>{35o83c#KJOpTpygBsWD9+@9qA3}?*HWOtn? z+SAae;5>nI2W(vTCWBHtE>0)ApGR!WM~mYKlsoV7*l9SPP5(+acvNspbU$?a6n93# z8Z8aMNU^MGg8?}p{wH3(C#I#iKQO;e2s~cG?NUH1bSUZWheLH=Ni;J^oGIzy!NJt)b1O9 z4T}+7eC{NWiH#r5Pcl4O-cc;ReXcZoDS3LwI!u5L)^<~=6 zh~%}`B|49H#!f2b4)<>X5lhr1eBOO1gVTX5fHoZ6gkNO-bMUChD&=lc;b*7cP3VCx zXi;fRM0+pe!o6y04YdI>YV`14C(VB}XrC{{%u?q`&*c22&$T(^y$vn*J zv3Xe`^+Wa!A@ugAyDP?zJS&GwaTT0aSDfB0BC)i)zOqAHFYW#x>fQuSj;iYW@9LhV zt9oYAlgwn6OhR=NU=k7t0!e@VZ1>zr z%`{bBDxdZ*g}{4G(f(or*%#SoDz*zYcO=+^Vs{OO*7jGRNAp-pSG^k{S+i4r{{9i^-uX63%B86Y+w%s=T7+JR5w&9d1UIq3ilrB*cEVz~q z?EVK~rP>R|)?E-1$CkF&!=+Q0pJf+%x~tB-NV7npC|~9tQG)Od?~fwmT$GgrTDEl0(SoI&Q#l{)%LNM zaN=nft)>@B=E=snL1m0O61WkmJtjVgCnw?a|a;PHppsNpQY_9|&yIbF7~77Kl21 z)lQy%x3TIija5;QE&Yj`HY40>G>f$I81a6V!OWdDBOD-z<*PHoB`jW3W`<|0XO_)rP|j$F~{VA47qA|vQR=ll7}e~QVu+dp`;gs?hC(dp0*Ed5Un2fc*UV$ibDa#0X0Q=n$#(x@=`6L!%luq?6jI5WrylHquR4S zG8dA6Z`|u{j+@8Sv~P5@mVwb~jFdz8+n6#06XR zTpPpzk9{ zQ6btZEac)VMS39>O_{igrZeyhIm>hgz>VAAPBr0nQhrIGW1d;_q)CvnQ0r{|B+B@XAAN^+Eb08iz5x_l8j+o_ANh4i?q7lm#5AJ?^__g;VP- zG;cSPSCECKQM)l+SVL0?NyAMIT2oWc4&OynN1ff+l)LHdFg)UIo0;3#%pOTj7@MMI z!qF3)V`E5(84G||8nGzJNfcZi|$dnUl=(hHS|FA0j3Q3b68ZSJPU;n+#N`$J8Baj*rV9lUO759lu2 zO%O1+iIg0y&%Lxb96$=|CtDl~{Ad;>VpvBbRw-XxY?~{;WL{k~|ReI*+N@}$P z>jPpr4lz*b7J5A@<`jme-7z!t?ho&fkre5hJbm;hayOk5_7?qbem!zd*z@i#z0jr! zF2_7IhehesA7$;%3%w05&OmR@VzvnI?+ekbH4T4LjyK7CUyGAp`3VW--5pYPl z-dMwjxMa9ODO)2zpEhHaMBkHn^WQlj{Z9cx z$U3$-v?nbOh^TsM>xvFY-~U{c&{lWOxnZRrjxB~DZp;Y`4X396$xcnLrGi<#iDJdH z8XAjbkOHdfTQ}@$>-L2Yuz2$bw$DP(td&kLVb_K;Pn%!OGl}S+654Xc&( ze5Y$jYAY7xhr=8v=}}MDxZuNK*XGQNID=1Um#U)TXXf&>-Dc{o+v&sMLL{!09}Z;# z(2+`(`;e3wcBE30+np6&6P~?G$OES;A=*w82%Zn~rCK1_XH||&h?0GbHvwN_B0z-p zoLE>wvc+M*0CV4ZN0=)H&0$!`7tjcKrwK8)ue~VB&%+bn>Tdsfcx;IEP80Fx z!2RRlwy}Ax?^zm-+d(3!y=C*tYPNxSRb%VUYu?RY8lFP%_3xI3Q~R&8UGj9^7W5cF zevp=kmiwBUdU-g|!xd54$iR-Fta>tUqC?a%I@pW5g=Tn>|1IicVKCMetU4z?I<`YM*vR zIG58=p1vYHWJJ{!w{58E``!1i45tWI&tDmit6dV3{nM<%TD1)H( zJQ%&j0fxB8NO-DbS#5qxNI*#NQ57~u!1A!8NY=C|*S?Rbxg4mH_X$8_II(_A)G{va zg=h)Im9)i}sA71snwnn?Or3z&i;zKNp$>}KQ57MuQbq>JH-7q!pXN9oh#zJXG`5dN zjYXFCQsZ)<1H5y*L&KFO)+|;t#56{OF3pcN%LEN()aF&&)&03*Y1~c9A1vWddp>y= z5=nD<>eCnwnXO3XrG2;*r*rO0M3Y&#*EC|-j*V!?m7xCSk$*H0Q`r*%xp`#PkQI@bt`2jb1YTGuolpkwVLQ0l>4SQ%C z$jy1Y3}`qCSZDlb;U7$wfK~h+!*Ag4#p-DbD_w~U6@^M3&=mn2GLsp~{8VTL07M>? z(8Q24bKj=gY-MuA0mFPJWN0Nfk7F@`fsqph$YW0BJx4aj)E2Ms)!t6{G# z!wRB!w4ePke#W~LpGFT!PJJh2Sk}VIclWW}!QAXGMV2R) zo&Sx7$~zbYdCjdpBHSx@%KiEi#3?-G_WF2uG?!aH9&Q>ub?vV{9tOkD-ugs%Jik8k zNj-BHeiG~93vSON!-4z@zjmKIGJFgx-j4qk{vvp3XzaYOo1MW!Q|9B;9(Rr9wu4WX ztENm8MW4omUvi&2Dtrs>d+MjccN6b%=chs)r1rw6!g=K2_`uQO6%_vU=ulhQ#(x@n zI@S;XT!4}NhYSKN+K?Q1DSz$u`*ip?j`NAfm?8e~W5O%**F|piG1%xQ9E&u^29#s5 zFs^my92;)UWyP`K5u@*7LXu~n#t_t#yvYS~+IF7_r!*c>J?}H&R{J-cd&~4HH>!*; zsU#;B&y; zNzxP!MCnP#It%!OP)EsA`qhL?Xb;4S$W#m;xA2ghCo7Wk)BTt}ykp^px z$1RiOAdifJ%hI<3Jj3K-oluKspZ>KI4PeWEc3LyJJ+9>`L)6nTn5$T`a^*LIc4Yv# z%aff(%4(c^-5+(U)3w|A60eo74BVpQ!;a_;---_TU3z@j)s-F@Y*lrtHf_G;?ms@9 zxM_O!arVRpOSD;gcJ{HF7beyP6)?ED~C^8e)@#4FFSBp&+{jSQ#XA)&orTBrH2D+>{=^w<;UHDC*pCx zQseavfBwX92YR&f#1TD$PaRur^*w4G$IkU1x;Od4foYFyjCt0IVjLcjp^UO38(yc~ zWEf~$%_Ku${V47aJIX-9$-jOi0?DcWPS0Oq`Dy66UZuc#Zn~GwI)C8b!w=4=BNfWX zI!HBqXz~US>X4K0rlfFD@2zzRU?Yd9PjY`hDLf{+*279&J?Z3d+HU9TcZyc>lX0N; zZfKk~Hn6fKJGtAiGE^#v>`|`ak$dT6CNQN?wcU9N6F#IPmf;ip-s2REs+YKrpAxB@ZiBf-4WUj9QEC07?eRmEHXIctM_|s6s9rD@m z9esGgU@}Fo2qHHnzn9ym8UN8WpT*1fh`ax@;nZQDmK0j=UTeaqRr*|5kvEBD=9#Dh zNpLFgH$NNp^V<79_x7({^to^=^DedWnaeLIbh~Fi$L7{YT;a6Fmk_-hzO~zFp^j{uBnAj;d)uHAUuDR4AP)~NAmjf zvI7rQPY>@`VyZv>NBCVXSDX=^8GP0aE(||Zz5j2irI=a3aaR8&(e!)v%U!iFoH*d` zbt)cdMCKuk=-`rMqCanC&BE}#bb02P7{k>|9T@4pdttac4u$0|+}-W!$dUP?d!GwG zm?fmE>Yv-wp2*9$YcW~`%@*I9~XnV6e z`o=L}IATHhMR&=?;U|5K9o?);ScqSAhg`x!oc1Ser}EYCu;BKg1z!!1%eP#0wNCnT zZ+wmQcCGvAWnp~S?Lv9wGl4&hf|UeF74Bbq;%J#T(Qfeint(nnm4XTBu68IQTB3bJ zOt#Y7d+EL{t4ZMgs7$_Z2t2QrP4?sU%-W(5|2Dmv`I%#o6;Uuek0p(5Ktd232R9`|G z^#dA?OLwcU4*T-#*ZkYnVgDBPa=kN;kS7Dqqn*L}c70RI7H-xx;bfm8;irmHR#%U^ zCfscN6GzMb_RA*}7H$G7Sp(2g2J<%r=*!=^CY&-&{jehf(h+~*KHq>oVy3QuDd!GL zm5_=wgV%;*ER29Ypar40OvfTde;BqoP`~DqYr{=u8<-HbV@4?uH-6+i<;O6v`q2#L zuL`Q^hn8g@T6%3bwdt)=`9k;TwK(9|3DdNUxP-5{X=IA@d%kT;X4;NBd>NkRweI9) z$cC20S;E=Rmtg_Fl9V#x6TyCO$spMqcbB>8WuIAB`R}DlS3E!oH{G&@#&KUfHttzk z9ji*J-5-x%TJ7<#bj4#;b6ngV_muzc-gSL={@zsUrdpS3bkQgeO5{!*@KrJ5Qa7Hk zv}#}N!;CpL-ehUjs`tj@{inzA6*}VvZV1nx`9{Wzc2GE)tpBLL_CFaD;2VqA+mQ5z4V=MPE&NpJY+bb+#PPm+X%N=;g;QoAi5$g zUbw>j_BQ0JH-^T4A2&(&b1R{8Jy&W3d-MiAGN zfx(&XkVl}PGl#zR2*Eo1ylxd|@GboYTJ8$>$g1$8`PT|=+egDggTK2ak0KpD=B|G< z)bYB1eKg#991@e+4VZ19K~Vl+wW!M!mX=)}3*SjnEraN4lLGsar^2V~)Qyhh485`&l4EWkJ8#~)@TH%Flb?4t{yf~HyvA>lPR{-zDt=I2 zGt}}6oB=K0ewNREXXuJwVlJk|p34SaQV_z8>M|7kHOD0ctcvpf4X zl_8ugzL`E_3jI1+d^eJjeViMuHS=9(jJ91O`SM%MoK4%=<36&}=;nz;fWz-r2A=Qx z9U^QJ^2%jfDjod)BPIL0ghM$UZ0Ld2CF>8P6VDw^d8{E~gem{Ib!4{nHn;S*;iq+& zV!j<_09BVy9~$^wI3qvm4_7>&M(}{RFJ0k2`doO|s6SDd#`rWPFJIx_@qD<;s5dCY zvZILkrsU6844wIWcnG0fL(jZOfKBjS_nw!--F4!edzpXd-1{}g_#pu5dc$79*(Lt8jc}YI;&t-!#uN0OM zEn{uh$~b8Yxt-QnN)G^V6aO53Dq1A|!E#h-a;x7%BLAEI9FF234Rimf)m+-Dd-Ts? zWxd)u6d*mQYq|O3{_t3k-@+eVv;@257+B00IaX!yV)3%}hrRnZd$wGzjbW{SqBt0)k}5Y*3^XtThv=45ejRHffdcz-muHbxp7 zM(=saJ-0!>9p(3GrT3-f6|4fBPJPDrwX$>Og+$dau%q_6)N}Xhabz3|^7PqP{UDZMLgm*X9n6iKIpzQDVX6!G$ z{xZd1CUPOoAW;%cG7VRH1l#}@EcS?|1U#tOqYLu$h^T5ZNVm|hpfLP}Ag(Hab&5=% zJ|=4dU@*TES95ceA8Anr<{U$AhUwt|;M%3Do|v~83lQE42!Q$EG?H_Jq#$=!v4+XL zimio{cVAk%C)%U*Q`Qukz$X7QN9B$+k@t{Vx8JC z#}-r``UOX%L!TzjV_Vvc`~{#mWG0?b!{mmd)WqQz7SfbY7JV;``@?>oEa1l^pFt5j zyS*&mE?ZxjO)S0%(GYLi$!3%CuhT$Uv{0V|H5Oo(SKABnGeDlEIp6!<%L`U+ZHf1q z=G=Z8KWhA1sR1n~tKZ8%yjufeyS0V`FVeQ*>F9^LpOjxtD_3zZY~TYRthce_srw_G zgaVneW)TU(%Y4)ZWVef~Yj&&1E$~+vVI&(=8o=>Stw$-NQres*9XcR@56ooaLczog~hBij5 zvSxj+6Li^B?k&9X*xRR|JZ_@P0GP$iG!kr3JgsUQd0E01M{=2y)E^4i%f$s9E&Bu#YrrrGU z(9fEnQuZM*2Ia*<1R`Y?>N)^=8De02P%NPONKA+6|5lsO6}E0n&u{!Kn?b#1)qGT; zy{3<7Y8yVXge^_8`KKt3*?5I5exXLS1@4tYqPWI6jFa+McFGu~xGO4%&hB(*C81D; zD0b;(RcHr+0WTGpULluN#RfEusuSnoL!^dIKH<_-i7DhbpmAJ)^+cEy0Y;UGo+y-} zLtWY0&#<@Df(`B9Syj8#s|B0jQc~IvD{C{sVohkqt?tf4quv^^mvZH3_BDrMk1&)- ziv(!x!;;2Jphc7WHxDplsAMAY&2QNDtD71ttd0B@*fpXlIao{HfW1~DXZ zz?$s^)oRzO-4&i9TIVwhEfoUW)*r%{b%)Tm?hv%EvG2V$28-`SHf|V$!amsIr!g3$ zG=@GKgFyh$s)CJye4GqnxR$&2u&7cStx0E|A?A3r%tyq(>0^~LxIwl(4ic$C*88#y zaZw~5kgL#W+29seJmd^s7Dl1>fnl{`pR3rXOTJP$7K+#xRHGD+o7Ah7=1`g*XN$!V z%)4PzpZmy1pcORJgR8cMgymMNvQlYmN5`jFihnp|t^KoB$J-Areey z-9mlLavB%0c9RNa3;B&Z;Ge90>N1!-zdAkxn>2Be!?+A`8o*$Hle( zqWO3{9MH$kaqtTSDa8q%sHy3qId1()JR-`8o-ER0LQB^GHU>wAsL}i3Y_fi8tO--z zN{33ZOFkBjsnOC-K$jK?Jmf4_v3On;RCIO)qiZ#PKP11W?Z)H`v=aH=c^+tn{N_%l|XEOzEveNmEi93Qs)dq)-0K=Hs}IIAuc|fgnX3VQ2&5l(&y38RqEwDmTnwD1~^OaHq5%tiifU z#P_%PvGkaoI!2p&OEBqnvX~%)XX; z&&-6ISbZ+N7(H(LiS@1Yp@Hh+6`p=|H?@*pIW|-a)+<_y{L60?6f_foLebEnUc!(OX9P~|$ zq-+5w%k|y#YerIt@Y%}1ov9Z3k_Kg;H%O2NP3pFQN0S1chQu`1l+Mzu;t9)FQcB*u zi1y9OhPX5l_Qj>hO3h`8c(wmomoYqGy^Im*f=9}OYk2tWmXBMV;$_w@4ZmG8PC!mA zR{|N#>x3AK0Ez|JvkI{dZJeJy-@3>4aW8|Fk);!)Hg(3vmP+1-{VRgEOwJ~FPZ=qB z_tF*HG9t;F8|A8qs#Z3i==D=wG*H8qz;03<@;Xw;o?Dl(-&T4if^3nbX$%Y|dxHxL zBp#!BmM<)3n2bU(vDyI=b2C`cHh_+;gYycEuj%+oYfYL3005aX?ILcK0_XJ$1Y*Jt zAOkcAE?85BHHb)B1>-=2p#HEHAyDF%h&$$?OZY8%j2-ihsA*j|)O-U;rh=5D%%E8# z9Tjw`D>G6{L={CTDTuGEu;L9MrnWkCWV*=(1-8EC*vSMOz#qJh1|L%+fRDkeQCF!A zYbcygVDI3@WTE;e-ZcTqlpAZFWy_l9)nP3~+D{XD!*q54pcSk}E9gcmF!cmJ5x74e z5_Q(Pj+&=43Iw@s=_tK33iu%FdW+qe-ePyAx3JS;Vr4RM`mv;tO;Qs>H+l8)Q)s>$ z?S)yPKKi6W9_>y1tX5`P(80cp)@u9H&UW)EcsWJDaMy0Zo)jPzxElEg38Lixu?%22 zOXMiiuu!<_(qFft5Ve1!8W?UxnNEWzUD^vo&&n-HFeX-OSOSCz>QN0@QECo+mozrw zp9QbzVB09le1R*|TR8+Fs<4YniAl71MvRx2snYIOX{$T(Ep+=XQ+i;#g0n4Gz#Lv& z=E*#^g7|moo_@mw$u0D5$r96%6O|1|%g1 zVd&EI+UNwns#MKu*BAwnHoXK??&og`6JECFl~?F{fmfhV#Pt)i&ZL?YD$t&_(3at) z=`AR?49>*pj7rK9+6c+7;I&(SWbE5nXJnD7Rt*CqrkgGsfEx!EVeXUy)Ht&8+mDRE z^Tv@y>B!2%UFX(!UB?`a7;oOjn+~^4xGF|d0hYzq(QY6J@nBZ7h-iiQt{$ zqTOk=spBF@?r~8ZORJGbrVYGeqnA)a0^=0b@X-f^BDeZU^KWL)So$+Gg$0^C?lG7Z;76k*h0paxSlJ54_*<-Og_A&9k$YDyVci7LwVLPh zv$KCn0yr0i&8(G*!nSs?+QCHZ7F%9nroTN#8o3poBvT1*?l0+_vwO&TC3{r?9M-PN zR`@dt00P`@m9F$lwb`^t1iSJG#KG3Vl0qfWqnNGH#!q^^UO7rJ@uIP$c|X;xh`ktU zni|j^_W}*R!-s7e#ZZE{SM!I+f*;xQ67FVttugS(Sd)waRa>RO8CVtl?X(&BmB!?8 z`LM-8)2xNG)eu!Irz2xI8)#e;TJ4}G;5*|M-dDwvJ9wKS-tNlYu9-xbeI0A2I?KmJ z;OLuJYfyIKBJf4pOVtK33#kVw>q22OJW%IUj0yMxssIvnhWviG&utI|AS8WLJrS7H z*hRHMsyT{-x5ZHGk^X;z<$TjwQ9vqn<&laE_F zkU`pxS0dDJ;VhrX9_`CF=Ih%wrjgHNgRyd{5e@GsPb;z>Y+rgryQ!drfq)b4@MEIx z!3gBm29+-OmFAH3Yq+SnLcu-8mEC2>M13_wGln|MiAQBvR4o}}F?Pulz$6;ed_J;)$xXqtr(89a*cm8s>v8uXW#^W!r(UH zvG642CQQ~aor{ncq;xJyHaZ7qME@y)i~LWD^F}^4cltJqOTq9U?%SPZCNG@AQr*XS ziN{y_=vD79QWWOJeI7v(P3M^a5Xb?e_k}i^7c%MEq+o;ca~!uzI|XUt_C1kq;`V(p zj!V}92lny&K};j%M`9&Ms6!<5AB&PZJEXnxvL3b!Yo!tFMtaL(&PR-a$hgxKte$7pWaH9Iyr8*1E0e7yez z-O_wjW1y()<2H41oV{%no_(Ezoa+?cC(tXgSq|C~iEHbRs1lPBrf1#81>Xu{o}oZ$ zbn+zbS)7QR$<6s;hz*L!wX0MRFd}EB+hMaPO}Q#tp={oWyt8?$iHI11u~9QM&94@W z$a}q^ApN8fxwTR!a^H|CsW6K)kD2kQI+6Qt@QIYh8B|8g=_CAYB64gv>pT#Vw@XwK zkt_9rArtd_(Pge=Wm|dnmu27X4wm{~$`-C>Ul`ZdEyU||*@Bw2Y}IHH4*@yq zSzYp#wpfwTtx9~S<%_Q>i{rW$1k~tz3SN!I#)|K5v1|)cc9VNhdy~QB1!=!#Y#5NS zps0vH>9hmV*CjtNd1%`?=3jqh1LUR&f!p(@Y{!YH2WB3~p1@Mi)n*NEA$E3|^4UOZ z^9hr%C-?yL9jeOI(8gN3aZ|%P;3esz2nzU*)Da#b-Bw4d<7tOm_w)(ai~UH3$E8t1 z?(*THXPc=ZgHheokmNvA)ZfHtZUO8{E#dQHFJp$RNGT;6;I*EP3r4Hpo#QMLN7H2RuQZu6o7a4 z#MH;HDot~#s`KShTBK02X0t8bT<>xsgAsAH1xsWlG?}Qy_T2`1$6@lOw)gH`W0M%Y z4b@S!E$bvV5fx190Cf0*$pyt0IXr5ETneUQ#{Le(@AY?3L)qV<4-`SpPPkC{Z=^mn zBMC_jl(8PPLiv;gjQW7r3tv?TWO3Qot3xqyD7Pph65iVd8Ackr!cwyx@Oe=HFH5)# zlWqxWoypGgOyd+F7Q{HVytbLFT=-6W+#JTW@SXdO!g0#%1|&eF2i)kC7jZOPqf#QWE9S1r^a}2=TC)+!%iOl_rclW1Np7ZSu2MBb~bD)=%ALMwTN%!c~WhYAwi3lbxn<1d`tLyzV%6eAQa5Q^3`wi`ABK}rv001Q$dXO@;G zF8nesY)(QJd7);sH`8AmCO^>sewL+L}-1cSAr1SPra-GwH$EAE0~f$E@rJ)T!g?30BRgT+9Syy z)5m{@{4?sWiJJ_QKMNnrv6k^1WAc+$N>&QT;$&&&?m+e;SN}{~BjV0UdF1ibu9Bv> z>oki!!@@|;YH6`xET+jK794^RDq%_>VZ75=u?)r4+nUR+MZ{5Ubw5@JfqcsUl7u*gtn1h5AnS2i!0Nt_9rr6K>ET7pM zdJSp2y&?}Z-y$E{!Bv7Ml^($~7%Hv~ux&TPR`{#e5Z94rNt_T%FsZZ;>Y)*0{hP9z zOL%{d=kOsKV>B)9S6^rww`r~#;y00LVVH%hgH$T|dCa>NHzT8E)#Rh_QoXShv&o|x z5tekQPYTg&zEyq~2>}4w+$jKrpg<$&W(L_x)RA%87J6ejWLh^2;<F~~B?v;HbqG@DPzVv4tg5;}Pax4M0R*&2=6#H$ zAR?#{9AcI{gIc6|%s^YPy{rU9J^|S0GbOM?r9_bVRAtUy4ttk|2C(amSb%d4kN(IZW7BktpD9@{d z1s~NVb%&l=Te4x|T(W5<{-{NLLP$kSP&$KpSXbo3x+rtoTtu7+)@K+(-WZ?En;s@w z^L_fFWMLi4){oD^cw{aOvr$ zav>mrUXov-d=909yeHgQoytgrQzJ=xerrm{VKGamcpYOi(OA#6qh$o@Y5KG)pAmJ# z=C$ypGvxhd)eZ~dG(T?+dAmt(?&2?Gn$WNP{e_$g`gN$k9ON%YHbl41^+hK&6dhA{ zb7)d)whVJOv)V18qsiEiSqTdy+CkFsOiB^2Vp5jbZ@Wqlcwp-yC|i!ZGCoD92a|&^ zisXq$4(e_;UIjqrGsk7km*RUFvKUh-?jeH$ZWQpP?2<2nk&4>_7XzM(ZFM#BEWWAl z7KZs1(GiEmJtDL+&G%&NitijO9w2FfKI6I;v4MbmoWB{l#f6Mn_2`j!)nUVEBtDjr z9T}8pO3cb*_4;xs^o?)bsE$xq4bT{cy3Cs?2W$3JmsJxXq%2z>t5Y5J0a0B#OrhE= zqN9!WEU_>Jv#T9YB?0I_F4{UcJAmR-5-cLHHIQI4K!IM31W}-AcsfLv(x7o_AmT|- z@*|R*Mj~TonPw?cJm zm^ZB7F)wF|H>CYScWK}dGKBZ9-#-LlWI6&3t$*N*vKhyz|C!ZElV}|j>@-9aR$G+G zEattUA|VuC6r+?+z%PtXAc&-VVwUj_z_NaFHsp%BH)+pIWt2hwy zVCY;I44wZ6!0@(EAO%?l29!2!XJnqxWE;Sser_BLuq$Ji>w^IcbZQN#!$B}OvT6)* zu8)*v<*Ai_bc-_&V29dVG4}>Z9w#RBZz$5LelG%gi#E! z$t=&K;U|o;*Kh}S73oU-xCc_)ksqri26qUVZlLV{4(_zALqhA}PKf=~NGNK+9h;4U zbfR@p2x-$$h+dOaTg)PWA#lQpd3GuCI;Fg-?U`+-9V9?2@CKgGuv?!I$N454rB%g8 zm|X|5E%wLl&E~xutt5##(1ax@Pi@Q%%x=3sdII3(5ssT+CdP~+W9@(|^Nh&WgCQ{& zM|>2njo}z<;vL}zEO0K1ML|5;8-)qs^%ABY4Y~^#AaC$J69cby+BzfWGh@i4JIpt(e{oc;Wlx6%WSn%N$k0B<)tkE#sWi+krY=TH zjHFs?rFX!Yc}HWIXMq54$1a332)N7z0&e4iS}x->);`5c$^J`o+T9XNpPpZ)of%}7 zyo#%KUM-cz2EOyVmF>d_myjs~!EQj5mfdx_R~BRYRINQ^1cpguoYeAYF~xqJlY)x8 zU6XKI=cJY(3u|6|rDICezVaf%5K#KP98gRJ(M;sTq~cLnf;j74s{)!Rbe9c{npkV( zpjbod3yH0C>fbE&G%%r+Pf;-2$amu%1{81CU8VLK?(S9vP{Rw(S${j$>94wLW%J_> z_sW^kCL8IqI9alitv1QncUB?5{x1MEN@Ia zmof2KL=xAGZ?vY|Y<9IB6LG7z^fGQQ5@FQFeP?VR(vqWCIl7p}$~E+ma#Lsiwf^;Q zsDq9DgUIL~p#vgqNHkld=b|@jw)kvoDn;PXMVM-UT2${Sy1lXg>a6I8w2NcX|;d!NW2$;4;4xzM>A-vPi z{>I0E0KBnfoguKvgKY^K0+zOhAxO7i2tqLN){R4XL$gnk1if5>229}C0E{6JxFs-F zGI{K@fYuAtRyIE-MeW5tVDjw&EiA}r_M%%;noSp7xx;i`n5c^`b{LpR{$pTn;F291 z<&y5HMN#`!Z^IrXTH6YrvPZES%3S+dtdM|rK;Rt^c!`T|V2~XKUdUULHi7iG?$(jC zSvN+=Ps1AdND(tc)Ry@%rARl{M-xjZ2TRB4#>_yaaXHQ;*k! z0?YKj+NTDbQ_*mQqe%r}a#DALdjW zV^lEF^vHYAkj&>9u;wCiiF`HyqD;SGRHo()Bg%Thdn&KDdz*>C)ti~YyvUBL-^=W6 z7JG&iVKRFIryfR`e;#8@X0MNbLl`67o0YC}VB0G|}q|a1jPrV+ndy*!VyvW|})8JwX^&-2%Y{M8oZNV=PNDE$MwM z{F_kVUdSbx{4Rpnp!lv;gJ547XPZsmtai!{Mt5x% z(lL26QC96=ljAw80*376c)~u6sV&p7$l&hMyw}i|=I51vf`Xok_&h-}&!>{PiTmgl zIDjz5NsLEI_wqjGNpH|hef<&utFT?<{Z^7HwlWSZO+K+wldLKn(Qen}sR9760WhZi zW8>3SeZHO92$0z87H6ai{J_Jag^6hVciClai|yO_%w>S*{wavaLyeexe;!V%H>$FPswfx__J;jjzdUk4HRn zup6$R$qQAus68F=p)&yo=JAL4Vf9Rc`k-`fVn2W%mjUEmE>o0XR~tI?D!~qXPnIF7 zQgA2_89th}9*RujnVEM2I>J(ohy}ncBdoF^+j%WHfY#tdfx9q-7Wde~XxiAk5uP1@ zm2NtO@LJu6PH*&>}4_QV^uHX$pfaL{T2bwe?@S!$njPO&LV873v z(u2GOnme-<1ky<7V$7k@gLyA+FX@h1Jt(dP-jAy^ExfWkKWy>!H2m%S+atcFNf`3a z>nH1>eY@@DFnNBit~aNMcFQeQ)Q5VK0}5F;gMWbKMK$O^0AUKnqZB8ieHAs(|)5Kp+PFQ`sJVpKoJ(nH7e0J+;EXmJorfC24#h5UW`0iTS z{CL#3D$e`8v==|kI)To)n=EN4ppb8)f;VyuMnV_A;bSgM&3(@H9bdpfY+j>)BW%Kc*xNXkHu++FcZ9~=o^bU(6Tc7Y@rlygg1Dd!E zBUoT0q=5DYcS4(VJ%qs&9E*l^J*cAwc>qv7Z%TSC>O{D@6oadlw_&u#m<$hvue0A& zbkwbB;PFW;DqM~SEx8;cx2o~u^z9>tDTrC~WD8E%`dxmAsH`USw)~(n`pinN)8^^P zXm8%qvLo)LgiPO@BN`=-PGvF$WC;2Kz!ekSLQ}RPche`CmDlc4s6Z z9|^=o1TEfx_#&FIT_yAn8cyRGfRro~!`ed5-F!9D%vLu=r4bqfV=zq8X9<i$0h~mvz2qV=(X2KNf8DYXK;4{MAY9>rn9KAh0BR-4%hax>k*(4qy7wT}t zL$|jMS=sz}ytdPBGJ^ZDE@iTvw_nk>Hs8hK|4bJ?UTPM;{Q%U3@~kg zDvGcyOChf8Wd3$fW46yugj!~q#*MRXpw?UownELkNwej85K((g`2d#Ul=z%cAaCD%JxSik^PBWc0I%`NeXq zx>8MvuU0R!2nK>Cyk{wUI!yi&k$~Mi`&iwxB+ZuOQ$UP;p=znkn6NY-mNlY2l9fY< zj4!40B*6$7NVAP##Eu{2PGjSgO}5Nk;|=fPP$B2l+vrX zdcjB`?d)N&{A18HJ44duk-LKA$9#TJ$BruY;ckAU>BlV97>kuv2Cal{%0701+7Hl( z2@|kqpcxuMCY~-uPK&+NDv@o@>q9TElYwl#1Y~{;67=C+;5OntON#_d=9nu<^mG}K ze9XLK3ZGH-F?uwqu-4>AJW$HXhkm7Scu-9FN9_4hl9^4@t>jB(f3i}aL(Oh|&NRDS zL|yhmsqPZ$#taFSkOi6nvtY8$){w-wl~AkniHesI70Ccx9WabmM5rx_A^YR8d5_Ar zxPb4TzrIB&}) zl<0nOebhhI_8f7bwy>NP5X{E6so)1lh{dhJzlrvC;f<(##2#_ts5;JPY!$>$aAp=}hNpHop z1bFZe!1u98H*gc)Oqb%kUx&R!p{Pi@7g+arO=1J4##|*Z2IWB*q@Ye)C+DHB$V(}Z zgK^D_wxmzfU?vC(fqD&rHikc2Yz%)epl0~vjy`SFJ2s3u&oT#M-s_^y!5QYP#tuuz zF32ZqV6hv(99n3=oDuaJF(*E3BbcM$+TfqX97Wu20CP@b2N{^-pRR*B=(7r}g?=?Z z!!Zc|8(0E(*GH1(oaWx$bu&&fi*a5TNe&)?BOX{A!V&5TMY0Ob3~L060INZhu9HP% z=u|Yea-p{H^(wT*KBlUfB9&2dN|r?t)Wd{>ETN2vX1AW8pLU|EWl@yPAg;!iLoqLs zi7X#y9)`$|36d+>6N5WJ4amF)FfHP-Nd^kp5_Mf0n6y!2M@cWJ!==j-tHFiWLb?96 zEGF+E1sxO`q5+{;iKpnl(4H5XO~8mSm6pqLvaZ7}vk0-knqtV7hy@Isp<@Xh zRtyQEidzkOfeb7L3+xlXqGlk|=k@c5Y=fjyr1JYn{W;3u>kT++7PKw#7`uZd^E2?{ zY(ux&0Nhz%dXcBNbX7W-HV^h;k0D#7C<5*>Ne>4?d$?zT(Cfh+?NV?jgXV_d-a#4~ zU@ykbCXvk0U}f{;u_Fx)HS$~5Ee-X#&~ZyL+Wx>)Ln2XG9$Q;;QAXL5G zT!i(xAibo3)4LnkV?fe6z;v+AuQMI|K2n7?9ok9<4 z#t4KpN(xd}s8jVpQeco=TKn1EnmCD-&5{Y_QfbId`+}&*tYy>l(gU*l2ZdyL63)y} z4m<0ItmT=w*i0XqlkZ`ENZPbhS<}Vo;VE{p653%06qZS};MYr-Isg=J=fdV<*>vFr z%6MZN3+=8~@|E4Oy)*WA?Cu=&cSWDffj7#CmcUVGhc(T4;Z`q7%9G-g*&<4s-4Z8G zElXyL4bx;|g3>XFWIY9{5->o~#p0blZM7$^&(?g!P@hJ;p?H_EIM@%c7zpM)h&4g=O4I zxaGCw+?rI&x{zheO-0p|=Ss@i!g?f)kvk$P3~%RrnKrmO+$ixm(}~Tw+)dmjTpTE?Qr>bX6wkQdZcy%nRll zYk~>#OVL^pGiG4v3y>1C;g#FPbG#dB$xXl|8C?&O&&SigL7vqixpFC@DzM zOqe@hW}%n!2qyd}*rHWK&L^jv^2T5S-GAtUb`+Z9kxv$Jq(W zvX7_28)D5xCf^t?$(+;+^2_iQO@rXzQL?E@A!CIV`LR}dqFx&$-VGb%m;kR~<3NIJ z^uao#hbmRk_O2*%%E*@(JsN;U@9iw~fz-nQiW@i&K=8T&kpv#SS z6m?SeUAIN!KH#y&u(w|zP%eK<=07cKaXaguZx0k0Bg3|sj^Ai~KYHx`^( znM~gQc=9RNCWRA|Bh3uht5{RhmGWuaDJX1|54MBK<=XWoXJmCOh8Q%Tm;q<J32XS0uANMhKA=I{4RtkT)O%$0H6MiwX=c7ZfxBV7W!#G8lt`A6`x4YjD;> zpU3<0^`+xezeR!N`uLb+oEG1)V;p8>c%TpbGMB+FCkT+gq!@FTE|+5xd=#9h{_Ub2 zxFTBM*p=_^1_xg2D*0#&E~ou_QI~ypk93gAs(&x`yZCQmbL$hWxc+|r|JC4UHN)A zt7WY{a=(2&+>0mE-moX{dn5cTzaD!deD`FtlR@fUp5O+a2zsuz_mD7X&jl^_+{jxGxiKx#?}A?p{k0{U9dthO zhcpi>T$Q(1KjQW-M!RrI)RJO!-@8|3PYEDNR;jK&n!Ip6(`cKYvDqhY>X&tfb!+%n zTFYG$MoasC(j;e&mf@9IE6iYX`6uqZQ8cC5%G|;z`s8}k_ULJ&5vbeT9TP|Qxdo-j z2x9nnA*Qg^eWMgb|If_hwpuvQc(Mb6+Pq^Gq7+H2g-;l#967Bwc0>z56gz%V>+Yv2RFERozW&-&hCspz_VvN zqle1ZH_-zQ7?bo>Z7N^y?i?MxgA=5V>5lqc+n8ui?%zKKXg}yyjERon@=Q0ryxqH^ z{jyp&chPuS9(QNuY1P9g9l6Y& z5KR`l+Yl6PIbzfVcS(QL_J0Hv5C03Gc-Xx?C?5XTK=H6^1jT~}if+x8tS)}Gq#6ZG z)l=i6Ek{D8S&(_neR@Llc^LR#CPdHHe)$xJfS~*`Mhyu?$Qx;-jaXIQTP9ZT%#k_L zE7;4H8Y|YS2-4xB`ol3;kNp5W1Ywl}Kr7ry;6hx4MIoN1tB!)@^D%}$7$btSdh0$A zM}6bb7uIR+2S2?#YtAjE3f;XXj(*nAT_Uzj$Wx2Ho7N}mrvJTut6y2M!A@F0V!e~Z zg&8b=CCGH!=;&-`Ay>(@eTWDqd-$pz;!k3j^@rG{&>&5p9){ieop84`b^@+~ra}G; z$1c%NlrF{*hs;H;qDS4m)o5a{*!`gzotiAV{7<>5IcAEdMdcuEtnYX-Lv=+OaZoNT*_TCnB1d+ zv)!{3qiMmbZp>!UoK2TM`m!C@fi{gzKl@Qcca=bGA=2)o%?RST*j>C?bjS3IR%Pae z#XqObIC+qZkDFsm8B`EX_wW{nMOJ@k@#fL_Iv%Z(FYQ)%@}=k8-?v1t`K~)RU)pqN zk10`6Cp;f8H9BwTJ(HtPWHs{_{ldMqC1Te46(8o5)Of3Cv;3&XZhk3eZcy>;CvJ8- zZWsM<)GsKkpWXJeo874Gqn$@R(^&Yco85=EkKU6%z0Ex{HPT_TzPW23YH05IhkSF( zDXcel!$ZEg?=}|R@{l#hL4P-FA6?tF{K1!VTL(B6lVuOOk4%S;z39%H9_`ziKBzYD z6da6J%G0&eSwdcP*9?7Xhv=*zSTyvXJ4U^Q;Oj%>cSRQ$$J=7^ z*N&j9qk544t4$MgXcAB^sQ}!~zlbJRB;IjswqHddh4R?}HK2%IA_O)$A#QeW{sR9- zGxkqRTj-vW>=B=|l$t}F+d-?KXSm}`MrTQps95x-xKLv_Wt_UmF=tDz4^;%S`A4ZE}(debl)#$nkn9(a4hd* z1S0TwKfYjj&New#wkeBJz@Vh`v*NEQ%@Uv_Nr4o)^#VqWyVECxhJ|(r^!enM^@1>o zQH-%xBp6T8*2puf-JrsQtKG4N3NR*#Ac?&dAqdTSaU#u_PmNSsnGn@z7~ zyR%fLcKJ4x22%zQ&#+Q?pQMVMnxh>YOu;PXip%Ws6Xx9ChmKy!1HO9 z(Axy_*ptkFMNU4SiirzelQu3`n2R16vcJf*P4hbnxgan5KXjcu|GPVW-m-f;CqUH; zzH(mcaf+@$;}^GlHFw-+EW}sUf4k;Ke``4|UjM;gK6dxb*Yln|`7N)|ZLM|LS>r3W zw#BKCJbg>Xxo>T5_~=7_rCI+`SV8jQj{|)b|Ag=4t$N(-c6&P7x@Ju^EK&8QFMT3g z?`WEdTJQTCdg=Gy8}1LUn7Kz1JwP7x`HU1WZv>~(xXHctbkwsqE)$tYnKM5-ezjb# zQCge|)~JS}W2n~F@cT$!!a-WW0#ym!`&UQR!%3EIJG#ui5GMEB$5_%VsMy(rK{l_N zWqw&4Wj?KiU0(==0mH8lP=1lv5H2}UVyV0uKS9YowL03ONTlT;idA&}xli{0o2b&_ znKjz|?I0&^4gv}quUwKO{L!;ryj6s|J+g-?o@uX0gR09rlp5IVwJ9m&*vI&K%a|=l zB*=d!9Y=mW+6c&epe`C(1ppH|7iS`d)ROA%5~ zgb|Di$``3H1~GEaIPIx89`7M%3jzQt86*=mo;R4gB%!W(iAhymz9YMjGlCst9tyJ= zY>uZWo4b!=(C++m+5Os*v_R+tRg>95v%JoIVDD&lC)5DE6AvH|-N05Fi}9f8Xd}TD@uCXsd2jW&TtxB6zt4Mo;6f?i-yz#UtMn z4FpTvneRdAT;lF~Pjq;&WN6ZU(aU*`mF_!`R(|0=b6~Vt^FL$&aF-s4^l+tn`amR^ ztK5Y5qCZ~gPIzzhrSy60LD6C9?Yx7KH-6>LK8T|L>}A<2gt05@zgQUus!hV)ydss0 z-ay_8_gm6fr%U7jIwA-#&vgQW&ULPtWd>&P^rk2XSwf7}E}LO6$KkYly)Tl@_Y?1n zwipn$G#hgp)xasdQ0bC8qF+-nUJ-2(u5C+R`|>>)LEQc;qB|+&DD?4Mwz@N#%;kez z4E3;?&f`e=FWni*8*$B@(GFZz-x+OTis61^+JupnmG;s;E2D4l>pxdUQ>I9J`dTpv zB@nT#sfG0my2ufMfW9q?QOJVskjY%rOf^ z9K++q=Y>18Jb1o!`hoMpas8}iG*DDjgU<&ZH_0ZC$amrSVSi2AZ|^S`zfScoULg#F@_Oud2sL~DyZ;V@H8U?H(E8WcJOAKH@ve^E3XqcVgnaAune!w-UzU%W7!Xy~lt*I~Dt-xY2Cjx}h6KwaZs?Qau;atg@{U$^oK z#~k{*YJr&|2I}kXw7a6yw_Z&tkW6&dRz7RtqQz^~7_hj&-&F&9X~|-@)!oro=B!Ga z!Xl>J#vCY_s7UyL=ZB-D`N0=;5xS7)k2Rf7@`)uhNDp1}526*F_EF+pIfqlvR(;() z{)1?baoOilKhw|qKJ%`t-4$)+K74o7>W;c6THf;H=P{yw&sFb@j(|gd;a)R*eCyum z%L&{VfGSAtXaAW7!nX6{vFwMi_s7`}RxptEb6bl0d$(FIMq-=CSd>Or^Xk6~9=x=;R?#;$P}{WyAeTUw>krsu!^ zakM+nw|;;ou5llHAi8kOZxHvjr-`jgGOGm1Ef2c5vNqGTWS3}S9s0M2 zcpnSgL(viK_bJGl$Rj4Ee4nd69PK=YA}z{LDSy%j$3GlxrU#~PadLI`VCaU2qYve` zel{~Qqa7p{)qm+^h~Zy~wDrH-_K!wCFW%IWki8TJ-1AuUC73oGPaMu2{jSlyE&1bR z)p0A27~AbuKNgJ+)(-vYG2ANed^!6Rma63bhF`hl$%bF;$#eBz&8)Sr+b_54Z)01UcZI-jLEoXmk30lPAb)dPaC{R0+&82TAfo^x@#v zp|3v?9T^0-y5f`3)B@2Iu5+i(u|w~9GTOT^^w6`>%|ZJ;Sp6}syddNM+3t&LqMd^4 z-F<7KS1=6U`rBx$No#*1yH|{8mRi~tJg$P?hD z=!0C||1woxbXUI|eQJWH0E{1~Y92%Z;DK>l{W!v%`{i=i_#+$32D6$|e5pHpt)cq9 z2aoP`H>}mHxjWaIHF@^xPIKPA!v2~qUy1tq(vN-CiwJyRL6A1`;a3bjhu_$PW};W4 zS>p{ym1;}JduXmZ2 zxIYE2<>nIw-+$4=TmQ(4gSG3V=8C)Q;!@~Fy%3G53eSLZn@4rIQ0k&^!RtsvpZHU> za}eC=u6ZrGu4Tbj|0GB3`~D08wJfn8?o)q>P7N+~&;KQQXUno{pO>p}%6~@lyS|1o z5?pMRIF$U-|8l__(TB$-H(b{EY`OoXXNS0xUysI>eStrA%KFQMi)IDNxC^A^;*??0HX?+#(~-BR}6I|`+D ze&?Rjq4nyQ%AdTk>hBLua$QZOy@My*+@_Lz^=CJg4!}13%cjzIf(M7rYc5SLaJ{35 zX`%0ztHIz=$qQU8PZ+yjIfgP>{LIkbqtd5?mP?=E!R_w2w$evi9#o|j?iX#PQ+LpW zM#&kn1nkC5ZXb(4)S=v-UAAY>NIdPIb+QtQM}4`yBsRF;iyhr=WqYZ`SXwcwUd*a@ z;T=}>-?W!%9zVJ%%;f&_L^HfrnFV?to!~L^5DLqsACZ{=Sd_t{P735@~S3x`1ysd3pWj$U9qdw zTYB~fNbeHc?|;^9*;U$m+8-uh3{)5|RZ0S^lhWp2s z-W{Cb+ImXw1GrxwGgjzuT90AH+Wu0nyQQZzhN2(#pyU436?;n`g>B96EzJooaX0ps z-qrGgec!#>TROFGF`snX)L*sKeZH?Wwe);Dxytx{RQ{4%(O2qYBv1C0 zp5D-hr5KMJSK5MazI$Bh(>)$O7PG-H&#=@o8s?A2l@2aF=Z6`woyfg%N;t;tJW%SK zbs^F4rtUMh^MV5$e)seFg68WK)Z_vz{h9Z^#i3((aXN^rT1_4xGe1tzR0(3 z;7|FXQ1&P7hs(vR6IyA5@^9SXdz4n>uPC_6o~7gQu>WX6X_IDEztz3SZB&2#VYhnE zQdh9Z9s9x3V%PQK&e3kiUydrd%l0a@Gxi(yDh&o#IE;+P(#q%J(!{itPwidm?|Dwh zQra;W)90%in!If9QqQR0$a;uHr>vXuqM^6q(uaZ_SKo)ww^_32ehGb0iWoG~28YA9 zDsTV=2+1OOM737&C*E>S?!8rZ%RF+QJGWYzJ>h2*vL&xbIOCGyJUf?Cvi(IWc=SH^ za<#No{_*?VCYzR~PkwS_T@0z#Zjd!v*);o*t8H4kZii)O95;tA##26DUPguj;zIQ& zH)rQXpRGkar5R^$9%K8<)Ukmbtt*z40rg%(!~6d3)~kbmacx+_r8Rd zHjq5d#XI=cs9<8U=$x$J)`u8gCAlao00567YwPCCl^-m$nJI{!p+$ z#ZYG&(Pq>9yCA`2ur$#1tnK2m2fW0-*kjAj4jnsK+9b$daKX@dlS(a3~W@%F_l4Eu#ZJ+=pwca}DHvy#&0!87h-N$D@R(?2w)^pjxm&{pq; zDWFBadzaE@zYa=M((&$>aZB*7wtl_3geld;NVY|1#@yhku~-fq!90!2>Sdvvk7$ z%!nRv2Ykqw`TwUQ`osU=i2m?@WkhTK2S>E#|H_Eo`X3z8TmPLA4Xz_XkW@Uc3@Zwl zZOOOPg3~13&#pAP$_MgeY6`!u7U$#-M6{!P8cepRB^uv8d{^FewwTFj$HQLAxeOvZ z;m1Rwk`a`GDdbfoCY@KCFbiYbMZ(}+tP%)}+LT3|gDuq`H%FS2l$)cplcV-}PWv00 z+51gLRiF3sx~Ilm?j%~E^Wg<1Nu-TY+W=qh_ojN|(j)C;qv^E}2Z zZN_eEhhJ$+99=iEofcVeFuv?PPC$^}Z@X6ZBi4dVf-I1V_TZIl%v9yT4GcJv zs>~{EpHz2fq(G^4coA!hfpSz^hNO44D5l zuhy;B$nMLoPf|gfxD=Rl&S&`+D9D*$%aYpV7vuLG6D$lq4InjR7IT_{LK_0)Lt*RD}4-6|J1`uOY_S@_v??8#tv=!ky3x4 zU**I3_3^p?i@W!ZkD}`0#&>2*Hko@T8`4QaHcNm2p-JxcP(%d8&;$eoI|^tJR8-LSd+zLR0`jQO`@EmuA3yS8XXegrbIZA> zALCvv6V!A_D(?zoB0PE^K3qL~B|3F|5J<^;ROcaJf+ciz0BFM!>b6ECQ0>Qo6F~d) zaicCWta~7wA(5gVG}tB}^Fbh*CDigkBgtT*{hzD+}ga_|7{6)4BsnE z9;=7l*u;RR7ErM>X?joNqu5XmPzFjpl%DQoWTZm~#2b{?tsj0;oq!Bbs0e_1fb65& zV@5;o1yl?){}Vck{FtcN-dG+bRIRu1M*`R+00l}(laY5s!UGc5tdG%y?&xV$OW(Zd zpZXNa@vr-|-R@HXD*kW#^j%sAg?9Kg-a*XT1@{h44tn?=AgiyDQLbonU$CJeH7efR z7anmKRqfXoX!Ze`(buR19>wOqM&*LowGyCMoAd46B| zj&AISRX(43_QTFNK*-uH!1Xk`Nm?=#L>EMJM_j$#j2z_)~v? zUckNa!QW+lfYmg|bu$|L{aQa~uXXD6sKHv||6%LWPY;J*|NX}Oo9eDu<;aOue%BRk zUb(!HYuJ;5l^HI?za~ z`PVmNkc1qgMs~0@hnO>0h&0RT8%_Prfu3SxD5Lt-nw5i$$_an15{Q0p?{j92f+tk6Ni+o)r`FS8xox4}hZuRu3~aI1 zZSz3fuz4V}NcCrodiaQj&nO_C^_EDYLC=6BETM_dpfXq;K7+HPgg$=8V510Rh^NYf z!Ab*^AFLRp4-N*o`5w&}tbo1NJvNa}4OYNj8-ndrLN$h{)r2>hDQLMPT85mT4IR~) z$54F=%^qT8BX2^1agDZ@+7uW;Z6p0zU{p3IzKiWY5#n=PApxvA45-3-S~=2q8SF%3 zxY1O5p4tpI+Qh>aO}7elV2xZawmZPn+~G$5#4kpn2AA*k7{r^ztc;-K}*mopad^g-;n^Aw?;;~W2SnX?iWVCUc_o!X_0xBA9OvGp1JjQq+ zKa}`7@I?qkd;#6&5F&0PcMi&6Vz=p-5!J)WjPYNU3TQq=%ru^P+zrOCz*Si&P-Hpatu1o@_@ zjoEC9(WWZa5aYyH1nj>dvV@ozz=Cu@HDJPMY`j&`5D0ivLZ#Em_j5F3dOuDvu20&k z2pbRuJxyJAaVf0Lt#lJX)Uu)$^(5nAbFV^haT>EQVk>=0#`Wn-=h~(fEV0$Bg`p=L z)m~Wbw47?3%N);|#!BxmEaSagB6{m9#z<`|ef$b!Gh4}=W;~Y6ol$z~8juwJ3-#vt zX-3QVgUnLDfO9-fdF2UY_(sr)X*gq{BR3s5D->#G!!qpd=}HFCd%96xY29Jx&CmjD zs*SrjAaEcRR_Yn^rW@;{_kv>bopENhqP$sHH84h!PB#iKH8nY5MiwZ+jKCYp|lS5_)Q2h9_70OPwl}I`JE5ld-!V zID+9f2Hxbqilw`YlI9x~>8^R$c)MuQJWRJry4ilJO)t+k`ndmKO&0RLX84<53aiI} zhi{#XJh8jw3y~*&H#YLb@209JdiXVCRwHS>{6G$fzg)bKy&12_y{5k%*zAY|) zQ~x!-gH(Ho0c#)XyTo`5m%~dS7+OU7Qp`pP^iJy7ACZ9mVv`vLfx0C zcP}k7YAg7B>oS8CNRJ^|E&L`}_~vrR6HBP_a`Z7$+qC5hk=nG}c*ssnq^55u4C2-| zjQf!E#v7{UPu?&ZG>59E8-W@?9jE)VthJF@^x|oI_z6l(A@9NP&IddhL^d)r7N+Y1Q3I@#=-u7_965jQFRvIa3yp`!{wRw;N8x7w(dtq?Z$>gijn zsFa6PM*ya~EBMxnwO;A|)v6o{q|j@t4c0eWyV}?vKVd-$Gn23v6)c24%=a|=Eu%tu z(L9JNR^SJS1>8!x(-1oya379WecR~pTSmPYeu*R}o|D%YRdObxDhr-ueA^^Dxdvv! z0GfjQe*Y6~Tm$k2b*%vj^b`HM28jA{&cvn-+bB0^WaOhJ_8lBz zo$v{*dg=Q~p|J=S!n@CF>sKS&3>3Ewx*099mU3;-6ypw+?aCXR4zWcjUBgFTf);_= z$@o^Om$$pE1Lommebep~s-c5HqkYUOeg>xp&o$N>Psz8ZW006$ggpHxTCvusk#k}< zYo$S|&)@(*u=?Rlc<+Su4f?__tm5h9e%q+icF7G+30bm3HP8NU@cH+xH|l#;5V2kLZ4GLad*kG`AK-+h)+80spcW}7OqoeN_l?>?ev-5tX z{4X{d{aSp@P3atWH~{rRFcK|jh7AHD1Vx*vm_KXjPL*LQ{JN>v&3Zsos`EK+eSMbJ zp$@G3>hBsEG3?9QayXp0F`NjDd=;%MGLqa#@hzrZMaIM^Cd;BqD;~1Rn3d0IsKu@V%iY?= zDQxkAZ&mej;u^bsOxXufXrGgIb3Q1qvA`{oZyzUmkO*fnp+r{=hYDbg&B61$RQ1PZ zJLAdjUU1fCjK8*r-rr(;BNr%#p3u3&{(hg+jr8*t$;y0DgHfU z3NDM^Gv-6Sduy>#tZ9(uY&Sm6fI=(62^O(ls|qK$&`u~;3H0tqSO%AsI8dQrIOwV* zYbq{wkx;@ym2lM}7wjU1Bf>>O33F7!Rf|j*salzji`_~nVYN!QT9N$oc9997%taVFqh#W2eLT#-qnT{s2ALVzznAwlM=6M7fme95$3U0K>p^j3*2OQ?R31 zB@N8D5iG@J90AV)nvb~Tvt1@rdA4FaYm|A}auX*>f)X;oTmeRzAn*ZUEocRX?3#42 zEKm`sK^qt0T6LIEp&_VjaX?EIf`Ci2?IOFe51AsMH2~OfL+r~AY$(*u##LDS=oz=z z!#9d4MsT7~8>cp7wmD=jY{ZCbBb!o0#Szs#d`$ud02d#=&3P?87D}5yR4fK=^=*(&Th2O-?txAMdR~i(ZWm z06PMu0ToA_I!Yc8I)1Y;9?TO78LCCwbn@e%jIM5|hO-2QYA?4C88?TF)O7Ge!A%ari2iE^VUvU@m^o={n zM_7oVtkoI<7_qt9-+dRFv>RgH19WL2aoa&t4;y(<2{?S%xG@u*jll^A4PJbJ!(JeU zZ>3ty0w3Gt6C>+(U?sMF?`3+V3qdk~XhZv+3h#PSI~}A+pmpudiG=E9pB7@{Q^$5XaX8l!!hF^-Eh!ooN)3W zLsD?|;~+9DL|&W1zFbiOm4}@z!Zve9%mSm&dXR^y{}qN2u=J z{GCyi2`#Klw(x*oPKR~=0FC|5cvRa&CEpqQlGfR_zx8^sB`kt>V7K^&!^-v)ua@}2@+^?HVcT(*!KaN12`i!*D|7LtP(lXF;d_Oaoi^Uow=be@XN-zT-_OnqcsA&^I+S!{AZ)q-PnHch-o={VvXoG zrLo#07-SkyRDAf20MkGn1e;~4J1h@%fZ0?VP|?|n4svk@g>|rrmd!Y)PQMs8cz{R) z1?3G*jt^Uq+jH?1khu|59Eql!i`P$_&Ax1L7qp8-pfoztH zJ89nqNTnB1)nAR;wG~mzPI>bhI?{0Rpq91`92Mb+5?S$(0I-FN5BdW2m@7rk{R-BA zlUDo+qS8e>e}yb!Q}Eoc;PF zJCaHaQU0>@8h{WRM^d^FpOA0JZ0nW?Z&i^D&n*uIV8F?Cm1@|hC z7L!lM+eKHPSs#jW6}*}r<@UOqE^KQc8SsFhVq^ktYrd%-diSs=wI}16{Ib*$!YL*T zl_LZ|5Ga?hDLEQL9>y{GZ3xEqUL4rWSx$O-w`hkQv}L!*DvuKv$gP{lAEVEnLm(I9{+?oI2nkhH4=k@Ti}EX! zRh`_bdkXQ@xO>3Tsoh7SVgj}T2%0QZz=?3;3HpT!J`(;I?gkRsOq`{s91>1h8f$6ab4-7K`K?N_Ab(3Wh@A{|qS64~7{$Zeg~O z5{N1^5>prM0QU-z%Zj3j_r|3)<^l>;Mnmk_L5+8*V~4BEj$w@OATI8d9lk6&^J5#vm+e>WCzY+@ta#PE_v1xNH^ajZ$w&|-}0r!MP_M0UTjcX^e)|;BrHF`G3JheaTdJRvbqk#0p5ix zR71fxlEe!dOtF9|en_oS#LJ#T_Wkh`k>@#S-&aZ%`SD}1K>$HurRRhe1yrScV=0&_ z8n@;bOlLb;q>2ZiDPZmuMY6k<(j0I%m=WQ%GVEo|XMRA)7}VwN;VYsByqJT_#5BR)34clxdF~>&Vf;e31|c|qceRMg4V{UPqedn?z3`CYbh*7A-eL+o zC|CeBDr`DBK0ZF3VjuGQFbBgX$0btpYXw_l%z6{MC$zL6q@_MAm%r&@Z}bh=nLDSasx_dB?yDAhJt*>>3?@TtH&uCq!cM7e+h;OnWydbJQ% ztQF-mSzQpPa7vbjmw#=KURWv-8coZUj|%mj zZf;sGDUEf@!Q(31VNkMM4?KiVj$`cu3`z?5&X$ZA z9V`5+voTch|GGI3Zxq?B%Fgg#z8wG*X;+)!^JQn48l{WMsfSq}3`7!QRh#n+eTW`- z{G0}+i|jH2WsucZ3Y3HC;!YS@n;Ae0izqikw9Hwi2OMC{Z*@Rd$e}~Jdy(a?)d3b^ z@qC)^_p>ALLV77fEUt3~>dH#=>9VT$ii9+nQgK-U+@mv$dizd5h6d!ASr!i8@6@M) z*o3xfXNt_QD4RvPcV~(&!6yS^zm_uArF@67Rxc(D++M~FHK2{%vPGt6@>~eHKBVng zVp*_mCC>lc)$>1R=U-}jhFAH|RzZFmpCuZ4wl9lRqyMT?+^E>JV24T~s8PFYye{PU zfU1>z8dgnItA1fVRH3rq@ewZL`Hp?_l#!fdfjJa*B0(Ql6ImYSj6rfpBzJuJHT!Y=ClA=#|3WAjaZ_8ezeU z8sahdoq4K;_+G25v|?CO4Cq~m!T}MQqJ&nsLDUsarE#?sCDC_`FOhcF66O4iCko#@ zB}J+o&Rq|=C)m+0rqmYAvD;eI7Pi~5J+qYCvHaSK_*ht5?5uK8SMm?uiV>zdGu#SZ zwfzPGO9l6NE={W=GX2Czs}4da0M0!-j)Qe46P-HCy*$2`>2MwKv_`?(uMxVI#ym9N z%ZM(@?!4?^%Zu>Tp?+I+#^LA2k*xzU$M*AQK`A#>^0* zXPSt#rF-GUmb73%PKr)Vam%m-a>Hizj3_fZ6+pN#qrkSX2Qw{JKieO z6Fu)QeYr2}b*r$suv%T_pnB$&4yrx2gK7Yrg|B_jE~?piIH=z6Lkb=W=2Bt{QMY~& zhG}4SVC8afJFt*gTn|wNuWeq}*mPhX^TlOrbb)0I%l#H&Hs&d#rGQG|OUqlQP}i1% z9V$H0QYzfY zL~L_&un)byw-uu%JwSUV=~d~6@8Ny^4E4EQ+=@%1R-z{^6=al%0bGN-f^8}sLQ^r(D&D08g&kDINnB+$62$5wgR<1UCM-OPGs zh7j~rAknLhJ6psGh9M6Ms90toTECB1k${mKd|y^PVqSxzEf1+OPt*8F03#VyuucyB zd<@Y?Jk<2l=(H$E=rIMm=)O;*Yf|(eh$)tQ8l6h`l#vP zp6!s<;%HmQqywx$8OjcgMimB%ddUaS7{;uDgL#g7!w-(&%dN#$E#+eu^C_VU3J++0 z0Cm*J9RH80e_K91nX~*M@f=dQ_M$HM{;k`KML3~K+T#!z7Ce5FsH}r^;^`o6QoJ*c zCmD`k=VLI;B79WIuKW~V$ZeJEz{1!VEa)H>0?-Dl-X_Xxna7c)f_y-Q#br&!@Y#V@ ztzC!t4LxwXVB?JEZWnA;u>5xMxmy*XmpfwpmC(74LOIF|Wv_UL*o)Mk?+_btdFxKa ziaUI#=$mkH0i64|eQWqw;mv>n9YLM%5_f>F{^niiQmx^uagI7!cL94bFW|sjQQ!I)!|khP zDZMfsOfhTZ7$8~~sqejFfc7GNey?Z|#nq!ys?u59n|c!O(KXS-x_~=t?Q{6~#c8b` zADrG<^w29zoeufqHP$X%Y=PuaPROxF&fo;9c)w^XPfSxulkKEI_k)vnlwBSn&`Vcf zLnmoxSJBB2Xy)OttIWki0Qj@rft};#^x5tKwV3I;ZlVR&((rB&lq{m9-GKBgqW8Lq zF<4SJJs>jldaR11L>kdpJSCAQmYJQ1JYD|IBrPwtDIIb2Tc;a$g28H&sHo@HrpsK6S!^$~Fw*8QSK#I?{1IQNb89$i10-<2pj?JmNMen$MU>x5JcuG+^b#*Y z96qqOXse%?Pn&v+B>m8QI^0|2#_Vw`1x4$^e2VQO(gR=4R}L&&D^c-@@B@PYr!}ZQ z0=C102Ke3$x7qg z5PK(eSVy_g(fL%^S0r};Zme?pIYKO|#w)HwC96AT?3LJgV0R5SoS`1G<1x3Y3vFXb zRc(j8v-VZGt*@vN$CcWRsT$E^Gy|jv7rRx1ePL%rKqF3pjexg}d?v{nn@?ey{?bf_FOW6j;!E-TJG3+ms z6@>Wp3M;owwlHcTlP#utAU3rL*!BUBiw{FLwQNzYyka-v%!6-Y%FHX51yBZqtwg#r zuN+gfb1k^Z4O!}bjEI+60JS(=Q5#~SmD&~IxhsDNd>&4DOO-$+ETOpZT6O7jt*Dml zM5C-R7WD+ASH2xel=}plwH`M7^wG6A1xpAPUnvy*xKR%33@nIZ*>T9zARCHbqsv7dMsPjB`Y zZyO58IhphS6FoIR<$861sG*;qN_z$XgIz)24iI%O%U0!aF~l?S$1uiTp4PrADqW#0 zQJa#B#5H9TyF4MfmV>4y4$M+LiLJxf=CFJ&sN7Jxi}hiww~&CV@`@i8eHIJ{rmn-9 z@RuTWV8NO&jXFIkd{?U#CWYyBP^GorC1e zqZ_vJBiuYIAE3zcJ1u`&Jna2*<4Haj=TX`-Vyt)jyP>Bg&xpriaFjV%RFS{Ib=5@8 zI*lvNncD{=+~+&=@?gP+d)0@)MDclgbcj%fd(N_kd+^a3+%yDCn6ywMuj1q@z`sFR zQ4C|jltC}fJ}aKX@)$f+$NH?<)&b+i~&^<4N!W0#tTB2TO)?2lzw&d|ee`W6LSj}gb12F-p>eBwX( z8jfFu8i8(tdINBi5NcGwT!#r%VVtOh%&o?$5$irqbk&vyKNu(SH5kaXn;>q$W%2|u z7MF~P;++I2D)E`YClO2qa3-+|)Atj_3uWIZchO3FYSQy!Co4d8c|j-zD2V<-rR_MO zT$)}Gm01C*^d0U%$gl#`z8Ay?{4p~piIZi~ybVy}00MhCnm7MN^({MIRNwObi()zK z@n*gRZHzVKnJjK`vpwF2bkAf#NcnNH7!XQ%>}ApRABZ&>A=Ziz$VL%si~?>CKR~~g ziM5|z#>QPp=~KYu3R06PVgqoKU#19u+|npu2XK7~69FiuFn1(}M13s&E+ig6rcGpL z!dKaubd~8x!VVcmW2cIn;B)WesY>KH@D~h_1!jmRL#Auc{Zp7bYDe+KGemC29B^W+ zBFJZ%OUHIbE^C*1s@DVNM(1XTFEHH)XEMWQ$}G`9sWleORBWIQvqX-fLtX4V$~RK! z$*s`TQ2<@M)fzTIBij~c<}9q-5?Zk^I*~5TQY_r~*$Vq_G+Xq?*e#wd>gz?d=(E`( zEmx@{GkUA652Ap*^Blp%00;A;7|W5xxVuC>H21lDW%Yjo9a2Q**&Rp~m6|{L(jMCNw zKYUdT)^1<%J$%|mF{Y+$J}gC+dab2M#;k1+;DrL?fU38{?}Y@+xBUb{TzDIjjin?^|yW&pI{)oonzdv+4baXNUS;IPYvhv~L z5jJ-W+dx-m?NTJDvlbt!+j@zd#H&_IzClnhx>{8( zD^e97y7a*&VZzfh)BQ@4pm-);-#BowuQ+RiPi)45(h*IuaEqvlYjFJ*D0+mWE^4;2 z1&jQ{Q5R2a6_0t3E>aAgHNjio69e@dj^fBr3TmuRGvQeH04ay3)BH|RNK9H7z+VA< zW8jt)F)|~spzLkUP{rW9U5tYc=3=;E%dn8z838HPB&p*97AuOabXu@t$D6k42&mWMS7KD6q{t1c0XQ8^?!T zt)nuxbx1u0Qx1ze^!j_<&?{X0cQ(pg_^-lN|R71ged(s@Sp`O4eLt$^a`1)RDvz=npInTG!U~uNY;y#aoqo8}JP+O`4uMO^T&awXoK2Ui z<-!yv22HWkn6ajYmFJ0i9f6MM0UCWoG<#qgtah;LvUsiFrUQ4wft7^-R|r=z;usKl zukRFdMSfxX9xy6U6N_W`Cjr<9muio>!=3UHrmVrXe_@RPEIEO;=6Svzw?LZelhUaF;0nDWH=b^;q-y4aN=}bKe-M za!dqNt1(D{ozWP&Bb*YAlxCbVBAmiF5^$+8v=S+j>j5gnwpd6yaZEJS-;1WBUqCOZ z&ZlCbzIS)<$ftnV0BY{fL@iwEe+CiIF6#RkaJ^mh+GjZKcF~XayTIo-OA+w!bCvUj z&jp9HJ+7XDv0ngSly##70LJ=IUUu!oBE5NZ`tgjpP+) z!H^zQREMvCB4}f%%h#gb-K!B56Pw5mQo{c6d?)4g0Au-W24H8ywcOieK|9)n80{C0o51wSw?$p=fb*-3Q`UYyo#nj@Ys3`CPrp4#^{W$7g7IxP2zw@vW%Txl9JGaBHMOei4e(YMaggOThTD zEe7+9A}!3Yt3>n>)#ds2Bf30)CVk8;l*zy?%;DnLuMUe}T(t$2rL=|Bm$$GX(!z$B zbk}znlrkB(g|(3uR?j5*PE<_h6nI^5_|AZd!~Vi`4rKg0?fFimwXwZjGm!AJsmbE6 zF?$CfipNz=6wW*>6utETOyEdwJH@bfve$6yOU?=>zbYryJq4QO3=KPlBlisLJq7u( zda6r(PXmECLvNhMia$eto(3w3Se|EKXK^Mt{vhgAf71#4Tf?76 z0efs}z;7f16ygtw@U9X{3=aB1e56%k^G$`_NI>-sktdF|6nT1^dYu)$wa4kmS+KQM z(M4R6S2@{VqasncNp`XY{_EpZ??)VYix5vkSmlrh+!4gOfY3t$f<^Sfj}Tj*rl@n` z7B(^hW#IQ@0eL~pao`+}o&yLtO>@tQdlgv}u9;nkxnNEldtRiP>rr)O3y0C+K!0{HY}8!^{_ET1~@G`}}svYQ{aKZOt* z(;I*UjA1uqDYUVNY@Biabx;O|H36>Y0V!X%6;-S`pue0L?LIxsB&ya^rf4xVvxn(V zUjk<@fGP`O07P&YD6>Csq+3Hk6+`(wWtP^R=Ju3*vNumg#)Ihj%NTjy%zSjzaP(tr zf|r)6e$qGQHQrFu@TSvCR?_0>+n#1q+TBZfaDSkeY!dy3vZHePzNM7j$gz=DKIzJ& z`$}Ks z?F;a69|6!_FX7Dx@K)gqSPObpXQ!-quC+r}40Y=(8-!|A>x6OEmHo`LSmt}`mfpls z#Kd+yecD$hr-UkHIhtM_)ujGYHA;%4?2A-2sg3D)Uzrr{9E&c2`aEQRa_1~OvFlRx z$sG`n_5FU4Pmbcv!JXr8P6NuOzK6RA!!K1gzOa82$0iJrOsF32sEq+WVb|ObjAt~^ z9V#lgJYVnfJu9sZ<-z-}D=cjl;Zj#!@NL68CKd(yWH~_edwpa1Ah*kdsDb!{ zO+GNPsw=e{B9FSuDgB(%k173>(hq6q%nE-8e+7EL+5p@mz<;}or|9gH^5Jsa3kD+S z6htym)HbQncp1nF0~qv>-vMe|(NWs;q#00wslXP}dju<;hdGhH@CYUREb3KWbmRvZ zM_F1H`}($=2*j{hrPwqEkQSsYJ3@Va7CE;RY;ueY#Njh^cx$(cKLqGdEP8liXI_U2 z^yUT53{sEbjDDO96c{Xq?@d-5MHz1}sbv(+9LQ&6aeiO~xagt&-*eaF zKZN-Gyh{#a#Z4_HOJb@ z3FBy&l+93Sv?*^+-Y^kwYFnpqu`8LtcN3_ODf=3muw|_YTxbHFG-dVj`@=P|hFF3^ z5fKU!Lo$zQ#LA(Nt1gX|y-|00pUmVTQ`#n$2@K(SpX|ckwjlb&iN%K|2%WI%hY!T3 z5A(n!ST)3HZGd7$RfnUY1D0Oa>hOayymneU!p|&_+d3xrt506X0ot0ElNp${d&|kH zcp6ns-s0jZr>bv7XC{I*!qbm7?HeZUhLMPu6_B@jylja}&v?l(Z|240l*Qwj1exq* zEkp3i){sa<)?cZ5qAZVhtrO)ioZQ$`g~*CaywZTo}O$ zSHhgU3kZOiCMQAb7Gya~9k)QV0qQuQVQ1lneMgC~b4KNRhN3xL8EJuphcOy*glv07 zx?}~Fjp>p-C67y&?3OO{^l7?W#9`_%Bq+p$DkCKJ6Ia1o_q7b!5ze0LWXc3GE6C?? zKed9a>>aTl6X)^WPTMMAd2FPQGG%2uUoI|PGG)K3B~~EIFGoMZinw50GoE1brKtvb z91SKsRl`xZtzQ#Ita@}kWySUnrNpZgZ<&;GDn*n@LELv#;tQuxjVyVGUbu}$X35zP zvu3Z|B&)@tNw_a7+hnSGEZby;N-5hUJ7vMxhZ{gg(^N`nlVbyRlg9({70AJ!t|&Xf zwPSE^CD~thO>*h^)NK=tj|=I69C=EcL^oHJLvYzyRrWz*lWMXn;M4SKlD!?Bs-|{Y zVs+UBPaUeuTHu)$RG0OtLR!Z<3rD|Fx$5Cd`3|kxvH5^+!i5K9l;}On zEbWml?W?yP^#63||4rbJiLs{Qa;@?LWcL6yVaswiptlF`1V2++8nYcCy;9%=bHN*$ zyXZx1M7~22O8F}KPA}9Cn<2qVPkj|#A%>3%d_Qz2X>zV4Okr*f$)=z8){x6^iLQz1 zEujWAC2M4ao<`PGSytg4+|OZGd(j$xOJN5K6KP#dSzb7>mH>pXc(CO&YstCZi!6|L z;^^64OAf|XZdF@eDS{tV8*uhcT31^>kM-HEj)JzM>d4#KcWxOGJmhsa3r^KRwn@Qf zu91^8?J$Y2ikEm2}xzZ4)mp?IxEPV%+t};)Ux6-GtOuZb`JwXQpQ&mou zoYqVG*}n^-8(upK>!~)Q=uT_@K2FT`Q=bNM5oAdz4dqE~E@_Qqx6}oUa=I9%D^+hc z=)}I#d~=~sEvwnN5@~%Sc|8hhjb%ELDm0d#^P46(r56PIHsNFFJzCjRw#DObO=Y$Q zVQXe{`K0`EFP2QaRe}o`UUQqv`Zak^qY;M0SPDE7zawI<-_g^`>B9>n0c*+87R(q2 z9D@uaR}0Az$lJ7#HR6u;0o??y-O{6o0)cgk)47Gr1G`~c3jpOsbf$$|oT};vx0{3B zV-@0>!dLKYRGd&Myb_pHH1N``cF6H6O{({9i%AS2+ELTKpGqu{~go{Zl1O#>IDu+FUCqi)Hr z+=J(x*UQQrx;><&fovJUuq%90KzX?nq=q=3ZAZxZ1EuM|jwZt5wM%7+;yf9258M+F!S#h-hC?(1oK|A9#dV*=&@Dkfd1ZN;QZrX9ni zX>;l#n`cN@@%A1e9Yxn|0UA=3_ks)?NFN5kA)6vhJ!>wEMz*LNL0w zLid7gYIS3pHf;U|!F+DwkUq6TU+8l;n?p{LC-Gcv-NW40lxe1Eje36JUT{Q%`8 znPb%VbLiBvyfx0vT(xM$RnzlqzFIEr?Qh;u%3P~8z#I@_t~H_~1I!qGf=;y_m$^2J zjc3H|J0Hw^-0Y?01FOhm2?6kns?J6Yao(ysoWbe#T~0&bU@Fbu5SW{~!%4vi5zwHr zj52t>goAO#oN{32;RZ~#QZM6I<&%~BE2E6gKVeqXPEg8|=Dm0Pm7itv)j$(*0|^a6 zUDAOuqDvO!qc{R=X8Parx|HUi$12gN?_Kg9&(?@HoEu}tfiJKEKX3(<-ATS#_W497 zIWF)fP#-4M8Lwg3!mPcrDj#n~(TYtXwaNvk4*Z=O<^|{zlu->q2!|x9aE}}VX~}|n zBuiC(xkpw=J@dm!M~(wV8V-EmSv=qfXyR}oo@bwXK(n8rNA6XbgZE0d#6i)zw4zXt zp{|`}G7<)LmInY#Z@y2abszaU1TV{Zxth#|RIxm*LN;p9Sq_Sm6#FrUEoJ#8*JkT7 zW7{9gEJ~gIv@+*Palv$k<93lw;Ub+woZvn8$s4sPl+gu<$~n5Pi)@he8=A#xQzt8{ zRD}GhFX|!>vNArnBTS(D_G5_q0i?+~_ap78=FPxrh^qmAD7V}n9YqK3m#uxn&jEZ2 zkSORkdt9aJUFH4w$njlewQBa}hUO&1`lb08NmD%#%rp%ZJKhznjA7KRn{318e~Qde z%t>Yb2Q&iQ+=;ZQo1BLu#+nJQ9k+aB#s$YeAnWj1{mz53xi|P0`T{OVP=81+)>58V z5`QQ7#uzS!MYa*;^R)G0S>H2fB`~iK>CcDd3GYbz3<%OUkAU!pcI~5}C5O?SkIE4o zz6a5&pm!DK*@XB;QP!@7^wXngzJ#iDm-jSM%56ZMu@=M3)DyK7FV$haxN|ee7JHVM zNCSD44l++!8wKC)E@QNORUE!Kkqs!4!p>Cj|4`!#Wol%+H{Fi&jXOVPG<481mCFzS zsQ?(^R3?yYGanbQWMOUK0LcbxFkzHoDh@ki@MFpTL|h1PK5Xfb^O_7vv)i>tUwx5gykBIxcOL_|#p>cmk}@ft5h? z!Ypv)U>y)XzVdn^)V<9sgNv3IdV-hbqCb0>srgvrRrM1(Q$_0b5N`eUZ82`4jmsIf z;}+yF-xlE(!ce|li(3wyX}!4(6eC1l|ZtEcUR`A$5tu)GB_1k0W7Wg(E8}DRC$rQd^q~d&YM@3In9Jk8O(7+43+?#O-@t z8S%M&kXd5$@Du@naKMI(F#^EY7EQXaSRunKgC0!p$Xov@krT2 ziQCZleTm!9sGi2H8tWYWywU{#ZH{(}(5{*zC(jWdo^Fa82|NjA9evC!?3w;MqY|Uy zI1}*YNh3j=l+dz~vPOdaeF#fZ2GyePM}nAj(WX&~qs3*Z?*~yVb7g!Bm*T$g9x>yT z>GOofXWFQLD3LZ=RtjfsJz8b%Jvvf7#Ef>=%3x6`p{^;zfgF8^EhZg=F^w7n{+xXN#XvrAaD{STPDrJt1NGBW7C*PYf`7bJ%u3Kxt)#fE|GR)Nm(;94Um+vju zjq>*3x1|#cJzh3p;7Pt>{?r2FmHw~hFaO_7Aod5g%my%0(|`u?qQ+cT)qVD|uo+pr zR&Zy}xI&kBZT~|)+VPxh3>cVRV%EUrh7vPC9mh$I6*Xj>S{PHuDc1F_aWcF5KCq8~ zn=!LeF(etYL?5uiSbYs*GEM*riLOxEczIV0Hf~5)>`gE^Wp z1J+;$>CJwqafxU!ub3c@Kv8+ZM2O`fHrnz$m>_tLFO;>F;xh8G?`~WGoS7>AfjYe? zp|~9Mza($sL%h#qnN5eM$RVB?&*SjeNcR%x&11pQByZI`3&$btdpb5%CM)r%n@PlA z;bgg4tM%n8IQi>ZQ>P(|5<@M-omIsujwD>>x0QxXk!{V8ndI2%st{e8D$^PDfY<|L z#)m>IfD&^sAhmmmu6cz~kKo6z$okw@FFjiw zmav-NDdiaWC$YAwC-Tpb^E~_QQXkBaujOxYX_7TjeSm1$4#h?QN`xV@MlwSe2oeq{ zJi}*-rQL)+!C^H{a>ecCr3Ezv?rlIQ4G`R+`-q*_OF8?q68Z#`9$PevWt5l_UMnqU z|Ew6)iZBg5Z?~L^tpu)6p8#}PpMZja({eun!L>Wf31IH=n~24LG*=I`R-uv0gTi`f zk!R)aEjRK^6I;8I^J5{n_xA{xIFFU`Jl3`c=&JJx);X2vAw0dIrYtua0pT;u z7;g;z`K6Op8+t;|htCgIR7D+LE97zmpCFi>r?5y|y)5QpuAqR@DUdYkJ3TfrpHa}# z@j`hX3s4FeIHkbHY-?`c#+bsdL#<)pIciNpuO1lB5aXU3!X`kw@XsAUJJ{3*c)O`(qS(qYb!q&mOiiLXE3u_ zhHFhlx^)R=;J7MGOtJAS&VvmI0HAJ_{b;0jI(_@POw-XP&qA1Hoc#vIQ2V=e{W`%4T zb4J)>wssEPvO;zN_uE=2lbs09LEBfzLH08{$-Q?a;>f@N{INIXG!S&IRg%r}I<1l; z09%i)l2zDDmRDt&P&`b@u)@!F8*ilS)r$DKb2XoT!J(_=7Ol}?n;v0mge|dnUvm-^ zW`L#uYqjzpSISo4OsFi-Tiy=v{~Lm?A@6ra>b6->+>63Tl6ETzQz9DV!zP)n7*PBnboM~GB&xj` zN|LbK=1P`rk~x3#+T5(TgDUG^+v~d-{M-`i+Ab#1?oGJu?+%n>{&|)jlR!t1sfw*l z;M?mB=@^8%EsQr@w(3P5ECL|g*x1}idw?xaELWD7fhr%IjKP+kaM;F3=HrPCP1Jd0 z;{;G=#|g@4fU;7IVl*Hc8^Xm1K$JD4KaPIzU2q(GsdEeCz9_b!gB+BKS{QX}f_L8& z*dL$6A!87j9bgYd`Igun;WcWbCFl=4;TV}MQ5r~#tr!>f)^9t_hTI)gqB6NaP>4t| zUgNnq`*F$6il#kzMxwt2NIg0TQxbJ#0z+mB61b~+w9nS^bdl z5IA=GDC)3Wh0FTGGBtJnL~J@N9&0UbeB=3mTgZ14=*(d`isLiz2>@mV;9(B`zoG-=PLx1}Hc9h|IkFouA)j^Sc#CWQKKFdm!)_`5F$Lgb*>9 z*Z^)CSWpY@)n!>zIIFUcHjjcD`Hi|9l^tR)+CesPK=4^?(K|;$(*8zYUhUm=$7E&s z8~h&tkbvEy`Bug9bcIjSQr^FwMaKsj1x}IlU z2)Un8I|rKoIA0l?fx4;Fx`=n`K|y84k$uzY#HVs5xM)L<%R?{(x$A`NQ2r`rAJ$Yh z3t3B>PRM4l#qYznkp}Ia1XQ~BeG;Ex&7BTb{tWs^20(pta=fJa{%Nzfu+PgK{_@zw#FY7*!ZrXL1ryIVKWAynug8RM# zUV$5``wei0l{DrX@Z68kp>II5(y>?R8wjb+I)VGk>kDGtdjpCs}k}aBmwDcst2?<=22X0ruXjY6Ij4a=Qd&25axPwrxJsd{zEhKfUG=)1z@BH>1 zBzigaU0y>d*r>N{8zN#7&QYa71>+bV8AZb)N{CL+UNBPfF$~I|BJ1Rpi2~v)dusCe zh#o>gOPz_T9u)*5Q1)1%ev%kl*3HFN?U3TLxQD}!NL zxCAOJt;@)&qiXQivwcs%gf_>gQy8lS?WNlh^NuKdMpZ zenzXT{SBKJ<%h zui<&+1$dohj0SmKb`gi-NTA3!zsdE81~cz>)`kJ8c2Ty1R!P<+K!|lT^b&yZ9(wbV zd@^fm__Lz@DgG2|Yvh^r-D9lD+o|mz;4PK}`}`rh>)N)L51O+P!gQc!eiv6<`e8Pz zNCR~9ZhZDG-MkOLzH_{pN$s3wH8;i-e8NFavoDhS`ORv6q}j^_*AMT-nX7Plx}4b_BeJcWSwGQk z5vUZL31sO&t-)8EO}=>ZM!TK~+MeLI@n(hwRk^4{^YyCX0>D#v2rqIA%&`#_43Vm~ zuQkCQfP;zVH5j~@By&e-9O%y^v!UH5YMN{g*WL?aM7p`OwLyQn*-wWgcTxrOIe3Uj z%QUm$rX?@atblmx_h*{5G0=sXW|ib^q4um3A7WI%DVehyDHmyXrrAK7NQju+!)|R7 zK2gsyhoI8@EHka#KG?1Kmu*(pX3&~!vw89!jmeYA+AYvnjbU~H0+w4vdnu-p zIRj+*>y^x@8oamVRWbAMDZ{FmDam`$wDSEB?N8unUNL~@3GiFFqKa7_S$9@38^&`U z<=Fu6*1Gr-dxW6G94yQS>E;}+nNH=H*(SIS0K~|HT*bj)Mpe{+nP^nad;pi})y(bK zVGmVDxrsEhy7_gro#A@R`4jz#*4iE6=L-Dkg=!=w<8bu-Ld$Z^TeO|QOS$G`t(EEl z5Fh4&CV@)Y&IJ`ykA3DOS{K3Y-&*3d<{=WYnv;xB0e9I)KC|cd4`i7tE8Bg*D+hA zt&R3Q$}`g$&PQ?S$Y(PYx4;@gq?&86?2b^;{ia1buQ6}J9!jli-l_o@_pE1rqPzmCnawF@TU9OpkHOqu5EbVnP>Fmh@sswwU8R)2K@^YR8e*$Q3K-Gi>=3GqCng-Y< z#dM^BS-(akr&E zmCszzkN!-azxhrC0iI5OHZpTuJOEU^vDrdD1h!v8nG_t>*sQOsf&Y-!H-*yC9*r$l z(chG2X0CsMleJ<%|6*n6zV|`-)^N09uOBW8MyL?cKh(_3YPJVLTxeMGXaHXV%MlC0 z?N9b6TMKb^*@L00=dqDz`~B2iw5geSP#Z&!_>Hk*#c(u_lus7l~sVQwA_N#AT`7DO@pM7KDlfZo2| zObIpg@%7k5B^2A*Y>B#VX>E3l3l)Y34^##0@I_kP+MEK#GTxJD0Nk)B-+sEgjoDC% z6nwy0KqN3jmft9=9-rUGK02I@!l$>7)nm&X-b`$$OwACdwKNkPJ6w?qz0g%Juz=K( zbondSaOeSOxc#hCY+Li5l=ty%>J?OOuV?qviO{WOw&bw3X10owm%#I?`D^)W;60|^ z@2{aU6t%_nD4}xg%>KX@Mz%AHaO7WqgLw}R?3^3T$8kw$Z?-dLu((dL(#j0#-rgLG z^t0`8=wVWBGC#t_ceDApSORelm;l_En=;#*EiNl}=w=+)OQ^vu=2N&VyT$Bt+3U(3 z%x0Y#u~DBQ{gTZPoZj%*ND#PJ3=Q;f>`ajXlwb&7nF|9LXHVnC4(2oX+Qzq;zN{b5=(x*-PcSm|I~Ue7uX9n6IE3OZ7^RGhW!t z4+QNO>7yG*0F(yV6`Yz}3hIrRAbm=^`{UqSEh>1w`+AwSdA`~e+2*3En#kiXXh=JZ=4hY9bE#4dEf)oXC+~3eoA#2cZqQjh=bXyeWin?0V3gbzfw(xo8wVIWpRz1AvE0 zLnD!c0Z(dJ!$X6`>b`8ZGqD%K6W)IajqamU51E~nPlNInT)HXd1jGWMO73|WxCl(4 z9yYJV<~BhMUv1z^;v9Ni^H%Y=}HT#%s+`Po#~8ip)~`K69*@ zOFs@YABD8$ou^ge~z2Re9R1Tx;@{$CT3_OM9Z0Hu?R>25dsGSxy0re4?gG z;U^qt{IrFJJZ;uQ*(FZ{@w-3?&zSX5?+wqGcj5BtGv;l0_tP_G#sAxSpBiko1EZ&C zusIHw8;6+vaM>`#9Dv4ZJ!@9R(|6CBZD{7RW>n4?mvSiqcDZiHvbK`hu!*J32tIHj zhSij#A^4+NL$IG!$%j!-hoR{EZ}j$1ppd`OrJ=wCexpD>_WEzsHeWsUwl6Q*m!N$) zYG1Shvwqa%T}s>-J;AYy7VOYHkHB{%FWTXJdSiAzpUPj<-}_I;U>D-a!{w6}92Ph7G490%OSzzMOfM1I&NMm_0Bk+*b&ox|A*zLJ@r_`}1%@NW+K(-c_7r zR!T#nlBV#5!8GHvjLLXGJUlqbw1X()`1WMMwhCYndwu34vtcVx^sIyf%W)=XL+0cV zyg~fS)wA9r78R>Xz_wL6p9bh;TSr_}j1iabKrrP+9024rk>v3V;~FGOhEG=cTv*U*@ddXK?we!$j*vvJLb-JyIvtKFeAYFOUt@evK4r}jtYeDe$t z3i%q&vt2afHM3DV;!(gxMG4Jn``vBqyIh`jESZwmfIH8l)CFcYKO%%WuxoGv`#917h#4L;4&3U%*eWw}AY^!8^$F+=b5->$4}Eah6Pu460Y~5X za#aVWjq5<+o>`1qqYjK~F5AIg8bkzQlY? zTNLcI#7xv$ECeGSOs^)6_Ndis!D1`GwqTshO9*b1_ysFwg_FQGjwA*9XT@e|bYhtq zE5^c~Rt<*(o*Kr^q~DjBDZPC|gt z0|-bFSd?O;T)T*h2p2(A6uS_bi1hveM2fM1QUyF9y$Tq56+wa^peTfn2>QG~vwKcX z5d7Zz`+Z-}>-po6d$VU}W@l%oe0pImcZj~h8=<>q7a42hhrYY!Knf8)0gbE)AJX%4 zJ&nq8r|e^opz@rF0k*jzTG8h9TM-SIMqB23Qsu0DYeTH}euUM~4E&LUe3#~W$TWQ$ zX~dTvueo?5&F5>uCVFXsr!xKdr6h|Hd3Pno?NHW3NHV?xV$pmzR-TC z%|cI#xojhKUFdo5ft@UO$|C7nXyU(Ie4<_W}c&-kF&De7b899GqrSr$wGBxQt!|QfVeFS>!1+`uZk)<$2A7o1$9c zNy@~UU@!2t#h)0xM0zn>>ovnNIt%pN*I@SZ>C>-0_0Ut{*Pa#}ql@howebz?5`n{R zU+T$1ZM&tOp2kwzzSJ{4iFxP!4w!*1)L=L%q1RgmR`Uw&T?Pj7JGyPTrw{HHE%)38 zg7KH-p3;^7Mu_@}P@63E6QQ_UOEp(`%9lF8GQH{s*kl&8;A12}H-iAY?UfatvN>0x zP{8aN=5hejYnnoH8sc!+EY8>hTCu`Y-#9|Qukf@mdXlvgWXyUPp?KJFvgaz#RbdI)Z7{_?fjz(DegY&A{bMSZs3 zINSqU*A$NqMiz$k;c(arL?H@tOf=tq7P#fn8oH07e1T9!KB*)UU93Xxbrm8;EJ;GkNzPJs-FRQ*N zm&4jJ#9YE)I3Gt({07W<3BVP1u#4r;gwJvz4X-b1=6zy2KQM05)}#C!P?=*us=LXw zV@&8oZ$@SauqO5{h*4008sFjD7~cVYJH24XO}O@CXn>H7`8e!uiI;^t_|C=yK= z+y|OiJ27>DRP{qxsk#|AI>-*t3nZZ&&;jSHj@FF2>CH02i)ouwM&t;fDVD}zb8;T> zP})&OBs2`I11+_FpbcgkGj|_XXXBklG&m65V;8%@qxPjG+CgF@KQSrOE0UkGWqjPH z4KSgd=JnC$&+yb`z=~y^I_2U8$9idb5!>mD4j-A$8S6v0A(s|^gNfg zAM>+V6IuV8dtl??zwd#uD6{v#!o&2%CQsw&9o*`_+ys3PSk{_`KR0ZG61{idTw)U} z#(S^{W^M+BkWWW9d(Psr=UdOeN&z;2vvjNy*bqvGgMx_w@MhBjPgb-o>u2EGmtHJ@ zf}nu57JwEgpjM?tGNo<7yn>zG0urQv7Hsjf#O2x+P#3>|InhT^%OL=_4e-)m`xb14 zrW69h-rGIRkq~SBc2B*qktZ>{Ek5@S$bQ16=^LuB(^D;??`OzH#?iOh@AR}v*vX-O z0b<=2jFa&fTy}q2xf7DCoxZqTo_h?K^|jyaDeFRrCfc{#Q#x_hB-R;T9ylE2`Q{(_6A=a_+l(@&!By4#Y8-~-IJ)Y9K`>lICski8U z<{nQLcfVziC+!wZuI=$WC3kLpiDQ|&LJSk8^t1L+x4oVW6W1Yop$5Zs(O%C4zP8@y zN#|?#eV%ORK8a@T^Yn)iR@MEuoTT~tJ@w7WpVDvpA>}(sWxs={1mcYEJnztvBcA6Y z-tEueQI4V}PsEjm5ap$Vo@pR6;}1g>JA?Wj_Uu5Ar#1&L|09vj0CoEiZV7e!sLv5k z2m0|aqW5$~%Nt z96jo(Y;JRp%M|e#QT8#&PaR>^o@1WV5Hx?D7h9Fi{scLz_C!sII0l|TT8n@DXGhd* z3p>Wu4BO=ky`hg9gVAhrVJ zWShwUz&SMn7*TttQt!U8Wo~drUHl{F;{SI>-~|!$ zH)qD?5S-{e@gF%e{%5|7?2KBDTK(cl{|`J;?T?J~g862Ld!`IwoqP(sl()e{fDcjOZUJ&I_1r03{dXoLc5L&;N~c z>ScSq{(I-tF}GMxn9~0j>-qmZ=hW(HeYN+A=3I1~T;^PykcP#W!``e#8r z6;bE2o_C?5xxZUPCdHofu<@^T4pN2UqBxp%$`o|voF@*Y(dRv{-*Y8Q6Zc_2!#F^8 zO5ZSCaf1Moi2Vi4)hL*@_RIpOwDDpWNc8ce@M4!NR<46eiG@Y40S`lD^FHr+B6jMx z;D*DXBF}QmB~<$Ylu!k<>H_GS0=jxZ%R}m3^mMZe%g~yO5S$gzp^KgY5WYTh$us65 z^cn5X8U^JO2Eu8f!sS%M%Y0dI+Ndb24|k3}+YRA8>yv0TuyGLXC8h|EafDO58Ca)A&-w=?P36=?65 zQoG+hoFeP&@1BX6&mmVm562ALjqi8caV==as#wl>Z2aLV6S@hc)Cwy1ho@|ejyZfo zn=XHN+TDgW)}?LW5On25P3^GF3adA*3tU?nRmf0(jDJttj4nsgM zGNTRPOn4ypur6wef*2HCafa|UoCgtQ`3%Og~`Qz zhwGp&r_rkGp3D^XK|?->Y&*6Fe&t~M0;KtVzwY_NNFL%gTr3Wnh88mxTYBe@CkrdoYH5 zkhB9NW~neBYO=X^tfBp5FY6#89T9#M1RU7o%q>QF$9aS@mW}g@1miPS%cYNNE8fQL z)T%j9J3W058zS9MkpJP-GGh%#XqM4B^1hEERNRZ=qoJZI8mTZ*pXG&|BP)t^UZGm&^+cG+ zMs43PaX&8G!o*VSz#-w{wVWSyUL3a-s{>WCJXAY>xWR4mWWp+&rIqj?sTd)0Icc81 z21eSLYp&@YAx3jQkQccv2ok)wXeW}O)-dFDTu3TJim!}S^h2b0H{oZ9^dW9#-~br_ zxP9*K^(c{x1~a0>n+dDJxL1x$7!DgTn5}h%M@a2xQ6czI99nyfzL%oK3M1?SeCr(j zZNh+0_%~~a0fMY!c1`Z+#v!vfBo91P{LyLwxI06Ez%pmk+6H?cmOGz`7j2A$6QP+v zGQ3PMdE@6sVSl^Hh0?;!DbXoQbanuN_nn~ZV+Iw z@jaYV0kNql4U?PiODiQt88uf!y2R`ubd1*~KsD_sC2^{(p@?u`-{_wx%brq!EE7g|6p5BXVsFbL%1U0&U2G?q>p>%o5Ma2`rw+ z09;l!tO=k?6RWL?IVETy%FWv!p5D2Bi#_Kn{>k;WE=89+*r}% zWEIepHGx~_zmo}17+A}fCWsv-kB{b_*2$$TrPSwTU1v5hJ3#4 zcJs5vM@cjMiZ0%#B|a+C@C`06Ucec*13|EjM#6xZejS58<95xC+e8(5AV(|+UByO8 z6kSnxS#)Y^EaGSw}n-oRj1a%K2#)jD(Qxm!f@6y?_q11&b`A5|0c9ElWdT*fd;`H8AZWn1aOALW!soa7K z^)C=&I#ahU^=InFbE&j^xEV|HNk8WLn+@t_9li4}k%QU$D(7^dL;{nkMm&*@`(h00ILOrD6#Xo3es7j{B z4}z*MqP7o;!G4!&U`v3lVqfU94~pR>>l`u*H0-#CM5U5-#V*`?9uk=)>p-eG2PWoW zF@t(M3SPp`9{lo%c#jr798~hzW1_Wjm@YpiKE!3*<6<5z&D)78;fGCpMo6^p-|azj z*lB7jQs`5nPFY)#u5In3e{>n9pWV{NNFZ;R-6~erW>NEzq6#MIm64j=S~^l_cFP(i zk~`Y$7AS6Jw{ZCn*exc{Z^CW?wcW^WLC=V_@HKl%3^KGcfwp;uuPnw`^fmqPw0H?L zQR@z1h(4m%I{*z8(83NP3rn@H0}xL>MLi?hG`%z*>9p>8Ry58nWRM9=`h6sVNdc{J*2J~i{D~v^0*@eC5a=marr~M= zs%<{?N{cE@+n*JYc>RHAHQtNuBseBTjZOefMRa#3(FB+IokbE&>m*|Fdrl|OJRQAa z#dBD(3jMa0r4;unJB#wkOy#03H_NbT%-d|3MfZ1x{=10!bru|uA02bdvhO;Bktw39 zow30YQ2*b7m&WpNf$9;+3K9_N|8J3n;QYGhL5|xg%f?L3%qFkU%6|(B9T;73{Gd#o$!<5eMcp9eX{@Z^SWqsH~m0*aek|i#0ZO+YnE<%LULB;$r44 zGX(z!G+;WBkATgSvYkg4{080kELIqIPvZ`kNA1D~?ZP(vTudgwTBfFUAgOuYZuf+J zxzFp)WBWN6FKDR+zeO8`;5pt8nmVwBN)do^+}nR7RMNd*!q7#)n!#<`D|lT&Mj;=# z49f2-w#U!=6Vf;h<3JdI^_ceONgCJ>XZsK>>L<#%`r!UhKk-Q3NPojKF58lHq^aXw z*z<=O1UI1Co84sW-nE#D-)JGRPVW9|k z^jBS?r=E=u^%F~=+bfo-RS4vZY7+d-Rm^F+BrLXA-V&jmXrGbbd(I=yDm7hx?R zWYi)0bkX^|ANGtv(qbMjXHP%687YfnU6#Q-t!`1YX2)7QgrtL7HBm7nr0KEEtG_rt z?7J^dhrEjiBf8c`+0mWjJ_vtzKpUKJOQ)U1ndJ`8p+hvXQ?XwPK|bVIBQ4qrjm8(d z<=*f|u)6pjFdiJrLunZp3)QIpJmt$*D+h78v70vm~v;fdH$F@ zqz3)P!*(7=D~9HKROx7KmWW4~gI?7i0=^AKz(eiHd`FX*7z`u(-u2Ud@koD zfskHo90P!(u?$EbhDp{c9!M$%x`C<;7k2~0yfz$1*RiEoHe5V}-*F=#<}0APM+o*T z8ahJUPg6$eR$E5l`wPa8)+9}j(OT#;Yc#l`0y>Yvy8;mxFr9KT($#VZhd_*mL_5d= z$lrO>PjfT{_(I}lvHzwGZu(58&&Gfl@X^UJ;s>O2`ev+X3CtqLiN3fSJx+W9F>s^t zz+{E=%6M>E`Sj;_@fI#`l4xx7qa`FdB#p$0=J3P}hxz0?8!~r-ra_*XplOgsxiL(N z%*9<4lNc_zGWtKfBa^3#y&B*rj&ZHI(K! z@18SJzx&Wc!QpRzpQs6ztVx>oYHnY;P7;}JX5r|i4?sN^(Z`cSHGO1&7RmSk<}O8( z^pW{vlKz6SABYNN_25{eHATC6=p<(v0eJD|+ibF?JD%0w$gw8j6+RsI=>O9Xg2#0B z13k3Z$sz}#1EYE4Kzt2K)S4{fIsYMhv*0*zQHRNJdBehKq(|kr4gs)-{Z7Vc2w$M$Qo#Km=P6GI9HRPK4>A15 zf*MsrvK=+@$CtWff~*9o1Kwf6r7m!~;1jU$OEDjV?7To!v-v%E0^&$bSpacaKKT{^ zy7r}6r@!N69?-On41?brFEYOq#d|LhobbTO=w}p2ukhAiZZNkdu3`cCg6} z2o#_Kfj~iv^}}Q#MSdmv!}M_2S2**dY1vm0-}he(IadMgSuDyWa|#7{+F%la$tVy+ z0HBaTs3ju48p9ad1euvin3b{~?Epw&oO86(F_UoBBpiH_{T=b7xxK~ax{#EZ!R`1hCohpST>cDzF)M1 zwDXPqA}gGS<(5Cv^!?AuNjyr#=cyDW_+eg|xMoC^IFVg8EO51`^ZT5&)ua-JyU zUXp0!_t+LiH1m6rM+uu%9MwN4QtIG4Fr$W7U}_oGGMxrFDAUC36MyoGo*D=XtZ|we z=2nQAG3X$)9Xtmf6vTQFU;$*>(t{$MLn`1*qb(xBLMCZ{h#o>Jg&oq^BIA(85A_d$ z*DIoj4vDP5fTC&aA(5zgY$n|8mulHKUb^BCw9Ch-{tqHEo!>368qiWPJ&KUcJmf2S zxct3|H1r1%-ISY!VTc~U5_{34J+`2Xpb5w_Yu6=OV|m=o;p-jJ>SgpEkGFpJgYd=x z;#*a$g$($wQ|MvwAO`;UVf`6OO2+j1Sw;{93?uvk?`Z6LxH=$q|8;05j??Aqq603E{V6(>T?u-> zYRDk$KWz*+)PS=Dyf7DD3OWsk{uJra!3FNWAV3;RFa9OQ8%M{5$(+z%`7PsW$qF@t z+A*)-vL~5WMl(ci-V;cG8`NyvP&vTpK+2FD!^30Bj8J>=MqS3@H8*9vj*@|0fP8$s z>sbD13$H;GFyb5rQx`Vl$5&{XQZ{2oO{TE#2TTNlUw6|{p&u4>p`%iKvSYlZ{2gF% znx&!$S7&b|af{O4B)!wmnlc4*8RY^sT;!|jlJ6N|AD`vfps(E$^oXxYsQd&d!?!a` zKFd0cx)E|BE;}L+e(nNh*@g3}zf?rZ7U=4cNcn2`c~pe@D@GQHG87&qb5NTbC3}SP z-vg(Zzggbn-P#o;cT&JKxZfKc*W)swO;2R4d|w$9n} zgRoP)Me?MKbcRt}5*iJ)#Q=Mz>{7Onu?BHTC~y})S;77~thx?)4~=~Bsw-Y)XI!L| zOtnMAIPlD4ZMWA>ca%bpDp|iYpJXQ10Isq^@f|Qo;NL(;3=`)n4ITC=$+FQuluXm0 z%VYZt^squ&c-`=V3Bb@AangZ?dM00rlgvZ(x}s-qN}No>Brb}RH$bE#ak6IGWoQUk zTBFrG_{Ge{?Kat7HC{esoS^>kasr^z9al9}dhx1;N|UaNdh}(2EQNixH35?CA}UId zss4pyI8-x=;Slc>n8F+uv>j z-Z@TB)z+tJg?%YqM<21(buqUy>d2TfJfAU^t9dM&iNZyWnKai8lv77dF~tTbrYOv- z2Z!4}IHDPzl?YP9xA4dW*|3p;qH|uEtc5QilTq9|NCA$q%v@fHW^`{|nI04T9BpeP z6YC+_C(;lGUZyi@7LNqNH)tcWIAtn+xi!^oxF8`1)s1gtTzssq{KS=P6WuVA0@eVf z4Jj~qZmi+72G|8i;o3m9<5P-#83hA^;8WVLp+1rCH4HkXr|q(Occ6@i%or3TW(qC7 z1E=peg*K9FoQgu)+DK;Ff%u9K;q^w6<(HKk%TAHUVQ0on3uyNypxtIS)~Ir6V_7E2 zp|x>XOVHXyjb*kz2&~dV&Rb_8Jk4SeTF)lEgJ|xk8;;chkp3N-NH)96Ya$uHPO>kH zn#in@qpA2ex*PO0W-Y_gXQwtKk0lR42TML!FBt!Y^TIgzk9kzPPNzT4vg^_{Zq#*j z+LBB%r!~d-*+Wk>)#s-q$=v8peSXH=>6{-^lguFbb08i7$$txydHhXC=E=clNt4V~ zzt$x4FJD8p6n0D>Cc3Z`(v#!Vdzoet4=oe-)x@#{?`|hiI`3`>LU?y0b_6UKgPKvh z<*;7uK$Dh>A?U393X!Q#UObcAUYMJ5M!r}+cDa6npW3biP4o5&5v?Z;=fDlCPkrco z<5!52OiSji67?9@ELkI}gdMXn>8Ula7(GhqYlX%;*wN8cZJj6;F^k6&j-5Jntzf+K z%UbbtIF~Ul!pojO*_?H-*yun_*NaE}1f6gCdI$%2Uuf1ET=E8(&lS;`4I(=OkAqLn z)EWviH)xl#!1E~8_(o)FatK>9(ofN77_q>9aiRXoEHBK}!LWHTZ45)O-))Ql-!Xg8 zg*5XUQB8N{)CI9?&U19(8=?2FGtM#_A@U2r`KLFEEX}eb1wjZ-340Ig&4@528hC^T zfJZ2f;umO+hqrDNOke%9@kWkMZ4wWbAoN^88{NfyQ@>4`|C_T3kZ~UsZPNT7kU?dd zwi&wHO}rWKhv&$b^qmg>M~BFs2wSz!d85Xd%t)8%0$s%H)#hVOH>#X7ms? zyo#BbXHt#r!b?xyCCA%zS30R?vM}spdy8x0E2g<*QApqBKo`rYu(?bO7I}c`dL2T9 zH(JOVHxwuNHn)&#j8L1|8FjZT#KwI29{IM5C;xuQ$;)qVB_G3ObgLj<2Xsg(?QW%c zo%Gi7HBAEXR@4<=wnoKry4qSks{twRTV2t+4Jy8)4Q=oQgWhO=#S?9H#m8;sa;Gaz z>m*U{e`ydu?q70gkW``j0~*Y}{lMR7oaHFW;H?pB??Pv%@h-{!%m%jf*8@@uHo#Td zI~Ad1c{DDYz{=IZ5>+#hBmEfhwbWEftWELII}b`WX`c9?pCW9T7%9JSau+ zo(+9ScE-0p{}4FE;}rI=w1Gw}jJC9tBNy;SOF4>x22*#`?qL~?URJe_Oe~8qPtH#F zl=vJD&l%;2X{J6b%WFX#>@FZg;R6!q;B%H~#qy`e-XPOD|F9Y z8tOx_%2X3%Q@4Qnf6-r$$r}VE%Yu&xLw)z8a8R4uzZEY^%`G|JMVu;uR-Z89^O#@U z^ErG6>?we5*Uk5>OF<(X^L!RN)Y!%mAkJA04|N>tdci-i^h|e$FXIGcET!OFf#D!g z*kB!zo6tgQO+ygAMk9Ilk^!vcZdiXB)3qAri@V{wK*lr(yxF(FWcx$zRUSw0EE$O+ zu|?!WFyD#$7|lW}8|%Ua8cInHToX!Nw}?`m0cwFB&@4SuUs7xveJm^&MqmQaH?#c+ zv%#J5aGvMnK}eGUnw14@NHyj~qyUfwsAL5@vXt823R4Ad1cIVK(t6cML;y<0Z3xha z$<$`*w0o;&I>WYUC|F~gsQIkcqH_=^C>)TDhDo~SS~ui1bru;2Q|)QPhrmSIA3A~M zd6;I)-4k{y{H^Sbq{U3IR!2@akhCR<>cpB_g8*g^FLL--{9^vq&+OqKuzD6GcR|pG z!F0Lk$0K4b1Z$uE$bz+n4$18otO?qARP@GiZF>x2wdI;$n*eSSKXS~;td|FUe3Cgc zzmR#)F-XylQVHDx=TC59@-2oxr%x!pFEL1B)2hKowaGYF4 zqDKJRXvq;IYb_%DYemKds6)|H8p*SwvThj=kwMB;4&S3GcDOvkETJTFSh%joqB;^UH{tGX9q^aY#Ci=tF6Ce#YSmIoE( zE~cV_Sa|Tu%ti;qVUsV4f`IgmS@|)S#EpWty_aqxu;EkNPz@}pXElg$^++nyrfRa~tzI?_Mv-l)YIS+nKef=qS)6i`KO?$+ zNEaZ5k8c=OLMrO!p|_)u(X$j$A7Mr_gJ^KBtd}+k{utWQjg8as3uwS^Y;Y(SQp?>` ztA>_Z7Szy!l|O4}!AixNnndVbQwuDo)x1Gq8OEM;vCX#?Alx4Mh8>{&dDT?3#^;K+EHBO`p8y<&&W(|W)_(V$~+T<8k2sgzx)gc zKLiTzDC=d8cYJA({s$J%n1>wy(p9nNhsJc&8yV}$g2JCW%KEq*sT-d_w?C^X&rs*1A2Y=0aS8J*p~)c@>XH7HUtR%Y8Zy&Aln@=Hcu{) z8Tf`exU@uLUVp5Z^8jAPU2q36Y-Jl5kZ$6)_H*=i+$u%4qR9o&Oz4S8q;H;;Z#?w} z0BE>1fiEt3HVoNmm=OO!7sJx+JAcVXP6=LDTsV^p`LnRi11;^oPzbx4?`TRVnH&lC z7WsJ;K7r;hQLQPqvy8l5_h-%KOQ`)~EPUX_m=?Q7E)2XIg1+ylRcDzTs(bWx?JOG` zFwKhg(&~)(6fG5Eu*egxlQ2096V{q1i;lEW@zi*(loZ|t9PDyR>;gT*dvtdf`3-VO zsOMxIsWY`Po-DWHMlv#)ZD6eJdl0;d zM`2yqi)Pno{&P@h7EryevN|r$b%hG6fJSu%{4Joh_T4G_u5>p!28Hvx;j;?pY&Y!K z0;=-7{KfWo5Mlwyy&N z`p13!MTvc#^@6OPN&l-514m}uix82tphGXpxd?VY>?QdcF76(Z_Rq5O<(HX6Yy~{4eu$LUY*fX_65SL^s1~< z2Y%XeF;)X`${%t<0mMdG4M9qB#0i(|RU+U7AR55$&{t)9?3rI)m0#d8{xvz<1NPbk ztcM2wLa1ErYx_EsLdG97;0-wgFRS_{FmFDMcoS;vd|Ldb++0RGJr5ne&T$X0pTk~4 z4iUe)u`9 zH{a2a`eR(Qtzn9r-ANzLq17=27sRJ~0hMP+w-7`SOp{V@;Sxb~iYj|NYO&uT;>;5{qIFBK)3&<-j z(fGs8W9YvJ^Al-7>JWp=!2@(^fb0XS#pmCZxe3Eysw^GrJNbDmAe#Jw=DjP~Gw8+l z^ps`3FSAKBh-0*I|3KM{(g(>%{GL2emceD&Kv~6Z4CFabPr%eclD&uOzxPkwM9stI zwn?S`xvO=9bXS>+ViL*ozMdBht0`Xc?EA7=)coSE7QC+|YkS|9xv13-qz{%H1toW| z9@RsGWo;nF^IhxEB6Lm#HyW)0S-n~fQjKXX3>D(x=dwpr{ zXb80PDRPXg8FOaC8djRZhXlqxEyiG^z>s6)5;QA2R@RHw!8qO4l@P$Te~*>VnCr&V zw`1j=QoF}v_iKNb5WizITSuAJ!tu0p99~dF&NNgWufK7`36(-GjF)j5+JIKmXPYT^ zKPk!1OMYmRKVH^D7bA8g*=M_kE16ZDf8CalLUj;$0|)$Wf||Pxpett;WqV02XvFF< zpQ<&rY_&4^%OacCxrp$jhP4j2)?TgXt7nSH5W=P=EAIGY|ySK-5m^nlGy~A_#dC*}kp)1F;^9>HUvow>&0J zIi9PgZF$iG1h1b8=E6%iQo&sKEf+FL&r~oI(OkIUIttkc9SXic;dU+zN8uG5f+L|$ z(|st-v6!110Cqo6e3% zmECb^@EKx~bBoB5Eqps?$mWKw;XsY{vpzg~#EAM6&7&n-?vHN~mxeCyoP{nI(Xm#COaFUf04ewwveWWSySrD6heX0u_7a%2FCp`pNLppupSDmCxbKe=`?! zQ31uyle3HwzOUy=gZ(p?&6lNX9AI4wusirmkP&izIHnRN)G(+=jSd~6?VK6^L!KTE zJLjk`Eq&JXGa>vX4E|l#4Cjtz;&?^sLV3zI^F}-(e6cm;OE3o|kOwx7^E4xm>Wk!4 zbo49vFeI$?eXQ%7#H!;rhNy{(Je z0K**%cbfiGY$A5sr(c7Vok=-MWsTUv^Dx#|)&*STbzkSD5?S8A@by_PV~o5&sxgG$ z<}|+GpPWpqq0B**%+)s1h45ZlI&*W#WCkD;r0_OWf#)Z$LMAUd#|p-8*nhe6Smc2% zMI+b9dXL`>WU)xt51A0^i0!3X$JzjeDa+!J#O6PSBrdyFw!TS7;{I!8wXn$uTMS6! zTPvS(QWj*mBP=^FD$wb5GLo|wpt3S$ua`Qt zLBsVjrPi{Iz$;i)u!LA-xNBrWxD>9%W`J>+#emoT%{EsVT9~PF|6kl;^!o;RclE2? z?=A(cmtlR6Y!rOubXL2scK1S@r|+wlD5f6Y$i&p3>gbZyQ&Ig;P_?T>b)ZwofNu7# zn-%*9M3Eb%x8=YWaB4)4*La`o3+4aK8|8TYqr&x?^(VHB(WAPtYLwFw!DOLK>JdHA zg*fhL!!*y{a2hpOm8K8ZgI+yDTi45UAZql9?~mvv_j6<_`{zY6Hpog4lnIvRfSTNI z@GrzoqPEYQ$x--q7jI0!*{3#W!u`HJicL7?Zvbt#jXGS8sHlPO;uRp+H_=ZkK)@Ez z%PZxB5m&#!0Yx}v-`16KrBQzvTbKcqh63&)W1glHPzIHW&Km*wot5_rzNCIgtma4= zv+YM02p{v!YM5|Ad$LAWqK+HoLUZwSO5G%%3g_@Sh?PTmn`G-!yZMIy@M-MLACdlg z46miU{OcB9Z@lrC0!`Xv5_lC*G$9J1Uiu~DRZJqWGe`EA57n>X*g@E zY-Be18m>XG_ z@EM0|VSFJq+5;DfzSLl^Y?Xk|ViJYtv^a7KTZbm=BZ$f}km42S*7d>xI}9% z2<}h#!d1cd)-=9bK?#Q>yOVW31Uh3TO*jPU4TOt_WWz-G#Q_VtfgM>|s?7qh)tdeQ z78(BEKgcZe@GhGC0~T;29sfZ#G!FR69)_8Cnq$;Z1+pk@)WE?SVbowDD$|HUx%Gx= z=z2u9GY^C!kR_~^3XjMaFk7vEl$~%{^dtD1^>q11IS&b)XB?Ha!^~e#(&3-wN8Y0G zuXw#5@j-8m`Z>a*`EO}i*h!NqjwB}i}Z5#L^x>P<5dH=9}HC&=Q7Du^%6h(j0qT=Du!-O=c9bjnm}k_Gf)Sfc8p7P3WIi( z{j#(@cbr?@g%>=+7s!L%DpxxeZ>1e>m5EP2?^bu9qDH8y8ODxh(DQZ}<4UC7p^5_( zeG#e}q_MOC5K(JYLp8kw91BgW>^nY8y@FHIGfZ(>gY9AJw$SU0?kO@{)r;3Z*%6hk zl&;tn4~472=CSQ`BwQ^wcW?Jii%?Dewl2R82wE3#>_9+(N7*zr8jWGl5v@4mQWHuinRitg!9 zcJ7xov1Rr|C}&+BAj8by8u}qlrJ#kr)(>t82VVc9EL3Zbz2?3bI}es%?Ar@3l)mRf zw5=F7qn{O4YZncTS7oV797eOa&&@|;mlu!5CJOmwi~HE4ajx})Tk6r+1vekf;y!`V z;Q8Em)y`bDh=#?hF*tjf392?ozDE+&8@St^pqL3X6BWyEIwayOK-~H$R(0M_aj~?0 zz6eFZI=lQ@BIxrXT75Puo|+^n#`%vXsZO=dY9tl{%*p49RgR_|T7qLxu%!?5U_G*2 zr67>TsVjwzzJZF8aHu9xTC!?toTc{3>dy2@Mk$!Y;3Vr_z{gudInV__3ED49Rs&fs zg7eMMNj8OR8HCH4&awg)OaQVuq79ez2^TWZKr+`r;fcRc2+1n@5Dc-!9WLuPE_CD? zfx<2PI6ejf>f)AX|5_VuOIFy~a0nHosP5tVX-F@cq$-wtJejIqLUe&`scKOc%VAhY z>kS&h75@+*;Qua+ruT|VjlX6qDRJKU1cLsFK1rWHuQJU6QMBcG)f)Q2(%qF85tbTt zS3@i431$%o!0X>K6MAs$REW~c3G>PxIw|5A!&?2Ah&c4atTO0l%j zo32LN`aD~#!LS>qdC>H2NLLNH1`+%<#&kvz|RZe{I#a5w;R#|=tkMRVXBk!75Ze{ZKEHuR5@cRxy!0K0O+tksYySTRb!*p zAh0vGEXRcDpRF1qAl|BMm65I^wCH05Y}F$x)ILL@rF6rq*{Zkk7tMcF)nn=ZJBF6@ z*RB8Anv*PYdIiD}H#m^0AtBZmD8iLP0fnSlCU&=*xr}-Kmb%fxHPpQ#hIfRj=_hb-??2`ohCO3D*GU`2pFrM8v828^u)gbOiyCABzw5b%o|c>jgUs*bUeKB=r~ zxv!g0PmCO_s?nA5DyzmB@H5!N+S?L8*ap=d50)o%3H9Xua{GeFyUX7Qs8e(9mZk5 zX@KfFxsIKa;hjjEVY*BFM9Qz8EGq@rameI{x zWgu7zUe6JUG*M!6?*O5LP>gCe55{u(^Sa@|Rd^6%!mq`eG>0D3Hn2sB6XprOAosQ# zxxG}lD%OpW-ST8;0zt!F>hpR;xiE}Z{v1Ym)zzDrvEQp>-t#Fl7nfahcdmLWUI(Lu zJv0VxT7y`yy@i(Ms&=6;n*+;Ls)lN&e{Q8tHB>|A=chH)L#fMsMxtYKZ%G8(L$&Z!%Y zfOjM6s_#R$xj)N_r|Gw=B;UKYD`kL&!3*RW`mmn*5aVx9U;Q4+1Bc-RAE;O(?p|8n z0O)ZdooS#NnX}eV^@b`jzQpOW&lWw>P*sjRg6YQhMs%fK*HvZTR}C>Cwpj-YDg9<0 zzuf^aw28lC1IWU{MyeGq)f0 z?RezZyD&)fl+s+i9Wj>kDTd2s^g(k~HhCWMNoIv{m=Tynb8tQWVjRvr&6PLj18!;} zvm%U+z(AKwa2edXbPJVbuG&IY3sv^MPlEDKX4ff?g2KC}XV~D}d55r46 z)&RU)4))D!fjDpGvIVrdrAp-M{+8+qd`d~>WQV)8s`B-_0S*vos8F$*dBxrOa=^Y^ zvg z2zJ~z0CB?x;zlWmE;i7$djTPTqFVQz_a)X zWCWoYTk{r&7K_yov1$l%f#~c}yev34KheDVR6@)KuC`X8H}Ejq?^C^yNR8z`W1-~v zm>#`flLL-A_M`hXAl-bws+%{AK`}J+Ah!QH0g9%voQdCf5T>OthP(ifo>vyOW=<$S zYrmazm+e0Ir)Tfn- zt?;Y=DejhUbS^?oDS|fe;z`H|4}M4sTPbf|q1_mr0QbR23TSApO}ud4K$pe!nvCI* z@yqSRhR(>Mvv7o4gMRgQV}RQ3iecK4cWwo+%VJtQj)n3Xts%nW4|JYr%-@7Z0AcwB zdJ>#Tar$t+CX+oCG{uKbx zTnzmW=^9EH>=Y|OP3uoCbO?AyTWMPTSl`H!Qf3tbrSJPo{Z@kvyGC*$KffDIFWGDX zj>Yx5C}w7XExH56ll(mtD_2cx7!Qp6oi9H*^B0wYLKg zvyhKPPl!VVYV|u{FP4j%7T5!`8D!ynpN$m&)ugRV^}|eJGk>KY?q?g}d(n@Z`vC>5 z*(vfot^swW$5l0x!l=j-UkX+y@xmZ__i;5Ce64J!y5aIpJJ`fbppETR!?c2aK}@)# zmSI-Apr6fZJJf_?#38_y4Z0<8AVHOy*fQDl3dm=RQ_y((P> z*(jjCD31{5cAit5$?eXsQ2e5H?bU6$SJ}$nD2KyZ&XC!e;Sx{5Decxzt!%GyYy7UQ z+WC`cmdE6>JxB~D47==V3=ZOe2nH2yi2uA#stkw-8$YSa;PTXy$}88ySuD)z zA8|iR=EKlt#FOf!yk)l12XhZYU!)@dyg9f688B0T;Pu@FzANRw8?h31Y5u#Je3$CK zTf=vpu~|R2mG9#HcSlOxUEn)T*DQ2i=zgpGxBU8%d>80ua*4XnOWZByyTB{H<-5Sp ze&V}E{@3TP#$AH{&c}DR>ASXg;VHhY;;*DNxXbq6E#*5sQXbkSz6-qYAm63?TVCNi z%o??N8tnJ2QXyQiQz4vtTJ;FstR?7OI;bCQ+M@=&^Ngwzssnt}>}NoD7f^+cT0Hki zN5z)!vpZ_e{>3@biFCQ6dRcAfE?77S$iU3oE_&-(^{8iEaj}82!e>>-P+dkXI{|a# zBfhuNp$H@KQGhWs=|m^B7<}Ed&Z@I{=38ppPo?wq#eV8OzAo>lDw##!(zJhLTTMU+ zZpDTb6}za;xQy(gx`1l`y$gsO1dn-6B_!pCWnzotAAI~kBX;GjiZFPOKc{9?9KbXc zkC}aNjs@=ETUdN|+%$|ldipHBvq@K#Q63a6NF@fq1Ev(&rWWkHaP7mQkcuJ5JGq@_Y(Js>Y)02Z=qk|%vAOS!;TisNOv4I}%1_2w= zT6I$$d1i~c*)#2VUfs?2bB3w1Jkz})9txje$3gU+>8`?Hv*Nq-g1Xm4{w*d0ZMci2 zYu!UV0H!RzhngQgXCp|-FE&!UmsNdp-bSLARj&EvM%wf;-U5C8iI-Ikan7X;hURfw z6A76ryrN2*i#Ag8SJa@`3k7RHRbj-CWL%@~Us1Qk{<0;wD7~k8FgAZ{a8a+Gss;;( zu?T=f$ozz3(N)f29Db{~bn z4L@)v%m=UGUKnF7(sq*%@+#@g{wTKYK?rJK!A!GXRZDCZE|vPcrb@+s44DU_B(r|j zj*$H68k+MONZuo~_cc|E+PtCug`J!K1~5ngi8s|fH0mu?AKSO!Ep=aDhA|7A60iK* zY6_NY{o7y^Kc~xYtM=6Jpb<&=??6t{;~iBoa9cY5bU;y$oiRb*(XMyYL}MOx?*$Rx z>omNVx-0a&7Vz)urMhL%PA&07?xqP`dd)r>uuD9r+dSP{b%?+0?==QWrV09vcK23~ zhuS}D<*D3S^TVJdb9c>z-!HV)Sy8sxG}zTJYoq`9=tZ^&LQk!2Adu@QjdQ>)Xek#+ zyXh2LF76ic7Of9v<^QriY6~ud`)ZNfSAA7A&$U6=QhP$I8SjG!xkl&us`k96Zv{<$ z?x#xS={>H!uKL4xp|{!F3WOA9TRaXY42@it8C|Mo@QPKK#$1OS?Df-(L;$@>{&76RbGIns!Ww-On=WYTv6F$9%a1)NdRdE@Pm| zgZgaBKo!Nj^UU{@?Uo4#>~1V@(Y|0XufT7c?4cv?LDE-58H3bqm6wD8)?iEw7C|f6 zU=f8uu+m>hy#}cUoSh9}2e~syS`g&*n?b5p>>

;v!f`peX!(RfCIIC4*KWC~Ee; zItkTbwZT}K^|WJtjF;XTtXlXNI#{wc@;_PW#Y5Cad_v!$dZlL%Rn_83t~9pnU>X7V zMxnzXMY#o7%P9KxC0I`~BISSJEi8^+*%cJ5$vLvm3{zj*4mTs;(}03!7w^Rkrc(Rr zI6SaF7@>|MAEj%gT4-*ZNlQkm+$5y?VKWgp+{1`IkY> z(W+|cX+izlSSP57Z@_5qfIO=cLlY7CTCqWX`k#?$^!!+r;4g1HR>he`F;uldTxy_V ztg`KfM~znZVJ_OtS8HLGtVN$!$AR0MMZ?CcY-%`OB>}iSFdp)MUBnJQ8^^2X>i~hU zcQ!Vt-@RzN9aJ{N`aK}+L9z4gSiDc+B#oMFh?AOsU;O~VaD%&>c8 z3m)B;3O^6a@O~cL>eJ#@kY-@%K?xK>v8qLgxVPi$+CM0L0_6L)8A}ek`1(b_=aHF! z7o!QC-4mBY^CkczYI$%1{kbPDGTd*=5-b`HfU0{Zs*z>z8Q~mT7*U<nA)r43NpgNVh*FGNxxNs6QN z#($t@+lmVqhG3JhTEi7kYwZ6(RkCZftXJ1!@3SQu)EQ}$RRdOQJTh6`7QRZWHDD0( zC1`>nk<@m+T0^s^sAl-$l326yR7entsO3~un&Wq4Nf5chl+&okRDE=YO=VQ;TRc^5 zHZbu1(;-aF_r3m+svC;y+|Sf5cU{VwVMkD(~?;LZ25>gty(ATLq)DNR9A2x1t@?Js@-fgFj{vtnX87U6uqNoD~S$azpvF*gV}2TvuNt8@prO7<<)$}5wpH0m)IU2df* zb5%85w#>zD-$dc_6kDL_?50I~;JvV7p1Lh;=xQy_yE0EbVh)J(VOk>%bErMP-l442 z3C*+IfVd%M9>5a-LJq4^c$2`Lc;RH-CxnC@C}V+Yl@T~Jhc>TaXb+HKADT$LSq3jq z8Qz6>B_t^IL7^JfEZk^v^@ih8ZV4&^hiVaSoI{1<;y-|hdBW$f=E~rvOG`8@d6IY; z3>akhrH2-(E)0`bE>x*}J+KgN9k_ZHfwcyy*=Ug_>f0|;J?{2vT8rftp~afkV!4HF ztqy>AM_2hxxK`65zoK8jz)}lJ{z~=Ky3;V|PM@TvqzjX5E6V z#z!vJE#@p%A90H%DlOLE9cafjq4ejk$}e-FCF+&D-#!Mv1;{VQM(FpORuPvlv5CP4 z3NQEzG5A2?6)t4L5+e;1{^f58Nlc*d1Q#+bia`Vl`+xFt2)+Nc$_^Ww4+Z4swBT!q zARvDJS|#dmJzyg26an~AoFV`>@IHg51~VD#e#YCk=~7iihw0~tGIAfiu~ZYs9lkTXO%yGcx`{D0z_VD-r@bKZ4YCa}%)G7efBAWg^5dT*D_qkQ7F+fJm)#`1K;&WDmulYEV z=GTc&#OOEX~uTcv%7=)hygw+swH(CpIrS7OS4P6Hw2)OjnN+8F@Yt@JxTRg6t zexSADe$N7%enY|-hrhr;?B~(f%ypV|xVBEQsoO*A)hPg2YXhbuY%!Y;ZK1cmQGFth z0S7SOcZ}pFm4)Y;Y=$!M7(KaBRVarS+t`eu0?WqiJ9yf2@CAt4S(`^YzE$o2kNd&< z|5y6?>3^vo#0UD1$HU6fTg}gjKtD0jqnVjuEDbzuLgom@P z;8-Wg;`*#GMj$#A09Y+hqfRx_qJvd}1we#14=0rCnD}71CTk2Wl-WNJ)gJG2>-X^w zR#+I?s71dGl6Z$=0u8{ts+QB)uL5Vy!J$yb#+v#r1sB-*Cg1{RH@1f`>okH;PnSZh z!2zoP)3gEuGicTi$;BP~8ITk#n}31itz%ZfbouF;F*FQj-(`67LH!Pr$+p(vUkTW5 zj{cpNys1^yjz;~-a&Z+a@OeP1Z15wv*p|S^gyd?1IdXK;ro0|X(*@3XZjRz;P9e}w zJIZG|T%gX}C`O(!u%s9{YOAWwIoY9^wm5E0J~i8_s>EJg046vTl3!3SOQ`o&DCqlA zm2D6+X=lC+TDVQsiq@KW7t4p2(7A1@FWU6nu4+eV5(8H4Kz0kZ!xpfB8t%}5>8Xnv zFb&@UL#8j!<>*7pS_o(~6zoUDng#ohm8%;9BU6*e-G2!STD)lT}W+vf_9% zxV*_IL_)Mu@)GPNuuV*mIsB=Au*kTSHyJo}@GkX2%6iCg;~Y_MoR;dQW(jmhayN#t zo~rFu6};;sdGoq0NY{}VOYhKlYx_yo3&es<9Dm7NkjE8-O-sbSOQyy z%vqAZ+YJ#EKN2R7kg*4Z)i!FdC%8S^a}>Aly$7<&gEVK4df0jFFh7<^-o47BOI%RY z*WRnDHRhcbZVxUH$p}(u&I!lh5XlOhem(jF;}Nw81$RTE06Rzw?W4VFyyuc;jboTU zmXOjk->2>f1O*BQA%Hju&u1BOH_<*-)=s+-&a^+R+o$FNA_Hi*qiy>^60f4Q->J8t z33F_`o;aZH$KB@#Kp2grO$XFczx$bH@ zh8=|E)5$}sHsu_G=n4AeA21o64r#Wm7-hCFF51}g;?1z-MT-AH8$#gWis+;Gxn%n6 z2UWc?JApggKXb716L*%I0ipF7*FbHk1)6M}{|Om~!NHFv?|IeJ{KTa3=T(Lddt++* zvFLM#?dp57=@g zqm8hm48XA4a;&CZ{+KTEf=O?lRAscw23p)@A0*DbVJp_I(EO7s$&seI(K%P}Tc!Y^ zD62K-Gy_^zR&zkpw0_9L_ezwj;@zhXBY zqSC*DX*fhfepQ`g{9Fo%@{M#I^^P*O^lz$XMnApn13KkUYbzV5vzaC{H8dA(!r3(1 zjrXwTJ5(#OIeJWG`u#VhXwYd@QMX{uW$|g15r-ClrfiJ$H9yHCJn57JAaVIhE{{NY z${7ta>Yh;p18;G-pC8YF`c>1>heoTPih$Zlg6$6=%94WRC4Rdy(JyI?KG zpH)3O-SA1K^_8s)hVAMGoBJ|Lex>acY+5t;NoI7w{RFhjJM>slSiC}}g}1(VF7Va~ z=TyBM2eR*R5OYsZ-~iI!o65nR@5? zA()=KpC~~+cMu0>jp}nq1 z4Za@)RJR-`t`7StOKRt#7WGu1sjj_nRbBY6tj`dym9$O1y66`OQFp7Ge#x4Hsm}a0 zt8?L;lq0~8xG@IA2FG>sd4eVf8XY08{;4kb74QqQmtUbH`ks2?SG|UT-?GM)ELsga zlAoXhgQuBBP+a4J4{KmZqNf7TwK!)$b-2Ddi6!f}(croam}v%sCz6)c-t5hp1DzNI zS<~XC@8J&%TD8PbxqvkXHua#L;m9qa&^NUCban5~z&iSvIVrJ?_Qsa4Hva|idUwUnF2iW#(g z=o61qQ8r@h7PCKl&@b}i-$bq8)GK}wj(-!iY*XL)#bdb2n~@-ry~ConMLfawHN=j~ z1m|$vFPst4l2~kKU*y;4aCE9_KLJD>3#u)vtRdFPoVk*G!J;l_7?E7pYq^#Jkp#T14RyZNj^*E=&q8 zf$-6(g~FR}sKnJb z^u%v!f(BqHV0w}n?Fnz$0_J_W?x{63gdoxhL&4CR>{4X&CrYVXg}A}w?t&qgWpZDT z;wm3Fva54M4|`D!WNeG^hi}g*^yE8F)u`n;Vr1Ttm%tSU;UgG#F;oSFa>zQ$_@HHx z)l3ZgH>-@-KcwSig3SxO)u@DAL3RA|+lb-n=UhP_et!fbc>PAR=+|&YN-*^HR@Z!{ zp-j7cf&Gl2u)-R`|A77fJ-?1-XgH#O*PSEUz-Eg>^{IDSu=H;2aYE{==3;=ge3R;s zCt6!CZBnOVH{dRpdxzL8(b+eizZ)!{A^HGwD)sk$N>G{?a>Q(i1BhwdaZd zelaOMmwx#{O}tcGY(9U7%>&iMK3}d$M*x5P=g%>d0wa8Aks^}hM zV@_g?f5#lu*Qjw2bR!GJmfrtaSEDp?TvwlN9oaCqCO(}A_-pW}8L27FaZ6APy7R?i_VqJH55;Y$smB!BbfzU`5wnwCapgDih=u zW)Z235Ilc^i{c-+)Ca!Scigz?#S_xq=h}-&;6vIL3C09QB?CcMA1D$bpw{#b;;vRk zaF-fJchP+a#84?`2|o&`^|Ydc*qaDp6x=6S>H>dOTeY?$4$diRS4Ytt*GNBi6ud^# zDC6x;;7UCLV$yy4rdAJ>nsffza;} z?m@GNrR~*CeMI|$hIU#p5Il-zRQ%3nGJM+A^&$0gACZ4-i79aQ* zf`tAzEQ-TI<`)A-Y6-NSrzF}q6qz@;iO}|@j+Y1%)7LO8wIy1 zUIAzcBl!ufqz9)MD_T?$x@{s6e&TTR&Z2pjMgltJB+r3qa_ZS zhl!I(JHDfLQ3Eib$IsGa!_F+TqFy*roKxbSQ&!~Y@jI^V zI@PygnG1Lx0hBn`?jhxODk7QDGtTi~a|3N?ivn&{>bFJh(@k%1asfr@epUL^j$z{3 z*wsj+U+0#TVkiXNXk*LWoJQSR5y_12R%ImfkGr)D#o*f;>!dpq*R3rOP>eWP&{IL< zZL#^}#@hk~9y~?VBrhcY#1X0TQ^cG81-K|sgHP6yp~e+F?%>P>$LQ)`aPzYQ??H9m zsY1bz%=f2?fH$y-I%BU^{dO9pI96Sv>Tz|J%&AM%h_kWQJE9_t5eq>@elSLy+?6+< z6qM1gCxJWU*B8y0@W}No2CE6w-s3@_o;FsTf*$;?)h^z-_Uu=jE?VIpYuf3egF3;M zBDEYAlLi_NskcrSg;vGe>KhblH#hbI=$V@mvLL$h_h=y^HrL0VV72OfhPbj>!(1)5 zNpxCj`?wonpWemOFjqZuhBz+YyyR~5I^WIJvLDL{hY~3DNjeh(j=k!%GsQ)CtTmoN<@Pkb0oHS?h>olrl#3{hvj<+;yoq{mgO28$etD>230+>T#ARO2BOgKbwG|lyL8z=wCBPR|DqI=|Kr#D6f&p~W| z#@XWLR-geJGiOs>!ks6lVS(qWV1ek`DnieaB0ZLc*6ivdx@72BZZ}HNM=QNZopGMH zDw&OeD8)U;>*tBdiTWqd&5-l8h2Mqeiwf^^>bLX7HQwi{uDJjwQ>*9~P4yzev;U`c z?^dr|jJkJMb-Dy~w{$6Nq6jm>sMif*E;8hsS~aG^O|dsz+S;A4i_{C3i9z7)4qYY& zj+(j{I##AxnlC2{=+C&<6@vzx|8&^NHB-pcJ9;4f@_64)}1XAM%=h*ODHEDgb((=H6K7 zEcVtv&e^^d)Ts|h3(5{W5xf`wI+$B8LE?|tfrYeXOKeN~;W z6?szpq4hbfAt4($z7SNiiF%EMAGT?$wZk4Yd7>EAY}Xuo)7>do?l(>) zGN7*c!9;PQ(ci4(t1{Jok{D?nnX9g!Bs!oU^CyWjlGcKV!mWc}J@!u-YT}jvXScp3 z;9+BsA4x+F+Kq}rf~|X@7qg8-Z@e%|g&!l}xEB}#C?e!F0fmt{D!#-JU|i%4(<=>K z6?INWnR|i}mm#bgZ<^sZ0R}Ii8c^;yvu%lE-NsXY%=M<(bKp7B!B$``0-CY_E9+7g?h(%G(^zM^ z3^YBd)sIMk4t~NKbR7dcX-I)N0h8xEADJ56$!@oa{4vk6Nm4uaQAoyq6uD#%GaoXN zGe6CbGl~Ums&hD&;yULpdL28Lh-v!mHW4myrzs{q*utC?w5u_&E5Z4QnY;kg zQZzU7F?NPV18ri`7yN=8V1dktd(4F8dJ$-+#UJ~C~T$J>cM2#&B9FT4$Yrz!3R`?e5DQW#j|ix zM0KuiB|Pk$O!6(b8y4-d22YGfGKqz9+cJ*y%aplPPL))xfFt}2TFWOP5C6_Y;}H_C=BW?3ZBI zU7}S0j$SR}V6RBC@4s6zQJ0KpUfz0_-m2$5Abvwl?j6?da$Wsn59)`jcyQ4nn93Y} zP+X>~@9|@*l-Mm$io;n;g(Dp*tU*nENVM*WGc)xaFI;_qV8Hb-1xeba1|n4imnD*A zVI~5R^I;bz!W+eh4`Fk{v3fc1P>t$VE^dzX$L&GmZuOWU`kp-dNn9Z#s6E>E-v~Fy zT|7D`UFRgl~Isrt{xokDcc zF8n@8V@#M~ynFupekj3Ju;YxY(asm;uEb6+X+7>cY8V0cgBm z=Zf`^Jg<9141!h~SvVfal;7DCpsZU5As-wVgHFbo6M9s1PG4m1Qyd$|(88*79t8)8 zYF?a&``WM6uk*x7say8Zq%+*gDc_<-&ll%dl^?68=8IxJ>*tFrFERz-upO6*^&0BT2Izv2bzNBSbLy|9%MP=W(WQ zQA__WLV1y|Jwss(fdh>X-iM%5d;Ts?a#cw+;2=O|zX^pNsFDtPOdQ697cbDFgGmcO zn8APY0@2DGy}S;ZqE;;sXCxp}7ZjbcDnx(l@O(9@Lfo9P*_Vd(NEv!?tJ+*4nwLzi z1x`)@0(1^_7@eyZ1gWI;NrXPAjK^WB5g_ zd0aG4pM4L{XlDr?$olMYQ3v0CFFhf~;n8*>!0!!p#X>Q~k1_hySIb2g)ohXI(w?;w z6FR1L4gebK9utC))|eO@VSD@{(armonzu+C4`BIlktoQlM~A8A4y7)5{;5^|C&iC+ zZRH2u=ZU(uLcDEYCAhXqq-(3@{}89bE7n#25RecxR1H`nPWR#WgHMSiUh6=u>i4wh z&gZzN#e}@N&C~bnU8L&&Su!n@+QC;e^qmd64mYf*uOF@&p4K?KU^#>;4eB^N^43yT zoJx{r3t~~BZ%!AdhI4wKx?#Dfgl=@Z6{2ffGhjqDjvFw893S9|T&IDPe6PBB1;itW zqO(Hd0_}^_S1E+v_>e9H)r^ONwt!K9%L`fV-M@Nsj_CaF(ZjLl1?jz$D#hUJ+L@rt zfWZwzsPQ~#w0V`{{0^8~eRTku)&L$zY4n9OI8q&aNyWH00p(VqLeGePEozqlBFGzS zw^iQJxO8|bnx$@dMufY@ey2k@6_S>S)e*j083^+p!J*?rx(o#YxBeNycu(IxBQ5|o zKkZrl>$Yb_0e(I5EU|Xgx@ScyJRu;82Flc^E-R4>$Gj`C52vUbR*K_j=81ryIIhTb z!#*=6VFQ!Vf8=ch%^dS=|G5?+U( zX`veWx;VAj>Id+qyK?{!V~JVDRGC`*x=@A-H-XdC$PJAr>Pv5kVx7OFOi25tLpj+hxJjhpMT<@Pecw&m(Ep-MA}1OO49>AU z&Z_ydDu2yxQyCWtjDid-m>UT!!Hon4iu;vK;@+Oiz+$Ju4={wRI3<9{7!r<~hW@{? z3=vSqFY;*I^*6mCIy7gTFgT6HXPNXursIU+vn^ir^)JC@YRem9^3fW42gy>!Y3NOP zQ(Wy^ziuCb#p8Nqtvd9UXx-Nc0fvlcz0R{6uwg%d@*Zb9C9Rsu~(U1v>va@ z)%dr>rPhIm)aJJ!5^Acd*JgujKvfNRnyO}(Bgd_3D$_OigQ`xg5#dv&!bgeoiWhFt zfH{vaP^D7|CkFJ(?y-hArB51%2Fct%)6I`?62wGFLrcbhsb&_^P`OG*TCJ`TEv(Wf z7k^YEytrT7@wWIIAmNO6#L0|-s@W$@G;Ad5)YI>XjxIxp-&54?cf^^=Pa8Md!IRYB z&EmAsE_hRMx`EFLjdN<5E?*F3%W$HvRm(SvyyomLHhvNVlV~*zxUl77!R7a6@n>wJ zezhXQOBCb%$ZDo8+5&nIhV5IRL(!n-;i1K}@cpF4q-(Zdv%aT3=A%LVYl}FW+U}^| z9tS1^y*JV0(J7cKP1c`W|E@UO`+$1uT~W}SdW;~5a22o3grVz3(iG08=4=I`XsBwj z6(E3$V-dRY)bcpF%HxG&u%Mtav)y|GPHbD+D{q!`WC(_|VoTj5D1 zSIs*N&(00o1wA|euwC@SquWO~)81F*A3>fo@gp2;I^B_K#HpJS;nmwY$goxi7pS*B z66bVoL`SYq#_jU&(v3^2M(@B~jCV=Zl#j(sJeB>47?9ck@=Vh#shMi+@mU4UbokRa zKbfEg7Dp9WpZEkwtwB{}XJ@PZpJ>AQ$R~Q{Lc7E@ISr{s$P2KD^P-^c*dq#Br8V`+ zRTx~gcHf*mxIFl7m$(eo|9Q9OkM7tl9%}3xBIY-u^{1jNr@=Tx;PvCt&9&_Q2hAN> zs($-aTvkvq*c8G+OTdB=M;)ZOMi9YH=NC2f`~4E8?-W)1`~i$t#FO!i%G7#MoTC-$ zu@B%rqtN>&-uFACJh#+~lXBPTv0x)HG6n4e`6mr;yMHGBf;ot)F81cW(_3kghJ1vi zCUT~{9G-h3(pm0;sET>&tEz_|v5af>i(UnhHTk_k78JQF(^P@j7_mg^qAx@35eX1}a` z;^O~6I_)Ln1$k0LKn$D;hS+l8fD-5$NibKrz)=X-?Exx3Rw@3E#NByRg(s?mbYu!x z0eUtff=g>WtuE{}HESB++q)3hRDsyE0u%u{x$4F*pv3l1<@-_;CO+o_v4Z&KKkXBR z&1NOgcPS7$t)wvH`pN_1#|6zxq;){2$&ix$1wk($ad<(`!E$H1CM+Af$JFrNPVlwFo7yj?iZdVch9XdP&sM)9j?+OF7FNTv!9=-4Z!K2ri z`?#w3S`=r_HDwHAHUDw7_iNEIn)V1;V_jkwb)-=O~fjmV3r^FpraD(Gvs zJ2l^c=ZeaaXeYrPAgRp{8o(i-mA*K74`UP(svrWK4KngzY~{T z4RSm{zv@7PyyC{jVt`>QSizsT=ZYu|;dO#j$}JsvPZ3%v9YaCC)ENCCh!X`=t-&uu z)u4#3;JqjKr5bz?XWBw_(Ls@$^ksS&6eluE4vOM@%}yKai=7PpH+06?_Zd#7`_-0% zkYPd46E)GH-2@DD@Th|L%<;yf-dBGBsr|9~>Id;ET3Ys_Xn!1Bgo8u0D@R>U;%cXN2uii|VhoQ3C$ft`Y)xAy|wPibGLMFz#T7Fpk#T7@8 zljkHdA_Zu?4nK)jS%)zar>Az>>&juy`AK8JCw|fz61#^YwC%3#A{db|{rVG>2|rMm z{VeXxn!C)nx=JVp*7G?P%hV4)gSEP)>WqJ3@VE+}a|CJ+dsNq7AQ1b9dhr)=2Oj-? z6&E+F(*&pXhm4y|eZ_-0U#M36DsF63`8qn4=B(xeQ{j{|v4(%BF9=uJ6|e78-7RU4 zsApzwtR(Lcn017IXuXdGt3x{YM3TOLaPA~6pF&MX(z{L>f9Bw>;K|>_geIry;kL4g zS$gj%(0iE-lJhpUE-4`wyvH9>K?IA`QWH3nApre?x-qf zscx3c9&wO)xv_#6R2{R*$UL}%sz*k2P&4@=HmLdh$w960%2QfTe;vQloY{P^*?sGg zQ2gaKdw9KRb~W>IV+GOdd}h`0kK61rq@&Gl=Zjdg_52xacJ^ENmF86N!DbJ>iNr$w za+{s{mT7hq^AKGzQV`89VR{$;xXrFYI@;`BzKAv3z@O1(ckRTlH0J;xY_^(-Z}`V; zwsxm!cJ?R8%Z(L8vjmdKQ&DJ0tZT4rrh&4NPFMhJw@BQ*)Z2v6@GJB*;_87M@I00gA zWALL*gyboTViM%`2GYT!U*zr^Orr(&Bi#bBofb?#q9zv0Ty=dw(sJs)fXwf2sE-i! z=S`KMM39cviW}3|yY8`fYG*+9N!n43t(FknsA`)_yF=+(y+JWkNCcM#^0*)M-ZpQX zeJtKky-%g*$%6iKBgL_wkNLv9jDDf3GnEDZrLIeoMM;a6V%8#U7p>RI6B zyE+Yc7*SH`Y@Jbwht8M{O<5KGCM{PzlOnUNx+GVFjW_U65^v?SrQr#?);r6jPieU^JhSEb8Q(zS^v!08%;6_(l^lx@8qvU8pA z(ETdOkj2NAo#WMI)xZonOwA3-VsT7$*P0SvXUJQR{eG_BynQ^gskevR+Rq50_NF_q zQ+KxF*qXn0zkM+a-&P9Qt;>HgsZ;)`(xg1Dd6RScq!;0FMz57EOB!guyBVH;bsQ29 z6Ge>mPLf>nac00yIE91@^m#32D$L-~x+r@@ES_|UM7h(p365tVMd zYuby7l>%846kcQfsd(l8ul|((f7YMU|F``~(CejE2-*F=0ml0E8W?30z^IaJIj}{! z_Li*W4%q)ki%2fEWkFB3h(-Rp{2?H)I3Wr^P)8l3lAhOD!ncS?qL$loJmM<7 zUk?lcJ_B<9=d$JH-r$Z|6sc2Ae?X^H`(|=J{Qbh2DwJ4wLx>yVEzRVV|5s<-fm|6* zTJ~!Efm6$0JaD!l(dfW2Z=6*uQ2nYoaP~z?F}}S4jOmUk-2) zY7}bcqyl*j+HBcQcE9i#hqqIbt)vp)9q24VcMW6o#?Ar7Y4~9x(91%<{s81e?#v z9OryCk1ailKehN1oDLZgH&%i(_es^emF&|sa!rvEe@&5!QzA9)nj)3g6e+x>P^~1d zDbx$Cb1rld&t>9Jz8QhrxqQ-Jl+_Vt$-uugyl9|^<7seQ@t0t;ak%Ev5+=E zE0LfyzLD_%3t2D%??uAfoaTm^G1Rj)d0Zp{4h1ia6+`94XlxkuVQbksP`VFva+R{$ z$ieg(azY!aO}!?xfwPdgYI+;l-}=EN#C~Xs5c@$LXd_EqbEZjcG9UJ;oEnJi;LcoD6kx zA?{f1+K?dzfG#4fsj9Z}N_Pt#?H&C5cCwufy$9U!4_)@~(p?+2e6meWW0>DL?PR~K ztpIBsWeMn?dt$lzq#cODY!}JD6>K=# z>;L|@018Ak*kOx{WXse?>FwUls4bGku0~Fpy2OG!dbA}{P`4}gI=h2>0KZCF>iB^f z9c8{Y1~BZI<2f1o1!RU1`#0MuA8-`CI>mE6~q2vY-iaIVfXIuEbmMG=6#HVUOaK79O@$br2hC$EaT!X z@;K|BWJBTKlN>&l!oNpt>>|%>KRp=)o)`Za4TLO!FNiEt99fzxKo;zgWe+vEtL)VN z-ebQ&*3nG?RQbw&>Oj9xRo+eh)0=y@4h09dZEPARHUu(s zt#-E>+e0o0)Sz(i?W!Mp$m_j<1Lntdz2vptz!CjJ?ddHG(;HT!O1L3L#1hPd=p(zh zw+0j|dO^ohSxMhvYuzMuULSel*v7gxP~bt^2pXlUg|HmjPJj^Ptd8bTQc0+(h~`i& zL|-#w@*pGsu8%ClDrNVTe@Zn%G7CdlsK)n|=OKS%Upd$;YjOHD@_LDsVUs9s^qq@4Ed%hPy7x45+^~CZ6D&H#iZk4Ea#gNVUJEZs}S&k_|_GThrJY*KXaVy zH3qXlHIuzO;Q$`}^+sHfB z=XhBRV7}&fNk_K}j>qX*rw$x1+i3@NP<$w*{&kB%VBewHF-Q*azN_vUg!!F|8R4ib zs^-0%lIm2L3=E=TfqHWgre@g!^~E4rU@cjok_O8M;Z;iwmJ_j3Nke2Ib2|@_4+dr? zr#eVi50Upk;F$`?RJfu`4khA_Div_BuWiR0PKUqjfHj12XZArC zx@@RC4_i%3gRp9NL#gmPL*>{swiC+cLUAZ3$m5M?FxQ@wnKzvv!!2jCShC|8#VZr` zQjZXyg|awPRVT=@uJwj|0-56MGD+UiL4Vur9VGm2%5v%#s7b?QuasTLA;9fgpq3Al zEr!;b5;*@fpz%y+7O{oCaH+!&fD#{AH;fLNg+ovq;HJC`@U*K!rJpD#WU*dzzr)W_ zhq~`XIUq0}WrC}!-aHZTVq?vy+<p(L|T+bUG{N%BwLx2i5V35OWg`u-8p>AJ)0 z3N*CRw5#F85XBy>3&dK;r&bmy?*;1T5wgw6%)w7kOLYjr5&W4bOtaa}YP`Xa0b)$) zP7=WlVCY>2%Yz?65EL{J#1ke0L9d+*;&`U&{wH}{ zx~>{^VpEkbP&fZc_Df%aexQYA?9RRF)j!F0CE9PnD(Vq#BM_3vgae`|l)7#BVr@`c zFiVevg8!^zie|Csbhe;3G$?E@#z|<1fCN_78}jB8a)RozQF2H+7Z0PQG-}@h#7&e1 zy$B~kZYhEeJ@oPwQgl;hYJs9F!~;0}HVQa=rW$;TEGSt^c5?n3z!7j*;w(TU z<1+qOhCfChlbBE=np7x~YPvfP;Z%MEn?$Ypc`U+-zQaYcHrHYpBrKC3KaFmc$MLA` zr^u^gCr3o_x)`_gGfvfl!M9G8-BIAksj}GmX`OmxEaYTc)ta%8lR@+HbXhQb6SPXH zl8ZwUdVbjJkr*r*;E&9Jy45d$pqXHvbyxY?%mo9ogmlc6!xd`(X|ktxo+=nEowTit z8boO@EHBiA(`Ej@X=L`{uXH1Ic>ZA{J;uoJzp1Mp&PCbbMHMje|Dz872X$@w*wi(B z=l?)myWP4z{Xeg3?yshjNXE`JbGlg8r0Kns}~ zz5mZ(qkcC80G#Si!P5WHRKIm1FhG!938?zz~!)oT5@@(x_do^T!n6*cNUJbbh7{zgqW zN4Bymda4J`kp)fG+Km+1r1NE~Mid#)B9Jfbu%A3%_Tc^hw%;$3b^+L`4XXbIv8lTF z0zFl?T_9%$mfZ_#`c?Jvh4S&hl2>%dI;5XS_&_Hwy+|HMBIqL7HFFjKkt*sCtszyW zcJN)KVl&fj#Wfe}CV#qEh62;y(KFrZ64~5(AyuVc0IcMGSchoXGKxn-v}Fa834c7qyngKQp{PD#%b>LR4i zeSvZvo))QRd8{G)@60x&fmT2AdO+3Iyo-YdyRR&2KfogN5)Z;75!xitGmFlK==cR? zE7a>($xhu5<5VIws@230I}!!7x_vIllp}bje*{UzX~uG%3SBMdVKA$&md}CUoj6XK zAULkhff}b7ki*EvD&>rqkApj3HC_%&_&`fNyc0kIe76A`BatRw(3?nvYFZ(}U{N_O zjSs{>pfs0+iPn=!G&Icb4}bPYX83h@8sziG!-s%QkAK+&SSm+EK31H_#}gI#ct?VA z^@MQQfr~zfb1+kk0vrh$OvpJ_aery9YCRu z1$2NJt(?_5L;Y=%?34Ho(oW4g>bXe(+t1aJNnrV2vefcxWJe#|d@7D6FP@W(A|rB= zLG|~^va?!rJ@DBF#F84eG?whFe!O1Fq=+_)5`UF9MfSzA*+4>OUjT)#|Es*neC-2- zfYt9h85ye#($yJrCj;#PZ@x8I<{jP6X^~0~8ywHghDvX~LG~f0th_XsX1 zZ#~FoZjc4JO&5Y=k+rwWe!kq`I(5n4;A?h@8grW*o#1zRACuFjQO;Oju+i_)s^LcI z_r_N<))zXeNX1RZ6zSKv2wFyX?6|&!ROl8Nv@5aUi2|X^=Gb0pL$Bg0 zdDW-bV_=MT(AStg;O8@??@&JFJ21xXJJsV38CDZZVP%*UYq3YE9P6+19F?&N(yX{X zaelft$~mLaz(eZe+vH^b+ps?5^bTnBa@}RZpdD+i{7AVN|;L*ExhLmzN8M_ zEw80aY{uAE$a+mQP<@;MUONz;yHLd!U;Fc`?VdTy>f* zZ^@^>Q=Xr?-glEDnkgu-MO9CiEn;Y9{9IY2((jd5awT}f?~@nAk!<&=<@d=2yp!}Xhy^Vcrl@o8 zm#0FA%$6YB!%}E_N-s4f^!wNDmm_hQGDM(^@aS3?>Dn*!E|VefTW6Mmbc1*>0P)~$ zWpaqJ-^>zfPm7c+^+}nw{Qss*7M850I*!j-qaWz@ku~`J8h_CW4|jHDOmE;Hu!Fn| zo6mGD{}|VA&N8Hfzt9(`9`jvZ%Ugnoo!&5}f!Aq_(^+1+=*v5gJn}-)H0C71FYp)3 zpI`Fa{jHvSbKJD4qv5gm>ldn5*DtQywZ$_HZh{v-wd7y5uYS~9RX!j`#n#3DpnO8C zer}?Utb^`AN4AS+^>b>~gR-)^f~wF2Wnjpp2oS4zua2unDHPp+*<3IF_#%`tp~{l z{i3XLIe1vPc0ZpRyOA=E=7Yww3#}p{&?QE_7{QK>+|5t98#(;wDLAbhgj9oSKSLG{ zs7~W9=EV}gC*(2LT;<)h9RY-F*nQMlA{>ylaN+pSc9QI=K8o-)KNs*-Z7; z40($6Rg$`6x$LD*nJI7Z?t^u->~4-yt}$-Zf1N2O58j;~_S2yVDKmppu;8H8EJq*W z9*hFA8uSS&uP6z4hPYy!`w~phGqYrNJH84*@`AS%s2dv3i2g$S20%|6h6A%?%NQ6$ zFovy;n=Lyv%0IKwuN?L1Y&rO-ticb1e%hjzJq*NMqpUe{K+>iMfJuTF*t|KiW!iSe z9g0XPW;`of1Pwh5kLxU#?Uu`2Too&a?yCkRJE`yI$SYFsVZ=<=Q=jJbzER-y9#WXb zc}=|P9G&pdbK@~1(9jjlsv}`Iu^F4LS3V-!HY(Os8;R=HM{skrOg;JtZp)Xc*B+6} zK)7G`sAP=qqIt3{jkKFH7$*5^;Gucg1dG(|^Pnj>MLj$Z_oEA|o}VXs!ZK3r`@8(E z)v_-ES*@K~JT%BcCmns{)RDUQs_Li5j5J}vcg%hu}`C_7@A3?EAssi2e>3EO4;J=d9k!7+ao68ANXWDITCDPHJEz>Vd&-#Qb=M95IEiv(}0fN>==faAf4YNim@a1i9GQ=gKpy=AQP z0xTij{ZTrXIu=Tr`D)u)uae9azIFM2IJR{qkSZcUwo^n%> z1PhX<6Ncl^VLwQX1Rv6NF@>60h9{OTp2xf;i&vs z**Cll0^CS{=WAiE3vP4u3-nhPoBdP_PNpIq9agD+5h)fACv{E2$-~dd)}8cWiIL(S z!WGzKQ)iBQ8bQiAy?BxY=3A)oJ_j279+k3Eo^@v2kjj3dK>Vn!0Sw~OV3&EVJK*%z zOXABKx~=}jZ@1lFcX&HUD`X`V`iB1S;jB0QKJ&hh4ttb*Uf!;zydc|mTuEhYckvcc zeLK>?WBLV*D7v zLwMVVv9g7btd3mCWs`ePx4EaD8Pb!B@87V|}<) z#he;DkXFY;&sinAT6^cH?yDq>m(@M1Wbf9MUt>O!oK<{~ z*ehpZHUCgI4QQs~YqfKg?A*HMA3$))&U<{29$Lo4E}dx#uKtJW@}lgPwIAXRx>wLn zbZAqou6a=oXd-)6)7ie4aF?=2^?eDN6I;~Wmt@!0^VeY_lbt8|VB1GtL!we=nzqZ< zsr@g>eugH|RLyGj)l0H>nkFW6#(l}^>z8CNLz~1G(S$^#$QLg|iuW&-v|1jQ^xI2Z zzToL<)M@}iy&At-4osC7Zr6C8xiqOU~efCHK`KF<)nzl85Vb$(Ehca8*o$ z(IeYYBHg+7BRn_*JNWxS^Gnabf$eJTtJ1M&Gn6?kjx5J>QpnrQn*q)@XART^G=}d- zCed}ofx|(Su93EdTkkn*mU-;xA$h) zYUpcntF>>Y8o5s9tDfs%QZRKEe++S>Yb6=BL@RXiBzkO}tiee%e!aX4wAMH4p}JPD zvR;?1Y!g6}K4~_4U|91d`d_Pty)HwAh-vAi{~Mdm%u|dP^AxA7o)I;3k+G;=-Tk^8 z%aEFF=oTm?l!e@)afR&}QWHmRKWhjw`ne%B+lR8?hRwf0PV0`4npzCzPq4t`#QB58 zoqZeEJ8T;riPEC7M7?@(1IRV>Cy)y79u&mr7@Lv!n(EsP7|&)UH_EQD;F=`oOt4Hk znmucyJOQqA=53T6T(7imY=o@>ywXbQXT}$mn{e^bsOZE^vUn(pW*k*CnOd9R#tZ1# zKLa%}gsroOF+BYY`-!T_XYFv~fU5nQWH0)Sz@U>sH<__@dP9z}%_pB|cNK2&PgMCE zvR#H2S42XIexlaDA=}yvNlGBRE9p;@G=Ikt{_=*L%^01jR6N3;BxqJIcvD7VbZXuK z*C+5IMaN1FZ-P~sqH^DYR^RJt#9R6n;mWt8rNx1GN0kcPSsFAzDq^7avXkLR0k@s zM!ixeLptne4}9Gw)Whw2cl-*6x@(Hz=Q`Oly(T3u72d88-HzVP`o9M}0#Bar$zlKI z<2CO|#>U?Mo@B(ZtoOBIb^rI}N&35%XeJnH={A~+Uzu=UL^9>?@8fc?LB06Cd@8R7 zu66)C37{Qw;X>NzwIl)9z*c<#mSwA2@&T@eK32)wWN)pi1Qni>(!GE075<*4EM;Y~l_% zV-)Z)#1?RB3LppVj=e$~Ww0b({G@i15#jN*AIe{G@5%CM8)ix)bFlPNRQ(RLx>U{j zSYFg|?khMXKLWK8)d7K~6F#YY6%-jA4`F8c8@l}kJ7w#P*I6E}XH5C3Q+CRobtm_= zJ&*-7sL%GuQ}O6sFHgk7m1)kY*Ff@Wy)LpFzqCbRl2c(Bp4Isf7ko~RQ@v z5w=86;u(7K!R38yx6U2r~??vn!>^$NOQlXb5)@52V0q7LqpeK0W{ z_se|kzJ~E&NfFUJ%A)Rif*y#5E8B1G3#!=}sFgk!~95 zah`BGPZcS(j8DE$J`DYNm zeG0Lf{&1#x@Br2>Q!PCJiPTr>jRUf6&rjE(Jrsx4MG{IUg%Cd5kAodp2cHEa}RyU&-bp(|P_O);eB=(z!YEL(py1 z+oU}psSv^*MjmaAFA=1>h!h25x$A~;<*0*n7lm4bqWJDBd6y2--NHTYTWHE5u`r!& zKJYb8w%65DU(2rjK|tV~_QVK?Dd;a|5GS>EZ=1vkL_kyOq@i)5c(xwgti(66%b;l3 zZhDP2l!ae6<<`i6z*abmr+Y@MjVO_F`!}*x>Sp+Znk)-hnm8R2UjS zgRh6+%L&TDGB7`6azHh?Yk|tBeahBU$FF26l+shf>8kU0vc=iNrRgW4Mx&-|Je0>; zaJ5P&k;=EA#EeEXqmQqIyIv-KdjaMpN;+W))#KmEY1x@j7KK&{j^OcyEveWGA|O)@ z{9cCJf~ra(RfRvGs)%iZpwPo!YY5;G$)rN+J5KptwmZ%oP2e_wSuJi`1Vm5cafUN8 zM8T9F4}cl>9W_RAP{EZVm=lWP_k1tgc1U;on(o4upJt#K2#jIavJX0sMyjcL9Mn2C zj~$fb+QDfhB0)ITjo|_xH)qkfaAGKn$M9EaVR*@dq9*pS>Uszpe5V?DNVb$_>v}=U zVC&YHt^4?IcD8!xkW6){|FlpliTyOQGt!*-JI#KE-TqFs`VjVWruyQL?AQ<9Y~1bJ zn%fsT#|6;V3E@j@-!|O77&NypDJQdi+k`^czN3DS?OO(mJRaxk*PeeWa1u;{JoGgk z?1rqppL+j_nVs>2lT5N?5)-wht8adh%}-3%y5ga%E*`J*vKMr|V})^|Lm?i- zGIA|v4VB4(4;>iGS(wz|DIoJf_38|~AOM{5t86u97up``FSfSv=`FTu@g!|=r{P=0CC5LWHVw_zBe_yC5qI-*}3DR*E9UkOjn|* z0ifS8&2Fc1f0J1!?h1?xw?-Aq632y$@T^G~7w&-PVdQtjvmVd(c$Q(pLwHWdvk=cx zTxj~QhYMx29#Gf*CUb|~-+hMdFO6=gP4HWwtkjBiUvpXevS30W#<3jnNhhMOpm8=RlcTtov zJUttq!0)SG5j`BZJJEz4&W$!9^s|GtDL}y2$!a8NC57BoNOBmfa2eCrn$4!&X&|(f z;kQ;>srD3GQ~5GS`uKNLvVfcqJ|B# z;3uU66M?t-2^KH}0yW!f4*(9@?6q5zuub~f3uDZ4?&d%cy>g-+68w@ zgnLvxz;gfzBjM?03Nkkb#$k3qn-~tY^40$JqdFNe3J^J}$D3zzT;? zyu?<99;-i`p!`0&P010?IXZlh^MFnf1RT^E+@ojfAZpqN)9MC%S< z=VHZuL%{I7uO3ga?E(OO(v4vQ2yj0uAyZFqHhGMEpqt-reWp8}P$zemwqV2P*#Rox zjR1a3O@Mw1o}~$4thk;nK)9YQIBnCj1-4T+?m^=oG#*a0vrEt*<4HyvOiQz|b72M? z78t94JiMx#T6FE09&ml;EG7=pa{->H^I~jyd>EUp1hWj>iClPhCt{OhC+fusk*pFW zq3qxb#LQ?UNdtri`nez$%{B!*GzQC`4Mq7w}n}7K)wc6 zLOv%9+oKTx=!FLW=miJVWrwra!V+ z>;M;wiw3{a0Eg`0=402YL9HPmHNv4-oYrO;N`VF3#W@^XoCdu(!BoemaSE=GOZ{mA z{pX?Rj`;@-6fXM1C_-G-9eU#;iCY=Hol&TRRR_EeWUKz1WcNLjz>6*AodlDpI`$tQ>^o1gKQE3G)_GrAy`F~=Jh(IcEh1Z2{DP@t85e# z-39m8&dO*}9A9jBcs>WE3ur8cWdm-}TTpMJBYw!#o!QaP>LMw0E&i}L=ByYD9N{*B z2=aR7I9(v(@>3~I2r@oEDL?}jPT-F)TzxQ7%e}A*PDb@?vfZ(S1rP^7BfjWq5kZ+? zo&Fut)W|Y|4KOecHHs{OBsH?cis~v2f(7wOY@zEOt^wB|D*!UMD^I9BHb3PgNbyu8 zMNLdr*yib>p}RwgeTax7pzQTUQ72bnV}fuUFk60Gz@UJ-fWZ~@fi#4D z&^zU@*N}iCOQ3>7o<9uj6&*C7ah3G}1CD=GHJQQ0P@!IoI-o-);ToSPFobP~V;w1; zsD&ObtlqW&9DGz{)s;{~B@J;XV6(&%7aBeo61i|p2)S^qjYjpF4oY&MV2(!_%RTL4;#xa{0i8@T?;jqE9T4HzeXh=%DTxI;dCNEHk!GC<}+&VHWW{ zO@&PEBs~_AS{mDsvEiJPvEh?E7M>-{z>-R^b!J5POIoQsfq8_4{NOYmICR3r1l9~d zOn?I9d&5B=Bt7)b6$Cjn4!jsh#_@%jT26!#JG@%PV+sSLT#`wv8YeI@cNuntYOBaAfbOcB!O1T5qE4SGI4!4zg9)3AUzo0m z4#IWfird+RDLI7M$A0n}=ZDx0Xbe*V+KoGiQ$mF%jK-&KK{Yx`BS<+;EUsi2q=0h+ zW}!NW13G#z#2pKUUE)GkV}bQ)0HS9V(#`?R-jF;PS^-)J=WYep7RWOIvWDaW*Ajn0 z9t7uF1W~qD4Y--B)0$KAmE*(;KAIGg1$;Xfn=3aY3C-moz=9?TW6e5Yw<{s|qLL0^ zkZ?MiN_@MJMkTuPeQxELlz=&74+OX;K(_}BjeR5#?h4@Q&5lh?gsHfhakTjRjgw@Q zkZ!0#VYeKDE;tohJrUwxH|jy6vj7@*abXXr{a8l@y&rK=MHi>qXaq6wa7U3Q;WVJ3 z>QrgJ2*q*0Te%BwNl0m_|77e}9M==W=~yR-H(gc@KHqoR#|O4WY(PN zi_wzbso=vGTnrb49(+;ZBlNxsx~#~m02n}EL2v=e$IBt(0YmcTwF@g=1TaT(8M<7faHW*=y4a%L^B;&a?XZ>I60cbn$b7H*>IQ#v z^-VK7P=a9-ZveY!oCsV9sS7F&mg3fzAOctfgz?8FwBQZCZQ3ug&Ni!kMi^DF+R=Tj zO=Jmheyw+(gpd%v2P{tjil`yLuohi$a0}=utOPPBVL~lLmS+Clg|35`fru8Y>v{vua+h8fTmnj`~-7jb8*tq+*xDoxsx~xGI(gj}eex z;xQ32dpstXE?th>2>iM@>{Bh9+hGux-`?WSP6SUu`Kju*)|Z_Ptn3O?A;op4Awk{U z+-`M&y9lAI6CtxmfRvO%S8C8eo8n@?6RJMjG^;0)ebHSTVP^NL!UUJ^1(WR=bv?Hu z`-Wd^U3Z07+mWs$y0+47*6u&90Cfl}8=2;M-XBdPveV3(B`1V#KrLZ4;(75gdyeN1*Q_APOf zMa8}fHyJAS;b_wZa`mC4lR9Mx%MC z?Lkh@v0>YHu&`R)O$v*JsCmr8T7^ssO9jhsZL-C1cshlJO0sYVpzmN3!0aI=fzKLJ z5(;4VIUwuMMLhUM+Xcb776fTLb9}e~2oR6*DiM@P8TB1;QcmX+zo%+?9F!RT-Nc{N zlz}n_F0ug*Kc`^e{tmwG=1@ec$ef8tg^H~bo{322l1kDk%p?&d@-QuIljMZ)Z-~wr zTYcQU=<^uUkr6^XM|0%rq&aeR(j2)uX^vc-G)JyZ;>hi#&s^35Vhbx(U@EM^VQib^ zdL+|Kay63vP=@LovOnp?8aS3B{f=YdRTAqR*dBOlIl@3e zES+I_ytwt^FYSJX>y5oZP;n|vk+7vx#?y~C1Xlo=#QD6Z@sOB>YVMP2OW4jWX~O9v ziU4a<>iQjyOwyx>e5QdiWK!r;kx8MS-AxL8?`KjN50Emyz!*mu%aNEeD{O$*^2XTf zR8*q!D?o~)PcF#o6l#YiE%Q)2V=d7Nu@GR2T>*#a1~_rd=@g1|HYs$Vw@IM`$C(s5 zFpMencA?$J>s7wi_JBc{ssi+o(kw$5b)Nv_nGD`z9I$6Hc`clHRDA;y85fqwn(lQ& zvsZUhx3;$PPDV(Fum$2!U#}J7-T~S&L3or9NWrfGQZ!6yqf^OFjR$9Z@FO&W(@ncK zK;nFii^tR_t-*Rwi2!*MBQGbLm&mmcBN_)HUXBhY@o`2tBScX)`RaXq7jBPLS$(*je;>M@$Y?_6`<^Fl<6-l^OHFl3lbp!*D>4`TChrIeXuH zjY<#Dl!Zzq4la%g?c0UgNk$r*N#?M(Qty+>SDDb+8dn$$C3mpSrWit}E++iy)K!G( zWU{EBee967fW>#CFy;~{2Si7lge504IBqaldDqKklI z#mOCS76H-~odV&ad#zW%imm`P3DNTTm|T({AiMDE@-!2WGy&s&C<@Z2zlK4!j~(S47b(&T-?YMY zFr+bQm}5*q8db~8dYCnXnIPyT1GWiz?YQWAmtX}c(IZ;b3mY;En~T!84UQ}1emtL4=70nyW5@)AIha4@)}P?RC(>6eC|CPIj&6Q=H#0 z`Eh3SGf zg*lDW)ub+V>%gOF4irPwqh0L6k}rKwQ~eR;dA0&Waj)VJ6eV>XX*jx311^^)VPz5> z6;+(%SB_Ea!+K3k8i~#(U;_f1Pz{A?C>>Ld?8gH#8V}l_{tz|2(*Uh_BspqeSNl{d zUEbf-9#5r9d~JX;Ug^^7>?qetmpR?+h|(p<1P3Gtl`f&Mq^{^@QybNVsoHKfeaw8_ z&F&HxFcRgdv(%}(-PQ+XSapAQyTDpjrj~ZMFHBs%2}+Jtn^Z;*JHPc|_~k?WWw7uC zC}er{u*ly#XqGh7s!eKC54(j`^M)GV!|u{be?Vx7`vxwY^?W+dZ&Fn~?3=7tHmM#x z?Y7qHP3r8P_K9hgbbE|gs^gr>8ER=yyGL4eG^cuo+S}9a2s4hXUO49tsh+*;wrLd` z@P#(4t=OP0>t&zsU8Jge*#8fjS2%;;4$6&i%PE+d8 zspHfqgYA~8>mWOI&R{#Y=s&D6S(Og43$k`X1s{rodS4?AUGZxM+nwML>yg2B_a?&~ zuqUz!O>Q-Kuw5XgZi87Hm={)fkWST(sHcb6t;M{Z$ajqoWBF~emP*hZg-Emm#~1JEgl6PMAbpy$9&b`*l&5)RIMIrcTM!}QeTd=3r;QHFmZrq z9VlRIW&e#%=A3F(sl;iJ@LNK}gL4D2*B@z*DP%eyQ!hPCv!&nu?FKLZLJDQ&o0~eL2hk z3fq!LNeuNzX>ba;)az^pB44e&-`hrYJ=G4RXwB^0Q2*d-RfA5o$5>FlE+1`&Poq*@ zTUX()tycI86m~$>>pUl=3#}VLZpn{h4X0mvCT#qnxCtE z-E+p+1>S?I#TdJJbKPg&fhC1AaL&7ppaON;7&|c$uOj$6H$%Apx3*@ot$it z5coK5a_|d9DXmC`q#Vs=ht*l9+gW-n0%N)EbUPcq2B)2F7qws)kjFWMHeI9(oTz5O zkJOuyA{nL#gp5ZQ$vngE+&^w5c&QsV5CGL5uEXRret+g(Is*sM|6=Y<;N&XG{qOGS zp0#^sdXjS{vn6x7Gf5^SAps*qK*&J|!32m9kWB?ag&9B=7gVql2pCoaL<$fk2trW6 zpj<#j7C{XP8Wa?-qEQyvcQjW~-|z3Kb9yETaPi*zzwd=l=2X|IQ_E9NJzG8X6p*81 z1Kz;FpyHR+STn#pPj!FYH`o{YzSRLimpfv= zKrt^*+K*ZNwfowBNI*;7f9%Hw$|Y|5_XayQyyjh`tM3gy(|vZa+!a5-SvABLc0kwp z6i+vH|6oSpN!`Loi(RF2+=BgsZqVdI`?K<`DRKRS4+y5v%CZB3gLt?803iJX_vZrw zos7ERz+j>U6Q8v!=gv-%#b&;lU*{yp(C$Bw8eecv^MKA5qPHa&|28n5upAS!f4q6y zgMudACOG%tAjtmU=6w$ijukuo;roIK9EN)AeZeQQOK*PP`-5k)p)LxQuqxUrejd1%%MnTzyiF^5wTO~N^;IRJeZawzdMqA`fyaRrLOHm!675n zAd2w0HY*1H8C4(1Swc-e=8UvXsn;Ex1{QPCYA z2^Mg+t#|~}dWD;PM6f%*K6^wkn|I$jBKQzNJGzeyW{!Ep)(^6_)?F)3On-C-9vN&) z8|NPx3}+v5|2Q%@6UK1HP%yKZz3`mmjYr*`LxC=imMcWN_S4#7N3fLFhJx)?%7Xem z>gEocL^(VRX*}O89}W)dc&s7*f)I!m-hz(LfyLK`gBept&nRlMKW-d#mTqqmi7dqH z5uZAdfbMpC9~B&)g72srB%dZ(t<4RTq!6>!dm;}aU$m7*PkBkz2b%KH#ULCT7mHME zK*jJOsny19;~N*7rDC&HtZ}l+Vcb=#h}sk!J*xRCxKMcX-J@C154tCh4&FB!9N6>) zj`toD^oOHAoU0Fa(T8Up6YQS5y`|tvKMVr*^fAGa4G%mAK7QNXc6`w3j{RuxsqAg; zsgDL9WF_x$Z18?J;kcm5ed|~z@5&WQzDt>)p@L^&i%>5Kp z>JfM8r-D5j)qVq5`{JiS_}kn&KONj)d3EG{?wp|F#(f4M^w%!_Oz^P1sOQDe=kj8= zlY*)4(vyP@xAdgo8?|@ap3LgF@a8X_9PFBHQtkDn^)0UTgkYS@R)Zip|9orm#!al6 zM7~co_)GKS$n9DmkGp-A*bdCcm#`O<0DIMvpo>m_dr2_IM+CxZRQe`oy9VoKndOAU zY}VJ^iSiUI4a#Z^ceoqs-CeZD~FvD{H$S_N3rKl1I6|{ zHTW26%U!1i@6TR*b7fi3nB^xE7q}fy3tH*g!qbAjbi~J;7EH0=IQbX@Yw4eE)oH;v zQzrA~)pALrdUGsi7+Wz%a#Wkq&-P|8X;H+K26Qzfqyv40O)@$=z&7q27@fVt>A~AA zv~`ZFZ&sbow0-{cK-aijayqo|1^4~agNa)T5}mR}g+^BNvp(vH#_J3-sEO5NQ`8LH zl+Oii;Nmu)3zlUY?ta1W^N!`gTJp{~BPiym`@*w>eVF5?&NlpOyw zt6!WGTwr-ckA@4f7rSqt8(dIK%IV-vgFE}2VEoM=|2*p<`F_3o@`|9Z|DR3TJ=Iy~ zj(9ME6jr8Z^l=eZ@aq+3ENDEB6Zs>^_~3bljDIzrnzRENm4T zBS~;>OSp9V`3AW^@v!s0c{3&W>6@?V!%Qn%!pQWYOoC33`5<29N4DPWc0uqCM3xt@f2RTRkh08=y@qO|u zyeKGd{%+@sf%+G!~xSq$1%Ro%g6cNdeuL6lvFAL_=(7l%hUv1P-o6;9E zFAo~s%2kZ@3+|Vzg3Il#NT_{w!R5gsK=$b6!M7OiMPCV4@p#7-!6{ZuWZ8=S>I(2n z)z&^NUm2`Pa@PAY&t4fcjt3&T=LIWo0uR|x&-NX%ax#VO^wr=G!tR_WwNtM$>|StH zFuC88+A^#Zm!=avnbUgaa1R9N5x3&1V7d`s94pD7Im#_I>PupOs`Tx;-(O`ctLAkFSvES_%r^|wAv7P`s$#(6%DdlGHUfo z)Z}!Orc~NZH#(Hoq(f;v=$Tr2pIzS{>X3i@*Gu zU_!lt!h`mjtAerb6K?${qqY+3feScG{fB5}TVD^St2NwxT~4w4*McV+R(hU&`8QBr z_WF8o6$tg`uLno-IQ&|8>f`Rm{xR#i;27>ZyX?B)bkJq;^}#tjZoEF&XVTJ^i1U9f zFtPR;edC%O#1RpZR2-p!&W@sqBb#NzH|jPo?N)pvXeew_xNp;p&^`Q(pw)PTt;;;? zQmZOils$e?@^idjwc~Auy4C~(jP0FkjFb+o32tTzDmMfZlPNgv4jAVlHw0s5s3uPA zPB(lbF$=Kz`uX8+aVD{Y&vlpG5QIhhgp=_@rKK(IjvE3la=!VY8-g|2dQSz;`4&{* z%*KcVdThn`zzRkMY!8Cd&dsGWZ*IRa_$t!V&Hr{&@Uc3U{}$g4zQW_aZwCW4_Czm3 z_vP=f*n{r`J2Rg5ekb^py=`F?+uM`B>)-ac*6#*`6xrsxNfGffEAo@?qGvqr!drQv zRhv&=eC<|y@rqt}evo`|#`l5)z=cP?2fCc<&b%!+i$~|}!G1LgVihmHJ?N@Y5X-ss z_Tc&&b0o)PCD_haRecM*P^BPSWms6b8AT=jhTe!v+V{V^BWO7lt?!qj`LQJR^^^=L#&*_CdLJ}aAc>-oC^ZREAw9rReiDWgu#2L9yi z6sv0P-NC>pP#t}DFwO231Uf6SDV0)0C!8`&+8mSe=P?O??kGKS^F4P5TW6*E^y6DO z6!jyh>W>AULgU%(!|E&n?v0 zf5>rbaff)^?XfnPGT{=tqC456EXL2{emKg=@6KNvJkn?}Mp_Ay@%v!fg})5)?(6pi zAD;9NmJ$Lp$_m@r^_6;XvorpMavR9iMiaSi?oWe5o%=B+JS$&1&wb;^?A)zz_x%`2 z;U;&?Pv8zWx!?XIxc_xaJm^lij}i~MKirp;XxXHW=iP}v3yyAjzLAa0=6Jf>>Y?Bu zH-BAll+~A~bjQQi;;+{Qe_y0tYMIab;h08O%X~G> z3@GU)|2#Ol#d1pLFy9BTY#z zzF#@`aj0Xp%-<-pNGAQOWqw&*QGhDkP|{3(F~2wElgg4IG{-yCCY?a*ehAGXP?J0= z#GIjuT4!X6VoXHL!50n@%?5^LuhlL6g^|%wgDY-2xCxI06USYHGXc2ARwb(i3?_z~ zD7D-Fkznz=L=}l$vA^LqiGyntjUR`nxkrr7#hySdyp}mZ6+QomNoIYI8h6b;hIG2< z(O~R5Rd<^&dTG{++vJ2kXLXivVxD18)f#`ygw%}^+g0nTMSpEP)0_2lTn&nLg0GQ6Anl+}08Q%L7*m_HTl zz~g&Qnd8WBo(g)+kTE+p@#%Q~kO;R$G&=$N)|h_<$=pZT=4u+P&$1(*w*FPO7w zUMk5FE`Y^Nja0fl4*iVqo$4#Z%L%m^Pmga@#7zs1CRZ{xzOB~Vp0>^MC!P-W+ibIZ zk7t6d=Oh8dxnSnoUjL3x?$st%HO0zxwL3ad@qC_J@O&`I-S%8C_JEPw zI(2oGt^&2dBf4T!B5iUzES^dJ(oS9jX5y9ezU&_=#&JcqA2+_VbBpJL{U&dAX{S}o zkufTf-NE19>8^S{sI-2QXlO8@AK{c)`rFM9K98h|TSwkZE%j*LV_pnyCqB;4Uku*E zW8fw109UvJUSjLyUiaur!AE&4ei;s~>Dy2ACm8tmFF{K9FH!i1|=nvQRIAig7p9O zp?uw5)yB_Glz(ew)<9+=Y;d^p&Vg*{^9_};?z#;CXDj!!4V($sipg%RBTOdY6f#jc z+Ho5kh0D=aiq^wJLSLs`o6EQ-ajz`~Zd?)S<7*$e%ex}X9jde@B<(ccKk zlg5*4jd#NPE7`oxu;z_&sHviP!BqjF90fSdBu4=xDyylBdf3h+rku5;_;RiBy|jrR ztgixJq1LprK9cx)_Qgx7{Y3V0{j)78nMrxynoD8N@Obty}ARzoDnzyN&W#dH(FlUKgu0i-dY~9AdTm1XvWS+E&Q6xVs zKXmr~!a)|L50h2pbhgFGvbvYL9qp=xLBfE1HNsZ_jQUYDLKpIsF_X6Cmw8@!HVgxvV9|9A9rW1)z;qwrF zW>u;qpDSYyp@n$NHbkH##f3k%V^439$u}Be^6@-{m?)RjVw<0P_2wDH2dkGSgL;FB zcXV$CZR!Sxs)^4?>l=45L8E!*Q|CK5;mtZJInjp|^z)DbB~pxxa^P*g+^CHjTM1Qs z(>+8p22pmJphI*vL1GQ$MGeHl8)_iT^F{;V7Xq^PRe6(9wEOl(k77KdsJ>-bi%K+> zTZD_&bKU%CsDP8cP(ifQzfqr0tA%8IokfpniDO#kg8~|)3mtFpMkrR42B-vQSUXh8 z(#(|1^P{=+RBJgP3ry^SR1?xV`K9=iWEQCaij+xC@-!jZS3<34;;F`8dr*rAjW5t6 zU+EgIbWD#4JQf9e^j1399HPWtz2$M7L+zmDAnIBGl^>_Ts=6Qb3fKCNple%bLD5%W z^)ywYy#NhPSwrOzVv=DxqF&mJg3_tQ(k;9~uqcmn2md3Oa2OxwDT2mvC$9Erot4I2 zTkY&%2|IIFvN;7Jv&W|MO}WUYI8wx+5*aD%VIJpJjm{E~UxL2qEI~&!&OQ8(pgbNM zta+YC5!Sq+N}zRbYo2Z`b-n)#w(S*k47{aF8gwS7SPr!01#@@wKZCw5z?+u^M^nHb z?kT&p7G7}6Y~a>WsEYHIC@Np+)JeI+PhptM0EkQDGctL((F8!Hgv-sin#)b^D3_a; zGdpu$1#v`fPaP3QTl4C>6yy%Sek5V!3bZt?glA5#svK7>okPDxFMQceeWQAfAa{7o z^dbuMmGK0c8t{OxJywiMR)|`!wI}2d6sW&LGs2mfl237thHb@Yf?o4vVxf^CGHW_= zxtNEpDH{%E?{r&bL#Z;mXTvEoYE#x>QwEwPhk59TIHP6QnI2N^OWE)pIFvEVU>LWW zvg!!0M<+dXX|fiL9x)K3smU@F7&qd#)>ADzTr*l#bdCbn4Upzd#Djn-eZrBY2^-B6 zl69)ZZ7fne#2s1}j;$7>LGfn-)N1?~Pt^0IIX2=F@->fH9H?ctrQ})J7L5|XrM)Hm zj8=0oX4Z*5BbJXVy_PlUA}zFB7mdHphl&`C-d~Ig*F_VO-+fU%LD)}i+M~5z^eK&Q z2<4ZWVdToX7ZIrz_rheNecV0#16hi4MW)@RWC^= zxedOuQMynGUv&RYqRn2+f35}wPF}Rcp96O8*Amt=<8Ogdn6a`Rb?e% z@iy^G%jel*WmmzevoaRkO-4c+p=ja*QoniL%`@Wt*;$3_d`Q1|u1#`RB61j1*C!b( z(9?+}V#U}>(>Lq%gUow5-)$e?!Bd9}EA&Rkqd7oI16V(>JdhCJhDrzU?lrbiGo?rL z8LR77B%lqJo{ABG*bqtjTGCG>=_^TFS6E+{lD7VmUP*dgZ&K)Ne%Jtbv5YkR8S56* zhvh2kQe&RuAA_`88~F~t@6&x=ZQQ%~-+tJDj-};CJ)1Oxo~0}yZU{x=4_2Qinlzfe z@>D${q!bOlT;Nfy!(A1k_W}}jQENY5k!V_#ILmcgB9CcST(=h<@2`B>4kd!ISt7j( zLCm214B4gS#M#UqS5XEI3gn29G?%_dOf@dq^}ow3G_AfziTN63s(83=Q+GIc&XLMP zcmVPJd93`FP9m;QTv(r6uHtQe9TYW{@)KlX*(p<=@uSLGrVnuI(qfhs<{x%u*aFAS zA&WK!SyNGQYL2tbtl_9ilC#aMR%H%W_U7=bPjg&06YYI9iX>~RD4JU=z1RZ%hJp`@ zcw4RWqvFn5p$cx8WGx<*wJ@3*4GOu+<3xl9i2{TQYf%-O;prJkuxUM#;dY^IU}J5> z*T3?WaZCaHJj0jMj{@ZOrR~t#S2U#=U*x|^8>SC(pxzIPNO_RrsTiEG0UMzy{Os8?WW=jWz zvLq{tj#!eF2D!B)3y@YV$-0CskQ}VL7Ni=atDr1hT`W-r7jzRT_Lr>EY#Oy(cfkUD z0}K<@-okBjLPkJV&S{b4hovr#tcc2_H&`T3eAylMTxYod`cbPwl5`&yr}Rt)UL}a^W;YpCat43m`LYB}y=9ScwbC|q z)g?*dB-&u+%41jphMcYO1Gyniu@FT%KU9`F{0hI(JK{%q2H+tTNEb!zrV;_9lCUB> zvOKkJpuAYwk&iynhnbk8<+j%O($2H4$i73hOsy*tguptY5JkCFB;z}XT|!`S%wu3< z(`azOk^zU?vJiGxCkPT5ZhZg}O?W0I56d(OV=d0enun-$Dxp!J;5i1^&eCtE?xR>! zxw6)jx=*+g@@;mQ+D}W~p?MZ=1J7aY37FI}l{$m*J=$3Am_o4qK%mXvCneDSr2wVViy)ahOFb1qx7Re=SN-2>&_;oL3l3j*%BQN%j_Bpk@H!B#R+6soM*5=AUnamYz_^pDq`i5|Y zK(l|%>M1vq?BpN1EoeOzj1%fuQo&$JXap-EG%3Ou%LfXgt5|yyx+ z4gMrhHAxk|4!$_nC)biZ!YA(_d5BNmLUMnfTtjk^Pp&38pMfC|8ilW~WM)OzsW2(1_o(05orOSL|M9$$JdH0?6u-A^%huVdP&KNH$ zx76WAji@WlvO6k>kGB#+d8jO7j_iRmd0r%fq@mOel`$#AzvU@InFv@rPZ2QP3Lyd( z@e~0wa~}CkjL>6wp>%M%P~^FtxSMZh2*SjQDG66toSIlm`iZq9Gy!B{KA*{n&=F5E zS7{IcJbA%C^N?@1a2a&Mwasj6pzE?11QF^J7x(sDy%0UErvmA(8@-U4FPfB)Btyd| zavs{0t{quNn=*=oz-vh;(gve4tXzl({}C|Slbw9IYJFax#~8#AAI(F$jbz@fr~`@$ z4zF0oGa<{%>WnP6Z%mfkM{_Af5HK=a@|Ox(dWzmsD$`ukF7_s_#($ zsb7?OtwlIDxDbC0qGu+Ki|Xe2G^Bb}k`1X|og^XE#L%(AkZP26DjP+r;f=3Ds>iwC zjR`xT*Ya2xMX&2qdaZ@m&oUcDuW>LKuJnx1>lvVfr`PR~WwV7{qu2FsLa+Oy8LvaH z(-_C1*Fr724ZTiLkzdejiTMVskr!`DuMMCHy*5AtQP|){zQ?>&3 zN$nQX70Hs%T}`sfC)bdSd{W`t1{v03;w=j^P-tcm3|l>Y4A6Ndd*Y>o@V3GUy&F{VU%RTxfb z5y>@IlxyAnVc2C<6Vg51NC1ghP=QqapJPYL6$pE%^n1B7NTYg1jt)W?NLG4*VzP$jd_GxIbD0u*Y!kvM)$_$*6^#+=Ls51)qyb_dm}#LHO(k}p zek1D7HCurtcah=XUgh&dy5gx4C`D3!%sPP;NAeo|%0+|vw|j5J-^Ij^1cC?*%GA56 zu0uizHv0{=J)_!~z9;l#nx*D72cRN)n7+5Ah^60je%y8UwOog4` zsChxJ#Tk``hw=yyj-WgB$mr!3xEwJQ88uc))HF~2*|1>51w?VgF<4#(u2{e%TZV%# zsFz)h$Q`OoU4~Ha!1riC8So34hupmtH6D@G`kGgZO~@2H@|f-RzFN$cPnz9|t}v*_ z`c%5tUDFj#sN#LbQHXr$9Q<=MkX-~kOU>7=)*{k87Ml*u>xC7>+^BO{HphB}GbA`P zp(AINt^k7g6{4l^m|O1Da7;xrK3K8aG@6i0W*s$zzMJ=9t?CIKqj{^35LuWu)hS2a zi!n+{Jke;SsBx&P1w>ZO(w9joni{h)&g|q;XUUl*#JAL-5Z_XfN+I5|oggdSPzASW zEialR$T9{Cn#Kyk{x5&Q7B$Egg9%M2B$C3KHOpoEF`{NKg*7uIDe#()N+W>qFwfzd z%8W60HEBF5`TLA?mQTo&%Hss`Ov+U~^B*bbMUPrRtBod-i+D!WfaswZsfplD_f%AI z1k@YK*Mtu!kPLMNPgR5%sW=Gs?8ZnigLpc&KBEDMGa(G)<#Qe zd6o}ZEXi=qphImS9WSrUdUi|l+H9pjCrGWzVk1IgK=^n0zVMR+CPl_g! z+FM!_4lBczg1f9Q96#N@jxxibag(6yTe&go7Xoi@t+leo{k1oIo9i7PE~tXx8S^(H z!6Ht1hlq{5kjMqYM{=delNVK5c!@C|U>h13QjP{TY^p(;K?4rNbh5=X1HSC?g0Wr- zE}nnM#L0B%Pa<)(H$Es&R;H)k4u%+u)0s76ad;!c;!JBD4J_-2 zuyq-8eOA^TJ|QeE1Ul&J8^Nw(#!}5m!nkBX1gVQ+T*@6`T-Y69TrJ*mQgnB8hCNjU zfhviMC2mHt+b*o^!NihSWX7nuLo(P>0CF(hKV;CvddN0}c${pSylc_}XrKkz)}O{& z4tCCz_vYU|@R}7lvueRG*VJL;R6ncof34(8XF~Ns1Q_j_xc>x#l{)5(Q3 zBE}+so+vf*5oJ*0JjL&lv4o5!uk0C-2QSDdH=08OyNO7r)G9L|R!IwN2HkG7Xl88U z+3uWh7$H~26r@$_7b8C2@CgN@8x~0lpU8s;dTWG-lX3Ve`31m!&~QBKm@@JbARq!5 z_oR>*^x1?p1=T@~_=Q_8ZG%hcd-?KU_GPEI+~EEYfe@l0X8dKVCl|4D%nkvoNxDYA zAb`lQ+6F_Zkg<&6c`oDaV=x>vkQLJCNTQcOUo45_up~($PMqj7(fE$_DJ1eEw9&m9 zo-~H%jcCX+>8<4{lb-BcoQf%T+Dw8g$7+_*k?~fm^nrKY9^y>q;3Y9^d=pRf|;z#I$1Nd!)?n_3#&(urV98`aj3l6scqIGrxCB16SgR0$XWO)tx7 zn~}m@n-_-5)e2+fv%3)oPS%N27AjH{zbm8VpwUvGs{G5?}e-Sj~u3Fn!F7O@7JX%CYv=*+Ts(*Yg` zJb)MrRZhau_=I|0ne{VhmsSBuc3DMDTUm_=y=0tdq=&>wp7bDQv3_h3YO58p)ao9d z6n4FvB3)%9T8Y1FF;M!3YLrICI`3C!orTOG{)o{?71lKY7Mwf_t}k^vO%A&jx58r( z)I>g68s2@eXq(4IKG}>M!BiG?3$wtbkzIIkdSSCtVoJz~;(BC4yllA{zcQ30?e05M!X0-@L|=J&&=AZ_CRK~KSMT@Skphb4W?`(lQG`-8)b@eQ z2UM4GG`O7x!=A=Q!`gy7WH20O@{$-}MYb{V#d3z%!b-EvrUpZ1*hFkO>5RPdI>E?0 zuM^0on_3`8-T@FDvO#uhGiFL#hy(7=gJHWxtV8yc=>YdX*?bNB>jZx01|>XXg|(Zi@^yUe3mB$vEbq`)Oz^y;C>tnFXkRwCTNOzwR`ASUGb#9hki+mUNy1%(iE>wGncd5 zg>f`@k)Dvw6)ll2apyMScuC7pgb_Mk(K1x}JPR?5QJ%1Xhho-?D)@<^H|)hvyd%of zqYD3Xpgzmuw{J_2xz1_f+u90r8?W3(?Se)V+kH@FOFXZaqlg z#r#HmZ?AEyriJ4V980}=Su;b!1R=n9L7E$`|HXHTU#v$cCj-^g7`J1Npkd78aoz6T zJAt3+Qmc34riT-&_qJ5V!vFKb(b(P!n>KqQD%4?|<{KXnIihv2o-0=*KUQQrg9c$T z=PLx-1-;Pniq>#$I4TkwV?N^TSXP1!h>Eqggxe_R!Us7W)#}GQiWlI&*ub8x_=CJj z14cM$i>JmzX<+vW17Y!~h`4ygVT-6@+(i}wEp1o?Pk~fG)bTg+B!>g9xZR1R->m=tjk#cvd4cU&QAVVyyFQ`ONsE_dIuCs*CDPp zmcEQkr8DN{LQrrI&j_RHbn(F%+P-RvW<>l7*i*-fw)Ifu9r7w@LW3?BJ<_#6ftz&t z(Ds}#9nsx9n>W^LCQ*y0(aVA{GNM;3ggPM3z))o@UF1G79E5PmVoR+RQNW$FWmx=B zJu4I;zyPMS(K+12Sm$miB-4kww3NBXbYME+BMSoPut zsvj{`!5?!HO8uxcX3tS~<^GmVFX4=J=gbUy*#f?1CJeJdTnNxC_4`zk)I8ssEDx5SQBW(dd)Au~|{qmQd z$jr=euPdRb;*0q)HIvyk1IA$#2SV7EkQzi+HPy1F?S#N!zul*{3TJf!h@&bI=oa}o zL_KEo?)I(1U3U2ur`)uow!9Us3wJ$Lx&nUAU5Hli3v@1`zGw6ti=nvQj*2HWVM$g^ zyKNmV+_9r#qNyG4)M|L59z9*Ot3lCN@|6~WpHvfbEa_D!$%GTz0q8Zj`?n6~RdqKv zh$a@Oi6GsibOmgk&QI`6#%(Ztp&qIgxq2??ynZzqSI~-uSVHBsN^`njD5tIM3*iK^ zs@h`?CoWXz_Zdnpq6&`X?5^9u@}8y_sWE5v)0>(^D)?P`8B#$@@?WE(*_Cd_Q$$Vk zw;scZ)uv8KVlbgW5TrL=b~WnT_0%Pvw}|}NL-C3m?-JRQah6D_R5iDv=zAo3aI#7m zG7X`JX?Tk%d+SO!b9UI>+86)%hu_!7jOW{K-`U|o4T{f;E_c)HaL2tlX2rBi0$-x% zs>UHSqKKhbYu}yeTw&I@I1|NbN z-<5Cl@>Wr-38gb^eXMB3;UOcc!bGP4gT{g}0jPx4M3!c-&4ZE^mO@hEU6MQELQ2`h zU?(vsDGLqIhEw7SFgRialn|HTrMRmJpaQ%a^zXa?I`YnoasHhb<3`>=mKvm~jB+a& zupV~N{2&e0PF{MV5*1x}PN)#mJIx7~&Yg~$ktv<01qma%v5qHf3SG2G*H^E{E$-8hgbCxjuI9)DNZn5zxrZgrbs+`&^f51tMEu`=jDMwa5`jf`k5v%m@- zH6nIH2$f+-zgh)ZF<0t2iTnoBsxCyg5%Zvu`g#D#iI+$>qA zj>Jn}b;oTVc8&9$WXyG?rWLv>wVn`wRdscrjhA0;UaIDfA8#Nqro`xd5u?ld#7lUmpNpY6r7t$y>y64(5TP?8 z#nQ?^CIr%+^b@ME%G|ei2u~=hjcA`lPS3;_J@AyZv7b3@aX-rgZjX0{Csp7%GSnon ze61N6B7SYqlOes*O!)h!-x*FszBJ0h2DPjf?4qnWGZFmtUw;m4NbC z<-p}n&JAa8^Xgf2SS)lrGy6jNLy-ucNPlQ+V14?7{jd0;v)mu%hMh$y1^1@siaoG% zhXOFW`qi_O+GN=OQu-s}#~0Ecs`{MthpIj;{h_M=p06~b9ByCh7G+!9-|1HS1JpX0$!wDmo4fxkH+Sc-^L=TR+%(=BmbB zccTBkxN{gD$i5NQO=#SVjLeOKnLPE2yB^;R~+{*_M;9m><)PsdsuX$MU#Dz zg~-1&8?U?MxlHLX1CrgggKY0Rx)LXRfezu(W)3meBoZtrxs5w0MsHnI@wAWN4#&!v zZr^$KXw`XbL=_P?6JXyr8rVPfzz$MihcxJ?lFlEwOStQ{U~~#_lIb)U%y9>>Il$sz zuzvuB3bz~%(em+QyM%AAewVgP8XSb}eJjPCh#y~1e<)h;73mM1fBItjLsHiT=??@6 zf(dI9U77zk*12mQ^zjbw?8f5y5q(WW-&}nANXL_f(xQ&bJK9eUxv2nUv&ICC!tGHQKZ4#Vx_dOY@kosD zQbwcOcYZjjdRE%5;CgEMLva0@NS`Q);QDg>fM=%N7K>CPvGJ7 zhk)>4`a?jtFa1#iLjNW}V6$d~kQfkF8xXGjp8)~}^_04BN%I>rj*+o- zY(6&Ey)fLFm38n!nV;k9;4vK2J(c}zTMS#&$WU>zbkUpizHQ|F)RFg-^#1Nm-g7)9 zrDy|s|2w^J82Nt6$oq+fDg_=@fyR*nw3=3c?%onVy-5YMn!bnHwZt!O@}5@H_vqy< z@n1H1KXK%Je^mwkt^yq+9iY{;f(d$m?m4^pxYi_G+^K7I8qy%$_} z<*FZjWp&-6+-A##J(R1B#qlb9XIdGGvK6)}el(Kn8}3!v`$lr{ANEYACH{qS^H#A! z$2Aru4v12pmMgNBVG`SAaDZ)zzp2sIS;1VfY6g@<>WP2838Y~E>5y0nE%8H}yoW8P z?;#|XJYC8-A_Ah%82G*&j) z394#Nw;QC0o{#qD1VNqNzgG8ptUT5KLBDWg&fG6Zu`NiuUW1dc^Fm#;!w3&1nQ~@)bP#{(iHW~;fawe8F;F4& zuC3#2M7AX097_ZoMs_;>#x3!sDps&!$mI;&R)#Ou5?`&iem;rl!&_U7r<`BQ<+v@m zwggXCZj;r7QIlL-c;_nD!<#UxsslD6o9rFPtm5cfSWwguPAx#3^0dZQa}4<_hwV>+u+p$gJ^W zs>GwFFr>ZMrNz)rum7YsS*mX}ob%X`kI+rt1P6?uwHL=#O#n3^bWEI^r`yKG+fsRI z6q|b^v9=+8LLI0tZD>a3$jg3HlW~nT4NB;lo^of(G{n#PF7pLPI5(3!B95JdGx2jO z)uej6sS>}tg2Yj)Gg6%cwK}^Y_c)H31>4*dwJT;GEDiCmYHjs^wN^ytQ7qO}*0`%o zKeC=tA9rP9$Ve;QRn~6^#p|#?u44fFqsHOleZont-P%^HU|?exyxX0yPdH`A0bok+ zJG_k-f_72k20BS{WsZm-)W(+EloxQD0%gU-khWLzWseJWV` zezP5g!8q+V6WADA$ZNKyW@hiMlX^mOM&^eEbQ7vI8nwfq#;VhAQ1G>^ur20hR(&(v_{XK_nLWK!=P^<_YkeA~S3Xp#dY|__KBjW#1n>pIl zq>q%AB4NMW-xr4gFia>8{Ty%;_6@tnYU9ph+U-qDRPBWwJZZCLD;>KfvuLpJs+z%K zl&S{hN0xQpcz@W}pZKlrtOfWkYHW#b*Wz!{>Vj&z`}YmUejr7{Pq?icQ}Ux9C=U?o*0)v$%69f&QWEvIJsx6SnXRM)ndE}trGn<@EJ zlf-Q+XI5}5EZb$4XWdrsZ|-d>#GS*joK+UQH{7aPkR;Earb^p9b~3QpWAfpDnevrg zA7MHokspc&i04EB&Ku)$1al=8-Hqx4WyB@Ug6t~Tig4;)ZC2BAsE$Z z;0WyjSn6hN^E=LPysS3EE*Y-63 zbAj0*0m8XG4h;L-nbV|Vn^X6h1H3V?ZzTQ#?3jYq-hJA^nv{mDW z_+?66ZH?qcuMuq(Zi&E4b^jEO2UwuM>rD7KN9j zvmwK}uZbils@zF6-U$1`POI|y(gydB_l4soiDA{G2@1cagCbsx9w2B{HvvK#3NHKp zFgWy$i%Niu23p5cJS*wbON{MeSU6RJ1hz-`me^fC8tzSgM4r9Xj8|NmtnrQF{Ksl^ zAM>0pFYk8GdO2|A0d$m> z*lP_)5(wV%u)d^Wl@hL98y4RAn+$7z_37YrSZpV5GOWd~GwrzYj2hK^)vz!fmG<}= zs`2+QaG4y1#P_B{#MgWj9!Oq#)8YViRB`ZJxIm=%<6F^*JJMM3d!q_By!Ae8QfX2l z!3@JTZ;8LAoJm>}Mw=2nQM>Hi-Gj|I6>H}T$#$t>v}D(x>C>se zur)JJ(+8u?MWf8_BvX}t#PW{nZ8j*A$T%?PY4qOL`;SmfW>b1|vbX6v!IcX2g806%*9`6i9 zzK&>%p>j9%3`8AV@*X$tAyJ4WPGdR#HEPwgp~&Cx5q4#|-9sM!ZPKdgR z9fukw2LTn%#r66%>eIzXgwbS5;ZHcP(%4HeAk!m(kc!z|yNS^HbeYA}<1RTO?0?U+ zJ?Piuy=yb|kn>1z!c39Os;-eP%i!_25^<+jk{T8_j$tlLdK z(gv}|kv52<{NpVD_?my*b7UA%@~I=kDSJ-doff7oFt)sfx`b0GLU1(M{NNcx(zzUx zCqUQ1uXdTR`cUowD{Kr`uyTi>(vH6VfuZo7)lvC{XiJsO^I&TqVcER8M0dD1&Flbj z4r;^!tsy=?#ay6A{4_`_JD|u>La^hHZ{2vWVpMT_8f=+%6yjA>QL3JeDS+v2h}Wn_ z@e1$+KO>}$Wao(A8}ZE=f!KUAlYrxt7`l6mTxc;NUfd!Hwv81s+!DTeTjVt`azg*!FNrj$OqW*cd;W$3)jl)>Xzzdy4 zgCeSMK3)x9xvM48RV70F^l<0MEVeV1Hj&380VjZTJx7OqlW&*#pvJu4s4jQ#(P8hA z@``{1$rEBXW|;+}V=pkORlrCP;Y6kM%KDG_dpi&FcbD55YXFQ(J>qGB7;Z`9E3>qa-27tw;(VvC z@8V;uzW$Gf;bcC!wD!p=eUidU{aurMa^Xi=!Y?>|p_AaNYhPTu@fY!p5K&wYDZ@F> zq$9VeOwBclSDEw;3U!?SSTb?En3cXD0!^G7^FXMy#ENp>3jk!9tMZfQ>skDzfh^~=f;)B zn^Y=*u$7SjM3SdhIvBx3^&R6vMk(KS5*hd6U&223%&}pRBaD^1;qh#zn{a$Mm96^u z$A|s9*=W;|u^DB!Pavaxut904NhV! z8~y1@k{31lF1peQ;otV`$J3NUQ#wa(NyVGsrW)lckVVNS*OKh=$#o89k z>E?YRoSXfX``jn68dTi1p9pu@+79~2rM7}lgnOKwP0Zm%B#g{MRG6db_CrDwo~-w} zo==9o4gM^T`@l3#-w@wGXCD-&0OixS$c>a)yshaSbM1Y-i7g=O56cY>2-Y=Q@FGYe zjhdr&nP3re_%}H#?L%?1J`~}_)-QZXk#6Efj!!Yvf_vzb;mka$Os6ZH2um-x=_iI$ zckm(Rp-PRgXTW?m0h57WQ+!z)rkdrg)*4406-MuG*6M&ULvbRT8XC&*?otfPU=Y~nVbIUaI)Qqt$@PiiBZ># z%z4?$Hqa?~V6T1E9sOyhc>SwKaOl-eWX`6kF65SSf7C~EHbd`|Hy;v@wrIL^xjU}J z?L4D?QgLI<<&ZNnaD{wtrPo)oozR2$&(U`At8(Uio&w+q6!LP41`e`{qx=aqF`4Aa%dCd%cX3CE44`nHIp z5@Xb(!-eZ(+)qA(&7Gq}0f&rvl*&`+J&T$_)Q+~zQI`*|bvZ_I(W2$J1lJJ7Prj0P z@axB8{P2Dw@oc})@L{cwaWajzi5rfK>*iIu!BSrV_p5R%WPa|}(Bt)d7(c?FsJl06 z^z)@K89-6N0qDAI4l@629zgcoNnxdGqAL4lTEq-#E|IKx%t6>^5X68`&}1@p(4G@J zfHbS)*=*tIP5*WwQG?8BLRcuMX9_FQ1I!+~dBxBpmO4eljQO z?r|?H3B&9a7k)PUP*LAOZpN@WCcEQ48kTiZgsDV4E^w=wS>r-XaV;vLvvFoB{%JbFw@Lsy|F z@tvELQm98eTUzXOvo7uI+!t!0J6HtSg_X&mVKSY_w2i>~1|ZtZXfDsXcld2fTSq+oq05)V*bAYYibP9Hj^Psd~hWq61BErDfrk z1!$9qXQiX`OSk(nOi`ZDu$ckUeso#5d*?6NjaJOZ5qk7YraZ>|bXhpHWsIy8V)flF zds-NDjIqFjV}!=q6`;<^r-gfRL(9ic3%4E+^`|+Ag1Tiidjd})E5v7u9JRz3zT%EP z9YJipoB6qLvD@kNuqFM9P+*&Vb+!NMhK;`3QY5-vVS$a^kYvo8efoWU+7$oz71#c` zw80O|@_@6GsiPnTWzlgJRtjsv0zq{9qk3c9ZJ!IrkLec=(uqIVC68jc$36QwB3x^A z0|+(=Bq~iLKHa@8S|0Y+_iNc}aR+Yk@-Uq0VXm`qbTtE|v$Jqx{8_j$seHsOi|+j8 z;mqpm)GGlfufsG@EUYhP+_H(uM>M8wAoO$ux~M~hiYkXhbU`sYipCp`qKQy-z~`A$ z>xGeJMW5%ulGQ~A)N!1Qx>cDSNh6gWNgHFv3zJFMa#-pd(%4n+@NT zUUu(4GmNHap@386o`{%ZCKWT)oY;ZgNr};=#wGZs`|6qDq;hypjsZ7-4aP~;nvm|sIT)!TRJWG`VzTWfH#Y}$xS>Z0#ek0lY>snml zR5t|4>=8^U79nPKxH85REoq!`9H}Yv{uGo6Bm0X^keaHfbRzVyTM-T@g{c3wo=9xV z=@tb>5Z?Qh-Ltd%<5}Tg)y`SubtV!B3FD`D{GaRr1HK^kP$%;pP1djB(pMTP$REb1 zyNFXd1=&-}Ls1CyBZ#_FlNuIs_zgD{M;I|=vj;J~b-qi1d7(pF>INZ@hyP9lvXCbb zOh2>`+q4;<#1ipwSlrELhm*L9>fy6F_BM^~6fMB7Y?`@q!m~Ljx#FDgBYsc{q)Ffx z#De~uI66bL*|vc+605-v1>TFBkL2f(q44wdhtkMAsit%xw#lGEPC6Vvn#N=}?&NdB zam|t)6*Z>Yed*kAQm=kaCF%!3M=cwxPC5|x@VThq-LCQT95l9DD(HBd?yDfU&3vCC z;LReRA_~s_K1FDpLwt&OIY&hAy}H6;5D+EQ&@kG3!_-399AOTXM6p6?NXAtQII6d?Aw-emXona9`uKpcJr0OQlzka zr23H4w1D)wZWje3C+e#Wg^s%oE5b$66-z)lS4NlQq?4yRW(+Bz2Issu?u`hWoo=(! zvz%_@^sJq3TcVR`I$Xxifh+`evW&A*1V1fjqDf5Q)}BgoJ{uaZ18VL^=Y?%LwRc{) zRQ2#Mx zD7SDW#1Z?gMIURUTXzui3PVW~rVQCj%FW)e(eC-6o!v*w)QZy`rx6x0EhfeA_aXTd z=Z^168yYxCit~?1BQ^!d0oIf2Y`LtPux#5L0ZpS$ph(t-S;Lk$hb6R1jEIQG#)ufR z1&+bxOex4iq!e0;&O+l@G(QP{Ti{r=;;MJ11OXv*J$4#Ri@7KA${p|p_A(T5NHOuT z_L<>}?GMpl4n!vdz@oSL04#3g#sfHHWB_UZ;ZSM+<*x%LWt+kVpwW_Q+P0dTqoj>s z?#3hF$T#rB1d?7228`uI6*Y*eVWq_P(5PCMR5jiZ6p?^MWJ-1IlWC?;*N&WmS$5>K;1;@YM)u3@(=OZs1M62^IJuipmvqDQL#5z1T5wFE zd(?$*?^NwNy9xbQkUBdtUoN=ln?UHa8Opp6q5)SnFBg0zTacjxW(B7S6s}cvLWiPu6E(wo& zofE@^70}2_Zo(JCY2(35&Ym|SYc^xRxS5&;GaOfJoleU ztam!AEF&JD615OvL(vd;!_js`2zH z39?W#b{Al^pkqNq!rQtF7H@zsuM&3Ksg#6l45HGUv?<6seh3d7_x9(z!J+v1A40>d z$D#ogUszEHI;9pRA4i{NbKwCg5?NbV$KE?c| zi;6l8i6)ObU=%o$yoJic07@oOkT@Hevn%*VWLRe8Mv|sTP0ew=nm7n4ge{y_m1@%F zO9poeYSEP^5mqjx28W`FuH&*WC?XFk;{k@)jid|Qe42s3FHg?i#GQ@?!@5S^q_$VB?at5G{1a^wU zS@E@3vn@ygp4js7+k=vBxGbFc?oJDG$f`zdgoR*2(35SC`)1&4ABb!4W9UPV+>z&d3bcSUuv4-weZN7afhKPDbrdi zs7K%;c*`TGOo{7<%L7W6DnK6p?I@#Yn9vby>h)UnS9ky5>d$xYX5U<%t1vh#!0Op1*O8>tuK1SHf)yy|ti11^4P#!Vgq?<@nLN zU|36xMZ+et0lt$YhZzJW?xKwFrA2G4^fKoi!%;66RK}TiqjP8G4;R?-twtU7r~w5` z>h?)t0qbhag5g43g-s)qGMoZ&NicE;{2-1b2l^vvPF%g|@hT@x2g1*ydF+aCzg@A9 z@6Rum*J90>UnC;*(zB8X^^IVOZ6;aRDzF}W6gy%^gKZl2@!gUu!}k>ZFaO#-d}a8d zqfCBh`$8?YMHQ{Lmb5N{y(Jq{P4Ts;gd0l+H*OL+M9K;5mAF0sS>%wrzUsvW3p#|@ zkOUj5Ton#Xs`nC9YZEIm7a>IOY)%CU)Fnc^mz&+87l(nXUKMVMJaIjrCGx}?$rA-H zPb{hT^28G_yXUS7_dxI1;p(s}+vWDXI(%2N)Ps6(cdR?_4|P30cp!_DCUNobK~GK4 zpKiJVC!(2`Z0#q9NMTzse^$aX#8Q$-%P_^V^cu#1I{)MI_2o zkvj?(Z5ScbLLDda)kmauCcTRX%7mP9Y#n`8d(H8m|EBsd<^Q^&lEE_69RF20^+at#jHqS)Q<+6FiL3kv z?isR@XQ?j@WWx7-NtPsVnUT?cq5$C9*M<#S|Mf1M-Z;{tpw)~tQy@N{4#64et#3_w z3?-IEmqEyDaErbkzPqOvcvD|8`bNI_f?8}Yo#)~ohU52IK}Di+s1r@BE*=tQp}uc% zf<}O1Q{|%jg3cq~WJ0aHG-#V-o7~^njaNT1oifh31q;2wf$(m@#RMi|FyeVEL$ z285%^!|EQBf>*BRd(kG~ZrB*!J8S~)FALs{|7YQSbqa6%p$0s>v3kB0cw1?~`)Utw zefGZ%@7`XM7&k)juL|JAgZe*;;LoK1#}jVQ101ipw*qi0Er37g0j|&fe*m~R!bSjJ zZ8YrvEWm%40{p*DQGWNoMNvA9fLEa?Kp4MjFHb|2N0Z}%=a+AZdWkj?qC|&~Ac_ea zz=#!JuSxSvFzTEEh09BF?~FPzvVTYy#CA%!@to1x7he%`X{uQJ#5orZfu&A&;EgyGl{BJeNPUeS%Lz^PaYcfRN~r{Ze&Ja$C4Dmz zIpiV>BhJUy7$c6?8TT!{C~gcRR890;@Z_|FbTs=WA3x){bbYB}oEPCB{&zv84K52i zUW@Z#YknfynJy6NzdhV{JV7yq`-FIuEFp&Qgg&U3EHT&p^jnz1R=6AP49AW^Nz$YV za>iRLEpFXS;WU^1J`wXQ-9NX2S*8J7<|fUB$0@rr3qdOZhQy<1Yrv?w+tvj=)lujpuIt4;YfAR~+GHDVX0k2Q zi&#lhBj_XfP6McvR1trgDmrJtxRKBFzvM<`i&66=e(X>+5gb`Yns_T})gyO!2~NlR zk&C~njf>)KN3mG*LnE1YrJ1aZTFLut(3C{ht7ZONnN8Z`W?T3#?wVWJ z_csyF-E)f~)S7tbag*W1uX*uKC*N$0U_D}_#`r(7G8)sB@t`oip|qtf4fH~R>vfh! zV=B_3F(8(@mEXpA>=8IhCm&sseZN$wZjNvJyG9HXX#Wl-kB!7iJa?H7c$J3r*5rPW zX_OR(1|URu>)$IpG!^&-26l~-GiAx7C#Bo!P0nnTpC$jqh~;yct}%6WBT>^Xx=Q3m zOvow58R|+dM^_%{G4@`+Oz4KMo1HzHq{fnOWD~v(@`IhU=}G%rS{vyi2H(9V5D9s6 z(jU<448!~sQ*DA_?vC$A$}~=D!*5_?<@66F24w`AvAjw>75!2Rz}b z{|ZmIsu9e73p}AOMJMruM9FN;ZZc9^^rN`nZU2u(`qgx#eMiN8;%-I!hu?tv*?V!n zulkXy;G1&4w=_~}*@(}3D*r#v=U+}o%FS@I{76yQU!Tw0dyVvEKT;KZ(~)k>=ezGB z#MLHL92KHAOdUA5E16K!oi?W8(9r)oR6L(h@!xyd9&eh&T3~9w2j72>ghRorCh0)J zy&VDy{(I>GW{`kdrvg?gz5I6wcxqXY&{rdXRa!6}J(>b~TTMnG(*Gw#ghEQrANL}H zB!uahS>8ZI@N_}urUL!I+*I)9CJ78+6bC3IAWJyBTyjBb{uq&t&B7#EM_9#i6E7X# z^~bhUI)2w1OUL=rO0f?~$J&yRsb3UA)^I=bW+zGo(>1^oUr|P#)&M=9V=Wz z5|wsi?@F6V{9d8Ee)V1HJ6eEpy5`zPHsxRxrBkphyQx3HfIgmgm*M8U^0p^3rBmv- z%Ligz z0vcVJ~$mdU7aiHl zx8;3d_n;qGz+6|NC@3v8K#qbNLZQLTeU#GNn4018*B_sDMT5Lv8xYztFEI%t`STPX z-hTe^cjx^?H)P?hV}0YE&G=8>1r`|cg(fIhLFs(7eWnBqm&qjXxXYtd$?t_8L8@5h z7MgN9TT`%~{4kr#^>IBmFNO5%awqRuk2VhW4po}mJAN8|kX@bpuniB z2ctIP#PJ-1rFyB=U+X0&s5a^45i@%pC=qv`1)b#<}tDRu&S;EubWG56R~Rn3q!9?)^Z3Gp6tmnYYtD*43<&R{wk zf`xRJjJ)}HE8jHiOn2JySvDtP(_{xol72PorNFWY?PmaagvYmoWgup*qJj7a8Gnz{K)faQGo`H#XgW%Y{~`Z^fz3Jx z`m(^S=cReARSkuhBINXbBc*zE%W9#ZSg;sRKE@GJ^Ubh(sv;J;#!I`mcKp!5Z`L85a*68wyipe)nI%P^ z4=`mM)ZJ+ESdw6spFEnuG1HeLd}WVXNhcXcFiw?Oxq_~Qo26!0JPNIcvw2NMFekN* z$;AFb>VrK}<2Er;^oh+V$`LAhlrM_RFjAB=W}}vMpNgHRKPUOJ1i;9aInW2jH@LeW z2&eB^O#OWP!jSx9>&9*>LUs~N$;iVzv~JL@c{CA!ly@WCF`3?y+wsA0w}m6?0}KbF z6#kL>iyKlT7G)9#G}#6tzlzX||M@q5vXs(Q=I(!x&5#~VKZ2Y(Pn`=SZ_!~kE<`Wz z=b#ev2G`fwIL9)8${5p-fB444W4-{g&;z8s5dUH2-MHn&XMf@DOzBMB1x#0E`5viy z-aEJojT!zML^PY0zqD3AGp)EQZNxt{m zn!fyxUxst#XpxAS21+kx;+bMY!%J}Ek zlZh$Dcwy_qs#Knh+lch#KnlIlUuy8FB%F2;cgKxCAJpg5{pbH5dv60~S5@A9pMAdO z%*>gYoy?p)lguR9=VU@=$bG}wHP%$4L`axr`D zefC}-_qxB=z3x?J`)E2%(9z@Slcr5Qgv#V6dYia+Lrr4WKou9f zY0}Y;oyK$!jVaaVwA0jSdznaXq#hsdk=zk7e5!CDppV zObH8BWOlQKkm|o6xfo^x9C+oMv~30iftKse5MYPDdk_4lEQ7wAN2Z3S6{G{XHhoiD zpd3IajG9rIG&B77SqiOk#D*k8Pnd0Hl6>b3d*ils45qXJ3E0#)O6s}4&|dY8m@@7y zAp_fFNZmrg7Ce|w>oEsyCOsCb@%0||I{G#%s%ZC#s#)Fm$m z5MbyEyhu01gNwT4K}25a5daX8UFh-f$f$Kytu5+(WdtRxiQYdpmcND^kXRYg&_-)r zqEC!t`Y<3k3@F4BYdIohcaXchW??}33RTlG^Y5(IaE|L?(+~t=h5k8XjCe}CJjo3o zmn<}pLb>tEfD?vt0Hnk9a4O(_2o*MMCAZ0nfD578f+dXdg z(=2Yr(;K92bSS++R7VHX8y1tJ{r?tUcc3y{Z)aIk{t8Q%N1iaLiA>6n^E$A#Ep;cb zBQ84hlY96LA4KX3l2<~`6x$1@IBxTw;0VfxbQo?bG_kIaSnRjlK{cyULEY`)>^cCO z8_rH(q|U4@q3D8xiLV4bmxxJ*>_u~3r`&jQA)6H)FSX3mAsZ(t451uTQ z*t|64d|m0G+D!Wbd{o+yS5j&Aa1KC|9Y|Bvsx6F09Jr(gQb$^!1$>f3sy-{|PvSla zHRF6aSr?>5!ye;(z;;eYStS8J$?7HN1y8Pk0TUIOG;1Ym)gmF6(^rCN z?okOoj_yTgGZBdL#~zVtJtXCOS#C*Day}9JT5*+g=pd(gI=^WiHr0&Z`dG%Y9TzW7lb7~+YW(D;^Z?HT-YX# zj0P{myFEo3`T3ydw)n({SQ`Fh{Q8F~7uKKpFp;dbeKAB0jBg(tbu}`2(h<4s z^I_L06r4}9j(BUJclVCyl`r`S-8O8&698Mq66fRevo`k`{Fb+*#PXg)pF8{2{FG=1 z7ys9U(uPz9Nm{?-r3Wk1+WVO?mr$xdUU`u7n7W5EnPrb2xa~9VxbNm|M>21>2-27E z?6Ljc+t*$yd@V*th^}S{8-DRFoyP!_Yn%=tTaP~_dl+V%*Kw!Zj+&pArhCm$-)OX3 zTTX0x*vDeiQ$uBTtPoeU%ULIz6f8^F42E=rTj~{%oDZ*0UJy@HeMj{L2d%4B@`0$A zq3lw5fGJr5iaz^{htwRu^WjRj(x;t;uh6Rszm5H{eF>=|%8?J>0_|x^JYDrLKb&)^ zJIgr>{{#-c{`5Ftz+V^gLV*3mCR&NCED|W{kgL`p{__K$`s)Yx9Qg9T3gUI#G@6E| ze)55*-*)Q{|MqaE0ePCZAvyFN4!MTW+8#$>wl`c`eKjKy^ShrvFaU-)0g zDUl4^+)^1Kg>6T-m)DYzn_YKc6%Xrc!nRfD(X<4nv5SSNQ16Lq(iU*^vzBv0d|J*z z=GpZuP4S?W!#f-?fNngh;Xwde;0*Oeg^MO?R0^TVH72!y$K9vZGpxac{+SuN1|4e4 zs#P?Jo#cTnAB}k;QMFO!N(8dTka-dPN12`6|9qqWZ2L0YT(dZbSH_LST)jMPp6?oa z!Za&JfsVYu0(tojaM8!_zlT01Zhq^lBXx?+G^MR&FiZE5s;L_`X%oC2_9g2FR<&zx zQMy;oZ7I`R3!5KZ4vOyi=%ZufGqvMhKMy898#`DMo)GQ(=%bVR23c!*jF#~PnrPx~ za1ynP@A7b{nIH6}AKHnQ>38MyskDKlHhJSsz=BZ) zjdar|IYEyE0XdH5WlI_x@iNh!pN#+bCzX-D_e$~LpEA>}hIsIJ`2Wh9R{X`ER2H?F z=#yh^N<7ZnO3+oR$^EX@07=olVuMm!v?n)O)qWJnw^|TiORZnala^ER6*0{MK-3?% zQBsVwO*(+BBC=7CJlP!oT1axEk*;fvws;=?)LWz&4AryyKlPTHlK-Iz+9~O+^raL1 zv(@NboSM#Rg-6FTmATr|b5lyRHp|LiNK>My=6-RDcwAEnCu@{0gra&q)wpQU5uo#{>_F)g;rb=7n_L>{q zEES`6n6Gnb4B|g|w6dW5Bip>+XIlv3yC1C#oq`Uwgw0r(N{hH~w~!0k+6Wi4jv+4C zPlH@+36{O+asH>3^Vv0Du!K6c-au*|%$HV2pw!|D#V7|#umS=Gu;m`M80D_1<^^SD zgzdJ>1(zGHVdh)W-T)g@Bm5p2wWUBNQ%=F0vS>6OV0n^#x1ODNf+K>XYI740LR_aj z+RG|FV__=TJJfAO4*Drw6yKvIJ`!Mix5@v(}anbmsU z^Z{fNv|^*FXf*7-XC}T@9QEIB4l?fjgXTB0*t}Lq7W3E!Dx_ouMz$oR<}y9dN42Jh zTz$Kep0bU{prcGm$PD%Pl8z}Taba#1>n_!9Q7`WFAN;H`z?v1G68mMJ=F)UD)Rv4% zUiB(yoQ#QM)IfiU!@RSxlIO0yTF!u0)CWXreyr<+f@qn~X~ z&Lqim^Kaasot&1Tm()mOzUVM%%s=M>R<9sokEu`UlaA#jImwuxojLdx@2|ZBCHr&e z?GmT!G;=s(-4<_SZk#FqrpGG53^^p=H|!dhOlgx$`4KXON6>A2`(u^YdEN2jkCCFF z9G4&GG9^Co@yh(!CEgBf?^(bSnnB2dI&y%_W}bz;KYv^);srsMXL*EnOvq4R?AvHPf(xR4!)mk-SUTx=U<| zxMC!$x#w!<}W@mm+NZDi0{B~!6E0sQ9MVoG=<8*!S z$;!(5pM-6kK2yZ_CuNir^Z+i!+;1s5F?6S*ak$@HgpYCERD=?^ZY;t(xNaySXt@%# zW1GF#Lr=QDrC4nh;YKgLChB_ySNX*YQSbR?M3K({0nX0T*YHs|Q{5qs=1d-EXm&Oe?Id(TH9%$Yu7@}?(@7qoVR+Yr1O5(hh6qb{; zCw8wYMHtM;Rau{0r)48b>l8-Q2ephaKX#hR(=sokHwr zNS(tVsnH(i1OWr!lyhiRkJ&d&;xShXtSG6a?%r<#_zP82ny3cF$8{Ei4y6Ytw7W$| zwbP7}Tg-m9KIDF-E!N2-Am~^98url^og{HTBc@!iQDdBPM@)3kDUrsK$@|_QG|3&u zw37|npy@#Z*TjB@vX6kA6ZzkHa5(u1=O6J+L0phiCic23r@%KZ{`X2Pu0K;LSpF(_^k0OpzKP(rrmPuYpmNIhojk^Os}S62 zMtNG>Hqr2oM#EcQWW#e`u+17k*hUX$qZ!{WPK;{2URUmK;VOrWGzY1f@xT9jWp=&b zzdxUNi*VfanF*!^=4xvcI$fC6N`(Tj(x>!dsMP`|o6Sd{ML51pWxP{^+@ZCR?Cv~Q zA^{$(PS0>0FL5P=!a`oxY78nYEwg|v!7djig&u4x;uMitD2aM7C`my{>je@NEV@fj z@XJsY`d8=yHYp0fcyNA|ykr?#;#DModYI~m(#z8(`MQiK8(6z*+fQqER0G0vmZ>QWM$v{XHADWxWp|rOGZwG50lP z^w8WT7R9+MIF(Xn%c6HW4>qyUqOT9 zHKVKT>4d9Bq=3InC>g=ly5pEZV#3KgrjMS2q!t zec(CDZ|z(}l!x@Cc{5G5Qrd-BN57sSQPUoERC8(4J_UXN;h)G8lgTX32;2{+H>Bg> zP0&e$KxY9}q95|3*&~WTc;J&g$#;e~*`?4JFMr_Vpr;P`|3x{P+seQs^)v*ruq#YlgW^-?Q+;KASzdf-G% z(ezDx zY|#hO8wkyPf<2C>DH{LAM?X`F})Fx?n!S1q_3nm z0@7cnH=3>~>2xJPY8pvvbm!*yl5Eg-O6nLX>3|>jqM=E|u?J~kiYtJjRv=vLLs>wF zogvWOEYOj35*~uA@^iuOErL9ShvWk$#Y@;qSY;tPSw4b-naw!nqldR{D6_VSCr+4y zpCtaPT+q9kIwcrzj`LwAQWmDXKL*11>)735Z@O@Ky_1V10Md741-op(7{pZS`sxhz z_Gn98+!c2u>5jBI2fL5Md@$nei7(0rr@x*wK;lyH{qBC8Vdv3VXi3TXatuqQ9_^{N z(tx=r^=xo)uFpLiS)2=9Y0=``kSm=f2~~^_=7Sk?VDDn6*iYG|A#5eu%vztq>In)1 zDDsHWqgo*ttkV@GEAdx_<$m(w(G&NvxSeB@@It!kk{7Wl0%jKa{Z$rol%Pv|5ceWt z0IFv>8N=3zGP73U?V1|}DYD9=B3miU6DzN9CVC|EyLMZ0w>Z}Hqn5Y%QOg_LSuj02 z65XAxmy+vGYnQf;syE5PtGk8nJ5r1Thk;@+lNnTUBUq|X0f)4)AW0ckD}?;<>x;o6 zu`&6Hk)Lu)C{Dh4+i6a6+}LRUeT!EB2x)?mu6xO@VkqKXf)6@DWeJOZD-EOX*yqEjA-4sNTqi$4`ym1 zleP%NqeMQ0B2xa7x!hDc{4N7VY00pVS)6u$Tbj`fv{_bKWIb z2UC$A?uGqTlnPJ~?;9iYl5+QZq{U4NE?pdYPr?Poi%i91CFF&cTk2$1V%Lp`z)DNR zC9Sk{@_LKgrn9{mC5r|K07yLAM%3PXIiAGWw{SBop`3~S;Va49A$H_I{TqJLL*pXW zuc9pj4GL)|uLHUKsP?vE{Ft}+kJ^xSY&bS79%$-FkA_*Fv?pDVEL@q{I;u z%twkkDK_m@sM=yC;t5==J9V?}@7X1?9xW40b4v#l{^8AEX<%LBAy7)Ib2-F#kxsj3 zT08HRt_#zGPl@=&Hsz$l^~Gu&sc=Qbrms#=Zv13NP{Ftx|5Z>i65%J#NlVs|6sI7e z!^1_4J+Yu|ZPPs+YJR%h$eDMS+UiCNO%rk;$E`~eCjD7d-}r_bM}`#qYVK4%P+HWQ zg4~km8vH!2Rb~E~_|177?6>%H(}TWx*~X=Ms6FvVDWwMz0A;}>i$>uVF4e{6*SNnl z?fZqc(<)C_wBZqN@$>h+sm)iXz@Z0W+7*tF)QJ3Vi)7EzA`EY_0%{&SUYxZ4dsfPX zv@}t}H5NxbK@c2Ete$o*!EqL%+ztpsn>Z$g% znOUs}S2xod6WPrirb@KmG;z!r9x+NNEous5>|TqFvJ+oXF*`x`Tc$U+E6!wm2FbjKAI;^nS1>XybW%PjKR? zdYxr9SVNRP*V>R$g?C8%B0z+~zaL=1ur zMCRdn%KeOW$Cd`g_!@y28uKJ$Afv!$bgNlt+|dM%{43%oU~fH#8_F91xXM8$enSu_ z(JN`TMNOu3IxQ4qGwnuu{GlMwsiWJ2V1}Cj_Pu{K2zpOwi8Y&09rZ4Fmbe|+44y^nFtJCCB;uN1eEF@Jabb1_M&!hmF zq*64AiAgnJbBt=Tt^p}d zxN1T#MxPv^OKF4G48-O*=O#?$z1yiQ5fYri*Tg0iJzT?W@305^09y_aQz-KqT4DnI zO0)+_h3VjubW6gAm7(kk3_M=1gq7j!Rg2%0yWSO7EY4jWR>4C;m+)-a|3761N zN4R8yfmh@c@PFB&-dtvrvRE_H;BOV_KK^?9-HCvU_`SjZhp2D(`GVkw#Kwk9@1%A| z3d7A`pEHpTffrU|OK`c$foLVZ7w&d?wrog=0p=1=aJQf5sfbBV>*nbJ@9f4)#~*JS zedo)*KW2BF!f0~IfnXhZP^~QvXJQ2Esl`pP5c$iNmA?AXcEFYHa7My$k z!~3Leciz#{zsgAm`wn6vp54GIK7}lsn2-ODr!(20agJ@!s6>0S@@wSUqwnAQjZ73o zTOVXIhT`g@WTQqUx-WaoMh(F4{2M2SC&$ymV0PhF{D=$VC=AG?EO`L{R|CLSMPaaB ztEq6p$Ec99fuxr4_m$-rXED91Rjv-Got?Tq)Q(S>Iy6^>RfY_yF=0_gRGI-hY%?eM zE*o)lnRDt|Um{C@9M9N%GQo)z)#Ta3KJI+zT^7ClJV295T#~0vpU@@Q$=Zn|A78a> z{EaRU>ZOTBw#|JR2VFxDP_rwZmjbPv{m|1(&T|4ZfQ zXPwbr#mA4X#;dBm41sbXD&iUxsh;Rv2l%R#eg)i22UALv^EIjjjG%c&-q7M<*WXz$%IX91Z^&KIb3qlj@x!6%WGtKq)i~El#eXDa`9`qi<NN0@b}bs7=Ag4m@ZxZj*{JntiM(g0 zc;VT|_dzdQNGJKzulgCF{?M+;KQ<0CA!L=`H5eQUV3iCu*U7@w*oUBQqYrwM)lp5E*Ph(QE3B zi(IpsXT?t~2+nn%o*rMjAn4Vn3xj1`XgG`?TNtdT{Ff&OZ%0DqPhrBa*G>t}4DMlf z54N7E5)?*MF*e#?oD!VGD_h)~`%Zz7$K&87_T5WgVs~RN35Ixh*GqyyF8}nBU{NUK zN8517A7w5OZ6?kp!~gi=t9tu*`OHPZ+#W|MZd0I0E?Nk>UAHJ$?)@bG%A(-x?A9ma z|5y}U(tdD4KZ`FrH8@>57yzL1L`;E|C=}ttd$nh-G=S=}qa(RJ|zqmf%Qz7!u0DiE4UPrO;C~1YF$x6P&*Hv+Tgt zMHhHdzEq9>&0)O8kLZON(UJ7`nny~lmRdIS#K_Gr$D8rfi-XzAzkg_KYcGqD(Q~N^ z9PRvmQtycw1XQ9^XO%bek%I5_$fvCBe+>S9iyE zEeTGWdhh}F`@8lvez)(&k9{7V9#p38LwTT{tp9DKjsIf;8RF|t4~B|+cGKpL_^qc0 zBL!Fd^y$H1&j%jQ__x5xqQkc*rEji`e{_0q(+L$uv6T!n1t|;BCbEP`d)Qhc3WO&) zcv`K;|C{)oX9Q>WwrlcB=&E`ulZ7 z3*5^!WR>t)v|1g;@{F|Gy@alR+L*>OUNtM?9QPEtW54is94>rsyyncHn%`Tj<>L>X z8C+aHSX4+dt1~T%RL(_vh;Et5bschZI@d8`W(ZBzadx-xh_(A6TCGZpdXP{1rGy}S z+U0T2MJ)BaQ*teHX6Eg7O}dEgU|j_N*7Ka9Fu(#LH10&h0HO&W%%szhYzMB0`Gf_}>c( z>x91Dt_;Gdxn0~Dlo>)KWTdM?n40f@$zH^KE7oSa`dqJF8*aplbF@4Ajwtu0b33~D z5?Jq4jhntDOxU3!kCNs$Hkx-0XAu=IzM1&3rNOjSzhrm|GC$7~rU$~06&%Q)%{!1k zqbLPHek2db2QL*Fd(})1N$EeJm1yjDND>lF_RoYZdIROYVdMkcaLTn}H0Ai32=%61 zCP|c#<+ccC+5aXo3}rR>ineBkDQXZ29!y|>&2<9E-xpy6mAlk9&hs(2wXPspd1>4)Hjh3p3D3^V=hvJCwi zh$Ey{WKT)mGA_qWrZ#Bk*eN#X>ufDCqR#joFAuKz&1A5_1}5}|qFgy4gUzl3qsVwi z2EZ@c067$YJ2K!XGMI#-Ha4loF(ZSGD$>`ad80yW9x|X|?aKeHnyF=p?N>X;5>P2Akk1AQ7<%0S0fAg*_Jc{|Y>aeV$wV4Y;8u*%a8<)d_|u@FDGx;Q z#!n2O@R}C??S(9CnY!Zlo)ZM%TEdezp#mH;Gvp&^%t;Xtx!HK}+`^cWc8@x~zZG?3 zGWhFYmTN@S|5g<{_*1o_%^h4|L<|_HOkza8X&UNBaU$jcrKxEiB!u8Xs~VimCV+V* zEZTYdNLK}WBXLv}ua0e!G|>xbOD$1=xa6PWx}~0k+0QDELimogqVRIvzJYX(=r;nb z$K~~72qmZdB)Wqb9>?ivDhZ>rNI3sKro-Nx&?1o9i53Cj9AAq-iGWp!4;_T#_=I<; zyq|KSMWDTqwx!q}txb7I*)k%O)`Tr^WO(KC;;rJr2$66FbR;59vw%QP4#?C76>SU@??|dr2HuuX$%>9 z0qgXT6MP}BZA%m|UQBC*fzqrrE&fVE-`kp9su!FxYZ|L)57YIL6#exxN~P(yD3w+Z zN~4K(ln2^n2U5|r3D*?MO1Zf5%7Eiw^#B%aYt|^W7TPPtnzG0LtqP9XoHoR^vB|AI zQdDn$bL+~?cZ`geoZepyPj}k91U1tsr6C-=!^S8G_&>%xqIPCn%k-nzJC;_)i*Enc z2QNg+q6R4-QdpeSr;M6{ZDY0ppYAP6MZ=^U=ApD2E26NNRs$no0^pyGS|n`Lr1YL= zY=!`&4G}HLpfQjlh=#s2lU zQdv32?HL%6=ZhnpJft=}t)ej}Tz7d)7T4WgFCsOsgc4qK&{^1!3#$on@si*I?@0Wr zOM*V{fq3+iV1Az*YiuRdNb__{{(45Xw-|r^5)ikcuQq9`&U6xFWf_@CMgaGA%F(WS zWF<*GOjl;5HS&XLsM1$V?wao7Z^#m2U`V`^<~LY*n0nC5F+}|jm%O7RxX=aI3OHip=)AdNPI;iWj#p-M(nUlTQ zuinBzs}5Au{`_r<96Q3IIC`G?y?!UMV#i$9=P)U_ZcuQ)`AWIj z2notFS!WK}OEa9^hMhd7Jhzm0PzEqo-bER}Sa}a+fK55t2YSl>Se)IVta!3Z7HcWi zip=Srq)0^mzN8pJS4nXQs&vJ=f{<~=@EwkSD2w87c5@bZbKQ~!-fX6V^7IO`iT6TX zp{p{)&vQ5Hvb8x%y<@*@pp%SWFEQur$t#5XxR47U3~>SWgsK(98gB9G6yOc(l4_SO z&TdPJghX#iiga;vQl#e_J*ZH*)LP63xK7RkR_0MQxLl2js`W8wm%MroEn4I~yWY7A zYaP|B94!1l$p5qJ{9$iRH5cvwmwS*!>>p~AL$PQ?u9=N?^8;Io^gAyPiU|kQ>N`fJ#;$>E&yM=Hp?lN?XEzpjHxRJvXtkSO~-+;0DJY!Jo)vM86Dy%z1X6z3OqCn;-;>oA zH&;H=BAp@Yfc`4&FHOo?l5G_IFpH)I;{a!55aiq075Bw^VFnM<09RuM^c@fL)rzpm zlaNAa5x@F1NW^@!pSg#_kEYo305d93!U?j{#5v%bH?&qvkG*qoKS0yfnqVl=t>tBd z_p`ah>Y^me5sINJ9;VpmijPoa!w(BP;2uH8>U14IqseFbwXo=bE_a@9fIZ!^-FzXMf>-9} zsUs)6n2x-de!R)`Bj>;po^bk$>Icj!KR?3^*^Dtm1_1hHGqyXKSpcLN`_AvV8QYP< z!e*>(V#Zu*Sfg1322j7|jLi361U$rJlwrfQf5_T13^L53e}-9mi6Bbc0L*CSLR+on zJFSM=1he*&I;$uoFA#&#m^q8-WDQ(-gq4NIiY!v?Oo|y9x!bvM1dc9_$#qARh2uhr zDU;lejeoP98?YaLu(&ZCY8dJ2XrJOUh>xq>({YL`T=7t@?l=H%9OUt(?(u$#umIz> zT;Om>afwsmA_{|xCT(;HzLNHideb5tMWPjsBGI~BqQM5Ygp5AP;1({<)$dHoLyL2p zl46JwoD|6eu|6pRAC$-xK4VFdMZD{269Dj+4Ws@|hA_K5$Ikb7lh`?CSdS9qvC#<_ zc?gjBiZ>E*@PC>6i(&5GBOZv6B5@$;u;z)hov(G zljH)~EdR@b;Wx_#a8Ggry+Sq>CWcg7N?1(NY$;(z4b)u`<4TGx53#tU*HQw5rD36% z+j{MbsO&}61t_pYuun~Ct9O{zCb+bO9m82RmM?TATw6n~#0K=xmDrR{P@&#qqq-tq zDdmX`0lO8MPHIV#PjFL~v5@!=z3Mc}>&ZHMR-2f}L6@PUY%h=xgoBA%l>P7)7Aa*4 zLT=p0Ti!&nyZ>klJL0`>A_A%-p7KA)>QHuJbut6Zv}F^fin45#fR3UJ+dfy6T^q_o z-l{lkuGpQJxoApR{32YjN3s88UxODIE~+30AHY_!B79(LQiKoOnGJ~*<_#F-CI!lv z@*}uq2!{Z{Dsq37xiE?n7o1W=ZR?9o=B2RWofP}rQzbD7U2!|bA=~MsF>K3<|6b)r zu_G%VE$PqS|0Tx#Ic z7jRF5X8HgGh6?a7EXOg*W+KNhdQmu=3cJdD2vPt0MD{Vv1&Xp);{IH!Lgw7Oq=!?dd zEQnQsW*J+5XZ_OzbAls@w5npSR0JkIC;BLf9Zh1T3(@CuqesV{b|+EIEVbpCwOPT93X0FP^DS93e@5C1TjKD|KBe~v9G zX*Yw;CCpefHKDmr$5Y-MgtPfw{mtb7mrTZKvoi_>FAmDOXIL{C?`3Ze&h$PUuYYqe z?VKN`y~`>Px~Na4yHC3Lq?LGF7s-usf|B2@wpCAUR-R0R6}C-=NWhroKnmH$zGIRV3AHXE0tZfLO|y?L0H7J(s8lSPxUlVtKI^Gw-S_PN zQABnZ5t6lP^lLYU>44Y<(M2Cz4OR`&-0|nG3W6n#m~XumWvbS=1^qGS@I!MUD|(x9 zd)TjDk+z;aCeL0K%)Fq?{QZ4d+mgu=Biy1#4?Yf{gMaJZI<9r6IHoeIM5>eX>nC* zV*phuF{-Pw#Wo>iv`$=doEO;;zkD<}p`IZ1wG%kk8+Io2m>_M_Z#^Kgv$hf>ZTf8r zPJQ=V31_;0BZLI9+KDfH6T3130j7m4f^Lb#apY(=QDGz%Y-{AuXZV_ zoraNIioS4HeA235O-M{TtHv&-eXqhIuXZu*M27x=eHG8f-&hsAoM71E>Y!H8GS`lH z{_0>TiFc$px46Z{K2o0EeMW}FAgEHgh5=^;iW4v^)SE+B<_;ki!ms1YLnwAaQ zBRvtxmHfYFqlfZxBv07MHGnKw&J*fnYmcmmC0zF1w3BXK?H;V=vdbP^MQNLrR?v+$ z<)l&Seiau{TB#C;Ia9oXM;lN#K}|{=mGN9wnLRdPkVs`{i#A~daG1StoI4uB&ak8= zoAiJrS{NRZ&{n*Y;(4yPi6R}<3mYh^v!K)$+tvG_Y#4cUEvfOl_SfP^!8n1?M)^Z` z{3k8N%0ShUiuOS^jtW{u1pLAvHq79c4(Bu@T@P z=Sq0QMhbf27PeoxfoaM%B~Nen!0#MxKrBUjjjfcliKm^JjWVy$H+SlWhdA18x~)S% z8@H2#D^$ud7vN=w6pT*Wbo|%x+di)jll6bB?*PH=%;#P!57QenS_L}x_Ll+O(wYf*b>C#pl0q8 zrq>5vQCl~1hRTqn!tu_!wy3aCl<+VA{C?6)*E&>O6?XL3I#}_6Pi4-tV;Q+cR^rU; z5S5Tu0Tl>ie-&zgA{Np%8%W_~79>te`}lFo}Tx=Tf>tja0V`qpkFpJ?7zGR@mcOKbCRQiSdW zQ@-cneQ}=sP(Ft~H~=A*ngY~=M8ZFuXAZ16l2=P>U@o|nZQtuSELbaBtlq1`ja_0o zsIdvgLlZErr%c&^d>{cbD4PITN#mk@O+eNILMC}4Am)j{ORZ5bexK5$ zp;@ld2dk>DDO!c#b9*=~?1WV5ggysKt`q$hQQ?}xPeRL`;WQ4@rONuBhSO*VN)M-9 z!r~kI&un{RSA6PQgO~T%DdDB$ye>tgXTlC`E;S!*vd?ZB(^#9P)&UAzWFZ=sxhHg( zAqc6XQ$H>g;!y(99Oq%M9_PpzWx#;2^%GBrb3^`9F!*yiI^*{1g6VaAuxM0KH*BI6 ze9xhe4w~vK1106DV69ug;)HU4 zE4UP{#iFuFoX$fOo=u-&>A!p>3Vn|L~VY8+uFYtb#? zyk+&bFB`k@ZEM%9-?VeAev?Tmqd{T1Mzhs}DUz-?F;d88+7fL=?`ZYkDSaPwNe?aq zYsY1H;Z6bG#Nq45LGd0+!`T6?cUXx;QR2{b9uh5*(F8~@Wf?#^J-ZHNc@`la=Cw85 zdBH|b6q*99s@k=Qmjh7{4Onv95}0kcTavnfoyp|oqk-h~p}dmfA<5~t`hs*Oxg8Rg zFE-LRii#fJ&SNG*MP#{kiE21#TisJyXXeE9L%ln?D@JKkRi(X8$vkBeWmtPKk4dP{ zcI%>aG&W}HU?fmg5ZWY*oD)Q90cg*W>i)lI`oROR2o;55Jmt^WLDw43`?KK00o)4? z?MPuLezlDaLLu{oO*s%>^JhVKyuoTG+5RK(l@j9-SOf#C)<~7~DO4N$SKwt#O3Jh=jTnDM%ULDcza2(FU5sz;V zN2q`t&+~4o;ngc~bRjljC7k!?>}I$wx|FcAuBZoICsu^TN#1u#{y(F>=zv3ZxrS2! zvRIFfEYuB0^#UwAB!g3pK_VeRfun>~g?_-lr*yAI+v1OQC{Gx=X$j4*V;qUeLb}8B zXiId@_q7>v9;zpH06HYE?o`=YtqX@wI%~NkZK?~<>nSU_2)P-Sz_3F`LWb8m@KeyK z8S*X)DR{xT4M`AmUWcfu$5mxJ?!4+O77s189FEBxzfpcnPz|GpReU!CWadux2176}3O0H^Xqi0{$}OkH<8GfdLD;?r<5Tb%mBN`0TPv z@TQGznunJFv!?}ndo=n_C9X6XqT`8hMGzt>uE%vx)=5EgbeZ^*0S5PTQVvcP-}c&K zPkn^fS>s}#p-ISDlEAyNRkTOetFzSsX-@W!2=8-X`%~PBZMj;fD47FkB`^I6sy;)9+fH8guGFvy(SLaNh_d~4vR%o1Dc)A z@Bya>gugI+30P(x|C#)61FJay{Z2H|DC_^NpxEl2={+N1Fg<=#9UgD$&?8E2&iJ=_ zLMg-Quw{Pcs~$+ib%$3CAZK3K=IJ0N^x&{nNd~y!FR;@q&=N+_e3qWqVMk=}3*t2^ zG159ts>(%ya zS2T4EcHDU88oiinym+mqrB^s<8EZ#$fVajir3SewOA# zVS5(TPKLp?CE9`RzyWO<8&w}vtnX3~4pWTxO~oU+G?cdrh}jtg3tfpNry*Bj!6|el z7M@vtlV+;(-y{{eC?^V+5@3;O!XM1T*qjicBJAF;Tb4XZJs_{Vt8lNXG&x2NqJhSp z1flVAa>i4U$z%>>x0ql=_7T0KDc1%WcWhL8XjGEv`)i+jB4fuCDI3dIxEadWsZm-+ zi0VZhg;Ro^>dbYO=q7WaQn~RAPb%l3|^O1k20|ZAdFBF6lSjVB`wP_ z3E)am3kM3Rex^aBz=diE=~+c9-AvC4URK~)tzg|O#oxb)+}o{krMB`!5I^*(C)@`0 z&{y<=WD)?$%MN8o%o0Rl&B~(6E%4qL+LnIey7*eN$>Dr1+wlVL3dTt8TE%;Zg?@9t zqyTKKxoS)BEg_c=h;L>*)E(xBa4DKoS zN=7&-;jDB(^iMjUF6xIK0eFk9w+cq%{M&0Jjj`#qrJ$WAf+xbH04Cnjk%Aav$;XYDi2oyDN9%Y zpjLEgA==MWXqBiC{XX&q<`!+WCudRO!4fWa+k-`vY^kcCt#CuA>rgqqfzXx8TG~)V zgfP+R_{dcRt#kjN`p1{Pn~ichxRc=J&nS$+Wvanxhr81{G>&$W^ysjPbl{M#u1oSk z=@I1Cl5|SGC-q9cCw0p-8P_j!KT))f?c{gsS(`1*P{y6{Y&IF zy5%yEP%X#;GoAPscE#u49L&I(gSzQ|tW7LPe!B81k);omu_8^CiPzm6%zV`>d1Y7v z09z>#D6J&~Qf+~Z?4bG}YqLe=mO|;D#dTF}mT}F5227TV8-k|E!8v48q1w7Bh9H0z z(x5qPbpI*iOWS1q)Bmj=c+7RXXrnhM z01blz1hLgZ6im542r-ze760>ogeQ9YbYsx=4G^37h8E*{-xDmX6G2g~>X_(p_`?+V z!xT-Q)(pRoBxUhq;v-V&uJ$yO~b@PrbjmM%106US-f1UA4T75TNV>Vu&a1|U(y zf!qPtJCVTbL2Kyyc&D9Aoq{VLnd-|UV~Zd1v(<7@@!XC&@DR#f&PO>GCnQitc!bbf z$px9Wf(xSY3NBN0)(Z<^t~ISr@wQeAxhw?B^oA|0uhx?JRj8o=&JbJb2k0{UC*`yTr>form`IR$*e zMPoRAJ)TUP0I?e*0||PiT6b$uYrSeHZi3VF1~eCbft?gmcA{kjm_(f+i0STWLuj_2 zb4CWIjb&&wq9@GD|1LD7kLhfpiWuFN2{^Ttib=`|T3*Sq>s~Dang!_=M!F=pqyuun zSM8YP#9tvcPT%S0vZgEnu4q=;gVW8=SUhtf`esI}W~dTyIh=76_>0^VR-x8&Fc7yr zx~=L5TRa0x3UzIV;Y$>QBoeCALLi-5iZ|8Ej=@=TI8uyurzvrw0l21k4PBt5={tEkvfEbcP)8ZWWl}@BqIx z0k0EY)4A6SaM*;WZDZ~hiNR2vGo4v1;eTVy8O>-90-lQxqST8lag^eosN#iVK$NB@z=aZQ?G_52?=%-K&QX<%&R@R{%i!Bs3L@hWot?`7o>FFIpf+2Yb5A&1ccJu3 z=Z4MK2J{4?*NS9~{b*r0JO22;dfoN;`e8^};LPfhOcFS7Z%PY?`~>{OiolUvHfKHk zkx)TIyA#MI;WxfVYVsDT8@p~%@lI(Xp+)huggB=+=^kOQLD$(N!O*qN`o=9PFi-1r zozK=|U70B@+0J6^3>Kuo4;P4OYn;}w|2AP0D&uk1IH5q17eCq>C#7VK(@M6+X{9oo zN+e^H!9BT?(z8rj{MBwtJt`sU7%bpSHO$YQVZnq__gxhVQE8%tiruUE2C=~3!`jI zV_2%e_$?Tpu8TfTFOc1a^weiu=LOeA(NnZ6O8kLwZZHFOEGDf3)R!3d?!`6Fjh&kU zGMG>^S<`C>*#$X)r0s5TyWUvcW(7%XO)-+xXVS8SmSvVZst8iJ#9-8v=}i=zr683d zF`|`P#7qS_&15PRplQ*^{%ma`CySgH1dZcIAoT(4469v+;(=^!-W@e9kA~~+FgYoC zR~^*%IH`2ewhVNl8XwD8#Ej{i2y%4NkGg6wYNoU`5mb;*t(gH!+~L5pLC%coCh24; zYh?ZWl1jRnj^!34-LUEHceFcX?o7upB{RdBcEAFtJ~NeWgIcU9g@aAYrt*vszI>w& z4U^FBPo-P`Id$Xf=F(Bs{jO?QIc4!;^q{a`Ri};!iyx3Th0Uc39w3rWUK}{8G=A>H zJ!Yy0OoGVC?ntlZq#K{;H{!{hbiIairFd8DARg(zMK}s=l ziPTcuoWx8jwD<+bm8K&RT6G6U>YKFqXKAIxGJ7{M?^t_QNtu!N0olxheY-=HgOoJ0`D z#@Fcz7hkI@TzpJdxcD;(7eAsaYRs(UTqu}Xmx&I477(CALMfcYA*vtSbnj`96_alRWG zwGY*sqz78x5aI9sH4JLz&1xxFpoZCYy>(4w;i8iM7F9fgHknY7Z^e2F%jzfgU0pWWFX`ouX+UTS0Wl zJ)yb8+T6<`wqhomQ*;~^EA)|C)+4PREOZ^Bbe2Gmf!gR$@t7W+r`^M{%P04Uua+FA zN9~}bmgP-7b_eK%)6Dv@aJv<*GWIj%@B)Lp3b!*Ew%SDEvGI1`eG+d+>G|UAwDrlw z+r@h~21E7tvHiRy8n?3-gt8!)V+n+Q(onRXlQv35B4~Nz51UobPe~^6mB`N$&H&sP zT)Pp>98%t)Lz8d}S2=AoFBznbyAbRZTsY5FoA=$+K%RAiX2lB#nw4KbQL$WBa^Zs; z+~@3-rNGjV3yURYw%QFr6Ft=-q3dE+YtoQv#A3ntY6T&Dx6s&DohWfuf_^V)Jn~+2 zASblMRtL6yW<>&J_A^&UbSYKm>yoL?!z;FQRb=arU4S&YQJxXAU*+6xy2E$NNaevJ zQBP9BzY)$8<#eg{;ry3caUIbWZ_A(Q>G6R&SvZ<%*~@LBCh6y0lW&PbYyOpEYMXD_ zzSeyEEQdEXRfT_{`4%cBtTP;`%SqKCE-eS3bi-Ch9NZ}yR?-$U zJxUQ%56MHG(?EN`?+(ZnuwgrTP5PwaD+LtW34-iEy&KHDHnhF_E5z+64QDS0Ud-u< zk-~-*e;h_ciBjTqD9~b;2_V%EV5j}WQx5q}0!Zzf!PqB&6K_Qp{}=km|a{CD7c8LUp-Nm z5)L0OIDXKn(enju#UP`k%+I`w2pV14sfeRMF0&JKSy@e%aXP}YxFz6-v4f92?xI~+ z4XnsVPrjRzSkb3pwEDBce_W(iX8T$E^_#t+VeFL~h4Jz@5XqES_{viM9A6G;jUInS z^ow`L<97seJ6-k!Q#{zG8!!9}2ei$L|K{Vt+-1~0NNv`(99!%m244@VeMNy1a_}{d z^FHe5pXg`Cqgnh~Jo6L5OT72Rul_`^xU-)MmagKDcBgEQ<4**$W)_|3Wy_eRl7TQF z1!eli$JK#a~z=swT3-W3d<#2rde9$u5%Y1d^hTW9)^frssP zm@7zO13AFz`chCWrND|e-N__5=*&C@I-BwIOa@Q(Q`z|AUm``BOG(E#Kw<;OW_Ot4 z3&Def!ff+Z6F{`k-8AzJq<|d>D}c%g6KJUIb%>Y%pRl&6yz}N=8C!f*MA+MIZpK6Q zCO9Ao59=^u&3MGq-3qxl!8M7bfPQU<>RI@ZF(O>NxmiQDyAjM?f|%2ysC@0TU9og1 zQZb0R4U1+JX*SHmfxd4Z4!hr|7Fhz_;Q5A=rVW)4BxEU^_32ju4XnfFh84)^Rm7q91 zb$cc2wlg;$eL_E#AYX)!CK8#_G|hLr>PkA8-F^+4f8Cb;s$JO*2`mvalu?E<62C4; z0Gy+HdD)Nv(<}PwBqT8RYJ*a^`#+mfK-?3}#$1GNc3zZtT>*p8e_sj)lJ!LYl-|U@ zydww`zJVRl;2R?+{2$9NfWoW^j(`Rtsssp(d)bly_3$SjT=)HLM+itTWgvsqHZ~UD zdRI_MpkQWza6*is3&yYO&Gr_`hiqSi60eOkr7|I^Bjq8ti2uEHhMz`u0 z39Un*=CAW&^*nul@_zJ8<7pgzA~^Zf_qCbWkPY3UxauL%yS1PDGvgnUD^m{bca`$vVhbavrnmkakd662f+=AA%pUyqgFE z4Ml@Z^r-(|s0K`SI5FAEgW*UW&v*1xI@gK_d?LNc#5dg)%t}a|Y$6lWj4t}bR+20* zr-UZ}dyxcmbGJy>wBXG~>UWCNnM76TSO7jHKH6r_=iQ;GDq1vICe2ux*Icg@q4Fha zo1eicDx~{7Hzt{k6)_J`Y5ajN1ic*iB$~w7Wx~aazVd}&+H~+xnW1>94WMYqaGCA! zlcx*u<6j`v?)LcfF9svhz3?V6TTQxG<+!>iF2Yr{ig^y)O%@22X=$iDdL*9fz zZEjY$6?f;!_OV+f`sE8YAt|$_y~y4hnOU?a6TlAQQzBko7;u*|pK@9!{q2aq{ns4$ z_P#j3Em&X-ltjN|i$ZzX9!J}b&p^YYIQp^n$KdglxcjyRy_#glNJFQ?4ZbK9Za~`g z@yw0o3^0XfYHTEd2EyS9g-SU5+|9en6B^YoCUMS&MkVQ)a!wvzE)v=8*(PF{8{Cn} z%sA)Q|0X!Gj(o=Dkhtqvb~#U)ca(UWIJ9uJc4AE94Lmb!WXkf-!iUkkEjY34Vxy|C zN$qt@X%4g}v7JDbm=#Q4qLCYqOc^xm8%!4jZyeg;nPbg-sl^J$EoNbNAg_yDZ05=` zIHtKymO(sQI;y~FF_$slqRhoaE+{2W5~+(!cL@e?OjC{@{adJB`hGJn|8KFy{@}mU z76a-%isfOCXbR#ES)b2+=~(Mi7$BZyhE-yPCMM3(RsP<1<@R9l|2rnmn;S#^Z!mEf z^3Vh~pFHf3e);&rP7$9`8{+Sqq%v^eupxfO-{E3)Dg(Kor-@}Fwk3dVuU=shXf)4h z5N>%1?D$vD}s_ITZY)K2w3E!v+*#9A@?Y!ZasD`ooQ~> zKDBP$?^E}ci7CHynOBulH~q~GfmKxI4;4=tQo=srGmf7=jexL$j?adDc0`1BP|s9A zOCJ}!KrAIorsUmShRcXn%w~p!f|p%a-85x73%Oj*gHqACm;@4xJEaD=s*}u>-00xU zBFa>`&@Ehzgi~3Ml)ht6L-%w*Z%4J-@+5ZWwr{y9!|w~9zH zT}8B_TSc^@TXF2xTAEgswA8>7pjd|6Vl(XG=7u@GSOB(LlnGw495LG7#wpEoUi%^3 zUMj1GZMUSyu}wM3lXHdY6k)pA(4)Ru&dGvRomtIDXlsf5pkp%~5py$`zEwY$7nJ3L zheOS8tW4jq7nn}HaaH;T^UkeuVB82Y%D)b0XMHIjX_3TP7X8>JQgE#Ul!&01=)l!U z_3??<_Ox|U*P4l6<4eCzvP+(gX?sSa&q$uMYV|qk(k+d5T%Qi;t)@;LkgEM+dgVU9 z-K%w5|Lbm0#@ZFq$TXQdeg|axO_rXhauPWe0$p2w68lGFYZYCDwOXQ%6IF-iGE=~Hua0p zab8NSYS*v&uA?hQ8&0~1miz*MK&L#aL0msg4enNhjckz}tSmWB-vPnVWtbA-!Fwk_ z(=_4OW?INgB9GmQeVAmRfizihXSTEu#%rvWCY}P9H|*17FB9c$RH%c|vCEo(uFrCu zIVM@BL-Lc4j=9t_Z*C1th~GJHJ|ZC#|CcOkyvT{{zrQOunSH^wfLLHaoRHD2&{Rc6 zwQ2p3lxt#lWKk0?@PN!~${EY@{R&FZKD*i46fAM4uGoB}=4gx7uHQwGjG83tQnn3C zDXQ{DmAAX+7F)h8dpeIXC;3a74*%&^xtAE3p_MH!x*TnmXRWcu$P1gjbdj+w+AIwP zv6-ekBGFVf+CsKD#3bb4B`J@q}7NvuTzJKpG zGEopc^3P;J{I#~#!B$g^3Fs_E%SonvDb!ALB<*9tnG%U?g#cz|^5$}W%?-t``&KZu zPGUeB&_Z*YvL_5?LOZx3%qHA76Dp~d`S&s*sSoXDm5!I?7ct^0Q|jMp5iwPXu1v_q zuNAcSpHkV5QVTiGe09}x5736BBjl^uF!Ks>Fy^I+B4{%z!%|tn&iMPvHRVi}_k?f> zB@@+NG9{njcmoTp$vDXe(z9PbK6!W0*NvXzq33A1h7J-J5PI=vevPWh+zn8Zw#I4e z3!9db#HO^$h^nosi@>66&9+MM409S*GfLbzc`B{F4g|my)w_@j(Vq&;ct3&ErbR($`i13FQ^jA?*P_NaSQlh4&9f332@HjlGq&xw{XKJ)LWmBcxP9`Q7 z4hH8G-UJpv;Wnn&{uJx45@Q=$d14YCp$wRj+Cc}CMJh;yb(lLa*)*;zjBcm?0=t6RaoM%slnw}`CeG1)k@A$m4#Gd%c zlbuRPDg*$5bfPD@!7@G>OQ(dM`(#s_UT_&pGtpt#IeRu{qKw)8E00;FAS%(;otkCH z@ZuHO-r!0Jx0DpD47VebnwUG(uxH$5vYa`$8Po#0Bm5ft} z=TLpfA5J~_(%d~ki`V`-j9wN+3GMrFeEPS8pL=`a1^*P>({_Xhey}^TC99O;*{28Nt?{|W^Hu{ruy#e=ox##lCcYw3OR=mhf!wrbxGzqk6|jW7OQ@IP#*(&F9H z`*{4d@7V|*{T|CAZUj2&gs?J35bh(P?I+`v`+^U7_s7re3r;)ZBkWR9P+U)qP*h_B zDB9DBcY_ZUqm4>t+$!?3l*cVAG_282^=*NQ<~|V2F1uIhNRf74 z`#|t&zusjHl-)-4`wkv7wixEo9A0FyfJ?3{@{VB8@8~Y8x_5iL}x;fO79@cThEx=z!1o=qo(3z<=8W)wkna$M(>THF7sHXta7;~^D@+w+fTvj`dD{HNk& z{~X*;Kl*;qKodVj6Ap7?&Rd$$p39t>ukrr(LC7fT^hMchl-j}$yw zXyz%3dp4dzyD*pd-3Nn*u4vLp5#5PSs^vi<>_k~e`e=8PPO1l-J(=jF;&p+^f$lw+PTXfh;aqcI<&zQs~eiDp&cg3&&w_x6MwgeOTyQDf>p}>o(q!@zf zkK&iOEB>p03qI}L7@vD6cs>~ zkxaB}V|>lyLFJ+yO>?bXm+g_BsDl|d*NuBGBHI3XK)(AOQuo);6BLgdq*v(t3dr?~ z@%J8YOs*2?&}o)ilgVY;(rnVOk;#)gM|{B2n4{msr#}%~?tL(R-xI-wU1@JT?N#@; z#E(6}i3v}|APa_LKL(|ed(;esyVeM$?D8D#5;Vy3+2fFWz-!TqvxHaBB z9-N(U#|*e9^|;T}VLvh!K|WF_TpDQ#W`wE$7`PoPVK*& z9Y)f{o3$+xzzJ~izNdoP904l&e|UQnI2+49eE2zMb~D2nW9B}_;LMpB`@ZkyL?IHb zD#W)%B~_y2$1_w%YV z*K^(L_ulvWPGpM`ZQnD`3LjIT+~efMf=Nw8;8>FMXE8W&9bU)*C2`Q z_Wa*WP4nSz>Gi8hO*8}r6;(P$C@4}G`4bclSSX3 zOON(=-q%0Axp5&e<_9J+8vfIG)t|X>h9c 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

PseudoScript
Module

cli

data

AddOpts #

public
cli::AddOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDAddOptsurlstringtagstringrevstringbranchstringpathstringnamestring
component

Args #

private
cli::Args

Parses argv with clap-derive into the chosen subcommand and its options, then dispatches to the matching command handler.

Parent

Sequence Sequence — dispatch scroll to zoom · drag to pan
SEQUENCEdispatchPERSONcallerCOMPONENTArgsPseudoscript::CliParses argv withclap-derive into the1dispatch(command: cli::Command)↩ return number
component

CheckCmd #

private
cli::CheckCmd

`pds check` — parse and statically check one file, print each diagnostic as `path:line:col: severity: message`, and exit non-zero on any error-severity -diagnostic. Emits no diagram.

Parent

Outbound

Scenarios

CheckExitCode

`pds check` exits non-zero when any error diagnostic is produced.

  • given a .pds source file
  • when the developer runs `pds check` on it
  • then every diagnostic is printed as path:line:col: severity: message
  • but the command exits non-zero if any diagnostic is error-severity
  • and a well-formed model prints nothing and exits zero
Flow Flow — CheckExitCode scroll to zoom · drag to pan
FEATURECheckExitCodefor CheckCmdGIVENa .pds source fileWHENthe developer runs `pds check` on itTHENevery diagnostic is printed aspath:line:col: severity: messageBUTthe command exits non-zero if anydiagnostic is error-severityANDa well-formed model prints nothing andexits zero
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[found.isErr][else]alt[anyError()][else]alt[text.isErr][else]alt[else isDirectory()]alt[modules.isErr][else]alt[files.isErr][else]alt[loaded.isErr][else]alt[dependencies.isErr][else]alt[modules.isErr][else]alt[config.isErr][else]loop[entries]alt[anyError()][else]alt[project.isErr][else]alt[root.isErr][else]COMPONENTCheckCmdPseudoscript::Cli`pds check` — parseand statically checkCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:CONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTChecksPseudoscript::ModelStatic analysis(LANG.md §2.2, §2.3,CONTAINERSyntaxPseudoscript`crates/pseudoscript-syntax`.The foundation crate:COMPONENTParserPseudoscript::SyntaxRecursive-descentparser for the §10COMPONENTLexerPseudoscript::SyntaxHand-written lexer forLANG.md §2. One passCOMPONENTResolverPseudoscript::ModelResolves a module'sdeclarations into aCOMPONENTVariantCollisionPseudoscript::Model§3.5 / ADR-006 — unionvariant collision. ACOMPONENTFeatureCheckPseudoscript::Model§5.2 / §8.1 — featurechecks. A feature'sCOMPONENTReservedNamesPseudoscript::Model§2.3 / ADR-012 —reserved-wordCOMPONENTTypeRefsPseudoscript::Model§3.3 / §8.1 —type-referenceCOMPONENTWorkspacePseudoscript::ModelThe resolved set ofmodules keyed by FQNCOMPONENTCrossModulePseudoscript::Model§8.2 — cross-modulevisibility resolution…COMPONENTBuilderPseudoscript::ModelProjects the parsed,resolved workspaceCOMPONENTArchitecturePseudoscript::ModelLANG.md §9 —architectural-princip…1findRoot(start: string)2findRoot(start: string)3findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>4ioError↩ Err<cli::IoError>↩ Ok<string>5isDirectory6checkRootless7readSource↩ Err<cli::IoError>8check(text: string)9check(text: string)10parse(text: string)11parse(text: string)12lex(text: string)↩ return syntax::Lexed13parseModule↩ return syntax::Module14diagnostics↩ return syntax::Parsed↩ return syntax::Parsed15analyze16build(ast: syntax::Module)17buildWithPath↩ return model::SymbolTable↩ return model::SymbolTable18run19check(ast: syntax::Module)↩ return syntax::Diagnostic[]20check(ast: syntax::Module, model: model::SymbolTable)↩ return syntax::Diagnostic[]21checkConstantCollisions22check(ast: syntax::Module)↩ return syntax::Diagnostic[]23check(ast: syntax::Module, model: model::SymbolTable)↩ return syntax::Diagnostic[]24checkItems↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]25anyError↩ Err<cli::IoError>↩ Ok<void>26checkWorkspace27load(root: string)28loadManifest↩ Err<cli::IoError>29loadModules30load(root: string)31load(root: string)32findModules↩ Err<project::IoError>33readEach↩ Err<project::IoError>↩ Ok<model::WorkspaceModule[]>↩ return Result<model::WorkspaceModule[], project::IoError>34ioError↩ Err<cli::IoError>↩ Ok<model::WorkspaceModule[]>↩ Err<cli::IoError>35loadDependencies↩ Err<cli::IoError>↩ Ok<cli::Workspace>↩ Err<cli::IoError>36checkWorkspace(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])37checkWorkspace(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])38parseErrors39buildWithExternals(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])40resolveEach41resolveEach42index↩ return model::ModuleEntry[]43runWorkspace44runEach45check(entries: model::ModuleEntry[])↩ return syntax::Diagnostic[]46graphOf(entries: model::ModuleEntry[])47collectModule↩ return model::Graph48check(graph: model::Graph)49checkBackdoor50checkCycles51checkSystemBoundary↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]52anyError↩ Err<cli::IoError>↩ Ok<void>
Sequence Sequence — runAll scroll to zoom · drag to pan
SEQUENCErunAllalt[else roots.isErr]COMPONENTCheckCmdPseudoscript::Cli`pds check` — parseand statically checkCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the project1discoverWorkspaces(root: string)↩ return Result<string[], cli::IoError>2checkEach
data

CheckOpts #

public
cli::CheckOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDCheckOptsfilestringallbool
container

Cli #

public
cli::Cli

`crates/pseudoscript` — the binary crate (`pds`). The composition root and +diagnostic. Emits no diagram.

Parent

Outbound

Scenarios

CheckExitCode

`pds check` exits non-zero when any error diagnostic is produced.

  • given a .pds source file
  • when the developer runs `pds check` on it
  • then every diagnostic is printed as path:line:col: severity: message
  • but the command exits non-zero if any diagnostic is error-severity
  • and a well-formed model prints nothing and exits zero
Flow Flow — CheckExitCode scroll to zoom · drag to pan
FEATURECheckExitCodefor CheckCmdGIVENa .pds source fileWHENthe developer runs `pds check` on itTHENevery diagnostic is printed aspath:line:col: severity: messageBUTthe command exits non-zero if anydiagnostic is error-severityANDa well-formed model prints nothing andexits zero
Sequence Sequence — run scroll to zoom · drag to pan
SEQUENCErunalt[found.isErr][else]alt[anyError()][else]alt[text.isErr][else]alt[else isDirectory()]alt[modules.isErr][else]alt[files.isErr][else]alt[loaded.isErr][else]alt[dependencies.isErr][else]alt[modules.isErr][else]alt[config.isErr][else]alt[anyModuleError()][else]alt[project.isErr][else]alt[root.isErr][else]COMPONENTCheckCmdPseudoscript::Cli`pds check` — parseand statically checkCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the projectCONTAINERProjectPseudoscript`crates/pseudoscript-project`.The disk-facingCOMPONENTLoaderPseudoscript::ProjectResolves and reads aworkspace off disk:CONTAINERModelPseudoscript`crates/pseudoscript-model`.AST to one resolvedCOMPONENTChecksPseudoscript::ModelStatic analysis(LANG.md §2.2, §2.3,CONTAINERSyntaxPseudoscript`crates/pseudoscript-syntax`.The foundation crate:COMPONENTParserPseudoscript::SyntaxRecursive-descentparser for the §10COMPONENTLexerPseudoscript::SyntaxHand-written lexer forLANG.md §2. One passCOMPONENTResolverPseudoscript::ModelResolves a module'sdeclarations into aCOMPONENTVariantCollisionPseudoscript::Model§3.5 / ADR-006 — unionvariant collision. ACOMPONENTFeatureCheckPseudoscript::Model§5.2 / §8.1 — featurechecks. A feature'sCOMPONENTReservedNamesPseudoscript::Model§2.3 / ADR-012 —reserved-wordCOMPONENTTypeRefsPseudoscript::Model§3.3 / §8.1 —type-reference1findRoot(start: string)2findRoot(start: string)3findRoot(start: string)↩ return Result<string, project::IoError>↩ return Result<string, project::IoError>4ioError↩ Err<cli::IoError>↩ Ok<string>5isDirectory6checkRootless7readSource↩ Err<cli::IoError>8check(text: string)9check(text: string)10parse(text: string)11parse(text: string)12lex(text: string)↩ return syntax::Lexed13parseModule↩ return syntax::Module14diagnostics↩ return syntax::Parsed↩ return syntax::Parsed15analyze16build(ast: syntax::Module)17buildWithPath↩ return model::SymbolTable↩ return model::SymbolTable18run19check(ast: syntax::Module)↩ return syntax::Diagnostic[]20check(ast: syntax::Module, model: model::SymbolTable)↩ return syntax::Diagnostic[]21checkConstantCollisions22check(ast: syntax::Module)↩ return syntax::Diagnostic[]23check(ast: syntax::Module, model: model::SymbolTable)↩ return syntax::Diagnostic[]24checkItems↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]↩ return syntax::Diagnostic[]25anyError↩ Err<cli::IoError>↩ Ok<void>26checkWorkspace27load(root: string)28loadManifest↩ Err<cli::IoError>29loadModules30load(root: string)31load(root: string)32findModules↩ Err<project::IoError>33readEach↩ Err<project::IoError>↩ Ok<model::WorkspaceModule[]>↩ return Result<model::WorkspaceModule[], project::IoError>34ioError↩ Err<cli::IoError>↩ Ok<model::WorkspaceModule[]>↩ Err<cli::IoError>35loadDependencies↩ Err<cli::IoError>↩ Ok<cli::Workspace>↩ Err<cli::IoError>36checkWorkspaceModules(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])37checkWorkspaceModules(modules: model::WorkspaceModule[], externals: model::WorkspaceModule[])↩ return model::ModuleDiagnostics[]↩ return model::ModuleDiagnostics[]38reportModules39anyModuleError↩ Err<cli::IoError>↩ Ok<void>
Sequence Sequence — runAll scroll to zoom · drag to pan
SEQUENCErunAllalt[else roots.isErr]COMPONENTCheckCmdPseudoscript::Cli`pds check` — parseand statically checkCOMPONENTLoaderPseudoscript::CliThe CLI loader:resolves the project1discoverWorkspaces(root: string)↩ return Result<string[], cli::IoError>2checkEach
data

CheckOpts #

public
cli::CheckOpts
Entities Entity diagram scroll to zoom · drag to pan
RECORDCheckOptsfilestringallbool
container

Cli #

public
cli::Cli

`crates/pseudoscript` — the binary crate (`pds`). The composition root and only I/O edge; a thin frontend that wires the pure library crates to disk, -HTTP, and a filesystem watcher.

Inbound

Outbound

Scenarios

CompositionRoot

The CLI is the composition root and the only I/O edge.

  • given the library crates that are pure over in-memory modules
  • when the CLI runs any subcommand
  • then all file reading, writing, HTTP serving, and watching happen in the CLI
  • and the pure core receives module text and returns values
  • but I/O and load failures are the only things that fail a command, via the exit code
Flow Flow — CompositionRoot scroll to zoom · drag to pan
FEATURECompositionRootfor CliGIVENthe library crates that are pure overin-memory modulesWHENthe CLI runs any subcommandTHENall file reading, writing, HTTPserving, and watching happen in theCLIANDthe pure core receives module text andreturns valuesBUTI/O and load failures are the onlythings that fail a command, via theexit code
ParseSubcommand

argv is parsed into one subcommand and dispatched.

  • given a command line for one of init, doc, check, eval, fmt, tokens, outline, svg, lsp, lang, skill, add, install, update, remove, list, or upgrade
  • when the CLI starts
  • then clap parses argv into the chosen subcommand and its options
  • and the matching command handler is invoked
  • but an unrecognised command or bad option is rejected with a usage error
Flow Flow — ParseSubcommand scroll to zoom · drag to pan
FEATUREParseSubcommandfor CliGIVENa command line for one of init, doc,check, eval, fmt, tokens, outline,svg, lsp, lang, skill, add, install,update, remove, list, or upgradeWHENthe CLI startsTHENclap parses argv into the chosensubcommand and its optionsANDthe matching command handler isinvokedBUTan unrecognised command or bad optionis rejected with a usage error
Components Component diagram scroll to zoom · drag to pan
PseudoscriptCliCOMPONENTInitCmd`pds init` — bootstrap a workspace: write`pds.toml` and a starter `main.pds`. Refuse…COMPONENTArgsParses argv with clap-derive into the chosensubcommand and its options, then dispatches…COMPONENTLoaderThe CLI loader: resolves the project rootand reads its modules through the `project`…COMPONENTDocCmd`pds doc` — the headline command (ADR-017).Load the workspace, check it per module…COMPONENTCheckCmd`pds check` — parse and statically check onefile, print each diagnostic as…COMPONENTEvalCmd`pds eval` — read a model from stdin andstatically check it, printing each…COMPONENTFmtCmd`pds fmt` — format to canonicalPseudoScript; `--write` overwrites the file…COMPONENTTokensCmd`pds tokens` — print the conformance tokenstream (`KIND@line:col "lexeme"`) to stdout…COMPONENTLspHost`pds lsp` — boot a Tokio runtime and launchthe language server over stdio. Spawned as …COMPONENTReferenceCmd`pds lang` (alias `spec`) and `pds skill` —print the bundled, version-pinned language…COMPONENTOutlineCmd`pds outline` — walk the workspace'smodules, build its graph, and print the…COMPONENTSvgCmd`pds svg` — render a single diagram to aself-contained SVG on stdout. With…COMPONENTDeps`pds add`/`install`/`update`/`remove`/`list`— git workspace dependency management…COMPONENTUpgradeCmd`pds upgrade` — download a release andinstall it over the running binary.COMPONENTHttpServerHTTP host for the generated site(`--serve`/`--watch`): `tiny_http` on…COMPONENTWatcherFilesystem watcher (`--watch`, via`notify`): watches the project root…CONTAINERDoc`crates/pseudoscript-doc`. Turns a resolvedgraph into a Svelte-rendered,…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…CONTAINERProject`crates/pseudoscript-project`. Thedisk-facing loader: resolves the workspace…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…discoverWorkspacesfindRootloadcheckcheckWorkspaceservediscoverWorkspacesfindRootloadwatchprepareDiagnosticsrenderrenderMarkdowncheckWorkspaceModulesgraphcheckformatfindRootloadrunStdiofindRootloadModulesgraphfindRootloadModulesgraphrenderTokensparseparse
data

Command #

public
cli::Command

The subcommand clap parsed from argv, with its resolved options.

Entities Entity diagram scroll to zoom · drag to pan
UNIONCommandInitCmdDocOptsCheckOptsEvalOptsFmtOptsTokensOptsOutlineOptsSvgOptsLspOptsLangOptsSkillOptsAddOptsInstallOptsUpdateOptsRemoveOptsListOptsUpgradeOptsRECORDDocOptspathstringserveboolwatchboolportnumberallboolformatstringRECORDCheckOptsfilestringallboolRECORDFmtOptsfilestringwriteboolRECORDTokensOptsfilestringRECORDOutlineOptspathstringRECORDSvgOptspathstringsymbolstringviewstringtargetstringthemestringRECORDAddOptsurlstringtagstringrevstringbranchstringpathstringnamestringRECORDRemoveOptsnamestringRECORDListOptsrootstringRECORDUpgradeOptsversionstring
component

Deps #

private
cli::Deps

`pds add`/`install`/`update`/`remove`/`list` — git workspace dependency +HTTP, and a filesystem watcher.

Inbound

Outbound

Scenarios

CompositionRoot

The CLI is the composition root and the only I/O edge.

  • given the library crates that are pure over in-memory modules
  • when the CLI runs any subcommand
  • then all file reading, writing, HTTP serving, and watching happen in the CLI
  • and the pure core receives module text and returns values
  • but I/O and load failures are the only things that fail a command, via the exit code
Flow Flow — CompositionRoot scroll to zoom · drag to pan
FEATURECompositionRootfor CliGIVENthe library crates that are pure overin-memory modulesWHENthe CLI runs any subcommandTHENall file reading, writing, HTTPserving, and watching happen in theCLIANDthe pure core receives module text andreturns valuesBUTI/O and load failures are the onlythings that fail a command, via theexit code
ParseSubcommand

argv is parsed into one subcommand and dispatched.

  • given a command line for one of init, doc, check, eval, fmt, tokens, outline, svg, lsp, lang, skill, add, install, update, remove, list, or upgrade
  • when the CLI starts
  • then clap parses argv into the chosen subcommand and its options
  • and the matching command handler is invoked
  • but an unrecognised command or bad option is rejected with a usage error
Flow Flow — ParseSubcommand scroll to zoom · drag to pan
FEATUREParseSubcommandfor CliGIVENa command line for one of init, doc,check, eval, fmt, tokens, outline,svg, lsp, lang, skill, add, install,update, remove, list, or upgradeWHENthe CLI startsTHENclap parses argv into the chosensubcommand and its optionsANDthe matching command handler isinvokedBUTan unrecognised command or bad optionis rejected with a usage error
Components Component diagram scroll to zoom · drag to pan
PseudoscriptCliCOMPONENTInitCmd`pds init` — bootstrap a workspace: write`pds.toml` and a starter `main.pds`. Refuse…COMPONENTArgsParses argv with clap-derive into the chosensubcommand and its options, then dispatches…COMPONENTLoaderThe CLI loader: resolves the project rootand reads its modules through the `project`…COMPONENTDocCmd`pds doc` — the headline command (ADR-017).Load the workspace, check it per module…COMPONENTCheckCmd`pds check` — parse and statically check onefile, print each diagnostic as…COMPONENTEvalCmd`pds eval` — read a model from stdin andstatically check it, printing each…COMPONENTFmtCmd`pds fmt` — format to canonicalPseudoScript; `--write` overwrites the file…COMPONENTTokensCmd`pds tokens` — print the conformance tokenstream (`KIND@line:col "lexeme"`) to stdout…COMPONENTLspHost`pds lsp` — boot a Tokio runtime and launchthe language server over stdio. Spawned as …COMPONENTReferenceCmd`pds lang` (alias `spec`) and `pds skill` —print the bundled, version-pinned language…COMPONENTOutlineCmd`pds outline` — walk the workspace'smodules, build its graph, and print the…COMPONENTSvgCmd`pds svg` — render a single diagram to aself-contained SVG on stdout. With…COMPONENTDeps`pds add`/`install`/`update`/`remove`/`list`— git workspace dependency management…COMPONENTUpgradeCmd`pds upgrade` — download a release andinstall it over the running binary.COMPONENTHttpServerHTTP host for the generated site(`--serve`/`--watch`): `tiny_http` on…COMPONENTWatcherFilesystem watcher (`--watch`, via`notify`): watches the project root…CONTAINERDoc`crates/pseudoscript-doc`. Turns a resolvedgraph into a Svelte-rendered,…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…CONTAINERProject`crates/pseudoscript-project`. Thedisk-facing loader: resolves the workspace…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…discoverWorkspacesfindRootloadcheckcheckWorkspaceModulesservediscoverWorkspacesfindRootloadwatchprepareDiagnosticsrenderrenderMarkdowncheckWorkspaceModulesgraphcheckformatfindRootloadrunStdiofindRootloadModulesgraphfindRootloadModulesgraphrenderTokensparseparse
data

Command #

public
cli::Command

The subcommand clap parsed from argv, with its resolved options.

Entities Entity diagram scroll to zoom · drag to pan
UNIONCommandInitCmdDocOptsCheckOptsEvalOptsFmtOptsTokensOptsOutlineOptsSvgOptsLspOptsLangOptsSkillOptsAddOptsInstallOptsUpdateOptsRemoveOptsListOptsUpgradeOptsRECORDDocOptspathstringserveboolwatchboolportnumberallboolformatstringRECORDCheckOptsfilestringallboolRECORDFmtOptsfilestringwriteboolRECORDTokensOptsfilestringRECORDOutlineOptspathstringRECORDSvgOptspathstringsymbolstringviewstringtargetstringthemestringRECORDAddOptsurlstringtagstringrevstringbranchstringpathstringnamestringRECORDRemoveOptsnamestringRECORDListOptsrootstringRECORDUpgradeOptsversionstring
component

Deps #

private
cli::Deps

`pds add`/`install`/`update`/`remove`/`list` — git workspace dependency management (§8.3). `add` resolves a git URL into `pds.toml` + `pds.lock` and vendors it; `install` restores `pds_modules/` from the lock; `update` re-pins; `remove` drops one; `list` discovers every workspace under a root. diff --git a/model/site/module/context.html b/model/site/module/context.html index ed52982a..1cea4af1 100644 --- a/model/site/module/context.html +++ b/model/site/module/context.html @@ -16,7 +16,7 @@ document changes to the server and renders the diagnostics it publishes.

Inbound

Outbound

Containers Container diagram scroll to zoom · drag to pan
PERSONDeveloperAuthor of architecture models: edits `.pds`files in an IDE and runs the CLI.SYSTEMPseudoscriptThe PseudoScript CLI — loads a `.pds`workspace into one resolved graph and…renderDocs
system

Pseudoscript #

public
context::Pseudoscript

The PseudoScript CLI — loads a `.pds` workspace into one resolved graph and documents it as a static site, or serves the language to editors. Cross-system callers couple to these published faces; the containers stay behind them.

#headline

Inbound

Outbound

Scenarios

DocumentAWorkspace

Render a `.pds` workspace to a browsable documentation site — the headline -flow, aggregating load, check, graph, project, and write.

#headline
  • given a directory holding a pds.toml and one or more .pds modules
  • and the modules form a well-formed C4 model
  • when the developer runs `pds doc` against the directory
  • then every module is loaded into one resolved graph
  • and C4 and sequence diagrams are projected as scene geometry the site's client islands draw
  • and a static site is written under the configured output directory
Flow Flow — DocumentAWorkspace scroll to zoom · drag to pan
FEATUREDocumentAWorkspacefor PseudoscriptGIVENa directory holding a pds.toml and oneor more .pds modulesANDthe modules form a well-formed C4modelWHENthe developer runs `pds doc` againstthe directoryTHENevery module is loaded into oneresolved graphANDC4 and sequence diagrams are projectedas scene geometry the site's clientislands drawANDa static site is written under theconfigured output directory
CheckAModel

Statically validate a model and report what is wrong.

  • given a .pds source file
  • when the developer runs `pds check` on it
  • then the source is parsed with error recovery
  • and resolution, visibility, Result-flow, and return-coverage checks run
  • and every violation is reported as a diagnostic
  • but a well-formed model reports nothing and exits zero
Flow Flow — CheckAModel scroll to zoom · drag to pan
FEATURECheckAModelfor PseudoscriptGIVENa .pds source fileWHENthe developer runs `pds check` on itTHENthe source is parsed with errorrecoveryANDresolution, visibility, Result-flow,and return-coverage checks runANDevery violation is reported as adiagnosticBUTa well-formed model reports nothingand exits zero
FormatAModel

Reformat a model to one canonical form.

  • given a .pds source file with non-canonical spacing
  • when the developer runs `pds fmt`
  • then the source is parsed and pretty-printed to canonical PseudoScript
  • and comments and blank-line runs are preserved
  • but unparseable source is rejected without rewriting the file
Flow Flow — FormatAModel scroll to zoom · drag to pan
FEATUREFormatAModelfor PseudoscriptGIVENa .pds source file with non-canonicalspacingWHENthe developer runs `pds fmt`THENthe source is parsed andpretty-printed to canonicalPseudoScriptANDcomments and blank-line runs arepreservedBUTunparseable source is rejected withoutrewriting the file
EditModelInIde

Author a model in an editor with live diagnostics.

  • given an editor that speaks the Language Server Protocol
  • and `pds lsp` running as a child process over stdio
  • when the author changes a document
  • then the server re-checks the document from its current text
  • and diagnostics are published back to the editor
Flow Flow — EditModelInIde scroll to zoom · drag to pan
FEATUREEditModelInIdefor PseudoscriptGIVENan editor that speaks the LanguageServer ProtocolAND`pds lsp` running as a child processover stdioWHENthe author changes a documentTHENthe server re-checks the document fromits current textANDdiagnostics are published back to theeditor
ServeLiveDocs

Preview docs that rebuild as the model changes.

  • given a generated documentation site
  • when the developer runs `pds doc --serve --watch`
  • then the site is hosted over HTTP on localhost
  • and a change to any .pds or pds.toml rebuilds the site
  • and the browser live-reloads to the new version
Flow Flow — ServeLiveDocs scroll to zoom · drag to pan
FEATUREServeLiveDocsfor PseudoscriptGIVENa generated documentation siteWHENthe developer runs `pds doc --serve--watch`THENthe site is hosted over HTTP onlocalhostANDa change to any .pds or pds.tomlrebuilds the siteANDthe browser live-reloads to the newversion
Containers Container diagram scroll to zoom · drag to pan
PseudoscriptCONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERDoc`crates/pseudoscript-doc`. Turns a resolvedgraph into a Svelte-rendered,…CONTAINERDot`crates/pseudoscript-dot`. Runs thefour-pass layered pipeline over a `Graph` t…CONTAINEREmit`crates/pseudoscript-emit`. Projects a viewinto a `Scene` and renders it to SVG; C4…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERIdeSession`crates/pseudoscript-ide` — the IDEapplication, Rust compiled to a single wasm…CONTAINERWebIde`web-ide` — the IDE at `ide.pdscript.dev`: aSvelteKit shell on Cloudflare Workers stati…CONTAINERLanding`web-landing` — the marketing site at`pdscript.dev`. A static Svelte build on…CONTAINERLayout`crates/pseudoscript-layout`. Thegeometry/text `Core` and the sequence…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERLspCore`crates/pseudoscript-lsp-core`. The singlehome for language intelligence as…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…CONTAINERProject`crates/pseudoscript-project`. Thedisk-facing loader: resolves the workspace…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…CONTAINERUniverse`crates/pseudoscript-universe`. Maps theresolved C4 model into the software graph…PERSONDeveloperAuthor of architecture models: edits `.pds`files in an IDE and runs the CLI.SYSTEMEditorIDEs that speak the Language Server Protocol(VS Code, Neovim, …). The editor spawns `pd…SYSTEMLlmProviderThe author's configured OpenAI-compatiblecompletion provider — hosted (OpenAI,…PERSONVisitorA prospective user reading the landing page.prepareDiagnosticsrenderrenderMarkdownformatrunStdiocheckcheckWorkspacecheckWorkspaceModulesgraphfindRootloadrenderTokensopenDocumentprojectflowsfromModelsnapshotgridLayoutrunPipelinelayoutparseprepareDiagnosticscheckcheckWorkspaceModulesgraphbuildflowssnapshotcompletedependencyModulesdiagnosticshovermountoutlinesetSourcechatCompletefimCompletelistModelsopenopenIdeshowInstalldefinitionformatEdithovercheckparseprojectgraph
Generated by pds doc.
+flow, aggregating load, check, graph, project, and write.

#headline
  • given a directory holding a pds.toml and one or more .pds modules
  • and the modules form a well-formed C4 model
  • when the developer runs `pds doc` against the directory
  • then every module is loaded into one resolved graph
  • and C4 and sequence diagrams are projected as scene geometry the site's client islands draw
  • and a static site is written under the configured output directory
Flow Flow — DocumentAWorkspace scroll to zoom · drag to pan
FEATUREDocumentAWorkspacefor PseudoscriptGIVENa directory holding a pds.toml and oneor more .pds modulesANDthe modules form a well-formed C4modelWHENthe developer runs `pds doc` againstthe directoryTHENevery module is loaded into oneresolved graphANDC4 and sequence diagrams are projectedas scene geometry the site's clientislands drawANDa static site is written under theconfigured output directory

Gr6UOZ?%Rc^aV-lB2VI<*K+`mcyrD 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­Lz`a;i1uMS_c(w&&WCTYFIYaWabSG4 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π57a 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 from self.approves(decision.verdict) + keep = Result from approves(decision.verdict) if (keep.isOk) { risk::Risk.clear(decision.intent) return Ok } refunded = Result from refunds::Refunds.create(merchant.value.id, RefundRequest from { decision.intent, owned.value.amount }) if (refunded.isErr) { - return Err(self.refundRejected(refunded.error)) + return Err(refundRejected(refunded.error)) } risk::Risk.clear(decision.intent) return Ok @@ -68,7 +68,7 @@ component Console for backoffice::Backoffice { } done = Result from refunds::Refunds.create(merchant.value.id, req) if (done.isErr) { - return Err(self.refundRejected(done.error)) + return Err(refundRejected(done.error)) } return Ok(done.value) } diff --git a/web-ide/src/lib/samples/acme-payments/charges.pds b/web-ide/src/lib/samples/acme-payments/charges.pds index ee54d1e8..c75772b5 100644 --- a/web-ide/src/lib/samples/acme-payments/charges.pds +++ b/web-ide/src/lib/samples/acme-payments/charges.pds @@ -104,60 +104,60 @@ component ChargeService for charges::Charges { id = shared::ChargeId from charges::ChargeStore.nextId() charge = Charge from { id, intent, amount, charges::ChargeStatus::Authorizing } charges::ChargeStore.save(charge) - key = IdempotencyKey from self.keyFor(id, "authorize") + key = IdempotencyKey from keyFor(id, "authorize") held = Result from charges::Gateway.authorize(amount, instrument, key) if (held.isErr) { - self.onAuthError(charge, held.error) + onAuthError(charge, held.error) return Err(held.error) } - return Ok(self.recordAuth(charge, held.value)) + return Ok(recordAuth(charge, held.value)) } /// Complete a 3-D Secure challenge on a charge awaiting action, promoting it to /// a usable hold. public completeAction(intent: shared::PaymentIntentId, outcome: context::NetworkChallengeResult): Result { - loaded = Result from self.loadPending(intent) + loaded = Result from loadPending(intent) if (loaded.isErr) { return Err(loaded.error) } - key = IdempotencyKey from self.keyFor(loaded.value.charge, "authorize") + key = IdempotencyKey from keyFor(loaded.value.charge, "authorize") cleared = Result from charges::Gateway.completeAction(loaded.value.auth, outcome, key) if (cleared.isErr) { - self.onAuthError(self.chargeOf(loaded.value), cleared.error) + onAuthError(chargeOf(loaded.value), cleared.error) return Err(cleared.error) } - return Ok(self.markHeld(loaded.value.charge, cleared.value)) + return Ok(markHeld(loaded.value.charge, cleared.value)) } /// Capture (settle) an authorised charge. Idempotent: a second capture returns /// the existing receipt without calling the network again. public capture(intent: shared::PaymentIntentId): Result { - done = Option from self.receiptFor(intent) + done = Option from receiptFor(intent) if (done.isSome) { return Ok(done.value) } - loaded = Result from self.loadAuthorized(intent) + loaded = Result from loadAuthorized(intent) if (loaded.isErr) { return Err(loaded.error) } - key = IdempotencyKey from self.keyFor(loaded.value.charge, "capture") + key = IdempotencyKey from keyFor(loaded.value.charge, "capture") taken = Result from charges::Gateway.capture(loaded.value.auth, loaded.value.amount, key) if (taken.isErr) { - self.onCaptureError(self.chargeOfAuthorized(loaded.value), taken.error) + onCaptureError(chargeOfAuthorized(loaded.value), taken.error) return Err(taken.error) } - captured = Charge from self.markCaptured(loaded.value.charge, taken.value) + captured = Charge from markCaptured(loaded.value.charge, taken.value) charges::ChargeStore.save(captured) return Ok(Receipt from { captured.id, taken.value.ref }) } /// Void an authorised-but-uncaptured hold, releasing the cardholder's funds. public release(intent: shared::PaymentIntentId): void { - loaded = Result from self.loadAuthorized(intent) + loaded = Result from loadAuthorized(intent) if (loaded.isOk) { - key = IdempotencyKey from self.keyFor(loaded.value.charge, "void") + key = IdempotencyKey from keyFor(loaded.value.charge, "void") charges::Gateway.cancelAuth(loaded.value.auth, key) - charges::ChargeStore.save(self.markVoided(loaded.value.charge)) + charges::ChargeStore.save(markVoided(loaded.value.charge)) } } @@ -165,16 +165,16 @@ component ChargeService for charges::Charges { /// caller (`refunds`) only after the network acknowledges; a failed refund is /// surfaced, never swallowed. public refund(intent: shared::PaymentIntentId, amount: shared::Money): Result { - loaded = Result from self.loadCaptured(intent) + loaded = Result from loadCaptured(intent) if (loaded.isErr) { return Err(loaded.error) } - key = IdempotencyKey from self.keyFor(loaded.value.charge, "refund") + key = IdempotencyKey from keyFor(loaded.value.charge, "refund") back = Result from charges::Gateway.refund(loaded.value.capture, amount, key) if (back.isErr) { return Err(back.error) } - charges::ChargeStore.save(self.markRefunded(loaded.value.charge)) + charges::ChargeStore.save(markRefunded(loaded.value.charge)) return Ok(back.value) } @@ -185,15 +185,15 @@ component ChargeService for charges::Charges { /// still unknown is left for a later sweep, so a captured cardholder is never /// wrongly failed. public reconcileCapture(intent: shared::PaymentIntentId): void { - done = Option from self.receiptFor(intent) + done = Option from receiptFor(intent) if (done.isNone) { truth = Option from charges::Gateway.lookupCapture(intent) if (truth.isSome) { - charges::ChargeStore.save(self.recordCapture(intent, truth.value)) + charges::ChargeStore.save(recordCapture(intent, truth.value)) } else { gone = Result from charges::Gateway.captureDefinitelyMissing(intent) if (gone.isOk) { - charges::ChargeStore.save(self.recordFailed(intent)) + charges::ChargeStore.save(recordFailed(intent)) } } } @@ -211,9 +211,9 @@ component ChargeService for charges::Charges { /// On an authorise failure: a DEFINITE decline marks the charge `Failed`; an /// INDETERMINATE outcome leaves it `Authorizing` for `reconcileCapture`. onAuthError(charge: charges::Charge, e: charges::ChargeError): void { - sure = Result from self.isDefinite(e) + sure = Result from isDefinite(e) if (sure.isOk) { - charges::ChargeStore.save(self.markFailed(charge, e)) + charges::ChargeStore.save(markFailed(charge, e)) } } @@ -221,9 +221,9 @@ component ChargeService for charges::Charges { /// an INDETERMINATE outcome leaves both intact and the charge `Authorized`, /// because the capture may actually have settled. onCaptureError(charge: charges::Charge, e: charges::ChargeError): void { - sure = Result from self.isDefinite(e) + sure = Result from isDefinite(e) if (sure.isOk) { - charges::ChargeStore.save(self.markFailed(charge, e)) + charges::ChargeStore.save(markFailed(charge, e)) } } @@ -268,7 +268,7 @@ public component Gateway for charges::Charges { public authorize(amount: shared::Money, instrument: context::NetworkInstrument, key: charges::IdempotencyKey): Result { held = Result from context::CardNetwork.authorize(amount, instrument, key) if (held.isErr) { - return Err(self.translate(held.error)) + return Err(translate(held.error)) } return Ok(held.value) } @@ -277,7 +277,7 @@ public component Gateway for charges::Charges { public completeAction(auth: context::NetworkAuthRef, outcome: context::NetworkChallengeResult, key: charges::IdempotencyKey): Result { cleared = Result from context::CardNetwork.completeAction(auth, outcome, key) if (cleared.isErr) { - return Err(self.translate(cleared.error)) + return Err(translate(cleared.error)) } return Ok(cleared.value) } @@ -286,7 +286,7 @@ public component Gateway for charges::Charges { public capture(auth: context::NetworkAuthRef, amount: shared::Money, key: charges::IdempotencyKey): Result { taken = Result from context::CardNetwork.capture(auth, amount, key) if (taken.isErr) { - return Err(self.translate(taken.error)) + return Err(translate(taken.error)) } return Ok(taken.value) } @@ -295,7 +295,7 @@ public component Gateway for charges::Charges { public refund(capture: context::NetworkCaptureRef, amount: shared::Money, key: charges::IdempotencyKey): Result { back = Result from context::CardNetwork.refund(capture, amount, key) if (back.isErr) { - return Err(self.translate(back.error)) + return Err(translate(back.error)) } return Ok(back.value) } diff --git a/web-ide/src/lib/samples/acme-payments/disputes.pds b/web-ide/src/lib/samples/acme-payments/disputes.pds index 76a1c2a8..5fdcce1f 100644 --- a/web-ide/src/lib/samples/acme-payments/disputes.pds +++ b/web-ide/src/lib/samples/acme-payments/disputes.pds @@ -72,7 +72,7 @@ component DisputeService for disputes::Disputes { /// acknowledged but holds funds only once. #[http("POST /v1/network/disputes")] public open(event: disputes::DisputeEvent): Result { - verified = Result from self.verify(event) + verified = Result from verify(event) if (verified.isErr) { return Err(verified.error) } @@ -90,11 +90,11 @@ component DisputeService for disputes::Disputes { /// The merchant contests a dispute with evidence: forward it to the network and /// move the dispute to `UnderReview`. public submitEvidence(merchant: shared::MerchantId, req: disputes::EvidenceSubmission): Result { - loaded = Result from self.getFor(merchant, req.dispute) + loaded = Result from getFor(merchant, req.dispute) if (loaded.isErr) { return Err(loaded.error) } - open = Result from self.contestable(loaded.value) + open = Result from contestable(loaded.value) if (open.isErr) { return Err(open.error) } @@ -102,7 +102,7 @@ component DisputeService for disputes::Disputes { if (sent.isErr) { return Err(disputes::DisputeError::NetworkUnreachable) } - reviewing = Dispute from self.mark(loaded.value, disputes::DisputeStatus::UnderReview) + reviewing = Dispute from mark(loaded.value, disputes::DisputeStatus::UnderReview) disputes::DisputeStore.save(reviewing) return Ok(reviewing) } @@ -112,7 +112,7 @@ component DisputeService for disputes::Disputes { /// a replayed ruling settles once. #[http("POST /v1/network/dispute-outcomes")] public resolve(event: disputes::ResolutionEvent): Result { - verified = Result from self.verifyResolution(event) + verified = Result from verifyResolution(event) if (verified.isErr) { return Err(verified.error) } @@ -120,9 +120,9 @@ component DisputeService for disputes::Disputes { if (seen.isOk) { return Ok(Acknowledged from { event.eventId }) } - loaded = Result from self.get(event.dispute) + loaded = Result from get(event.dispute) if (loaded.isOk) { - self.applyRuling(loaded.value, event.ruling) + applyRuling(loaded.value, event.ruling) } disputes::CallbackLog.record(event.eventId) return Ok(Acknowledged from { event.eventId }) @@ -137,11 +137,11 @@ component DisputeService for disputes::Disputes { /// Forfeit a dispute the merchant never answered: mark it `Lost`. The funds /// were already held at open, so no further debit is needed. public forfeit(dispute: shared::DisputeId): void { - loaded = Result from self.get(dispute) + loaded = Result from get(dispute) if (loaded.isOk) { - open = Result from self.contestable(loaded.value) + open = Result from contestable(loaded.value) if (open.isOk) { - disputes::DisputeStore.save(self.mark(loaded.value, disputes::DisputeStatus::Lost)) + disputes::DisputeStore.save(mark(loaded.value, disputes::DisputeStatus::Lost)) } } } @@ -149,23 +149,23 @@ component DisputeService for disputes::Disputes { /// Apply a ruling: a win records `Won` and raises `DisputeWon`; a loss records /// `Lost`. applyRuling(dispute: disputes::Dispute, ruling: disputes::DisputeRuling): void { - won = Result from self.isWin(ruling) + won = Result from isWin(ruling) if (won.isOk) { - disputes::DisputeStore.save(self.mark(dispute, disputes::DisputeStatus::Won)) + disputes::DisputeStore.save(mark(dispute, disputes::DisputeStatus::Won)) disputes::Events.won(DisputeWon from { dispute.id, dispute.merchant, dispute.amount }) } else { - disputes::DisputeStore.save(self.mark(dispute, disputes::DisputeStatus::Lost)) + disputes::DisputeStore.save(mark(dispute, disputes::DisputeStatus::Lost)) } } /// Read a dispute on behalf of `merchant`, refusing one that belongs to /// another merchant. public getFor(merchant: shared::MerchantId, dispute: shared::DisputeId): Result { - loaded = Result from self.get(dispute) + loaded = Result from get(dispute) if (loaded.isErr) { return Err(loaded.error) } - owns = Result from self.ownedBy(loaded.value, merchant) + owns = Result from ownedBy(loaded.value, merchant) if (owns.isErr) { return Err(owns.error) } diff --git a/web-ide/src/lib/samples/acme-payments/gateway.pds b/web-ide/src/lib/samples/acme-payments/gateway.pds index e69fa9cd..aee6706d 100644 --- a/web-ide/src/lib/samples/acme-payments/gateway.pds +++ b/web-ide/src/lib/samples/acme-payments/gateway.pds @@ -115,7 +115,7 @@ component TokenApi for gateway::Gateway { } method = Result from vault::Vault.tokenize(merchant.value.id, card) if (method.isErr) { - return Err(self.rejectTokenize(method.error)) + return Err(rejectTokenize(method.error)) } return Ok(method.value) } @@ -140,10 +140,10 @@ component IntentApi for gateway::Gateway { return Err(guard.error) } if (guard.value.isSome) { - return self.reloadIntent(guard.value.value) + return reloadIntent(guard.value.value) } created = PaymentIntent from intents::Intents.create(merchant.value.id, req) - gateway::Idempotency.record(idem, self.intentId(created)) + gateway::Idempotency.record(idem, intentId(created)) return Ok(created) } @@ -155,7 +155,7 @@ component IntentApi for gateway::Gateway { } done = Result from intents::Intents.confirm(merchant.value.id, req) if (done.isErr) { - return Err(self.rejectIntent(done.error)) + return Err(rejectIntent(done.error)) } return Ok(done.value) } @@ -165,7 +165,7 @@ component IntentApi for gateway::Gateway { public confirmAction(intent: shared::PaymentIntentId, outcome: intents::ChallengeOutcome): Result { done = Result from intents::Intents.confirmAction(intent, outcome) if (done.isErr) { - return Err(self.rejectIntent(done.error)) + return Err(rejectIntent(done.error)) } return Ok(done.value) } @@ -178,7 +178,7 @@ component IntentApi for gateway::Gateway { } done = Result from intents::Intents.capture(merchant.value.id, intent) if (done.isErr) { - return Err(self.rejectIntent(done.error)) + return Err(rejectIntent(done.error)) } return Ok(done.value) } @@ -192,7 +192,7 @@ component IntentApi for gateway::Gateway { } done = Result from intents::Intents.cancel(merchant.value.id, intent) if (done.isErr) { - return Err(self.rejectIntent(done.error)) + return Err(rejectIntent(done.error)) } return Ok(done.value) } @@ -219,13 +219,13 @@ component RefundApi for gateway::Gateway { return Err(guard.error) } if (guard.value.isSome) { - return self.reloadRefund(guard.value.value) + return reloadRefund(guard.value.value) } done = Result from refunds::Refunds.create(merchant.value.id, req) if (done.isErr) { - return Err(self.rejectRefund(done.error)) + return Err(rejectRefund(done.error)) } - gateway::Idempotency.record(idem, self.refundId(done.value)) + gateway::Idempotency.record(idem, refundId(done.value)) return Ok(done.value) } @@ -247,7 +247,7 @@ component DisputeApi for gateway::Gateway { } done = Result from disputes::Disputes.submitEvidence(merchant.value.id, req) if (done.isErr) { - return Err(self.rejectDispute(done.error)) + return Err(rejectDispute(done.error)) } return Ok(done.value) } diff --git a/web-ide/src/lib/samples/acme-payments/identity.pds b/web-ide/src/lib/samples/acme-payments/identity.pds index 022113fe..8d6b0d87 100644 --- a/web-ide/src/lib/samples/acme-payments/identity.pds +++ b/web-ide/src/lib/samples/acme-payments/identity.pds @@ -86,7 +86,7 @@ component Keys for identity::Identity { if (merchant.isNone) { return Err(identity::ApiKeyError::InvalidKey) } - granted = Result from self.permits(key, need) + granted = Result from permits(key, need) if (granted.isErr) { return Err(identity::ApiKeyError::InsufficientScope) } diff --git a/web-ide/src/lib/samples/acme-payments/intents.pds b/web-ide/src/lib/samples/acme-payments/intents.pds index cbca7c31..e0eac4be 100644 --- a/web-ide/src/lib/samples/acme-payments/intents.pds +++ b/web-ide/src/lib/samples/acme-payments/intents.pds @@ -121,11 +121,11 @@ component PaymentIntents for intents::Intents { /// Secure requirement parks the intent in `RequiresAction` for the cardholder. /// #headline public confirm(merchant: shared::MerchantId, req: intents::ConfirmIntent): Result { - intent = Result from self.getFor(merchant, req.intent) + intent = Result from getFor(merchant, req.intent) if (intent.isErr) { return Err(intent.error) } - ready = Result from self.confirmable(intent.value) + ready = Result from confirmable(intent.value) if (ready.isErr) { return Err(ready.error) } @@ -137,59 +137,59 @@ component PaymentIntents for intents::Intents { outcome = RiskOutcome from risk::Risk.screen(input) blocked = Result from risk::Risk.isBlocked(outcome) if (blocked.isOk) { - return Err(self.reject(intent.value, outcome)) + return Err(reject(intent.value, outcome)) } review = Result from risk::Risk.isReview(outcome) if (review.isOk) { risk::Risk.flag(req.intent, "elevated risk") } - return self.proceed(intent.value, instrument.value) + return proceed(intent.value, instrument.value) } /// Complete a 3-D Secure challenge on an intent awaiting action, then resume /// the authorise-and-capture flow. Called by the cardholder, not the merchant. public confirmAction(intent: shared::PaymentIntentId, outcome: intents::ChallengeOutcome): Result { - loaded = Result from self.get(intent) + loaded = Result from get(intent) if (loaded.isErr) { return Err(loaded.error) } - pending = Result from self.inAction(loaded.value) + pending = Result from inAction(loaded.value) if (pending.isErr) { return Err(pending.error) } - cleared = Result from charges::Charges.completeAction(intent, self.challengeResult(outcome)) + cleared = Result from charges::Charges.completeAction(intent, challengeResult(outcome)) if (cleared.isErr) { - return Err(self.afterChargeFailure(loaded.value, cleared.error)) + return Err(afterChargeFailure(loaded.value, cleared.error)) } - return self.afterAuthorized(loaded.value) + return afterAuthorized(loaded.value) } /// Capture a manually-captured intent the merchant has decided to settle. public capture(merchant: shared::MerchantId, intent: shared::PaymentIntentId): Result { - loaded = Result from self.getFor(merchant, intent) + loaded = Result from getFor(merchant, intent) if (loaded.isErr) { return Err(loaded.error) } - ready = Result from self.capturable(loaded.value) + ready = Result from capturable(loaded.value) if (ready.isErr) { return Err(ready.error) } - return self.finalize(loaded.value) + return finalize(loaded.value) } /// Cancel an intent before capture, voiding any authorised hold so the /// cardholder's funds are released promptly. public cancel(merchant: shared::MerchantId, intent: shared::PaymentIntentId): Result { - loaded = Result from self.getFor(merchant, intent) + loaded = Result from getFor(merchant, intent) if (loaded.isErr) { return Err(loaded.error) } - cancelable = Result from self.cancelable(loaded.value) + cancelable = Result from cancelable(loaded.value) if (cancelable.isErr) { return Err(cancelable.error) } charges::Charges.release(intent) - canceled = PaymentIntent from self.mark(loaded.value, intents::IntentStatus::Canceled) + canceled = PaymentIntent from mark(loaded.value, intents::IntentStatus::Canceled) intents::IntentStore.save(canceled) intents::Events.canceled(PaymentCanceled from { canceled }) return Ok(canceled) @@ -202,16 +202,16 @@ component PaymentIntents for intents::Intents { /// outcome still unknown is left for the next sweep — the intent is never /// abandoned while its charge might be real. Every branch is idempotent. public resume(intent: shared::PaymentIntentId): void { - loaded = Result from self.get(intent) + loaded = Result from get(intent) if (loaded.isOk) { charges::Charges.reconcileCapture(intent) receipt = Option from charges::Charges.receiptFor(intent) if (receipt.isSome) { - self.complete(loaded.value, receipt.value) + complete(loaded.value, receipt.value) } else { failed = Result from charges::Charges.definitelyFailed(intent) if (failed.isOk) { - self.abandon(loaded.value) + abandon(loaded.value) } } } @@ -225,11 +225,11 @@ component PaymentIntents for intents::Intents { /// Read an intent on behalf of `merchant`, refusing one that belongs to /// another merchant. public getFor(merchant: shared::MerchantId, intent: shared::PaymentIntentId): Result { - loaded = Result from self.get(intent) + loaded = Result from get(intent) if (loaded.isErr) { return Err(loaded.error) } - owns = Result from self.ownedBy(loaded.value, merchant) + owns = Result from ownedBy(loaded.value, merchant) if (owns.isErr) { return Err(owns.error) } @@ -250,25 +250,25 @@ component PaymentIntents for intents::Intents { proceed(intent: intents::PaymentIntent, instrument: context::NetworkInstrument): Result { auth = Result from charges::Charges.authorize(intent.id, intent.amount, instrument) if (auth.isErr) { - return Err(self.afterChargeFailure(intent, auth.error)) + return Err(afterChargeFailure(intent, auth.error)) } - action = Result from self.actionRequired(auth.value) + action = Result from actionRequired(auth.value) if (action.isOk) { - pending = PaymentIntent from self.mark(intent, intents::IntentStatus::RequiresAction) + pending = PaymentIntent from mark(intent, intents::IntentStatus::RequiresAction) intents::IntentStore.save(pending) return Ok(pending) } - return self.afterAuthorized(intent) + return afterAuthorized(intent) } /// With the hold in hand: capture now for automatic capture, or park in /// `RequiresCapture` for the merchant to capture later. afterAuthorized(intent: intents::PaymentIntent): Result { - auto = Result from self.isAutomatic(intent) + auto = Result from isAutomatic(intent) if (auto.isOk) { - return self.finalize(intent) + return finalize(intent) } - awaiting = PaymentIntent from self.mark(intent, intents::IntentStatus::RequiresCapture) + awaiting = PaymentIntent from mark(intent, intents::IntentStatus::RequiresCapture) intents::IntentStore.save(awaiting) return Ok(awaiting) } @@ -277,9 +277,9 @@ component PaymentIntents for intents::Intents { finalize(intent: intents::PaymentIntent): Result { receipt = Result from charges::Charges.capture(intent.id) if (receipt.isErr) { - return Err(self.afterChargeFailure(intent, receipt.error)) + return Err(afterChargeFailure(intent, receipt.error)) } - done = PaymentIntent from self.mark(intent, intents::IntentStatus::Succeeded) + done = PaymentIntent from mark(intent, intents::IntentStatus::Succeeded) intents::IntentStore.save(done) intents::Events.succeeded(PaymentSucceeded from { done, receipt.value.charge }) return Ok(done) @@ -290,20 +290,20 @@ component PaymentIntents for intents::Intents { /// (a timeout — the money may have moved) parks it in `Processing` for the /// sweeper to reconcile, never failing it on uncertainty. afterChargeFailure(intent: intents::PaymentIntent, e: charges::ChargeError): intents::IntentError { - sure = Result from self.definite(e) + sure = Result from definite(e) if (sure.isErr) { - intents::IntentStore.save(self.mark(intent, intents::IntentStatus::Processing)) + intents::IntentStore.save(mark(intent, intents::IntentStatus::Processing)) return intents::IntentError::Uncertain } - reset = PaymentIntent from self.mark(intent, intents::IntentStatus::RequiresPaymentMethod) + reset = PaymentIntent from mark(intent, intents::IntentStatus::RequiresPaymentMethod) intents::IntentStore.save(reset) intents::Events.failed(PaymentFailed from { reset }) - return self.declined(e) + return declined(e) } /// Drive a reconciled-as-captured intent to `Succeeded` idempotently. complete(intent: intents::PaymentIntent, receipt: charges::Receipt): void { - done = PaymentIntent from self.mark(intent, intents::IntentStatus::Succeeded) + done = PaymentIntent from mark(intent, intents::IntentStatus::Succeeded) intents::IntentStore.save(done) intents::Events.succeeded(PaymentSucceeded from { done, receipt.charge }) } @@ -311,7 +311,7 @@ component PaymentIntents for intents::Intents { /// Abandon an intent whose charge never completed: reset it for retry and /// raise `PaymentFailed`. abandon(intent: intents::PaymentIntent): void { - reset = PaymentIntent from self.mark(intent, intents::IntentStatus::RequiresPaymentMethod) + reset = PaymentIntent from mark(intent, intents::IntentStatus::RequiresPaymentMethod) intents::IntentStore.save(reset) intents::Events.failed(PaymentFailed from { reset }) } diff --git a/web-ide/src/lib/samples/acme-payments/ledger.pds b/web-ide/src/lib/samples/acme-payments/ledger.pds index 0de3ead1..be8c62f0 100644 --- a/web-ide/src/lib/samples/acme-payments/ledger.pds +++ b/web-ide/src/lib/samples/acme-payments/ledger.pds @@ -65,14 +65,14 @@ component BalanceService for ledger::Ledger { /// time alone. #[onevent(intents::PaymentSucceeded)] public onPaymentSucceeded(event: intents::PaymentSucceeded): void { - entry = BalanceTransaction from self.creditFor(event) + entry = BalanceTransaction from creditFor(event) ledger::EntryLog.appendOnce(entry) } /// A successful refund debits available, immediately. #[onevent(refunds::RefundSucceeded)] public onRefund(event: refunds::RefundSucceeded): void { - entry = BalanceTransaction from self.refundDebit(event) + entry = BalanceTransaction from refundDebit(event) ledger::EntryLog.appendOnce(entry) } @@ -80,14 +80,14 @@ component BalanceService for ledger::Ledger { /// available, held until the dispute resolves. #[onevent(disputes::DisputeOpened)] public onDisputeOpened(event: disputes::DisputeOpened): void { - entry = BalanceTransaction from self.disputeDebit(event) + entry = BalanceTransaction from disputeDebit(event) ledger::EntryLog.appendOnce(entry) } /// A won dispute reverses the hold, returning the disputed amount to available. #[onevent(disputes::DisputeWon)] public onDisputeWon(event: disputes::DisputeWon): void { - entry = BalanceTransaction from self.disputeReversal(event) + entry = BalanceTransaction from disputeReversal(event) ledger::EntryLog.appendOnce(entry) } @@ -102,14 +102,14 @@ component BalanceService for ledger::Ledger { /// so two concurrent payouts cannot both draw the same funds, and the balance /// can never go negative from a payout. public withdraw(merchant: shared::MerchantId, payout: shared::PayoutId, amount: shared::Money): Result { - debit = BalanceTransaction from self.payoutDebit(merchant, payout, amount) + debit = BalanceTransaction from payoutDebit(merchant, payout, amount) return ledger::EntryLog.appendIfAvailable(merchant, debit, amount) } /// Return drawn funds to available when a payout fails to leave the bank, by /// appending a `PayoutReversal` (idempotent on the payout). public restore(merchant: shared::MerchantId, payout: shared::PayoutId, amount: shared::Money): void { - ledger::EntryLog.appendOnce(self.payoutReversal(merchant, payout, amount)) + ledger::EntryLog.appendOnce(payoutReversal(merchant, payout, amount)) } /// Build a pending `ChargeCredit` from a payment-succeeded event: net of fee, diff --git a/web-ide/src/lib/samples/acme-payments/notifications.pds b/web-ide/src/lib/samples/acme-payments/notifications.pds index 8b51726c..9c8eec8e 100644 --- a/web-ide/src/lib/samples/acme-payments/notifications.pds +++ b/web-ide/src/lib/samples/acme-payments/notifications.pds @@ -10,19 +10,19 @@ public component Notifier for notifications::Notifications { /// Alert a merchant that a payment was disputed and needs a response. #[onevent(disputes::DisputeOpened)] public onDisputeOpened(event: disputes::DisputeOpened): void { - context::EmailProvider.email(self.recipient(event.merchant), "Action needed: a payment was disputed", "A cardholder disputed a payment. Submit evidence before the deadline.") + context::EmailProvider.email(recipient(event.merchant), "Action needed: a payment was disputed", "A cardholder disputed a payment. Submit evidence before the deadline.") } /// Alert a merchant that a payout failed and the funds were returned. #[onevent(payouts::PayoutFailed)] public onPayoutFailed(event: payouts::PayoutFailed): void { - context::EmailProvider.email(self.recipient(event.merchant), "Your payout failed", "We couldn't pay out to your bank; the funds are back in your balance.") + context::EmailProvider.email(recipient(event.merchant), "Your payout failed", "We couldn't pay out to your bank; the funds are back in your balance.") } /// Confirm to a merchant that a payout reached their bank. #[onevent(payouts::PayoutPaid)] public onPayoutPaid(event: payouts::PayoutPaid): void { - context::EmailProvider.email(self.recipient(event.merchant), "Your payout is on the way", "A payout to your bank account has been sent.") + context::EmailProvider.email(recipient(event.merchant), "Your payout is on the way", "A payout to your bank account has been sent.") } /// The email address for a merchant. diff --git a/web-ide/src/lib/samples/acme-payments/payouts.pds b/web-ide/src/lib/samples/acme-payments/payouts.pds index 33f27659..85000164 100644 --- a/web-ide/src/lib/samples/acme-payments/payouts.pds +++ b/web-ide/src/lib/samples/acme-payments/payouts.pds @@ -63,7 +63,7 @@ component PayoutService for payouts::Payouts { return Ok(existing.value) } balance = Balance from ledger::Ledger.balance(merchant) - due = Result from self.payable(balance) + due = Result from payable(balance) if (due.isErr) { return Err(due.error) } @@ -72,23 +72,23 @@ component PayoutService for payouts::Payouts { if (drawn.isErr) { return Err(payouts::PayoutError::InsufficientFunds) } - destination = context::BankAccountRef from self.destinationFor(merchant) + destination = context::BankAccountRef from destinationFor(merchant) payout = Payout from { id, merchant, due.value, destination, payouts::PayoutStatus::Pending } payouts::PayoutStore.save(payout) - return self.send(payout) + return send(payout) } /// Send a recorded payout to the banking partner. On rejection, restore the /// drawn funds to the ledger and fail the payout (surfacing `PayoutFailed`); /// on acceptance, mark it in transit for the reconciler to settle. send(payout: payouts::Payout): Result { - key = PayoutKey from self.keyFor(payout.id) + key = PayoutKey from keyFor(payout.id) transfer = Result from context::BankingPartner.initiate(payout.amount, payout.destination, key) if (transfer.isErr) { - self.refund(payout) - return Err(self.translate(transfer.error)) + refund(payout) + return Err(translate(transfer.error)) } - inTransit = Payout from self.markInTransit(payout, transfer.value) + inTransit = Payout from markInTransit(payout, transfer.value) payouts::PayoutStore.save(inTransit) return Ok(inTransit) } @@ -99,11 +99,11 @@ component PayoutService for payouts::Payouts { public reconcile(id: shared::PayoutId): void { loaded = Option from payouts::PayoutStore.fetch(id) if (loaded.isSome) { - pending = Result from self.inTransit(loaded.value) + pending = Result from inTransit(loaded.value) if (pending.isOk) { state = Option from context::BankingPartner.status(pending.value.transfer) if (state.isSome) { - self.applyState(loaded.value, state.value) + applyState(loaded.value, state.value) } } } @@ -121,22 +121,22 @@ component PayoutService for payouts::Payouts { /// Apply a partner transfer state: settle, or restore-and-fail on a return. applyState(payout: payouts::Payout, state: context::BankTransferState): void { - settled = Result from self.isSettled(state) + settled = Result from isSettled(state) if (settled.isOk) { - payouts::PayoutStore.save(self.markPaid(payout)) + payouts::PayoutStore.save(markPaid(payout)) payouts::Events.paid(PayoutPaid from { payout.id, payout.merchant, payout.amount }) } else { - self.refund(payout) + refund(payout) } } /// Restore a failed payout's funds to the ledger and record the failure, /// raising `PayoutFailed`. Idempotent: a payout already failed is left alone. refund(payout: payouts::Payout): void { - fresh = Result from self.notYetFailed(payout) + fresh = Result from notYetFailed(payout) if (fresh.isOk) { ledger::Ledger.restore(payout.merchant, payout.id, payout.amount) - payouts::PayoutStore.save(self.markFailed(payout)) + payouts::PayoutStore.save(markFailed(payout)) payouts::Events.failed(PayoutFailed from { payout.id, payout.merchant, payout.amount }) } } diff --git a/web-ide/src/lib/samples/acme-payments/refunds.pds b/web-ide/src/lib/samples/acme-payments/refunds.pds index 4a7f10c2..f7fbe949 100644 --- a/web-ide/src/lib/samples/acme-payments/refunds.pds +++ b/web-ide/src/lib/samples/acme-payments/refunds.pds @@ -51,7 +51,7 @@ component RefundService for refunds::Refunds { if (intent.isErr) { return Err(refunds::RefundError::IntentNotFound) } - ready = Result from self.refundable(intent.value) + ready = Result from refundable(intent.value) if (ready.isErr) { return Err(ready.error) } @@ -60,10 +60,10 @@ component RefundService for refunds::Refunds { refunds::RefundStore.save(pending) back = Result from charges::Charges.refund(req.intent, req.amount) if (back.isErr) { - refunds::RefundStore.save(self.markFailed(pending, back.error)) - return Err(self.declined(back.error)) + refunds::RefundStore.save(markFailed(pending, back.error)) + return Err(declined(back.error)) } - done = Refund from self.markSucceeded(pending) + done = Refund from markSucceeded(pending) refunds::RefundStore.save(done) refunds::Events.refunded(RefundSucceeded from { done.id, done.merchant, done.amount }) return Ok(done) diff --git a/web-ide/src/lib/samples/acme-payments/vault.pds b/web-ide/src/lib/samples/acme-payments/vault.pds index 6ecba669..f1276371 100644 --- a/web-ide/src/lib/samples/acme-payments/vault.pds +++ b/web-ide/src/lib/samples/acme-payments/vault.pds @@ -34,16 +34,16 @@ component Tokenizer for vault::Vault { /// Tokenise a card: validate it, exchange it with the network for an /// instrument token, store only the token plus a safe display form. public tokenize(merchant: shared::MerchantId, card: vault::CardEntry): Result { - valid = Result from self.validate(card) + valid = Result from validate(card) if (valid.isErr) { return Err(valid.error) } - instrument = Result from self.exchange(card) + instrument = Result from exchange(card) if (instrument.isErr) { return Err(instrument.error) } id = shared::PaymentMethodId from vault::TokenStore.nextId() - method = PaymentMethod from self.represent(id, card) + method = PaymentMethod from represent(id, card) vault::TokenStore.save(merchant, method, instrument.value) return Ok(method) } diff --git a/web-ide/src/lib/samples/acme-payments/webhooks.pds b/web-ide/src/lib/samples/acme-payments/webhooks.pds index a75552f0..06186fa6 100644 --- a/web-ide/src/lib/samples/acme-payments/webhooks.pds +++ b/web-ide/src/lib/samples/acme-payments/webhooks.pds @@ -37,44 +37,44 @@ component Dispatcher for webhooks::Webhooks { /// Deliver `payment_intent.succeeded`. #[onevent(intents::PaymentSucceeded)] public onPaymentSucceeded(event: intents::PaymentSucceeded): void { - self.dispatch(self.encodeSucceeded(event)) + dispatch(encodeSucceeded(event)) } /// Deliver `payment_intent.payment_failed`. #[onevent(intents::PaymentFailed)] public onPaymentFailed(event: intents::PaymentFailed): void { - self.dispatch(self.encodeFailed(event)) + dispatch(encodeFailed(event)) } /// Deliver `charge.refunded`. #[onevent(refunds::RefundSucceeded)] public onRefunded(event: refunds::RefundSucceeded): void { - self.dispatch(self.encodeRefunded(event)) + dispatch(encodeRefunded(event)) } /// Deliver `charge.dispute.created`. #[onevent(disputes::DisputeOpened)] public onDisputeOpened(event: disputes::DisputeOpened): void { - self.dispatch(self.encodeDisputeOpened(event)) + dispatch(encodeDisputeOpened(event)) } /// Deliver `payout.paid`. #[onevent(payouts::PayoutPaid)] public onPayoutPaid(event: payouts::PayoutPaid): void { - self.dispatch(self.encodePayoutPaid(event)) + dispatch(encodePayoutPaid(event)) } /// Deliver `payout.failed`. #[onevent(payouts::PayoutFailed)] public onPayoutFailed(event: payouts::PayoutFailed): void { - self.dispatch(self.encodePayoutFailed(event)) + dispatch(encodePayoutFailed(event)) } /// Retry deliveries whose backoff has elapsed (driven by the scheduled sweep). public redeliver(): void { due = Delivery[] from webhooks::DeliveryStore.due() for (delivery in due) { - self.attempt(delivery.event) + attempt(delivery.event) } } @@ -84,7 +84,7 @@ component Dispatcher for webhooks::Webhooks { seen = Result from webhooks::DeliveryStore.seen(webhook.id) if (seen.isErr) { webhooks::DeliveryStore.record(webhook) - self.attempt(webhook.id) + attempt(webhook.id) } } @@ -94,13 +94,13 @@ component Dispatcher for webhooks::Webhooks { attempt(event: string): void { deliverable = Option from webhooks::DeliveryStore.deliverable(event) if (deliverable.isSome) { - endpoint = string from self.endpointFor(deliverable.value.merchant) - signed = string from self.sign(deliverable.value) + endpoint = string from endpointFor(deliverable.value.merchant) + signed = string from sign(deliverable.value) sent = Result from context::MerchantEndpoint.deliver(endpoint, deliverable.value.payload, signed) if (sent.isErr) { - webhooks::DeliveryStore.save(self.onFailure(deliverable.value)) + webhooks::DeliveryStore.save(onFailure(deliverable.value)) } else { - webhooks::DeliveryStore.save(self.markDelivered(deliverable.value)) + webhooks::DeliveryStore.save(markDelivered(deliverable.value)) } } } diff --git a/web-ide/src/lib/samples/acme-tickets/backoffice.pds b/web-ide/src/lib/samples/acme-tickets/backoffice.pds index a4760c6e..be860831 100644 --- a/web-ide/src/lib/samples/acme-tickets/backoffice.pds +++ b/web-ide/src/lib/samples/acme-tickets/backoffice.pds @@ -66,7 +66,7 @@ component Console for backoffice::Backoffice { } live = Result from catalog::Catalog.putOnSale(event) if (live.isErr) { - return Err(self.notFound(live.error)) + return Err(notFound(live.error)) } return Ok(live.value) } @@ -79,7 +79,7 @@ component Console for backoffice::Backoffice { } dead = Result from catalog::Catalog.cancel(event) if (dead.isErr) { - return Err(self.notFound(dead.error)) + return Err(notFound(dead.error)) } return Ok(dead.value) } @@ -92,7 +92,7 @@ component Console for backoffice::Backoffice { } refunded = Result from orders::Orders.refund(order) if (refunded.isErr) { - return Err(self.refundRejected(refunded.error)) + return Err(refundRejected(refunded.error)) } return Ok(refunded.value) } diff --git a/web-ide/src/lib/samples/acme-tickets/catalog.pds b/web-ide/src/lib/samples/acme-tickets/catalog.pds index 26a1ec01..90b7476b 100644 --- a/web-ide/src/lib/samples/acme-tickets/catalog.pds +++ b/web-ide/src/lib/samples/acme-tickets/catalog.pds @@ -106,7 +106,7 @@ component Events for catalog::Catalog { if (found.isNone) { return Err(EventNotFound from { id }) } - live = Event from self.transition(found.value, catalog::EventStatus::OnSale) + live = Event from transition(found.value, catalog::EventStatus::OnSale) catalog::EventStore.save(live) return Ok(live) } @@ -118,7 +118,7 @@ component Events for catalog::Catalog { if (found.isNone) { return Err(EventNotFound from { id }) } - dead = Event from self.transition(found.value, catalog::EventStatus::Cancelled) + dead = Event from transition(found.value, catalog::EventStatus::Cancelled) catalog::EventStore.save(dead) catalog::Signals.cancelled(EventCancelled from { id }) return Ok(dead) @@ -129,7 +129,7 @@ component Events for catalog::Catalog { public settle(id: shared::EventId): void { found = Option from catalog::EventStore.fetch(id) if (found.isSome) { - next = Option from self.lifecycle(found.value) + next = Option from lifecycle(found.value) if (next.isSome) { catalog::EventStore.save(next.value) } diff --git a/web-ide/src/lib/samples/acme-tickets/identity.pds b/web-ide/src/lib/samples/acme-tickets/identity.pds index afa72219..86e7c51b 100644 --- a/web-ide/src/lib/samples/acme-tickets/identity.pds +++ b/web-ide/src/lib/samples/acme-tickets/identity.pds @@ -79,7 +79,7 @@ component Sessions for identity::Identity { if (user.isNone) { return Err(identity::AuthError::BadCredentials) } - ok = Result from self.verify(creds, user.value) + ok = Result from verify(creds, user.value) if (ok.isErr) { return Err(identity::AuthError::BadCredentials) } @@ -102,11 +102,11 @@ component Sessions for identity::Identity { /// Authenticate, then require the `Organizer` role. public requireOrganizer(token: identity::SessionToken): Result { - user = Result from self.authenticate(token) + user = Result from authenticate(token) if (user.isErr) { return Err(user.error) } - allowed = Result from self.ensureOrganizer(user.value) + allowed = Result from ensureOrganizer(user.value) if (allowed.isErr) { return Err(allowed.error) } @@ -115,11 +115,11 @@ component Sessions for identity::Identity { /// Authenticate, then require the `Support` role. public requireSupport(token: identity::SessionToken): Result { - user = Result from self.authenticate(token) + user = Result from authenticate(token) if (user.isErr) { return Err(user.error) } - allowed = Result from self.ensureSupport(user.value) + allowed = Result from ensureSupport(user.value) if (allowed.isErr) { return Err(allowed.error) } diff --git a/web-ide/src/lib/samples/acme-tickets/inventory.pds b/web-ide/src/lib/samples/acme-tickets/inventory.pds index c6a7ce25..26421dae 100644 --- a/web-ide/src/lib/samples/acme-tickets/inventory.pds +++ b/web-ide/src/lib/samples/acme-tickets/inventory.pds @@ -91,11 +91,11 @@ component Holds for inventory::Inventory { /// tier pool. Overselling is impossible: if the pool cannot satisfy the /// request the allocation fails and no hold is created. public reserve(event: shared::EventId, tier: shared::TierId, quantity: shared::Quantity, owner: shared::UserId): Result { - free = Result from self.noActiveHold(owner, event) + free = Result from noActiveHold(owner, event) if (free.isErr) { return Err(free.error) } - taken = Result from self.allocateSharded(event, tier, quantity) + taken = Result from allocateSharded(event, tier, quantity) if (taken.isErr) { return Err(inventory::InventoryError::OutOfStock) } @@ -110,7 +110,7 @@ component Holds for inventory::Inventory { /// tier is genuinely sold out — not merely when one shard ran dry — so /// sharding adds throughput without weakening the no-oversell guarantee. allocateSharded(event: shared::EventId, tier: shared::TierId, quantity: shared::Quantity): Result { - preferred = SeatShard from self.pickShard(event, tier) + preferred = SeatShard from pickShard(event, tier) first = Result from inventory::Pool.allocateFrom(preferred, quantity) if (first.isOk) { return Ok(preferred) @@ -124,7 +124,7 @@ component Holds for inventory::Inventory { if (found.isNone) { return Err(HoldNotFound from { id }) } - live = Result from self.ensureLive(found.value, owner) + live = Result from ensureLive(found.value, owner) if (live.isErr) { return Err(live.error) } @@ -139,11 +139,11 @@ component Holds for inventory::Inventory { if (found.isNone) { return Err(HoldNotFound from { id }) } - held = Result from self.ensureHeld(found.value) + held = Result from ensureHeld(found.value) if (held.isErr) { return Err(held.error) } - moved = Hold from self.transition(found.value, inventory::HoldStatus::Committing) + moved = Hold from transition(found.value, inventory::HoldStatus::Committing) inventory::HoldStore.save(moved) return Ok(moved) } @@ -157,16 +157,16 @@ component Holds for inventory::Inventory { if (found.isNone) { return Err(HoldNotFound from { id }) } - done = Option from self.existingAllocation(found.value) + done = Option from existingAllocation(found.value) if (done.isSome) { return Ok(done.value) } - ready = Result from self.ensureCommitting(found.value) + ready = Result from ensureCommitting(found.value) if (ready.isErr) { return Err(ready.error) } - allocation = Allocation from self.allocate(found.value) - inventory::HoldStore.save(self.transition(found.value, inventory::HoldStatus::Confirmed)) + allocation = Allocation from allocate(found.value) + inventory::HoldStore.save(transition(found.value, inventory::HoldStatus::Confirmed)) return Ok(allocation) } @@ -177,10 +177,10 @@ component Holds for inventory::Inventory { public release(id: shared::HoldId): void { found = Option from inventory::HoldStore.fetch(id) if (found.isSome) { - live = Result from self.ensureReleasable(found.value) + live = Result from ensureReleasable(found.value) if (live.isOk) { inventory::Pool.restoreTo(found.value.shard, found.value.quantity) - inventory::HoldStore.save(self.transition(found.value, inventory::HoldStatus::Released)) + inventory::HoldStore.save(transition(found.value, inventory::HoldStatus::Released)) } } } @@ -192,10 +192,10 @@ component Holds for inventory::Inventory { public releaseSold(id: shared::HoldId): void { found = Option from inventory::HoldStore.fetch(id) if (found.isSome) { - sold = Result from self.ensureConfirmed(found.value) + sold = Result from ensureConfirmed(found.value) if (sold.isOk) { inventory::Pool.restoreTo(found.value.shard, found.value.quantity) - inventory::HoldStore.save(self.transition(found.value, inventory::HoldStatus::Released)) + inventory::HoldStore.save(transition(found.value, inventory::HoldStatus::Released)) } } } @@ -206,10 +206,10 @@ component Holds for inventory::Inventory { public expire(id: shared::HoldId): void { found = Option from inventory::HoldStore.fetch(id) if (found.isSome) { - held = Result from self.ensureHeld(found.value) + held = Result from ensureHeld(found.value) if (held.isOk) { inventory::Pool.restoreTo(found.value.shard, found.value.quantity) - inventory::HoldStore.save(self.transition(found.value, inventory::HoldStatus::Expired)) + inventory::HoldStore.save(transition(found.value, inventory::HoldStatus::Expired)) } } } diff --git a/web-ide/src/lib/samples/acme-tickets/notifications.pds b/web-ide/src/lib/samples/acme-tickets/notifications.pds index 2e595744..523cb312 100644 --- a/web-ide/src/lib/samples/acme-tickets/notifications.pds +++ b/web-ide/src/lib/samples/acme-tickets/notifications.pds @@ -9,19 +9,19 @@ public component Notifier for notifications::Notifications { /// Alert a queued attendee that they have been admitted to buy. #[onevent(waitingroom::Admitted)] public onAdmitted(event: waitingroom::Admitted): void { - context::NotificationProvider.sms(self.contactFor(event.token), "You're in — you have a few minutes to buy.") + context::NotificationProvider.sms(contactFor(event.token), "You're in — you have a few minutes to buy.") } /// Confirm a completed purchase and its tickets. #[onevent(orders::OrderConfirmed)] public onConfirmed(event: orders::OrderConfirmed): void { - context::NotificationProvider.email(self.recipient(event.buyer), "Your tickets", "Your tickets are in your wallet.") + context::NotificationProvider.email(recipient(event.buyer), "Your tickets", "Your tickets are in your wallet.") } /// Notify the buyer that their order was refunded. #[onevent(orders::OrderRefunded)] public onRefunded(event: orders::OrderRefunded): void { - context::NotificationProvider.email(self.recipient(event.order.buyer), "Refund processed", "Your refund is on its way.") + context::NotificationProvider.email(recipient(event.order.buyer), "Refund processed", "Your refund is on its way.") } /// The contact for an admission token's attendee. diff --git a/web-ide/src/lib/samples/acme-tickets/orders.pds b/web-ide/src/lib/samples/acme-tickets/orders.pds index 35ebf844..66cc4824 100644 --- a/web-ide/src/lib/samples/acme-tickets/orders.pds +++ b/web-ide/src/lib/samples/acme-tickets/orders.pds @@ -105,13 +105,13 @@ component Reservation for orders::Orders { if (sellable.isErr) { return Err(orders::ReserveError::NotOnSale) } - within = Result from self.withinLimit(req.quantity) + within = Result from withinLimit(req.quantity) if (within.isErr) { return Err(orders::ReserveError::ExceedsLimit) } held = Result from inventory::Inventory.reserve(req.event, req.tier, req.quantity, buyer.value.id) if (held.isErr) { - return Err(self.unavailable(held.error)) + return Err(unavailable(held.error)) } quote = Result from pricing::Pricing.quote(req.event, req.tier, req.quantity) if (quote.isErr) { @@ -170,9 +170,9 @@ component OrderService for orders::Orders { orders::OrderStore.save(order) charged = Result from payments::Payments.charge(id, locked.value.total, req.method) if (charged.isErr) { - return Err(self.afterChargeFailure(order, charged.error)) + return Err(afterChargeFailure(order, charged.error)) } - paid = Order from self.mark(order, orders::OrderStatus::Charged) + paid = Order from mark(order, orders::OrderStatus::Charged) orders::OrderStore.save(paid) allocated = Result from inventory::Inventory.confirm(req.hold) if (allocated.isErr) { @@ -181,10 +181,10 @@ component OrderService for orders::Orders { return Err(RefundFailed from { id }) } inventory::Inventory.release(req.hold) - orders::OrderStore.save(self.mark(order, orders::OrderStatus::Refunded)) + orders::OrderStore.save(mark(order, orders::OrderStatus::Refunded)) return Err(orders::CheckoutError::AllocationFailed) } - confirmed = Order from self.mark(paid, orders::OrderStatus::Confirmed) + confirmed = Order from mark(paid, orders::OrderStatus::Confirmed) orders::OrderStore.save(confirmed) done = OrderConfirmed from { confirmed, buyer.value.id, allocated.value } orders::Events.confirmed(done) @@ -198,13 +198,13 @@ component OrderService for orders::Orders { /// real outcome against the provider rather than guessing. Treating a timeout as /// a decline is how a charged buyer loses their seat with no record. afterChargeFailure(order: orders::Order, e: payments::PaymentError): orders::CheckoutError { - sure = Result from self.definite(e) + sure = Result from definite(e) if (sure.isErr) { return orders::CheckoutError::PaymentUncertain } inventory::Inventory.release(order.hold) - orders::OrderStore.save(self.mark(order, orders::OrderStatus::Failed)) - return self.declined(e) + orders::OrderStore.save(mark(order, orders::OrderStatus::Failed)) + return declined(e) } /// Refund a confirmed order (support- or expiry-driven): reverse the charge, @@ -212,11 +212,11 @@ component OrderService for orders::Orders { /// order is not marked refunded and the seats are not freed until the money /// is actually returned. public refund(id: shared::OrderId): Result { - order = Result from self.get(id) + order = Result from get(id) if (order.isErr) { return Err(order.error) } - ready = Result from self.refundable(order.value) + ready = Result from refundable(order.value) if (ready.isErr) { return Err(ready.error) } @@ -225,7 +225,7 @@ component OrderService for orders::Orders { return Err(RefundFailed from { id }) } inventory::Inventory.releaseSold(order.value.hold) - refunded = Order from self.mark(order.value, orders::OrderStatus::Refunded) + refunded = Order from mark(order.value, orders::OrderStatus::Refunded) orders::OrderStore.save(refunded) event = OrderRefunded from { refunded } orders::Events.refunded(event) @@ -239,7 +239,7 @@ component OrderService for orders::Orders { public onEventCancelled(event: catalog::EventCancelled): void { affected = Order[] from orders::OrderStore.confirmedFor(event.event) for (order in affected) { - self.refund(order.id) + refund(order.id) } } @@ -252,16 +252,16 @@ component OrderService for orders::Orders { /// charge might be real, so a buyer is never failed after being charged. Every /// branch is idempotent. public resume(id: shared::OrderId): void { - order = Result from self.get(id) + order = Result from get(id) if (order.isOk) { payments::Payments.reconcileCharge(id) receipt = Option from payments::Payments.receiptFor(id) if (receipt.isSome) { - self.complete(order.value) + complete(order.value) } else { failed = Result from payments::Payments.definitelyFailed(id) if (failed.isOk) { - self.abandon(order.value) + abandon(order.value) } } } @@ -277,7 +277,7 @@ component OrderService for orders::Orders { complete(order: orders::Order): void { allocated = Result from inventory::Inventory.confirm(order.hold) if (allocated.isOk) { - confirmed = Order from self.mark(order, orders::OrderStatus::Confirmed) + confirmed = Order from mark(order, orders::OrderStatus::Confirmed) orders::OrderStore.save(confirmed) done = OrderConfirmed from { confirmed, confirmed.buyer, allocated.value } orders::Events.confirmed(done) @@ -287,7 +287,7 @@ component OrderService for orders::Orders { /// Abandon an order whose charge never completed: release the hold, fail it. abandon(order: orders::Order): void { inventory::Inventory.release(order.hold) - orders::OrderStore.save(self.mark(order, orders::OrderStatus::Failed)) + orders::OrderStore.save(mark(order, orders::OrderStatus::Failed)) } /// Read an order, or `OrderNotFound`. @@ -302,11 +302,11 @@ component OrderService for orders::Orders { /// Read an order on behalf of `owner`, refusing one that belongs to another /// user. A non-owner is told `OrderNotFound`, never that the order exists. public getFor(owner: shared::UserId, id: shared::OrderId): Result { - order = Result from self.get(id) + order = Result from get(id) if (order.isErr) { return Err(order.error) } - owns = Result from self.ownedBy(order.value, owner) + owns = Result from ownedBy(order.value, owner) if (owns.isErr) { return Err(owns.error) } diff --git a/web-ide/src/lib/samples/acme-tickets/payments.pds b/web-ide/src/lib/samples/acme-tickets/payments.pds index 5fe922af..5780b210 100644 --- a/web-ide/src/lib/samples/acme-tickets/payments.pds +++ b/web-ide/src/lib/samples/acme-tickets/payments.pds @@ -89,24 +89,24 @@ component PaymentService for payments::Payments { /// calling the provider again. /// #headline public charge(order: shared::OrderId, amount: shared::Money, method: payments::PaymentMethod): Result { - existing = Option from self.receiptFor(order) + existing = Option from receiptFor(order) if (existing.isSome) { return Ok(existing.value) } - key = IdempotencyKey from self.keyFor(order, "charge") + key = IdempotencyKey from keyFor(order, "charge") payment = Payment from { order, amount, payments::PaymentStatus::Charging } payments::PaymentStore.save(payment) held = Result from payments::Gateway.authorize(amount, method, key) if (held.isErr) { - self.onChargeError(payment, held.error) + onChargeError(payment, held.error) return Err(held.error) } taken = Result from payments::Gateway.capture(held.value.ref, amount, key) if (taken.isErr) { - self.onCaptureError(payment, held.value.ref, key, taken.error) + onCaptureError(payment, held.value.ref, key, taken.error) return Err(taken.error) } - charged = Payment from self.markCharged(payment, held.value, taken.value) + charged = Payment from markCharged(payment, held.value, taken.value) payments::PaymentStore.save(charged) return Ok(Receipt from { charged.id, taken.value.ref }) } @@ -118,16 +118,16 @@ component PaymentService for payments::Payments { /// is a deliberate scope cut, not an oversight — refunds are off the surge hot /// path and rarely contended. public refund(order: shared::OrderId): Result { - loaded = Result from self.loadCharged(order) + loaded = Result from loadCharged(order) if (loaded.isErr) { return Err(loaded.error) } - key = IdempotencyKey from self.keyFor(order, "refund") + key = IdempotencyKey from keyFor(order, "refund") back = Result from payments::Gateway.refund(loaded.value.capture, loaded.value.amount, key) if (back.isErr) { return Err(back.error) } - refunded = Payment from self.recordRefund(order) + refunded = Payment from recordRefund(order) payments::PaymentStore.save(refunded) return Ok(refunded) } @@ -139,9 +139,9 @@ component PaymentService for payments::Payments { public settle(order: shared::OrderId, ref: context::ProviderCaptureRef): void { payment = Option from payments::PaymentStore.byOrder(order) if (payment.isSome) { - awaiting = Result from self.awaitingSettlement(payment.value) + awaiting = Result from awaitingSettlement(payment.value) if (awaiting.isOk) { - payments::PaymentStore.save(self.applySettlement(payment.value, ref)) + payments::PaymentStore.save(applySettlement(payment.value, ref)) } } } @@ -153,11 +153,11 @@ component PaymentService for payments::Payments { public reconcile(order: shared::OrderId): void { payment = Option from payments::PaymentStore.byOrder(order) if (payment.isSome) { - awaiting = Result from self.awaitingSettlement(payment.value) + awaiting = Result from awaitingSettlement(payment.value) if (awaiting.isOk) { truth = Option from payments::Gateway.lookup(order) if (truth.isSome) { - payments::PaymentStore.save(self.applySettlement(payment.value, truth.value)) + payments::PaymentStore.save(applySettlement(payment.value, truth.value)) } } } @@ -170,15 +170,15 @@ component PaymentService for payments::Payments { /// outcome still unknown is left for a later sweep. This is what lets the order /// saga recover a timed-out checkout instead of guessing. public reconcileCharge(order: shared::OrderId): void { - done = Option from self.receiptFor(order) + done = Option from receiptFor(order) if (done.isNone) { truth = Option from payments::Gateway.lookupCharge(order) if (truth.isSome) { - payments::PaymentStore.save(self.recordCharge(order, truth.value)) + payments::PaymentStore.save(recordCharge(order, truth.value)) } else { gone = Result from payments::Gateway.chargeDefinitelyMissing(order) if (gone.isOk) { - payments::PaymentStore.save(self.recordChargeFailed(order)) + payments::PaymentStore.save(recordChargeFailed(order)) } } } @@ -195,9 +195,9 @@ component PaymentService for payments::Payments { /// On an authorise failure: a DEFINITE decline marks the payment `Failed`; an /// INDETERMINATE outcome leaves it `Charging` for `reconcileCharge` to resolve. onChargeError(payment: payments::Payment, e: payments::PaymentError): void { - sure = Result from self.isDefinite(e) + sure = Result from isDefinite(e) if (sure.isOk) { - payments::PaymentStore.save(self.markFailed(payment, e)) + payments::PaymentStore.save(markFailed(payment, e)) } } @@ -205,10 +205,10 @@ component PaymentService for payments::Payments { /// the payment `Failed`; an INDETERMINATE outcome leaves both intact and the /// payment `Charging`, because the capture may actually have settled. onCaptureError(payment: payments::Payment, auth: context::ProviderAuthRef, key: payments::IdempotencyKey, e: payments::PaymentError): void { - sure = Result from self.isDefinite(e) + sure = Result from isDefinite(e) if (sure.isOk) { payments::Gateway.cancelAuth(auth, key) - payments::PaymentStore.save(self.markFailed(payment, e)) + payments::PaymentStore.save(markFailed(payment, e)) } } @@ -245,7 +245,7 @@ public component Gateway for payments::Payments { public authorize(amount: shared::Money, method: payments::PaymentMethod, key: payments::IdempotencyKey): Result { held = Result from context::PaymentProvider.authorize(amount, method, key) if (held.isErr) { - return Err(self.translate(held.error)) + return Err(translate(held.error)) } return Ok(held.value) } @@ -254,7 +254,7 @@ public component Gateway for payments::Payments { public capture(auth: context::ProviderAuthRef, amount: shared::Money, key: payments::IdempotencyKey): Result { taken = Result from context::PaymentProvider.capture(auth, amount, key) if (taken.isErr) { - return Err(self.translate(taken.error)) + return Err(translate(taken.error)) } return Ok(taken.value) } @@ -263,7 +263,7 @@ public component Gateway for payments::Payments { public refund(capture: context::ProviderCaptureRef, amount: shared::Money, key: payments::IdempotencyKey): Result { back = Result from context::PaymentProvider.refund(capture, amount, key) if (back.isErr) { - return Err(self.translate(back.error)) + return Err(translate(back.error)) } return Ok(back.value) } @@ -298,7 +298,7 @@ public component WebhookHandler for payments::Payments { /// replayed webhook is acknowledged but changes nothing. #[http("POST /webhooks/payments")] public handle(event: payments::SettlementEvent): Result { - verified = Result from self.verify(event) + verified = Result from verify(event) if (verified.isErr) { return Err(verified.error) } diff --git a/web-ide/src/lib/samples/acme-tickets/pricing.pds b/web-ide/src/lib/samples/acme-tickets/pricing.pds index 5fbb59bc..429a5bbb 100644 --- a/web-ide/src/lib/samples/acme-tickets/pricing.pds +++ b/web-ide/src/lib/samples/acme-tickets/pricing.pds @@ -43,9 +43,9 @@ component Quotes for pricing::Pricing { if (base.isErr) { return Err(TierUnavailable from { tier }) } - surge = SurgeFactor from self.surgeFor(event, tier) - unit = shared::Money from self.apply(base.value, surge) - total = shared::Money from self.lineTotal(unit, quantity) + surge = SurgeFactor from surgeFor(event, tier) + unit = shared::Money from apply(base.value, surge) + total = shared::Money from lineTotal(unit, quantity) return Ok(Quote from { event, tier, unit, surge, total }) } @@ -56,9 +56,9 @@ component Quotes for pricing::Pricing { surgeFor(event: shared::EventId, tier: shared::TierId): pricing::SurgeFactor { snap = Option from pricing::Demand.snapshot(event, tier) if (snap.isNone) { - return self.neutral() + return neutral() } - return self.curve(snap.value.pressure) + return curve(snap.value.pressure) } /// The no-surge factor (multiplier 1.0) used when demand is unknown. @@ -100,7 +100,7 @@ public component Demand for pricing::Pricing { public onConfirmed(event: orders::OrderConfirmed): void { fresh = Option from pricing::DemandLog.seen(event.order.id) if (fresh.isNone) { - self.record(event.order.event, event.order.tier, event.order.quantity) + record(event.order.event, event.order.tier, event.order.quantity) pricing::DemandLog.mark(event.order.id) } } diff --git a/web-ide/src/lib/samples/acme-tickets/tickets.pds b/web-ide/src/lib/samples/acme-tickets/tickets.pds index 8021c990..98a31cbb 100644 --- a/web-ide/src/lib/samples/acme-tickets/tickets.pds +++ b/web-ide/src/lib/samples/acme-tickets/tickets.pds @@ -47,7 +47,7 @@ component Issuer for tickets::Tickets { /// loop silently. #[onevent(orders::OrderConfirmed)] public onConfirmed(event: orders::OrderConfirmed): void { - issued = Result from self.issue(event.order, event.allocation) + issued = Result from issue(event.order, event.allocation) if (issued.isErr) { tickets::Quarantine.stranded(event.order.id) } @@ -57,14 +57,14 @@ component Issuer for tickets::Tickets { /// cannot be redeemed at the gate (no paid-then-refunded double entry). #[onevent(orders::OrderRefunded)] public onRefunded(event: orders::OrderRefunded): void { - self.revoke(event.order.id) + revoke(event.order.id) } /// Mint the tickets for an order's allocation and deliver them to the buyer. /// Mints exactly the ticket ids the inventory allocation named, so credentials /// match the seats that left the pool. public issue(order: orders::Order, allocation: inventory::Allocation): Result { - minted = Ticket[] from self.mint(order, allocation) + minted = Ticket[] from mint(order, allocation) tickets::TicketStore.saveAll(minted) tickets::Delivery.deliver(order.buyer, minted) return Ok(minted) @@ -79,7 +79,7 @@ component Issuer for tickets::Tickets { revoke(order: shared::OrderId): void { held = Ticket[] from tickets::TicketStore.forOrder(order) for (ticket in held) { - tickets::TicketStore.save(self.markRevoked(ticket)) + tickets::TicketStore.save(markRevoked(ticket)) } } @@ -98,11 +98,11 @@ component Redemption for tickets::Tickets { if (found.isNone) { return Err(tickets::RedeemError::TicketNotFound) } - admit = Result from self.admissible(found.value) + admit = Result from admissible(found.value) if (admit.isErr) { return Err(admit.error) } - redeemed = Ticket from self.markRedeemed(found.value) + redeemed = Ticket from markRedeemed(found.value) tickets::TicketStore.save(redeemed) return Ok(redeemed) } diff --git a/web-ide/src/lib/samples/acme-tickets/waitingroom.pds b/web-ide/src/lib/samples/acme-tickets/waitingroom.pds index f6ba88b7..3ad6bad3 100644 --- a/web-ide/src/lib/samples/acme-tickets/waitingroom.pds +++ b/web-ide/src/lib/samples/acme-tickets/waitingroom.pds @@ -53,7 +53,7 @@ component Queue for waitingroom::WaitingRoom { /// Join the queue for an event. Refuses with `QueueClosed` when the queue is /// shedding load — the backpressure valve for a surge that outruns capacity. public join(event: shared::EventId, user: shared::UserId): Result { - open = Result from self.accepting(event) + open = Result from accepting(event) if (open.isErr) { return Err(open.error) } @@ -65,7 +65,7 @@ component Queue for waitingroom::WaitingRoom { /// position polls during a hot on-sale never hit the enqueue path. public position(ticket: waitingroom::QueueTicket): waitingroom::Position { snap = Option from waitingroom::QueueStore.snapshot(ticket.event) - return self.estimate(ticket, snap) + return estimate(ticket, snap) } /// `Err(QueueClosed)` when the queue is shedding load. @@ -84,7 +84,7 @@ component Admission for waitingroom::WaitingRoom { if (found.isNone) { return Err(waitingroom::WaitingError::AdmissionInvalid) } - return self.unexpired(found.value) + return unexpired(found.value) } /// `Err(AdmissionExpired)` if the token's window has closed. @@ -100,7 +100,7 @@ component Gatekeeper for waitingroom::WaitingRoom { /// of remaining inventory and in-flight checkouts, so admission never outruns /// what the inventory and payment paths can serve. public admitNext(event: shared::EventId): void { - room = number from self.headroom(event) + room = number from headroom(event) due = QueueTicket[] from waitingroom::QueueStore.dequeue(event, room) for (ticket in due) { token = AdmissionToken from waitingroom::AdmissionStore.grant(ticket) @@ -118,10 +118,10 @@ component Gatekeeper for waitingroom::WaitingRoom { headroom(event: shared::EventId): number { seats = Option from inventory::Inventory.snapshot(event) if (seats.isNone) { - return self.budget(0, 0) + return budget(0, 0) } inflight = number from waitingroom::AdmissionStore.outstandingAsOf(event, seats.value.version) - return self.budget(seats.value.available, inflight) + return budget(seats.value.available, inflight) } /// `max(0, seats - outstanding)` — the admission budget left. diff --git a/web-ide/static/pseudocode-skill.zip b/web-ide/static/pseudocode-skill.zip index 10e9f6ae1f9e7a7948e0b26d69f1ab9604a8a11a..be96ea5fd0f14b4f6f86b91573ffad2d61a046a5 100644 GIT binary patch delta 15299 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 Q9hUeQWoD=j<^OB>KM|K4sQ>@~ delta 15142 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 Date: Wed, 24 Jun 2026 16:32:37 +0000 Subject: [PATCH 2/3] fix: type postfix chains rooted at a bare same-node call (refs #71) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit base_owner gained no OwnCall arm when self. was dropped, so a chain like Pick().first() (no from) and member-completion at the . after Pick() resolved to nothing. Add the arm via a shared own_call_type helper + a regression test. Also: drop stale self.Run(true) from the §2.3 lexical fixture, correct the parser self.-recovery comment, regenerate model/site + IDE wasm. Addresses Shockwave review. Co-Authored-By: Claude Opus 4.8 (1M context) # pre-commit-ok --- .../lexical/2-3-result-self-keywords.pds | 4 +- .../lexical/2-3-result-self-keywords.tokens | 7 +-- crates/pseudoscript-model/src/infer.rs | 44 +++++++++++++++--- crates/pseudoscript-syntax/src/parser.rs | 5 +- model/site/module/cli.html | 4 +- model/site/module/context.html | 2 +- model/site/module/model.html | 4 +- model/site/module/syntax.html | 4 +- model/site/universe.html | 4 +- .../lib/pds-ide-wasm/pseudoscript_ide_bg.wasm | Bin 2404898 -> 2405073 bytes 10 files changed, 55 insertions(+), 23 deletions(-) diff --git a/CONFORMANCE/lexical/2-3-result-self-keywords.pds b/CONFORMANCE/lexical/2-3-result-self-keywords.pds index f7f25303..faf5e4ed 100644 --- a/CONFORMANCE/lexical/2-3-result-self-keywords.pds +++ b/CONFORMANCE/lexical/2-3-result-self-keywords.pds @@ -1,6 +1,6 @@ // §2.3 — `self`/`Ok`/`Err`/`true`/`false` tokenise as keywords; `Result` and -// primitive `number` stay IDENT (classified in type position). +// primitive `number` stay IDENT. `self` is reserved (no call; ADR-041). Make(): Result; -r = self.Run(true) +r = self == true return Ok(false) diff --git a/CONFORMANCE/lexical/2-3-result-self-keywords.tokens b/CONFORMANCE/lexical/2-3-result-self-keywords.tokens index 57d42498..c6b37b36 100644 --- a/CONFORMANCE/lexical/2-3-result-self-keywords.tokens +++ b/CONFORMANCE/lexical/2-3-result-self-keywords.tokens @@ -12,11 +12,8 @@ SEMI@4:28 ";" IDENT@5:1 "r" EQ@5:3 "=" KW_SELF@5:5 "self" -DOT@5:9 "." -IDENT@5:10 "Run" -LPAREN@5:13 "(" -KW_TRUE@5:14 "true" -RPAREN@5:18 ")" +EQEQ@5:10 "==" +KW_TRUE@5:13 "true" KW_RETURN@6:1 "return" KW_OK@6:8 "Ok" LPAREN@6:10 "(" diff --git a/crates/pseudoscript-model/src/infer.rs b/crates/pseudoscript-model/src/infer.rs index 5258ed28..6ab9d23d 100644 --- a/crates/pseudoscript-model/src/infer.rs +++ b/crates/pseudoscript-model/src/infer.rs @@ -126,12 +126,7 @@ fn expr_type(ws: &Workspace, from_fqn: &str, expr: &ast::Expr) -> Option // §5.1: a bare same-node call resolves to a callable on the enclosing // node; its type is that callable's declared return type (ADR-041). ast::ExprKind::OwnCall { name, .. } => { - let node = enclosing_node(&ws.module(from_fqn)?.ast, expr.span.start)?; - ws.module_model(from_fqn)? - .members(&node) - .iter() - .find(|m| m.name == name.name && m.kind == crate::MemberKind::Callable) - .map(|m| m.ty.clone()) + own_call_type(ws, from_fqn, expr.span.start, &name.name) } // §7.5: arithmetic yields `number`, every other operator yields `bool`. ast::ExprKind::Binary { op, .. } => Some( @@ -197,9 +192,28 @@ fn postfix_type( result } +/// The declared return type of a bare same-node call (`Name(args)`, ADR-041): +/// find the callable named `name` on the node enclosing byte `at`, return its +/// declared type. Shared by `expr_type` (the direct result) and `base_owner` +/// (a postfix chain rooted on that result). +fn own_call_type(ws: &Workspace, from_fqn: &str, at: u32, name: &str) -> Option { + let node = enclosing_node(&ws.module(from_fqn)?.ast, at)?; + ws.module_model(from_fqn)? + .members(&node) + .iter() + .find(|m| m.name == name && m.kind == crate::MemberKind::Callable) + .map(|m| m.ty.clone()) +} + /// The node/data owner a postfix base denotes: the node/data a path names. fn base_owner(ws: &Workspace, from_fqn: &str, base: &ast::Expr) -> Option<(String, String)> { match &base.kind { + // A chain rooted at a bare same-node call: `Pick().first()` — resolve + // the call's return type, then the node/data that type names (ADR-041). + ast::ExprKind::OwnCall { name, .. } => { + let ty = own_call_type(ws, from_fqn, base.span.start, &name.name)?; + type_owner(ws, from_fqn, &ty) + } ast::ExprKind::Ref(ast::Ref::Path(path)) => { let segments: Vec<&str> = path.segments.iter().map(|s| s.name.as_str()).collect(); resolve_owner(ws, from_fqn, &segments).or_else(|| { @@ -407,6 +421,24 @@ mod tests { assert_eq!(owner, ("syntax".to_owned(), "Token".to_owned())); } + #[test] + fn owner_at_dot_types_a_chain_rooted_at_a_bare_same_node_call() { + // Regression (#71/#73): a postfix chain rooted at a bare same-node call — + // `pick().kind` — must type. `pick()` returns `Token`, so the `.` after + // the call resolves to the `Token` owner for member completion. Before + // the `OwnCall` arm in `base_owner`, the chain fell to `None` (ADR-041). + let src = "//! m\n\n\ + public data Token { kind: string }\n\n\ + public component Picker for M {\n \ + pick(): Token;\n \ + public run(): string {\n \ + return pick().kind\n }\n}\n"; + let workspace = ws(&[("m", src)]); + let dot = (src.find("pick().kind").unwrap() + "pick()".len()) as u32; + let owner = owner_at_dot(&workspace, "m", src, dot).expect("typed chain receiver"); + assert_eq!(owner, ("m".to_owned(), "Token".to_owned())); + } + #[test] fn local_types_read_literal_and_from_annotations() { let src = "//! m\n\nsystem S {\n go(): void {\n n: number = 42\n p: Parsed = Parsed from { n }\n }\n}\n\npublic data Parsed { x: number }\n"; diff --git a/crates/pseudoscript-syntax/src/parser.rs b/crates/pseudoscript-syntax/src/parser.rs index 8654e665..2a0d9591 100644 --- a/crates/pseudoscript-syntax/src/parser.rs +++ b/crates/pseudoscript-syntax/src/parser.rs @@ -1261,7 +1261,10 @@ impl Parser { Some(TokenKind::KwSelf) => { // `self.` is removed (ADR-041); a same-node call is bare // `Name(args)`. Recover `self.Name(args)` as that bare call so - // only this diagnostic surfaces and the body still resolves. + // the body still resolves: a name that resolves draws only this + // migration diagnostic. An unknown name additionally draws the + // normal unresolved-callable error — the same one `Name(args)` + // would draw after migrating, not extra noise. let token = self.bump().expect("peeked self"); if self.eat(TokenKind::Dot).is_some() { let name = self.expect_ident("callable name"); diff --git a/model/site/module/cli.html b/model/site/module/cli.html index 20dc584c..40d583df 100644 --- a/model/site/module/cli.html +++ b/model/site/module/cli.html @@ -14,9 +14,9 @@

CheckAModel

Statically validate a model and report what is wrong.

  • given a .pds source file
  • when the developer runs `pds check` on it
  • then the source is parsed with error recovery
  • and resolution, visibility, Result-flow, and return-coverage checks run
  • and every violation is reported as a diagnostic
  • but a well-formed model reports nothing and exits zero
Flow Flow — CheckAModel scroll to zoom · drag to pan
FEATURECheckAModelfor PseudoscriptGIVENa .pds source fileWHENthe developer runs `pds check` on itTHENthe source is parsed with errorrecoveryANDresolution, visibility, Result-flow,and return-coverage checks runANDevery violation is reported as adiagnosticBUTa well-formed model reports nothingand exits zero
FormatAModel

Reformat a model to one canonical form.

  • given a .pds source file with non-canonical spacing
  • when the developer runs `pds fmt`
  • then the source is parsed and pretty-printed to canonical PseudoScript
  • and comments and blank-line runs are preserved
  • but unparseable source is rejected without rewriting the file
Flow Flow — FormatAModel scroll to zoom · drag to pan
FEATUREFormatAModelfor PseudoscriptGIVENa .pds source file with non-canonicalspacingWHENthe developer runs `pds fmt`THENthe source is parsed andpretty-printed to canonicalPseudoScriptANDcomments and blank-line runs arepreservedBUTunparseable source is rejected withoutrewriting the file
EditModelInIde

Author a model in an editor with live diagnostics.

  • given an editor that speaks the Language Server Protocol
  • and `pds lsp` running as a child process over stdio
  • when the author changes a document
  • then the server re-checks the document from its current text
  • and diagnostics are published back to the editor
Flow Flow — EditModelInIde scroll to zoom · drag to pan
FEATUREEditModelInIdefor PseudoscriptGIVENan editor that speaks the LanguageServer ProtocolAND`pds lsp` running as a child processover stdioWHENthe author changes a documentTHENthe server re-checks the document fromits current textANDdiagnostics are published back to theeditor
ServeLiveDocs

Preview docs that rebuild as the model changes.

  • given a generated documentation site
  • when the developer runs `pds doc --serve --watch`
  • then the site is hosted over HTTP on localhost
  • and a change to any .pds or pds.toml rebuilds the site
  • and the browser live-reloads to the new version
Flow Flow — ServeLiveDocs scroll to zoom · drag to pan
FEATUREServeLiveDocsfor PseudoscriptGIVENa generated documentation siteWHENthe developer runs `pds doc --serve--watch`THENthe site is hosted over HTTP onlocalhostANDa change to any .pds or pds.tomlrebuilds the siteANDthe browser live-reloads to the newversion
Containers Container diagram scroll to zoom · drag to pan
PseudoscriptCONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERDoc`crates/pseudoscript-doc`. Turns a resolvedgraph into a Svelte-rendered,…CONTAINERDot`crates/pseudoscript-dot`. Runs thefour-pass layered pipeline over a `Graph` t…CONTAINEREmit`crates/pseudoscript-emit`. Projects a viewinto a `Scene` and renders it to SVG; C4…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERIdeSession`crates/pseudoscript-ide` — the IDEapplication, Rust compiled to a single wasm…CONTAINERWebIde`web-ide` — the IDE at `ide.pdscript.dev`: aSvelteKit shell on Cloudflare Workers stati…CONTAINERLanding`web-landing` — the marketing site at`pdscript.dev`. A static Svelte build on…CONTAINERLayout`crates/pseudoscript-layout`. Thegeometry/text `Core` and the sequence…CONTAINERLsp`crates/pseudoscript-lsp`. The stdiolanguage server (tower-lsp): workspace…CONTAINERLspCore`crates/pseudoscript-lsp-core`. The singlehome for language intelligence as…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…CONTAINERProject`crates/pseudoscript-project`. Thedisk-facing loader: resolves the workspace…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…CONTAINERUniverse`crates/pseudoscript-universe`. Maps theresolved C4 model into the software graph…PERSONDeveloperAuthor of architecture models: edits `.pds`files in an IDE and runs the CLI.SYSTEMEditorIDEs that speak the Language Server Protocol(VS Code, Neovim, …). The editor spawns `pd…SYSTEMLlmProviderThe author's configured OpenAI-compatiblecompletion provider — hosted (OpenAI,…PERSONVisitorA prospective user reading the landing page.prepareDiagnosticsrenderrenderMarkdownformatrunStdiocheckcheckWorkspaceModulesgraphfindRootloadrenderTokensopenDocumentprojectflowsfromModelsnapshotgridLayoutrunPipelinelayoutparseprepareDiagnosticscheckcheckWorkspaceModulesgraphbuildflowssnapshotcompletedependencyModulesdiagnosticshovermountoutlinesetSourcechatCompletefimCompletelistModelsopenopenIdeshowInstalldefinitionformatEdithovercheckparseprojectgraph
Generated by pds doc.
diff --git a/model/site/module/model.html b/model/site/module/model.html index e068f78f..1f5d67f6 100644 --- a/model/site/module/model.html +++ b/model/site/module/model.html @@ -98,9 +98,9 @@ (§5.1) or a `data` record field (§3.4).

Entities Entity diagram scroll to zoom · drag to pan
UNIONMemberKindCallableFieldRECORDFieldnamestringtysyntax::Typespansyntax::Span
container

Model #

public
model::Model

`crates/pseudoscript-model`. AST to one resolved graph; static checks (resolution, visibility, Result flow, return coverage); the §8.3 dependency resolver; and the LSP analysis primitives (completion, folding, semantic -tokens, inference). WASM-safe.

Inbound

Outbound

Components Component diagram scroll to zoom · drag to pan
PseudoscriptModelCOMPONENTResolverResolves a module's declarations into asymbol table (LANG.md §8). FQNs are…COMPONENTWorkspaceThe resolved set of modules keyed by FQN(LANG.md §8). Built once per workspace from…COMPONENTChecksStatic analysis (LANG.md §2.2, §2.3, §2.4,§3.3, §3.4, §3.5, §4, §5.1, §5.2, §6, §7,…COMPONENTCrossModule§8.2 — cross-module visibility resolution.Walks each module's qualified references —…COMPONENTArchitectureLANG.md §9 — architectural-principle lintsover the resolved graph. Beyond §8.2…COMPONENTResultFlow§6 — flow-sensitive `Result` / `Option`typestate. Each binding carries a state…COMPONENTReturnCoverageADR-016 — return coverage. A disclosednon-void callable MUST return on every path…COMPONENTMacroTargeting§2.4 / ADR-015 — macro targeting. Everybuilt-in macro (`onevent`, `schedule`,…COMPONENTParentKind§4 / ADR-010 — C4 parent-kindwell-formedness. A `for` parent links a nod…COMPONENTVariantCollision§3.5 / ADR-006 — union variant collision. Atop-level `data Name` followed by an inline…COMPONENTFeatureCheck§5.2 / §8.1 — feature checks. A feature's`for` target MUST resolve to a node, not a…COMPONENTReservedNames§2.3 / ADR-012 — reserved-word identifiers.A declared identifier MUST NOT be a reserve…COMPONENTTypeRefs§3.3 / §8.1 — type-reference resolution.Every named type in a declaration — a field…COMPONENTBuilderProjects the parsed, resolved workspace intothe architecture graph: structural nodes…COMPONENTDeps§8.3 — the dependency resolver. Parses amanifest's `[dependencies]` and a…COMPONENTCaretResolveCaret resolution — the engine every cursorfeature shares (`lsp_core` hover,…COMPONENTCompletionContext-aware completion (the model-nativeproducer `lsp_core` maps to LSP items):…COMPONENTFoldingThe foldable regions of a module: everymulti-line disclosed declaration and…COMPONENTSemanticAST-aware semantic colouring: eachidentifier classified by its declared role…COMPONENTInferenceLocal-binding type inference, for inlayhints and hover. Assignments are untyped (`…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERIdeSession`crates/pseudoscript-ide` — the IDEapplication, Rust compiled to a single wasm…CONTAINERLspCore`crates/pseudoscript-lsp-core`. The singlehome for language intelligence as…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…CONTAINERUniverse`crates/pseudoscript-universe`. Maps theresolved C4 model into the software graph…renderTokensbuildflowssnapshotbuildcheckgraphOfcheckcheckcheckbuildcheckcheckbuildWithExternalsparse
data

ModuleDiagnostics #

public
model::ModuleDiagnostics

One workspace module's diagnostics, attributed to its FQN. Every span lies in +tokens, inference). WASM-safe.

Inbound

Outbound

Components Component diagram scroll to zoom · drag to pan
PseudoscriptModelCOMPONENTResolverResolves a module's declarations into asymbol table (LANG.md §8). FQNs are…COMPONENTWorkspaceThe resolved set of modules keyed by FQN(LANG.md §8). Built once per workspace from…COMPONENTChecksStatic analysis (LANG.md §2.2, §2.3, §2.4,§3.3, §3.4, §3.5, §4, §5.1, §5.2, §6, §7,…COMPONENTCrossModule§8.2 — cross-module visibility resolution.Walks each module's qualified references —…COMPONENTArchitectureLANG.md §9 — architectural-principle lintsover the resolved graph. Beyond §8.2…COMPONENTResultFlow§6 — flow-sensitive `Result` / `Option`typestate. Each binding carries a state…COMPONENTReturnCoverageADR-016 — return coverage. A disclosednon-void callable MUST return on every path…COMPONENTMacroTargeting§2.4 / ADR-015 — macro targeting. Everybuilt-in macro (`onevent`, `schedule`,…COMPONENTParentKind§4 / ADR-010 — C4 parent-kindwell-formedness. A `for` parent links a nod…COMPONENTVariantCollision§3.5 / ADR-006 — union variant collision. Atop-level `data Name` followed by an inline…COMPONENTFeatureCheck§5.2 / §8.1 — feature checks. A feature's`for` target MUST resolve to a node, not a…COMPONENTReservedNames§2.3 / ADR-012 — reserved-word identifiers.A declared identifier MUST NOT be a reserve…COMPONENTTypeRefs§3.3 / §8.1 — type-reference resolution.Every named type in a declaration — a field…COMPONENTBuilderProjects the parsed, resolved workspace intothe architecture graph: structural nodes…COMPONENTDeps§8.3 — the dependency resolver. Parses amanifest's `[dependencies]` and a…COMPONENTCaretResolveCaret resolution — the engine every cursorfeature shares (`lsp_core` hover,…COMPONENTCompletionContext-aware completion (the model-nativeproducer `lsp_core` maps to LSP items):…COMPONENTFoldingThe foldable regions of a module: everymulti-line disclosed declaration and…COMPONENTSemanticAST-aware semantic colouring: eachidentifier classified by its declared role…COMPONENTInferenceLocal-binding type inference, for inlayhints and hover. Assignments are untyped (`…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERIdeSession`crates/pseudoscript-ide` — the IDEapplication, Rust compiled to a single wasm…CONTAINERLspCore`crates/pseudoscript-lsp-core`. The singlehome for language intelligence as…CONTAINERSyntax`crates/pseudoscript-syntax`. The foundationcrate: source text to tokens and a typed…CONTAINERUniverse`crates/pseudoscript-universe`. Maps theresolved C4 model into the software graph…renderTokensbuildflowssnapshotbuildcheckgraphOfcheckcheckcheckbuildcheckcheckbuildWithExternalsparse
data

ModuleDiagnostics #

public
model::ModuleDiagnostics

One workspace module's diagnostics, attributed to its FQN. Every span lies in that module's own source, so a tool with the FQN-to-file mapping publishes -each list against the right file.

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleDiagnosticsfqnstringdiagnosticssyntax::Diagnostic[]RECORDDiagnosticseveritysyntax::Severityspansyntax::SpancodestringcodeDescriptionstringmessagestring
data

ModuleEntry #

public
model::ModuleEntry

One module's parsed AST, resolved symbol table, and FQN, as held by a +each list against the right file.

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleDiagnosticsfqnstringdiagnosticssyntax::Diagnostic[]RECORDDiagnosticseveritysyntax::Severityspansyntax::SpancodestringcodeDescriptionstringmessagestring
data

ModuleEntry #

public
model::ModuleEntry

One module's parsed AST, resolved symbol table, and FQN, as held by a `Workspace`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDModuleEntryfqnstringastsyntax::Modulemodelmodel::SymbolTableRECORDModuleinnerDocssyntax::InnerDoc[]itemssyntax::Item[]spansyntax::SpanRECORDSymbolTablemodulePathstringsymbolsmodel::Symbol[]membersmodel::Member[]unionVariantsmodel::FieldlessVariants[]constantTypesmodel::ConstantType[]
data

NodeDoc #

public
model::NodeDoc

A node's documentation, lifted from its `///` block (LANG.md §2.1): the summary (compact-diagram text), the extended description (tooltip text), and its tags (` diff --git a/model/site/module/syntax.html b/model/site/module/syntax.html index 9723ac0a..3cdfb84c 100644 --- a/model/site/module/syntax.html +++ b/model/site/module/syntax.html @@ -24,7 +24,7 @@ tooling; the human-facing text is `message`. `codeDescription` is an optional URL the code resolves to — an article explaining the rule — which the LSP surfaces as the diagnostic's clickable link. Empty when the code carries no -article.

Entities Entity diagram scroll to zoom · drag to pan
RECORDDiagnosticseveritysyntax::Severityspansyntax::SpancodestringcodeDescriptionstringmessagestringUNIONSeverityErrorWarningInfoRECORDSpanstartnumberendnumber
data

DocBlock #

public
syntax::DocBlock

A `///` doc block split into summary and extended on the first blank `///` +article.

Entities Entity diagram scroll to zoom · drag to pan
RECORDDiagnosticseveritysyntax::Severityspansyntax::SpancodestringcodeDescriptionstringmessagestringUNIONSeverityErrorWarningInfoRECORDSpanstartnumberendnumber
data

DocBlock #

public
syntax::DocBlock

A `///` doc block split into summary and extended on the first blank `///` line (ADR-009): summary feeds compact diagrams, extended feeds tooltips, tags carry the ` ` markers.

#name
Entities Entity diagram scroll to zoom · drag to pan
RECORDDocBlocksummarystring[]extendedstring[]tagssyntax::Tag[]RECORDTagtextstringspansyntax::Span
data

Expr #

public
syntax::Expr

An expression (§7, §10): its form and source span.

Entities Entity diagram scroll to zoom · drag to pan
RECORDExprkindsyntax::ExprKindspansyntax::SpanUNIONExprKindMarkerFromPostfixOwnCallRefLitUnaryBinaryParenRECORDSpanstartnumberendnumber
data

ExprKind #

public
syntax::ExprKind

The expression forms (§10). `Marker` is a built-in generic constructor — @@ -68,7 +68,7 @@ matching the conformance token goldens.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSpanstartnumberendnumber
data

SpannedTrivia #

public
syntax::SpannedTrivia

A trivia element paired with the source span it occupies.

Entities Entity diagram scroll to zoom · drag to pan
RECORDSpannedTriviatriviasyntax::Triviaspansyntax::SpanUNIONTriviaLineCommentBlockCommentBlankLinesRECORDSpanstartnumberendnumber
data

StepKind #

public
syntax::StepKind

The step keyword class of a feature step (§5.2). `And`/`But` continue the preceding step's flow phase.

Entities Entity diagram scroll to zoom · drag to pan
UNIONStepKindGivenWhenThenAndBut
data

Stmt #

public
syntax::Stmt

A statement valid inside a callable body (§7), with the leading trivia that preceded it.

Entities Entity diagram scroll to zoom · drag to pan
RECORDStmtkindsyntax::StmtKindleadingTriviasyntax::SpannedTrivia[]spansyntax::SpanUNIONStmtKindAssignReturnIfForWhileExprStmtRECORDSpannedTriviatriviasyntax::Triviaspansyntax::SpanRECORDSpanstartnumberendnumber
data

StmtKind #

public
syntax::StmtKind

The statement forms (§7).

Entities Entity diagram scroll to zoom · drag to pan
UNIONStmtKindAssignReturnIfForWhileExprStmtRECORDAssignnamestringvaluesyntax::ExprRECORDReturnvaluesyntax::ExprRECORDIfcondsyntax::ExprthenBlocksyntax::BlockelseBlocksyntax::BlockRECORDForbindingstringitersyntax::Exprbodysyntax::BlockRECORDWhilecondsyntax::Exprbodysyntax::BlockRECORDExprStmtexprsyntax::Expr
data

StringLit #

public
syntax::StringLit
Entities Entity diagram scroll to zoom · drag to pan
RECORDStringLitrawstringspansyntax::SpanRECORDSpanstartnumberendnumber
container

Syntax #

public
syntax::Syntax

`crates/pseudoscript-syntax`. The foundation crate: source text to tokens -and a typed AST, emitting the shared `Diagnostic`. WASM-safe and I/O-free.

#critical

Inbound

Outbound

  • from cli::string
  • from format::Parsed
  • from model::Parsed
  • call syntax::Lexer · renderTokens
  • call syntax::Parser · parse
Components Component diagram scroll to zoom · drag to pan
PseudoscriptSyntaxCOMPONENTLexerHand-written lexer for LANG.md §2. One passyields the conformance token stream…COMPONENTLineIndexPrecomputed newline offsets turning a byteoffset into a 1-based (line, col) pair in…COMPONENTParserRecursive-descent parser for the §10 grammarwith error recovery: on unexpected input it…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…formatcheckcheckWorkspacecheckWorkspaceModulesgraphbuildlex
data

Tag #

public
syntax::Tag

A ` +and a typed AST, emitting the shared `Diagnostic`. WASM-safe and I/O-free.

#critical

Inbound

Outbound

  • from cli::string
  • from format::Parsed
  • from model::Parsed
  • call syntax::Lexer · renderTokens
  • call syntax::Parser · parse
Components Component diagram scroll to zoom · drag to pan
PseudoscriptSyntaxCOMPONENTLexerHand-written lexer for LANG.md §2. One passyields the conformance token stream…COMPONENTLineIndexPrecomputed newline offsets turning a byteoffset into a 1-based (line, col) pair in…COMPONENTParserRecursive-descent parser for the §10 grammarwith error recovery: on unexpected input it…CONTAINERCli`crates/pseudoscript` — the binary crate(`pds`). The composition root and only I/O…CONTAINERFormat`crates/pseudoscript-format`. The canonicalformatter: parse, then pretty-print the tre…CONTAINERModel`crates/pseudoscript-model`. AST to oneresolved graph; static checks (resolution,…formatcheckcheckWorkspaceModulesgraphbuildlex
data

Tag #

public
syntax::Tag

A ` ` tag from a doc block, including the leading `#` (§2.4).

#name
Entities Entity diagram scroll to zoom · drag to pan
RECORDTagtextstringspansyntax::SpanRECORDSpanstartnumberendnumber
data

Token #

public
syntax::Token

A lexical token: its kind, source span, and rendered lexeme (LANG.md §2).

For most tokens `text` is the raw source slice. For `Doc`/`InnerDoc` it is the doc text with the marker and surrounding whitespace stripped; for `Tag` it includes the leading `#`.

Entities Entity diagram scroll to zoom · drag to pan
RECORDTokenkindsyntax::TokenKindspansyntax::SpantextstringUNIONTokenKindKeywordIdentPunctuationStringLiteralNumberLiteralDocInnerDocTagHashLBracketRECORDSpanstartnumberendnumber
data

TokenKind #

public
syntax::TokenKind

Every lexical token class (LANG.md §2). The `name` rendering (e.g. diff --git a/model/site/universe.html b/model/site/universe.html index a304150f..f31657b0 100644 --- a/model/site/universe.html +++ b/model/site/universe.html @@ -12,8 +12,8 @@

PseudoScript
Model

Universe

The whole model as a 3D scene — drag to orbit, scroll to zoom, click a - node to open its docs.

Systems

Flows

  • dispatch 0 hops
  • run 22 hops
  • runAll 1 hop
  • add 0 hops
  • install 0 hops
  • list 0 hops
  • remove 0 hops
  • update 0 hops
  • runAll 1 hop
  • serve 54 hops
  • run 10 hops
  • run 6 hops
  • serve 0 hops
  • run 0 hops
  • run 9 hops
  • lang 0 hops
  • skill 0 hops
  • run 9 hops
  • run 3 hops
  • run 0 hops
  • editModel 11 hops
  • renderDocs 55 hops
  • installCli 1 hop
  • tryInBrowser 4 hops
Generated by pds doc.
- + node to open its docs.

Systems

Flows

  • dispatch 0 hops
  • run 18 hops
  • runAll 1 hop
  • add 0 hops
  • install 0 hops
  • list 0 hops
  • remove 0 hops
  • update 0 hops
  • runAll 1 hop
  • serve 54 hops
  • run 10 hops
  • run 6 hops
  • serve 0 hops
  • run 0 hops
  • run 9 hops
  • lang 0 hops
  • skill 0 hops
  • run 9 hops
  • run 3 hops
  • run 0 hops
  • editModel 11 hops
  • renderDocs 55 hops
  • installCli 1 hop
  • tryInBrowser 4 hops
Generated by pds doc.
+ diff --git a/web-ide/src/lib/pds-ide-wasm/pseudoscript_ide_bg.wasm b/web-ide/src/lib/pds-ide-wasm/pseudoscript_ide_bg.wasm index b661abd8fd0688784dbbd5cce55ef37cce1d7a91..f829094504791b224df46875a8771ec47f543b8b 100644 GIT binary patch delta 182447 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 S#R0L>maUdmY2Kx6inWrG=Uj;V> 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 delta 181836 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

  • 1*L{wXfJtA8ST*}=A;5DOjXk3!jCPRT@2=V%U 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 Date: Wed, 24 Jun 2026 17:53:53 +0000 Subject: [PATCH 3/3] =?UTF-8?q?feat!:=20remove=20`self`=20entirely=20?= =?UTF-8?q?=E2=80=94=20no=20longer=20a=20reserved=20word=20(refs=20#71)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the transitional `self` keyword kept only to diagnose the removed `self.` form. `self` is now an ordinary identifier: `self.Name(args)` parses as member access on an undeclared `self` and fails as `unresolved reference `self`` like any unknown name — no `self`-specific diagnostic. - Lexer: `KwSelf` token and `self` keyword removed (KEYWORDS 27->26). - Parser: `self.` recovery arm and expr/sync KwSelf cases removed. - Model: KwSelf arms dropped from resolve, complete, semantic; dead keyword filter removed. Ident fallback handles `self` as unknown. - Highlight: `self` no longer coloured as a keyword. - Spec: LANG.md §2.3 keyword grid; ADR-041 + decisions index reflect `self` freed; migration-diagnostic alternative recorded as rejected. - Conformance: `5-self-removed.reject` deleted (`self.X()` now parses); lexical fixture renamed `2-3-result-keywords`, `self` shown as IDENT; self_calls.feature asserts the generic unresolved-reference diagnostic. - Stale `self.` test fixtures migrated to bare calls; `self`-specific unit tests deleted or repurposed to the bare form. - Regenerated IDE wasm, skill zip, bundled LANG.md. Gate: cargo test --workspace green; clippy -D warnings clean; fmt clean; model_conformance green. Per @JonathanTurnock request to remove `self` completely. Co-Authored-By: Claude Opus 4.8 (1M context) # pre-commit-ok --- CONFORMANCE/lexical/2-3-result-keywords.pds | 6 +++ ...ords.tokens => 2-3-result-keywords.tokens} | 11 ++--- .../lexical/2-3-result-self-keywords.pds | 6 --- CONFORMANCE/lexical/README.md | 2 +- CONFORMANCE/syntax/5-self-removed.reject | 11 ----- .../syntax/5-self-removed.reject.expected | 1 - LANG.md | 4 +- crates/pseudoscript-doc/src/highlight.rs | 1 - crates/pseudoscript-doc/src/render.rs | 2 +- crates/pseudoscript-emit/src/project.rs | 2 +- .../tests/completion_adversarial.rs | 9 ---- crates/pseudoscript-lsp-core/src/complete.rs | 7 ++- crates/pseudoscript-model/src/complete.rs | 30 ++----------- crates/pseudoscript-model/src/resolve.rs | 12 +++--- crates/pseudoscript-model/src/semantic.rs | 5 +-- .../tests/features/self_calls.feature | 8 ++-- crates/pseudoscript-syntax/src/parser.rs | 40 ------------------ crates/pseudoscript-syntax/src/token.rs | 6 +-- decisions/041-drop-self-qualifier.md | 5 ++- decisions/README.md | 4 +- web-ide/src/lib/bundled/LANG.md | 4 +- .../lib/pds-ide-wasm/pseudoscript_ide_bg.wasm | Bin 2405073 -> 2402987 bytes web-ide/static/pseudocode-skill.zip | Bin 21086 -> 21092 bytes 23 files changed, 44 insertions(+), 132 deletions(-) create mode 100644 CONFORMANCE/lexical/2-3-result-keywords.pds rename CONFORMANCE/lexical/{2-3-result-self-keywords.tokens => 2-3-result-keywords.tokens} (74%) delete mode 100644 CONFORMANCE/lexical/2-3-result-self-keywords.pds delete mode 100644 CONFORMANCE/syntax/5-self-removed.reject delete mode 100644 CONFORMANCE/syntax/5-self-removed.reject.expected diff --git a/CONFORMANCE/lexical/2-3-result-keywords.pds b/CONFORMANCE/lexical/2-3-result-keywords.pds new file mode 100644 index 00000000..444f000e --- /dev/null +++ b/CONFORMANCE/lexical/2-3-result-keywords.pds @@ -0,0 +1,6 @@ +// §2.3 — `Ok`/`Err`/`true`/`false` tokenise as keywords; `Result`, `number`, +// and `self` (no longer reserved, ADR-041) stay IDENT. + +Make(): Result; +self = Ok(true) +return Ok(false) diff --git a/CONFORMANCE/lexical/2-3-result-self-keywords.tokens b/CONFORMANCE/lexical/2-3-result-keywords.tokens similarity index 74% rename from CONFORMANCE/lexical/2-3-result-self-keywords.tokens rename to CONFORMANCE/lexical/2-3-result-keywords.tokens index c6b37b36..70a42d08 100644 --- a/CONFORMANCE/lexical/2-3-result-self-keywords.tokens +++ b/CONFORMANCE/lexical/2-3-result-keywords.tokens @@ -9,11 +9,12 @@ COMMA@4:22 "," KW_ERR@4:24 "Err" RANGLE@4:27 ">" SEMI@4:28 ";" -IDENT@5:1 "r" -EQ@5:3 "=" -KW_SELF@5:5 "self" -EQEQ@5:10 "==" -KW_TRUE@5:13 "true" +IDENT@5:1 "self" +EQ@5:6 "=" +KW_OK@5:8 "Ok" +LPAREN@5:10 "(" +KW_TRUE@5:11 "true" +RPAREN@5:15 ")" KW_RETURN@6:1 "return" KW_OK@6:8 "Ok" LPAREN@6:10 "(" diff --git a/CONFORMANCE/lexical/2-3-result-self-keywords.pds b/CONFORMANCE/lexical/2-3-result-self-keywords.pds deleted file mode 100644 index faf5e4ed..00000000 --- a/CONFORMANCE/lexical/2-3-result-self-keywords.pds +++ /dev/null @@ -1,6 +0,0 @@ -// §2.3 — `self`/`Ok`/`Err`/`true`/`false` tokenise as keywords; `Result` and -// primitive `number` stay IDENT. `self` is reserved (no call; ADR-041). - -Make(): Result; -r = self == true -return Ok(false) diff --git a/CONFORMANCE/lexical/README.md b/CONFORMANCE/lexical/README.md index c4238fbd..a4614aa3 100644 --- a/CONFORMANCE/lexical/README.md +++ b/CONFORMANCE/lexical/README.md @@ -90,5 +90,5 @@ marker); a `?` in type position is a parse error, not a lexical one. | `2-1-comments-and-docs` | §2.1 — `//`/`/* */` discarded; `//!` → `INNER_DOC`; `///` → `DOC`. | | `2-2-paths-colon-vs-dot` | §2.2 — `::` (`COLONCOLON`) walks a path; `.` (`DOT`) accesses/invokes. | | `2-3-keywords-vs-idents` | §2.3 — keywords vs. greedily-matched identifiers that merely contain a keyword. | -| `2-3-result-self-keywords` | §2.3 — `self`/`Ok`/`Err`/`true`/`false` as keywords; `Result` and primitives as `IDENT`. | +| `2-3-result-keywords` | §2.3 — `Ok`/`Err`/`true`/`false` as keywords; `Result`, primitives, and `self` (freed by ADR-041) as `IDENT`. | | `2-4-hash-disambiguation` | §2.4 — `#name` tag in a doc, `#[` macro open, and a literal `#` inside a string. | diff --git a/CONFORMANCE/syntax/5-self-removed.reject b/CONFORMANCE/syntax/5-self-removed.reject deleted file mode 100644 index 6ed00e70..00000000 --- a/CONFORMANCE/syntax/5-self-removed.reject +++ /dev/null @@ -1,11 +0,0 @@ -// LANG.md §5.1 (ADR-041): the `self.` qualifier was removed. A same-node call -// is bare `Name(args)`; `self.Name(args)` no longer parses. - -public system Banking; - -public container Mainframe for Banking { - A(): void { - self.B() - } - B(): void; -} diff --git a/CONFORMANCE/syntax/5-self-removed.reject.expected b/CONFORMANCE/syntax/5-self-removed.reject.expected deleted file mode 100644 index a87c9f2f..00000000 --- a/CONFORMANCE/syntax/5-self-removed.reject.expected +++ /dev/null @@ -1 +0,0 @@ -`self.` is removed; call `Name(args)` directly (ADR-041) diff --git a/LANG.md b/LANG.md index 71f84ee1..3450d103 100644 --- a/LANG.md +++ b/LANG.md @@ -47,8 +47,8 @@ Every cross-reference is a **fully-qualified name (FQN)**, derived from the file ``` system container component person data constant for from -public self -return Ok Err Some None +public return Ok Err +Some None if else while in true false feature given when then and but diff --git a/crates/pseudoscript-doc/src/highlight.rs b/crates/pseudoscript-doc/src/highlight.rs index 0c441cef..1c7fc154 100644 --- a/crates/pseudoscript-doc/src/highlight.rs +++ b/crates/pseudoscript-doc/src/highlight.rs @@ -88,7 +88,6 @@ fn token_class(token: &Token) -> Option<&'static str> { | TokenKind::KwFor | TokenKind::KwFrom | TokenKind::KwPublic - | TokenKind::KwSelf | TokenKind::KwReturn | TokenKind::KwOk | TokenKind::KwErr diff --git a/crates/pseudoscript-doc/src/render.rs b/crates/pseudoscript-doc/src/render.rs index f15d128c..6d4db153 100644 --- a/crates/pseudoscript-doc/src/render.rs +++ b/crates/pseudoscript-doc/src/render.rs @@ -745,7 +745,7 @@ mod tests { #[test] fn every_diagram_is_adaptive_inline_svg() { - let src = "//! m\n/// Sys.\npublic system S;\npublic container C for m::S {\n #[manual]\n public Run() {\n self.Step()\n }\n Step();\n}\n"; + let src = "//! m\n/// Sys.\npublic system S;\npublic container C for m::S {\n #[manual]\n public Run() {\n Step()\n }\n Step();\n}\n"; let g = graph(&[WorkspaceModule::new("m", src)]); let pages = build_pages( &g, diff --git a/crates/pseudoscript-emit/src/project.rs b/crates/pseudoscript-emit/src/project.rs index 63974409..50c2b980 100644 --- a/crates/pseudoscript-emit/src/project.rs +++ b/crates/pseudoscript-emit/src/project.rs @@ -1331,7 +1331,7 @@ mod tests { "m".to_owned(), "//! m\npublic system Shop;\npublic container Api for Shop;\n\ /// Validates orders.\npublic component Validator for m::Api {\n \ - #[http]\n public Check(): void { self.Help() }\n Help(): void;\n}" + #[http]\n public Check(): void { Help() }\n Help(): void;\n}" .to_owned(), ); let Scene::Sequence(seq) = project( diff --git a/crates/pseudoscript-ide/tests/completion_adversarial.rs b/crates/pseudoscript-ide/tests/completion_adversarial.rs index a0a631cd..ca68fd0f 100644 --- a/crates/pseudoscript-ide/tests/completion_adversarial.rs +++ b/crates/pseudoscript-ide/tests/completion_adversarial.rs @@ -171,15 +171,6 @@ fn binding_type_annotation_offers_types_only() { // --- member `.` : only the receiver's members ---------------------------- -#[test] -fn self_member_offers_own_members_not_other_nodes() { - let l = labels( - "//! m\npublic system A {\n alpha(): void;\n}\npublic container C for m::A {\n beta(): void {\n self.~\n }\n}\n", - ); - assert!(has(&l, "beta"), "own member missing: {l:?}"); - assert_none(&l, &["alpha"]); // A's member must not leak onto C -} - #[test] fn cross_module_member_offers_public_only() { // `dep::core::Svc.` — a private member of a dependency node is not callable diff --git a/crates/pseudoscript-lsp-core/src/complete.rs b/crates/pseudoscript-lsp-core/src/complete.rs index f731a089..a1dba09d 100644 --- a/crates/pseudoscript-lsp-core/src/complete.rs +++ b/crates/pseudoscript-lsp-core/src/complete.rs @@ -70,9 +70,12 @@ mod tests { #[test] fn adapter_scopes_members_with_prefix() { - let src = "//! m\n\nsystem S {\n run(): void {\n self.he\n }\n helper(x: number): uuid;\n}\n"; + // Member completion after a node receiver's `.` offers that node's + // members (`helper`), not the general keyword scope, through the LSP + // adapter. + let src = "//! m\n\nsystem S {\n run(): void {\n Engine.he\n }\n}\ncomponent Engine for m::S {\n helper(x: number): uuid;\n}\n"; let ws = workspace(&[("m", src)]); - let offset = (src.find("self.he").unwrap() + "self.he".len()) as u32; + let offset = (src.find("Engine.he").unwrap() + "Engine.he".len()) as u32; let labels = labels_at(&ws, "m", src, offset); assert!(labels.contains(&"helper".to_owned()), "{labels:?}"); assert!( diff --git a/crates/pseudoscript-model/src/complete.rs b/crates/pseudoscript-model/src/complete.rs index 4d3564bc..791d6ff4 100644 --- a/crates/pseudoscript-model/src/complete.rs +++ b/crates/pseudoscript-model/src/complete.rs @@ -179,7 +179,7 @@ fn member_items( tokens: &[Token], dot: usize, ) -> Vec { - // The token-based path covers `self.`, `Module::Node.`, and a bare binding. + // The token-based path covers `Module::Node.` and a bare binding. // A multi-step chain (`Repo.fetch(id).value.`) has no single base token, so // fall back to typing the receiver expression at the cursor via the AST. let owner = owner_before(ws, from_fqn, tokens, dot) @@ -208,8 +208,8 @@ fn member_items( } /// The `(module, node-name)` the base token before `tokens[dot]` denotes: -/// `self`'s enclosing node, a `::`-qualified node in another module -/// (`identity::sessions.`), or an in-scope node name in this module. +/// a `::`-qualified node in another module (`identity::sessions.`), or an +/// in-scope node name in this module. fn owner_before( ws: &Workspace, from_fqn: &str, @@ -218,10 +218,6 @@ fn owner_before( ) -> Option<(String, String)> { let base = tokens.get(dot.checked_sub(1)?)?; match base.kind { - TokenKind::KwSelf => { - let node = enclosing_node(&ws.module(from_fqn)?.ast, base.span.start)?; - Some((from_fqn.to_owned(), node)) - } // `a::b::Node.` — the base is qualified, so it names a symbol in the // module its qualifiers spell, not this one. Offered only when public // (or in this module), mirroring `::` path resolution (§8.2). @@ -328,11 +324,8 @@ fn type_items(ws: &Workspace) -> Vec { /// cross-module reference can be started — pick the module, then `::` drills into /// its public symbols). fn general_items(ws: &Workspace, from_fqn: &str, offset: u32) -> Vec { - // `self` stays a reserved word only to diagnose the removed `self.` form - // (ADR-041); it MUST NOT appear in a model, so never offer it. let keywords = TokenKind::KEYWORDS .iter() - .filter(|k| **k != "self") .map(|k| item(k, CompletionKind::Keyword, "keyword")); let modules = other_modules(ws, from_fqn); let Some(entry) = ws.module(from_fqn) else { @@ -610,23 +603,6 @@ mod tests { // Each narrowing context must stay scoped — the trigger before the prefix // governs — and must not leak the general keyword set. - #[test] - fn legacy_self_dot_still_completes_members() { - // `self.` is removed syntax (ADR-041), but the token-based member - // completion still resolves it gracefully so a user mid-migration is - // not stranded; the `.` narrowing scope must not leak the keyword set. - let src = "//! m\n\nsystem S {\n run(): void {\n self.he\n }\n helper(x: number): uuid;\n}\n"; - let ws = workspace(&[("m", src)]); - let offset = (src.find("self.he").unwrap() + "self.he".len()) as u32; - let labels = labels_at(&ws, "m", src, offset); - assert!(labels.contains(&"helper".to_owned()), "{labels:?}"); - assert!(labels.contains(&"run".to_owned()), "{labels:?}"); - assert!( - !labels.contains(&"system".to_owned()), - "general scope leaked: {labels:?}" - ); - } - #[test] fn types_after_colon_with_prefix() { let src = "//! m\n\ndata D { x: numb }\n"; diff --git a/crates/pseudoscript-model/src/resolve.rs b/crates/pseudoscript-model/src/resolve.rs index 18d5e190..6feec103 100644 --- a/crates/pseudoscript-model/src/resolve.rs +++ b/crates/pseudoscript-model/src/resolve.rs @@ -195,7 +195,7 @@ fn unique_symbol<'a>(ws: &'a Workspace, from_fqn: &str, name: &str) -> Option<&' matches.next().is_none().then_some(first) } -/// Resolves `.member` after a `self` or node/data base — including a qualified, +/// Resolves `.member` after a node/data base — including a qualified, /// cross-module base (`a::Svc.op`). fn resolve_member(ws: &Workspace, from_fqn: &str, tokens: &[Token], idx: usize) -> Option { let member_name = tokens[idx].text.as_str(); @@ -204,10 +204,6 @@ fn resolve_member(ws: &Workspace, from_fqn: &str, tokens: &[Token], idx: usize) let base = tokens.get(base_idx)?; let symbol = match base.kind { - TokenKind::KwSelf => { - let node = enclosing_node(&ws.module(from_fqn)?.ast, base.span.start)?; - ws.module(from_fqn)?.model.symbol(&node)? - } TokenKind::Ident => { let segments = path_segments(tokens, base_idx); resolve_node(ws, from_fqn, &segments)? @@ -385,8 +381,10 @@ mod tests { } #[test] - fn self_member_resolves_to_callable() { - let src = "//! m\n\nsystem S {\n run(): void { self.helper() }\n helper(): void {}\n}\n"; + fn bare_same_node_call_resolves_to_callable() { + // §5.1, ADR-041: a bare same-node call `helper()` resolves to the + // enclosing node's callable — goto-definition lands on its declaration. + let src = "//! m\n\nsystem S {\n run(): void { helper() }\n helper(): void {}\n}\n"; let mods = [("m", src)]; let ws = workspace(&mods); let hit = hit_at(&ws, "m", src, "helper", 1); diff --git a/crates/pseudoscript-model/src/semantic.rs b/crates/pseudoscript-model/src/semantic.rs index 6a400335..9fda6794 100644 --- a/crates/pseudoscript-model/src/semantic.rs +++ b/crates/pseudoscript-model/src/semantic.rs @@ -120,7 +120,6 @@ fn is_keyword(kind: TokenKind) -> bool { | TokenKind::KwFor | TokenKind::KwFrom | TokenKind::KwPublic - | TokenKind::KwSelf | TokenKind::KwReturn | TokenKind::KwOk | TokenKind::KwErr @@ -451,12 +450,12 @@ mod tests { #[test] fn callable_param_type_and_calls() { - let src = "//! m\n\nsystem S {\n run(name: string): uuid {\n return self.alloc(name)\n }\n}\n"; + let src = "//! m\n\nsystem S {\n run(name: string): uuid {\n return alloc(name)\n }\n alloc(n: string): uuid;\n}\n"; let tokens = semantic_tokens(src); assert_eq!(at(&tokens, src, "run").kind, SemKind::Method); assert_eq!(at(&tokens, src, "name").kind, SemKind::Parameter); assert_eq!(at(&tokens, src, "string").kind, SemKind::Type); - assert_eq!(at(&tokens, src, "self").kind, SemKind::Keyword); + // A bare same-node call (ADR-041) colours as a method invocation. assert_eq!(at(&tokens, src, "alloc").kind, SemKind::Method); } diff --git a/crates/pseudoscript-model/tests/features/self_calls.feature b/crates/pseudoscript-model/tests/features/self_calls.feature index d40df9f9..5f99741a 100644 --- a/crates/pseudoscript-model/tests/features/self_calls.feature +++ b/crates/pseudoscript-model/tests/features/self_calls.feature @@ -1,8 +1,8 @@ Feature: Bare same-node calls resolve to a same-node callable (LANG.md §5.1, ADR-041) A same-node callable is invoked by a bare call `Name(args)`. A bare call - naming no callable of the enclosing node MUST be rejected. The removed `self.` - qualifier is diagnosed. + naming no callable of the enclosing node MUST be rejected. `self` is no longer + reserved: `self.Name(args)` resolves nothing — `self` is an unknown reference. Scenario: A same-node call to an undeclared callable is rejected Given the model file: @@ -39,7 +39,7 @@ Feature: Bare same-node calls resolve to a same-node callable (LANG.md §5.1, AD """ Then there are no diagnostics - Scenario: The removed `self.` qualifier is diagnosed + Scenario: `self` is an ordinary identifier — `self.Name(args)` is unresolved Given the model file: """ //! example @@ -49,4 +49,4 @@ Feature: Bare same-node calls resolve to a same-node callable (LANG.md §5.1, AD helper(): void { self.helper() } } """ - Then the diagnostics include "`self.` is removed; call `Name(args)` directly (ADR-041)" + Then the diagnostics include "unresolved reference `self`" diff --git a/crates/pseudoscript-syntax/src/parser.rs b/crates/pseudoscript-syntax/src/parser.rs index 2a0d9591..8e8894dd 100644 --- a/crates/pseudoscript-syntax/src/parser.rs +++ b/crates/pseudoscript-syntax/src/parser.rs @@ -1027,7 +1027,6 @@ impl Parser { | TokenKind::KwErr | TokenKind::KwSome | TokenKind::KwNone - | TokenKind::KwSelf | TokenKind::Ident | TokenKind::String | TokenKind::Number @@ -1258,44 +1257,6 @@ impl Parser { kind: ExprKind::Literal(lit), } } - Some(TokenKind::KwSelf) => { - // `self.` is removed (ADR-041); a same-node call is bare - // `Name(args)`. Recover `self.Name(args)` as that bare call so - // the body still resolves: a name that resolves draws only this - // migration diagnostic. An unknown name additionally draws the - // normal unresolved-callable error — the same one `Name(args)` - // would draw after migrating, not extra noise. - let token = self.bump().expect("peeked self"); - if self.eat(TokenKind::Dot).is_some() { - let name = self.expect_ident("callable name"); - let (args, end) = if self.at(TokenKind::LParen) { - self.parse_call_args() - } else { - (Vec::new(), name.span.end) - }; - let span = Span::new(token.span.start, end); - self.error( - span, - "`self.` is removed; call `Name(args)` directly (ADR-041)", - ); - Expr { - kind: ExprKind::OwnCall { name, args }, - span, - } - } else { - self.error( - token.span, - "`self` is removed; call a same-node callable as `Name(args)` (ADR-041)", - ); - Expr { - kind: ExprKind::Ref(Ref::Path(Path { - segments: Vec::new(), - span: token.span, - })), - span: token.span, - } - } - } Some(TokenKind::LParen) => { let open = self.bump().expect("peeked `(`"); let inner = self.parse_expr(); @@ -1580,7 +1541,6 @@ impl Parser { | TokenKind::KwFor | TokenKind::KwFrom | TokenKind::KwPublic - | TokenKind::KwSelf | TokenKind::KwReturn | TokenKind::KwOk | TokenKind::KwErr diff --git a/crates/pseudoscript-syntax/src/token.rs b/crates/pseudoscript-syntax/src/token.rs index 35232a60..e798e089 100644 --- a/crates/pseudoscript-syntax/src/token.rs +++ b/crates/pseudoscript-syntax/src/token.rs @@ -22,7 +22,6 @@ pub enum TokenKind { KwFor, KwFrom, KwPublic, - KwSelf, KwReturn, KwOk, KwErr, @@ -106,7 +105,6 @@ impl TokenKind { TokenKind::KwFor => "KW_FOR", TokenKind::KwFrom => "KW_FROM", TokenKind::KwPublic => "KW_PUBLIC", - TokenKind::KwSelf => "KW_SELF", TokenKind::KwReturn => "KW_RETURN", TokenKind::KwOk => "KW_OK", TokenKind::KwErr => "KW_ERR", @@ -164,7 +162,7 @@ impl TokenKind { /// The reserved keyword spellings (§2.3), in declaration order. Every entry /// is recognised by [`TokenKind::keyword`]; a test pins them in sync. - pub const KEYWORDS: [&str; 27] = [ + pub const KEYWORDS: [&str; 26] = [ "system", "container", "component", @@ -174,7 +172,6 @@ impl TokenKind { "for", "from", "public", - "self", "return", "Ok", "Err", @@ -211,7 +208,6 @@ impl TokenKind { "for" => TokenKind::KwFor, "from" => TokenKind::KwFrom, "public" => TokenKind::KwPublic, - "self" => TokenKind::KwSelf, "return" => TokenKind::KwReturn, "Ok" => TokenKind::KwOk, "Err" => TokenKind::KwErr, diff --git a/decisions/041-drop-self-qualifier.md b/decisions/041-drop-self-qualifier.md index 22696358..4788a380 100644 --- a/decisions/041-drop-self-qualifier.md +++ b/decisions/041-drop-self-qualifier.md @@ -2,7 +2,7 @@ **Status:** Accepted **Supersedes:** ADR-004 -**Affects:** LANG.md §3.3, §5.1, §8.1, §9.2, §10 +**Affects:** LANG.md §2.3, §3.3, §5.1, §8.1, §9.2, §10 ## Context @@ -16,7 +16,7 @@ A direct call (`Node.method(args)`) does not have this problem: the renderer fol - A same-node callable is invoked by a bare call `Name(args)` — a sibling, or the enclosing callable itself for recursion. The `self.` qualifier is removed. - A bare name **in call position** (immediately followed by `(`) resolves to a callable on the enclosing node. A bare name not in call position is unchanged: it resolves only to a parameter, a binding, or a `for` binding (§8.1, ADR-030). -- `self` stays a reserved word (§2.3) so the parser diagnoses the removed `self.` form and points at the bare call. `self` MUST NOT appear in a model. +- `self` is not reserved (§2.3). It is an ordinary identifier with no special meaning; `self.Name(args)` parses as member access on an undeclared `self` and fails resolution like any unknown name. No `self`-specific diagnostic. - Sequence rendering: a same-node call renders as a self-message **and** the renderer follows the callable's body inline, emitting its cross-boundary calls, exactly as a direct call to a disclosed callee does. Recursion is stack-guarded — an in-flight callee renders as a single self-message with no expansion (§9.2). A method on a local value or chain intermediate (`x.f()`) stays a leaf self-message; it names no node callable and has no body to follow. ## Consequences @@ -28,5 +28,6 @@ A direct call (`Node.method(args)`) does not have this problem: the renderer fol - The checker resolves a bare call to the enclosing node's callables and applies the same arity and argument-type checks as any call (ADR-022, ADR-023); a name matching no callable on the node is reported as unresolved. - The implementation splits the trace step: a same-node call follows its body, a local-value method stays a leaf — both still render as self-messages. - The worked model, the bundled samples, the conformance cases, and the authoring skill are migrated to the bare form. +- Rejected alternative: keep `self` reserved to emit a migration diagnostic on the removed `self.` form. The value is transitional only, and it leaves a dead keyword in the grammar — every lexer, highlighter, and completion path carries a `self` case for a token no valid model uses. Pre-1.0, with no published models to migrate, the cost outweighs the guided error; `self` is freed as an ordinary identifier instead. - Rejected alternative: keep `self.` and only fix the renderer to follow its body (issue #71's fallback). The qualifier carries no information the enclosing scope does not already supply, and its collapsed self-message was the source of the silent drop. A bare call is indistinguishable from any other call in the model, so the renderer follows it under one rule — one call shape, one rendering. Two spellings for one call is the divergence ADR-036 settled against. - The call-vs-construction ambiguity does not arise: construction is `Type from { … }` (§7.2), never `Name(args)`; a bare name followed by `(` is unambiguously a call. diff --git a/decisions/README.md b/decisions/README.md index 39129d1e..bbebe6a4 100644 --- a/decisions/README.md +++ b/decisions/README.md @@ -178,7 +178,7 @@ Read in full for the `//! Configuration` shadowing bug that motivated it, and th ## [030 — A node, type, or variant reference is always its FQN](030-require-full-qualification.md) -Every reference to a node, type, or union variant MUST be its FQN, including one in the same module; a bare leaf name resolves only to a parameter, a binding, or a `for` binding. `self`, member access, primitives, and `Result`/`Option` stay bare. The checker flags a bare same-module node/type/variant name and is gated to a named module — the path-less single-file check stays lenient. +Every reference to a node, type, or union variant MUST be its FQN, including one in the same module; a bare leaf name resolves only to a parameter, a binding, or a `for` binding. Member access, primitives, and `Result`/`Option` stay bare. The checker flags a bare same-module node/type/variant name and is gated to a named module — the path-less single-file check stays lenient. Read in full for the four-meanings-per-bare-name ambiguity it removes, and the workspace-vs-anonymous gating. @@ -244,6 +244,6 @@ Read in full for the Java/C#-precedent rationale and the rejected implicit-void ## [041 — Same-node calls are bare; `self.` is dropped](041-drop-self-qualifier.md) -`self.Name(args)` is removed; a same-node callable is invoked by a bare call `Name(args)`. A bare name in call position resolves to a callable on the enclosing node; `self` stays reserved only to diagnose the removed form. The renderer follows a same-node call's body and emits its cross-boundary calls, ending the silent-drop trap (issue #71) ADR-004's collapsed self-message caused. **Supersedes ADR-004.** +`self.Name(args)` is removed; a same-node callable is invoked by a bare call `Name(args)`. A bare name in call position resolves to a callable on the enclosing node; `self` is not reserved — it is an ordinary identifier with no special meaning. The renderer follows a same-node call's body and emits its cross-boundary calls, ending the silent-drop trap (issue #71) ADR-004's collapsed self-message caused. **Supersedes ADR-004.** Read in full for the call-vs-construction non-ambiguity, the same-node-vs-local-value rendering split, and the rejected fix-renderer-only alternative. diff --git a/web-ide/src/lib/bundled/LANG.md b/web-ide/src/lib/bundled/LANG.md index 71f84ee1..3450d103 100644 --- a/web-ide/src/lib/bundled/LANG.md +++ b/web-ide/src/lib/bundled/LANG.md @@ -47,8 +47,8 @@ Every cross-reference is a **fully-qualified name (FQN)**, derived from the file ``` system container component person data constant for from -public self -return Ok Err Some None +public return Ok Err +Some None if else while in true false feature given when then and but diff --git a/web-ide/src/lib/pds-ide-wasm/pseudoscript_ide_bg.wasm b/web-ide/src/lib/pds-ide-wasm/pseudoscript_ide_bg.wasm index f829094504791b224df46875a8771ec47f543b8b..a12ee8bd5b24c74b24065f0189f00a599a20bf7e 100644 GIT binary patch delta 141334 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 diff --git a/web-ide/static/pseudocode-skill.zip b/web-ide/static/pseudocode-skill.zip index be96ea5fd0f14b4f6f86b91573ffad2d61a046a5..93fe390a1a969752ad638e15b9b0337c59039f81 100644 GIT binary patch delta 18448 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 z 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 D6H^T` delta 18444 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