@warren-dean/code-kit 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +37 -0
- package/README.md +19 -9
- package/bin/code-kit.mjs +353 -39
- package/hooks/guard-bash.mjs +30 -14
- package/hooks/lane-audit.mjs +44 -1
- package/hooks/lib/adapters/context-graph.mjs +75 -6
- package/hooks/lib/adapters/index.mjs +18 -0
- package/hooks/lib/config.mjs +43 -2
- package/hooks/lib/dependencies.mjs +26 -9
- package/hooks/lib/harness.mjs +2 -2
- package/hooks/lib/next.mjs +34 -3
- package/hooks/lib/plan.mjs +29 -0
- package/hooks/lib/queue.mjs +75 -0
- package/hooks/lib/reviews.mjs +18 -0
- package/hooks/lib/rules.mjs +8 -4
- package/hooks/lib/shell.mjs +1 -1
- package/hooks/lib/timeline.mjs +77 -0
- package/hooks/mod/art.mjs +200 -0
- package/hooks/mod/loop.mjs +68 -0
- package/hooks/mod/panes.mjs +943 -0
- package/hooks/mod/register.mjs +978 -15
- package/hooks/mod/register.test.ts +1449 -14
- package/hooks/mod/review.mjs +102 -0
- package/hooks/mod/view.mjs +430 -38
- package/package.json +1 -1
- package/skills/init/SKILL.md +5 -4
- package/skills/review/SKILL.md +8 -1
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"name": "code-kit",
|
|
10
10
|
"source": "./",
|
|
11
11
|
"description": "Keeps AI coding agents inside your project's rules, from idea to merged code: spec design, lanes, layer rules, protected paths with an approval log, spec-check and design gates, proof-before-finish checks, dispatch, review, build status and CI verification, configured per project from its docs",
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.7.0",
|
|
13
13
|
"category": "development",
|
|
14
14
|
"tags": ["guardrails", "architecture", "lanes", "layers", "spec-driven", "ci", "multi-agent"],
|
|
15
15
|
"license": "MIT"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Keeps AI coding agents inside your project's rules, from idea to merged code: spec design, lanes, layer rules, protected paths with an approval log, spec-check and design gates, proof-before-finish checks, dispatch, review, build status and CI verification, configured per project from its docs",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Warren Langeveldt"
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
What changed in each release of code-kit, newest first. Versions follow the plugin manifest and the npm package `@warren-dean/code-kit`. Each release is also on [GitHub Releases](https://github.com/warrendeanlangeveldt/code-kit/releases).
|
|
4
4
|
|
|
5
|
+
## 0.7.0 (2026-10-10)
|
|
6
|
+
|
|
7
|
+
The rest of the harness, in the mod (Claude Code 2.1.287 or later), and fixes from building a whole app with it.
|
|
8
|
+
|
|
9
|
+
**The lead keeps the build moving**
|
|
10
|
+
|
|
11
|
+
- **The lead loop.** When the lead is idle, the mod prompts it with the next step `code-kit next` reports: dispatch the ready stories, review a finished branch, build the lead's own story, or merge the head of the queue. `harness.autonomy` decides how hands-off it is: `autonomous` takes each step, `propose` offers it in the band with Go, `off` does nothing. Until you choose, `init` asks, and the loop offers its first step with Keep going, Ask each time and Off.
|
|
12
|
+
- **A step that doesn't take goes to you.** The lead is prompted with one step at most twice in a row; after that the band offers it ("Merge lead/st-1: still next after 2 prompts. Ask the lead again?").
|
|
13
|
+
- **Stalls.** A lane agent with no tool call for `harness.stall.nudgeMinutes` is nudged; at `restartMinutes` the lead stops it and dispatches its story again; after `maxRestarts` the band asks you.
|
|
14
|
+
- **Pause and Resume** in the band, and "Milestone done" when every story is.
|
|
15
|
+
- **Hold and ask.** A call your approval would allow (a new package, a protected file, a kit edit) waits up to `harness.hold.minutes` while the band asks you, then runs once you approve, or is refused.
|
|
16
|
+
|
|
17
|
+
**Review and merge**
|
|
18
|
+
|
|
19
|
+
- **The reviewer agent.** With `harness.agents.reviewer.on`, a read-only agent reviews each finished branch in the background, grades its findings blocker, concern or nit, and the lead's review starts from them. A blocker means the branch goes back.
|
|
20
|
+
- **The merge queue.** Branches that pass review merge one at a time, in the order they passed, each verified against the base as it is then. One that conflicts or fails is sent back to its lane. `code-kit queue` lists it, `queue add|drop` changes it, `queue merge --delegated|--person` merges the head.
|
|
21
|
+
- **The first merge is yours.** Who may merge is read from the config committed on the base, so before the base has one, `next`, the band and the refusal all say the first merge, which brings code-kit's rules onto it, is yours (Merge in the band, or `code-kit queue merge --person`). After it, the lead merges where the rules delegate it.
|
|
22
|
+
- A merged lane's worktree is removed when it holds nothing uncommitted. Its branch is kept.
|
|
23
|
+
|
|
24
|
+
**What you see**
|
|
25
|
+
|
|
26
|
+
- **The Lanes pane, redone.** Counts in the header, what needs you with a letter each, tabs for Lanes, Queue, Usage and Map, keys on every action, a pixel character per lane that shows what it's doing, and a timeline of each story's work.
|
|
27
|
+
- **The story drill-down:** its requirements, spec-check, review findings, verify, usage, the steps taken and the diff.
|
|
28
|
+
- **The traceability map:** every requirement as a cell, by spec, coloured by its state, live.
|
|
29
|
+
- **Context Graph in the lanes,** when it's installed: each lane's cards owed, its understanding of the files it edits, and the rules on them.
|
|
30
|
+
- New commands: `code-kit story <id>`, `code-kit timeline`, `code-kit hold`, `code-kit queue`.
|
|
31
|
+
|
|
32
|
+
**Fixes**
|
|
33
|
+
|
|
34
|
+
- Text a command carries isn't a command: a quoted `echo` that mentions `npm install` adds no dependency, a heredoc or quoted newline doesn't end a command, and a redirect elsewhere in a line isn't a write to the kit.
|
|
35
|
+
- A read-only agent (a reviewer, a card writer) is judged by what its own shell command changed, not by the lead's uncommitted work in the checkout it shares. Read-only agents may write the paths any actor may, such as Context Graph's cards and decisions.
|
|
36
|
+
- An env file's template (`.env.example`, `.env.local.sample`) isn't treated as a secret.
|
|
37
|
+
- Context Graph's settings committed with your `Ctx-Ratified-By` trailer pass verify, as its graph does.
|
|
38
|
+
- Refusing a shell command that names the approval log or an approval now says to read it with the Read tool.
|
|
39
|
+
- `init` offers `/context-graph:init` when Context Graph is installed but has no graph.
|
|
40
|
+
- The mod keeps working in a headless session where the agent list or registration fails.
|
|
41
|
+
|
|
5
42
|
## 0.6.0 (2026-10-10)
|
|
6
43
|
|
|
7
44
|
The first parts of the harness, in the mod (Claude Code 2.1.287 or later):
|
package/README.md
CHANGED
|
@@ -267,6 +267,8 @@ Editing an agent file can't loosen a rule. And the agent files are kit files (`.
|
|
|
267
267
|
With Claude Code 2.1.287 or later, code-kit's mod shows the project in the session, in the terminal (VS Code's terminal included) and the Desktop app. Older versions skip it and keep enforcing everything through the hooks.
|
|
268
268
|
|
|
269
269
|
- **The band** sits above the prompt whenever something waits for you, and is gone when nothing does. It shows:
|
|
270
|
+
- an agent's call held for you: installing a new package, writing or committing a protected file, or a lane changing the kit. Rather than stopping the agent, the call waits while the band asks ("web wants to install dayjs · 1:53"). **Approve** opens the confirmation and, once you confirm, the same call runs; **Refuse**, or no answer within `harness.hold.minutes` (2 unless set), refuses it as before. Under `autonomy: autonomous`, a call within `approvals.delegate` is approved as delegated without asking. Nothing is held under `claude -p` or the SDK, where nobody can answer;
|
|
271
|
+
- the lead loop, under `harness.autonomy`. `/code-kit:init` asks you how hands-off you want it. Until you've chosen, the loop's first step waits in the band ("code-kit can keep the build moving between your prompts") with **Keep going**, **Ask each time** and **Off**, and your answer is recorded as your setting. Once the lead has finished a turn, the loop keeps the build moving: with the lead idle and nothing typed in the prompt, it asks `code-kit next` and prompts the lead to dispatch the ready stories, review a finished one, or build its own, never the same step twice while nothing has changed. A step the lead was prompted with twice in a row and that is still next goes to you instead, in the band: "Merge lead/st-1: still next after 2 prompts. Ask the lead again?" with **Go**. **Pause** and **Resume** stop and start it. Under `propose`, each step waits in the band for **Go**; under `off`, the loop does nothing. A lane agent with no tool call for `harness.stall.nudgeMinutes` (5) is messaged; at `stall.restartMinutes` (10) the lead is asked to stop it and dispatch its story again, at most `stall.maxRestarts` (2) times, and then the band flags the lane. When every story is done, the band says so and the loop stops. With `harness.agents.reviewer.on`, a finished branch is first reviewed in the background by code-kit's reviewer agent, which the lead starts: it runs `verify` and the review checklist, read-only, and grades each finding blocker, concern or nit. The lead's review prompt then carries the findings, and a blocker means the branch is sent back. The pane shows each review, running with its clock or what it found. If the reviewer hasn't reported within 15 minutes, or the plan's 5-hour use is past `harness.background.pauseAtPercent`, the lead reviews without it. A branch the lead's review passes joins the merge queue (`code-kit queue`). Branches merge one at a time, in the order they passed, each verified against the base as it is then: the lead merges where `approvals.delegate.merge` is on under `autonomous`, otherwise the band shows the head with **Merge** for you. Who may merge is read from the config committed on the base, so a branch can't grant itself merges; the first merge, which brings code-kit's rules onto the base, is always yours. A merged lane's worktree is removed when it holds nothing uncommitted. A head that conflicts or fails verify goes back to its lane. The pane lists the queue, and lanes whose branch waits in it read `queued`;
|
|
270
272
|
- approvals agents have asked for: **Approve…** opens a confirmation with a reason prefilled from the request, which you keep or rewrite;
|
|
271
273
|
- stories finished and waiting for review: **Review** asks the lead to run `/code-kit:review` on the branch, and **Merge** runs `verify`, checks included, then merges if it passes;
|
|
272
274
|
- a finish check failing in this session: **Lanes** opens the pane;
|
|
@@ -275,7 +277,7 @@ With Claude Code 2.1.287 or later, code-kit's mod shows the project in the sessi
|
|
|
275
277
|
|
|
276
278
|
Each button has a digit: type it in an empty prompt to press it.
|
|
277
279
|
|
|
278
|
-
- **`/lanes`** opens the Lanes pane
|
|
280
|
+
- **`/lanes`** opens the Lanes pane. Its first line counts the stories by state (building, in review, queued, sent back, blocked, ready, merged), with the loop's state and the plan's 5-hour use; press a count to show only those lanes. Beneath it, whatever needs you (held calls, approvals, reviews, merges, stalled lanes, outliers) is pinned with its key. Tabs on **1** to **4**: **Lanes**, each lane with its agent, story, branch, state, and its current or last tool call with the time since, amber once quiet and red when stalled. Each lane has its own small pixel character, tinted in the lane's colour, whose pose shows its state: working (animated while its agent works), waiting on you, quiet, stalled, done or resting; the lead's wears a crown. Under each lane, its story's timeline on a shared time axis: building, then in review, with send-backs (↩), approvals (◆) and the merge (✓) marked where they fell; **Queue**, the merge queue; **Usage**; and **Map**, every requirement in the specs as a cell by spec, its glyph and colour saying whether it's done and tested, done but untested, in progress, todo, without a story or removed, with a legend counting each. **h**/**l** and **j**/**k** move between cells and specs (or pick one from the list), showing the requirement's stories, their branches, and the tests that name it. **j** and **k** move between lanes, and the selected lane's acts are on **a** (approve), **r** (review), **s** (send back, with your reason), **m** (merge), **n** (nudge its agent) and **x** (stop it); **p** pauses or resumes the loop, and **f** filters the lanes by name, agent or story. **Enter** (or **o**) opens the selected lane's story: its requirements beside its spec-check report, the reviewer's findings by severity (each a way into the diff), `verify`'s problems, its usage and loop steps, and its diff against the base, file by file, with the acts its state allows. **b** or Escape goes back to the lanes. Inline (when the terminal can't dock it beside the transcript), it shows the counts, what needs you and a line per lane. It stays current within 2 seconds of a commit, a branch change, a plan edit or an agent starting or stopping. `/lanes` again, or Escape, closes it.
|
|
279
281
|
- **Refusals** a code-kit hook gives an agent are drawn as cards: what was refused, the rule, what to do, and Approve… where your approval would allow it. The full text is a press away.
|
|
280
282
|
- **`/harness`** opens the harness settings: how the lead loop acts, how long a call waiting on your approval is held, when a stalled lane is nudged and restarted, the reviewer agent and its model, and the use at which background agents pause. Changing one asks your reason, writes `.claude/code-kit.json` and logs a `kit` approval. Lanes, paths and rules still change through `/code-kit:init`.
|
|
281
283
|
- **`/approvals`** lists the requests waiting and the approvals in force, with minutes left. **`/verify-branch`** runs `code-kit verify` on this branch. Neither calls the model.
|
|
@@ -336,7 +338,14 @@ code-kit stops [--session id] [--json] # finish checks tha
|
|
|
336
338
|
code-kit sent-back <branch> [--reason "…"] # record a review's send-back: status shows the story as sent back until the branch moves on
|
|
337
339
|
code-kit settings [--json] # the harness settings in force, with their defaults
|
|
338
340
|
code-kit settings set <key> <value> --reason "…" # change one, as the person: written to the config and logged as a kit approval
|
|
339
|
-
code-kit
|
|
341
|
+
code-kit queue [--json] # the merge queue: branches whose review passed, in order
|
|
342
|
+
code-kit queue add|drop <branch> # the lead queues a branch its review passed, or takes it out
|
|
343
|
+
code-kit queue merge --delegated|--person # merge the head, verified against the base as it is now; a conflict or failed verify sends it back to its lane
|
|
344
|
+
code-kit story <id> [--json] # one story's requirements, spec-check report, diff against the base and verify (without checks), for the drill-down
|
|
345
|
+
code-kit timeline [--json] # when each story's work happened: its branch made, last commit, merge, send-backs and approvals
|
|
346
|
+
code-kit adapters [--json --session id] # the adapters in use; with --json, what they know of each lane's work in a session
|
|
347
|
+
code-kit hold <id> [--minutes N] # used by the mod: a held call waits here for the band's answer (--answer approved|refused)
|
|
348
|
+
code-kit approve <name>... --reason "…" [--lane name] [--delegated | --via pane|<tool>] # record a person's approval from chat, or (--delegated) grant one within the delegated rules; a package name stands for its dep- approval
|
|
340
349
|
```
|
|
341
350
|
|
|
342
351
|
`verify` compares the branch with where it left `--base` (default `origin/main`, then `main`). A branch named `<lane>/…`, or given as `--branch`, is held to that lane. `--no-checks` leaves the project's checks to CI's own steps. `status` reads `docs.specs` and `docs.plan`.
|
|
@@ -352,13 +361,13 @@ code-kit approve <name>... --reason "…" [--lane name] [--delegated | --via pan
|
|
|
352
361
|
| `docs.principles`, `docs.plan` | no | The engineering principles and the implementation plan |
|
|
353
362
|
| `lead.paths` | yes | What the main session writes. `.claude/**` is always added. |
|
|
354
363
|
| `lead.outside` | no | Paths outside the repository the lead may write, e.g. `../shared-lib/**`. Claude's memory and scratchpad are always included. |
|
|
355
|
-
| `anyActor` | no | Paths every writer may change (e.g. the lockfile). `.claude/state/**` is always included. An entry may be `{ "glob", "reviewer" }` to name the lane (or `"lead"`) that reviews changes to it; otherwise the lead reviews them, and `who` and `trace` say so.
|
|
364
|
+
| `anyActor` | no | Paths every writer may change (e.g. the lockfile), read-only agents included. `.claude/state/**` is always included. An entry may be `{ "glob", "reviewer" }` to name the lane (or `"lead"`) that reviews changes to it; otherwise the lead reviews them, and `who` and `trace` say so. |
|
|
356
365
|
| `lanes.<name>` | yes (may be `{}`) | `{ agent, paths, exclude? }`: the agent name maps a subagent to its lane. A worktree with a `.lane` file holding the lane name makes the main session that lane. |
|
|
357
366
|
| `protected[]` | no | `{ glob, approval, why }`: logged on every commit. Anyone but the lead needs a person's approval (see [Approvals](#approvals)). `.claude/**` is always protected as `kit`. |
|
|
358
367
|
| `designGate` | no | `{ register, screens: [{ glob, not? }], howTo }`: screen files wait until the register (`{ "screens": [{ "file": … }] }`) lists them |
|
|
359
368
|
| `layers[]` | no | `{ name, paths, mayImport, denyPackages? }`: the first layer whose paths match a file owns it. A layer may always import itself. |
|
|
360
369
|
| `importAliases` | no | `{ "@app/domain": "packages/domain/src" }`: resolves non-relative imports to repository paths |
|
|
361
|
-
| `shell.block[]` | no | `{ pattern, why, person? }`: never run. `person: true` marks a person's act, which the lead may do for them with `approvals.lead` on
|
|
370
|
+
| `shell.block[]` | no | `{ pattern, why, person?, command? }`: never run. `person: true` marks a person's act, which the lead may do for them with `approvals.lead` on. `command: true` matches the pattern from the start of each command the line runs, so a heredoc or quoted text that mentions it isn't refused |
|
|
362
371
|
| `shell.restricted[]` | no | `{ pattern, lanes, why }`: only the lead and these lanes |
|
|
363
372
|
| `postEdit[]` | no | `{ files, exclude?, run }`: after each edit of a matching file. `{file}` is the file. Exit 127 (tool not installed) is skipped. |
|
|
364
373
|
| `checks[]` | no | `{ name, files, exclude?, run[], each?, owners?, ifMissing?, timeoutSeconds? }`: before finishing, when matching files changed. `each` runs the commands in every changed folder matching that glob. `owners` limits who may change the files (the lead always may). `ifMissing: "fail"` makes a missing tool an error (the default is to skip). |
|
|
@@ -366,7 +375,7 @@ code-kit approve <name>... --reason "…" [--lane name] [--delegated | --via pan
|
|
|
366
375
|
| `approvals.lead` | no | `true` lets the lead act on what the person says in chat, for when `!` isn't available (on a phone, say): it records their approvals with `code-kit approve`, and runs `shell.block` commands marked `person`. Default `false`. See [Approvals](#approvals). |
|
|
367
376
|
| `approvals.delegate` | no | `{ protected?: [approval names], merge?: true, dependencies?: { licences?, minWeeklyDownloads?, maxMonthsSinceRelease?, allowInstallScripts?: true \| false \| [kinds] } }`: approvals the lead may grant on its own, with `code-kit approve --delegated`, and with `merge`, merges into a protected branch with `code-kit merge --delegated`. Dependencies are checked against the npm registry; the defaults are MIT, Apache-2.0, BSD and ISC, 10,000 weekly downloads, a release within 18 months, and no install scripts. See [Approvals](#approvals). |
|
|
368
377
|
| `branches.protected` | no | Default `["main", "master"]` |
|
|
369
|
-
| `harness` | no | What the mod's harness does in the session: `autonomy` (`autonomous`, `propose` or `off`; default `autonomous`), `hold.minutes` (how long a call waiting on your approval is held, 0 to
|
|
378
|
+
| `harness` | no | What the mod's harness does in the session: `autonomy` (`autonomous`, `propose` or `off`; default `autonomous`), `hold.minutes` (how long a call waiting on your approval is held, 0 to 10; default 2), `stall.nudgeMinutes` and `stall.restartMinutes` (default 5 and 10), `stall.maxRestarts` (default 2), `agents.reviewer.on` (default `false`) and `agents.reviewer.model` (default the session's), and `background.pauseAtPercent` (default 80). Change them with `/harness` or `code-kit settings set`. |
|
|
370
379
|
|
|
371
380
|
Add `.claude/approvals/`, `.claude/state/` and `.claude/code-kit.draft.json` to `.gitignore`, and `.claude/approval-log.jsonl merge=union` to `.gitattributes`, so merging branches that both logged changes keeps every entry. Commit `.claude/code-kit.baseline.json` if the project has one.
|
|
372
381
|
|
|
@@ -433,13 +442,14 @@ Other tools share a project with code-kit and keep files of their own. An adapte
|
|
|
433
442
|
|
|
434
443
|
- how to detect the tool;
|
|
435
444
|
- what the tool adds to the rules: paths for the lead, paths any actor may write, protected paths, blocked commands;
|
|
436
|
-
- the setup init should apply
|
|
445
|
+
- the setup init should apply;
|
|
446
|
+
- what the tool knows of the lanes' work, for the Lanes pane (its `facts`).
|
|
437
447
|
|
|
438
448
|
While the tool is detected, its additions are merged into the effective config, like the kit's own defaults. Run `code-kit adapters` to see them, or switch one off with `"adapters": { "<name>": false }`.
|
|
439
449
|
|
|
440
|
-
| Adapter | Detected by | Adds
|
|
441
|
-
| --------------- | ----------- |
|
|
442
|
-
| `context-graph` | `.ctx/` | `.ctx/**` for the lead. `.ctx/decisions.ctx` and `.ctx/cards.ctx` for any actor, since every agent records decisions and file cards. `graph.ctx` and `config.toml` are protected (approval `ctx`). No Claude actor may write a person's `Ctx-Ratified-By` trailer: ratifying is a person's act (with `approvals.lead`, the lead may add it when the person says so in chat). A delegated trailer, `Ctx-Ratified-By: <ratifier> (delegated)`, is the lead's alone, under Context Graph's `[delegate]` rules. `verify` accepts a `graph.ctx` change whose commits carry a person's trailer (`ctx ratify --commit`, `ctx drop --commit`) without an approval-log entry. Agents can't run those commands. |
|
|
450
|
+
| Adapter | Detected by | Adds |
|
|
451
|
+
| --------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
452
|
+
| `context-graph` | `.ctx/` | `.ctx/**` for the lead. `.ctx/decisions.ctx` and `.ctx/cards.ctx` for any actor, since every agent records decisions and file cards. `graph.ctx` and `config.toml` are protected (approval `ctx`). No Claude actor may write a person's `Ctx-Ratified-By` trailer: ratifying is a person's act (with `approvals.lead`, the lead may add it when the person says so in chat). A delegated trailer, `Ctx-Ratified-By: <ratifier> (delegated)`, is the lead's alone, under Context Graph's `[delegate]` rules. `verify` accepts a `graph.ctx` change whose commits carry a person's trailer (`ctx ratify --commit`, `ctx drop --commit`) without an approval-log entry. Changing Context Graph's harness settings (`ctx settings set`) is the person's act too. Agents can't run those commands. With `ctx` on the PATH, the Lanes pane shows each lane's edits made without understanding and the cards it owes, and a story's drill-down lists the files still unread and the rules on its files, agreed and proposed; **v** opens a file in Context Graph's pane (`/graph <path>`). |
|
|
443
453
|
|
|
444
454
|
Its setup:
|
|
445
455
|
|