Repository navigation
Commit bb60b86
docs(skills): objectstack-data teaches membership keys,
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ82udicoCE8dxKwR8vrMoM9W)_
Fixes #26297
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:`skills/objectstack-data` 教五件 18.x 已发布、技能没教的事:①
`rules/security.md` 新增「成员键」一节(`membershipKeys` 声明在名册对象上,`userField` /
`valueField` / `filter` 三个成员、拒收规则、每请求一次的系统读且失败即零行、与 owner 作用域 / 岗位 /
共享规则的选择规则)和「岗位只授它点名的集合;门户用户是 `external`」一节;② `rules/relationships.md` 在
`controlled_by_parent` 旁教 `sharing.controlledByParent.ownerMayEdit`;③
`references/seeds.md` 补 `columns` 选项行和 `applyOn: 'create'` 小节;④
`references/examples-objects.md` 两处过时的 `{ type: 'lookup', reference:
'user' }` 改为 `type: 'user'`;⑤ eval 加门户成员题一道,种子题与发票行题各扩一句。六行 token
上限按实测调整,裁决原文写在行旁。
- **为什么改**:AI
作者建门户或按名册限行的应用时,没有这些规则就会逐行手写策略、以为岗位同名集合会自动授予、种子重放覆盖掉管理员的修改;`reference:
'user'` 的例子会被原样抄进一个不存在的对象。
- **风险与回滚**:只改发布技能包的文字、两个 eval 夹具和棘轮脚本的六行上限,不改运行时;回滚即 revert 本
PR(上限行随之回落)。
- **先看**:① `skills/objectstack-data/rules/security.md`
新两节(成员键示例块与四条要点、岗位/`external` 两条);②
`scripts/check-skills-token-ratchet.mjs` 六行上限及其注释;③
`evals/hooks-security-seeds-datasources.json` 第 6 题。
- **两分钟验证**:`node scripts/check-skills-token-ratchet.mjs` → 末行 `81
authored bundle file(s) within their ceilings`,其中 `rules/security.md is
3693 tokens (ceiling 3693; headroom 0)`;`pnpm --filter @objectstack/spec
run check:skill-examples` → 新标记的名册对象块随 265 个示例通过类型检查。
- **需要你做的**:Tier H(`skills/**`),请 approve 或直接 Merge when ready。
## What changes
Card #26297, the six Measured rows (D2–D7) and nothing wider:
1. **`rules/security.md` — "Membership keys"** (after the RLS section,
whose placeholder table already named `current_user.KEY` without saying
where it comes from): the choice statement first (rows keyed on a *named
record* → a key on the **roster** object, never a stamp on every row or
a policy per record), a type-checked roster example (`account_member`
with `membershipKeys.portal_account_ids: { userField: 'user',
valueField: 'account', filter: 'active == true' }`) and the policy
fragment that reads it with `in`; then four bullets — the three members
and what each may name; the refusals (one name per stack, the kernel's
own names, no contribution through an object extension); the
once-per-request system read (no read on the roster needed, 1,000-value
cap, a larger set / failed read / non-compiling `filter` matches no
rows, whoever writes roster rows grants the key); and the choice rule
against owner scoping, a position's `positions` and a sharing rule.
2. **`rules/security.md` — "Positions grant only what they name; portal
users are `external`"**: a position distributes only the sets its
`permissionSets` names (ADR-0131 D3/D4; a namesake set is reported,
never granted; a name matching no set confers nothing), with the
one-line position shape; the `external` membership tier for portal and
partner users (closed list, one tier per member, docs anchor), which the
`everyone` baseline does not reach, sees no member directory, holds no
business unit, and for which every org-wide default is owner-only — rows
reach it only through explicit grants (a position or set whose row
policies bound them, a sharing rule, a manual share). `check:role-word`
(ADR-0090 D3) refuses the reserved word in this tree, so the prose says
"membership tier" where the spec's constant file says otherwise.
3. **`rules/relationships.md` — "Owner edits under
`controlled_by_parent` — `ownerMayEdit`"** under the master_detail
pattern, plus "owner opt-in `ownerMayEdit` (below)" in the type table's
Sharing cell (the card's row at L16): what a detail inherits, the
two-line opt-in, what it does not widen (insert, delete, predicate
updates, on-behalf-of writes; the detail's own row policies still AND
in), refused at parse off a `controlled_by_parent` detail and one level
up.
4. **`references/seeds.md`**: a `columns` row in the `Seed` fields table
and a section "Columns the app owns after the first load —
`columns.FIELD.applyOn`" after the import modes: why a replay reverts
app-owned columns, `applyOn: 'create'` semantics per mode, the refused
key, and the cross-link to the import mapping entry's `applyOn` (taught
in objectstack-api; not restated).
5. **`references/examples-objects.md`** L42 and L88: `{ type: 'lookup',
reference: 'user', … }` → `{ type: 'user', … }` (the 18.x form; a `user`
field's target is fixed to `sys_user` and a foreign `reference` is
refused). Both blocks are `os:check`-marked and still type-check. This
is the one stale text the card names, and the only removal.
6. **Evals**, in each file's existing inline-array shape:
`hooks-security-seeds-datasources.json` eval 6 (the card's acceptance
prompt: portal staff read only the orders of the accounts they belong to
— expected `membershipKeys` on the roster,
`current_user.portal_account_ids` in the policy, `userField` /
`valueField`, the set bound through a position's `permissionSets`, the
`external` tier; `must_not_contain` pins the object-level `permissions:`
key), and eval 4 gains the job-owned column (`applyOn: 'create'`);
`objects-fields-relationships.json` eval 2 gains the owner opt-in
(`ownerMayEdit`) and pins `added_by` as `type: 'user'` with
`must_not_contain: "reference: 'user'"`.
`SKILL.md` is untouched: its `controlled_by_parent` row (L76) and the
security pointer line (L48) sit at 3 tokens of headroom, and the card's
Wanted names `rules/relationships.md` for `ownerMayEdit`;
`references/_index.md` is generator-owned and unchanged (the spec files
involved are already listed).
**Token-ratchet rows** (`scripts/check-skills-token-ratchet.mjs`), per
the maintainer's ruling on the seat's decision card 「skills 修复卡的教学和 eval
都撞 token 天花板,怎么付?」, tap **A** (2026-10-27 01:21Z), verbatim and
untranslated: 「A:先削重复,余额按实测提高」. Step one, cut duplicates first: measured
on `origin/main` `c51aed4f`, none of the four `.md` files carries a
repeated sentence (a sentence-level scan of each file: 0 repeats in
`security.md`, `relationships.md`, `seeds.md`; the only repeat in
`examples-objects.md` is the `os:check` marker + import line that opens
each type-checked block), and neither eval file repeats a case — so
there was nothing to cut and no surviving-home list to give. Step two,
each touched row follows its measurement (`ceil(utf8 bytes / 4)`):
`rules/security.md` 2956 → 3693 (+737 at headroom 0);
`rules/relationships.md` 3676 → 3873 (+201 landed on 3672, 4 absorbed by
headroom, ceiling +197); `references/seeds.md` 1299 → 1566 (+267 at
headroom 0); `references/examples-objects.md` 1779 → **1769** (the two
stale fields are a net cut of 10 tokens; the row follows the measurement
down); `evals/hooks-security-seeds-datasources.json` 1095 → 1404 (+309);
`evals/objects-fields-relationships.json` 946 → 1050 (+104). Every row
re-pinned at zero headroom; each comment quotes the tap. Only
`objectstack-data` rows are touched.
**Two readings** (lines, and tokens as the ratchet counts them):
| File | Lines before → after | Tokens before → after |
|:--|:--|:--|
| `rules/security.md` | 249 → 312 (+63) | 2956 → 3693 (+737) |
| `rules/relationships.md` | 401 → 418 (+17) | 3672 → 3873 (+201) |
| `references/seeds.md` | 142 → 163 (+21) | 1299 → 1566 (+267) |
| `references/examples-objects.md` | 197 → 197 (0) | 1779 → 1769 (−10) |
| `evals/hooks-security-seeds-datasources.json` (not .md, reported for
the raise) | 55 → 65 (+10) | 1095 → 1404 (+309) |
| `evals/objects-fields-relationships.json` (not .md, reported for the
raise) | 45 → 45 (0) | 946 → 1050 (+104) |
| **Whole package** (`SKILL.md` + `references/**/*.md` +
`rules/**/*.md`, 14 files, raw file bytes) | **3736 → 3837 (+101)** |
**39497 → 40692 (+1195)** |
Removed: the two stale `reference: 'user'` spellings only.
Sequencing (zero verbs beside these numbers): #26393 landed the `when`
section this PR's membership text sits next to, and is not restated;
#25640 owns line 1 of `SKILL.md`, which this PR does not touch; #26392
taught the import door's `applyOn` in objectstack-api, which `seeds.md`
cross-links.
`skip-changeset`: the published skills packages carry no `package.json`;
nothing is released from any package.
## Why
An AI author building a portal or a roster-scoped app from this skill
had no rule for a set keyed on a named record, so it wrote per-row
policies by hand or stamped an owner on every row; it expected a
position-named set to grant itself; it let a seed replay revert a status
an admin or a job had advanced; and it copied `reference: 'user'` into a
lookup to an object that does not exist. Every key here is already
carried by `@objectstack/spec` 18.x (`Metadata-protocol: none`); the gap
was the teaching.
## Tests
- `node scripts/check-skills-token-ratchet.mjs` — exit 0: `81 authored
bundle file(s) within their ceilings`, the six touched rows at headroom
0.
- `node scripts/check-skills-token-ratchet.mjs --self-test` — exit 0,
`79 cases pass`.
- `pnpm --filter @objectstack/spec run check:skill-docs`,
`check:skill-refs`, `check:skill-examples` — see Verification; the new
roster-object block in `security.md` is `os:check`-marked and
type-checks (the policy fragment beside it is unmarked, like the file's
RLS block).
- Evals are fixtures (the repo has no eval runner): every `must_contain`
string of the new and extended cases occurs in its expected output; the
`must_not_contain` strings were checked against the expected outputs by
hand.
## Acceptance notes
- `SKILL.md` L48 (the security pointer line) does not name membership
keys and L76 does not point at `ownerMayEdit`; both would need a raise
of the SKILL.md row for a few tokens. Not filed: observation only.
- `evals/README.md` (headroom 1) was not updated to name the new topics.
Not filed: observation only.
- The dispatch order's "`skills/**` inside the package's ceilings"
cannot hold at the measured headroom (0 on five of the six files); the
seat's claim widened the surface to the touched ratchet rows under the
ruling above.
- The PR body's first two lines are the harness-required attribution
block (the os-dev exception); `Fixes #26297` follows immediately.
## Verification
Gate list derived with `node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack` on the final tree (base `c51aed4f`,
head `e63f6ec2`), each run locally with the exit code captured before
any pipe; `--ran` reconciliation below. No commit followed the gate
runs, so every reading is of `e63f6ec2`.
**Reconciliation** (`node scripts/pm/dispatch-gates.mjs --ran ran.list
--repo objectstack-ai/objectstack`, exit 0): `52 derived, 51 run, 1
NOT-MEASURED, 0 UNRUN`. The one NOT MEASURED is `pnpm
check:dual-build-cjs-loads` (exit 3: its prerequisite is a whole-repo
build; this diff touches no package source, and CI's `Lint & Repo Gates`
runs it — a declared narrowing). Two readings were taken twice: `pnpm
check:dts-closure` exited 1 on a first pass that raced the still-running
closure build (plugin-auth mid-emit, "1 built package missing
declaration files") and exits 0 re-run after the build (`38 built
package(s) swept - 160/160 declared declaration file(s) present`); `node
scripts/check-comment-mask-corpus.mjs` was run alone after
`check:skill-examples` (exit 0, `18297 files, 0 disagree`). The closures
for `check:skill-examples` and `check:doc-formula-expressions`
(`@objectstack/client-react...` and `@objectstack/lint...`) were built
under `scripts/pm/os-verify-lock.sh` (slot `issue-26297`, VERDICT
command-exit 0, 251 s held). `check:pm-dispatch-gates` ran detached on
the final head: fast tier, 1901 cases pass, 299 s, exit 0.
<details><summary>Every derived command with its exit code on e63f6ec
(53 lines: the 52 derived, plus `check:skill-docs` and
`check:skill-examples` the dispatch order asked for)</summary>
- `node scripts/check-ci-filter-parity.mjs` — exit 0
- `node scripts/check-closing-keyword-parity.mjs` — exit 0
- `node scripts/check-closing-keyword-parity.mjs --self-test` — exit 0
- `node scripts/check-declaration-mirrors.mjs` — exit 0
- `node scripts/check-declaration-mirrors.mjs --self-test` — exit 0
- `node scripts/check-doc-route-spelling.mjs --advisory` — exit 0
- `node scripts/check-doc-route-spelling.mjs --self-test` — exit 0
- `node scripts/check-dts-emitted.mjs --self-test` — exit 0
- `node scripts/check-scripts-symbol-anchors.mjs` — exit 0
- `node scripts/check-scripts-symbol-anchors.mjs --self-test` — exit 0
- `node scripts/check-self-test-wired.mjs` — exit 0
- `node scripts/check-self-test-wired.mjs --self-test` — exit 0
- `node scripts/check-self-test-workflow-commands.mjs` — exit 0
- `node scripts/check-self-test-workflow-commands.mjs --self-test` —
exit 0
- `node scripts/check-skills-token-ratchet.mjs` — exit 0
- `node scripts/check-skills-token-ratchet.mjs --self-test` — exit 0
- `node scripts/check-whole-set-label-write.mjs` — exit 0
- `node scripts/check-whole-set-label-write.mjs --self-test` — exit 0
- `node scripts/ci/assert-turbo-remote-cache.mjs --self-test` — exit 0
- `node scripts/ci/plan-test-core-shards.mjs --self-test` — exit 0
- `node scripts/ci/prune-turbo-cache.mjs --self-test` — exit 0
- `node scripts/pm/bare-root-worklist.mjs --self-test` — exit 0
- `pnpm --filter @objectstack/spec run check:skill-refs` — exit 0
- `pnpm check:agent-test-spelling` — exit 0
- `pnpm check:bash32-floor` — exit 0
- `pnpm check:cli-command-ids` — exit 0
- `pnpm check:corpus-claim-drift` — exit 0
- `pnpm check:cross-package-test-inputs` — exit 0
- `pnpm check:doc-authoring` — exit 0
- `pnpm check:driver-memory-census` — exit 0
- `pnpm check:dts-closure` — exit 0
- `pnpm check:entry-guard` — exit 0
- `pnpm check:gitlink-declared` — exit 0
- `pnpm check:nul-bytes` — exit 0
- `pnpm check:parse-guard` — exit 0
- `pnpm check:pm-governed-merges` — exit 0
- `pnpm check:pm-skill-id-lint` — exit 0
- `pnpm check:pnpm-filter-targets` — exit 0
- `pnpm check:pnpm-flag-spellings` — exit 0
- `pnpm check:ratchet-remedy-authority` — exit 0
- `pnpm check:refd-timer-probe` — exit 0
- `pnpm check:role-word` — exit 0
- `pnpm check:skill-compatibility` — exit 0
- `pnpm check:skill-frame-sync` — exit 0
- `pnpm check:skill-identifier-liveness` — exit 0
- `pnpm check:sourcemap-no-sources-content` — exit 0
- `pnpm check:watch-hint-literal` — exit 0
- `pnpm --filter @objectstack/spec run check:skill-docs` — exit 0
- `pnpm --filter @objectstack/spec run check:skill-examples` — exit 0
- `pnpm --filter @objectstack/lint run check:doc-formula-expressions` —
exit 0
- `pnpm check:dual-build-cjs-loads` — NOT MEASURED (exit 3, PREREQUISITE
NOT MET: whole-repo build)
- `pnpm check:lean-entry-closure` — exit 0
- `node scripts/check-comment-mask-corpus.mjs` — exit 0
- `pnpm check:pm-dispatch-gates` — exit 0
</details>
<details><summary>Token ratchet on e63f6ec</summary>
- `skills/objectstack-data/rules/security.md is 3693 tokens (ceiling
3693; headroom 0)`
- `skills/objectstack-data/rules/relationships.md is 3873 tokens
(ceiling 3873; headroom 0)`
- `skills/objectstack-data/references/seeds.md is 1566 tokens (ceiling
1566; headroom 0)`
- `skills/objectstack-data/references/examples-objects.md is 1769 tokens
(ceiling 1769; headroom 0)`
- `skills/objectstack-data/evals/hooks-security-seeds-datasources.json
is 1404 tokens (ceiling 1404; headroom 0)`
- `skills/objectstack-data/evals/objects-fields-relationships.json is
1050 tokens (ceiling 1050; headroom 0)`
- `81 authored bundle file(s) within their ceilings; 10 generator-owned
file(s) measured, not ratcheted.`
- `--self-test`: `79 cases pass.`
</details>
<details><summary>check:skill-examples on e63f6ec</summary>
`265 prose examples type-check across 3 surface(s) — every marked block
parsed, so tsc ran the SEMANTIC pass on all of them` (264 on `main`; the
265th is the new `os:check`-marked roster object in `security.md`).
</details>
## Human Minimum
Each item is one rule from [CONTRIBUTING.md › Human
Minimum](https://github.com/objectstack-ai/objectstack/blob/main/CONTRIBUTING.md#human-minimum).
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(No schema change.)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` is CI's run (repo-wide scan).
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. Nothing publishes (`skip-changeset`); both declaration lines
are filled in above.
- [x] 6. `packages/spec` not touched.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English (the 维护者速读 block and
the quoted ruling are the required exceptions).
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbXTWvHG6MXFD7Gywf2)_
Co-authored-by: objectstack-fleet[bot] <332303061+objectstack-fleet[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>ownerMayEdit, create-only seed columns, the position-to-set binding and the external tier (#26416)1 parent 26e7c75 commit bb60b86
7 files changed
Lines changed: 171 additions & 16 deletions
File tree
- scripts
- skills/objectstack-data
- evals
- references
- rules
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
561 | 561 | | |
562 | 562 | | |
563 | 563 | | |
564 | | - | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
565 | 572 | | |
566 | 573 | | |
567 | 574 | | |
| |||
591 | 598 | | |
592 | 599 | | |
593 | 600 | | |
594 | | - | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
595 | 613 | | |
596 | 614 | | |
597 | 615 | | |
| |||
746 | 764 | | |
747 | 765 | | |
748 | 766 | | |
749 | | - | |
750 | | - | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
751 | 783 | | |
752 | 784 | | |
753 | 785 | | |
| |||
799 | 831 | | |
800 | 832 | | |
801 | 833 | | |
802 | | - | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
803 | 839 | | |
804 | | - | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
805 | 849 | | |
806 | 850 | | |
807 | 851 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
37 | | - | |
| 36 | + | |
| 37 | + | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
| 40 | + | |
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
53 | 63 | | |
54 | 64 | | |
55 | 65 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
17 | | - | |
| 16 | + | |
| 17 | + | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
21 | | - | |
| 20 | + | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
| 42 | + | |
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
88 | | - | |
| 88 | + | |
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| 53 | + | |
53 | 54 | | |
54 | 55 | | |
55 | 56 | | |
| |||
65 | 66 | | |
66 | 67 | | |
67 | 68 | | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
68 | 89 | | |
69 | 90 | | |
70 | 91 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
92 | 92 | | |
93 | 93 | | |
94 | 94 | | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
95 | 112 | | |
96 | 113 | | |
97 | 114 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
119 | 182 | | |
120 | 183 | | |
121 | 184 | | |
| |||
0 commit comments