@labacacia/nps-sdk 1.0.0-alpha.5 → 1.0.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/CHANGELOG.cn.md +29 -5
  2. package/CHANGELOG.md +29 -5
  3. package/LICENSE +0 -0
  4. package/NOTICE +0 -0
  5. package/README.cn.md +8 -13
  6. package/README.md +8 -13
  7. package/dist/nip/index.d.ts +1 -0
  8. package/dist/nip/index.d.ts.map +1 -1
  9. package/dist/nip/index.js +2 -0
  10. package/dist/nip/index.js.map +1 -1
  11. package/dist/nip/reputation-client.d.ts +116 -0
  12. package/dist/nip/reputation-client.d.ts.map +1 -0
  13. package/dist/nip/reputation-client.js +261 -0
  14. package/dist/nip/reputation-client.js.map +1 -0
  15. package/dist/nip/x509/oids.d.ts +9 -10
  16. package/dist/nip/x509/oids.d.ts.map +1 -1
  17. package/dist/nip/x509/oids.js +3 -4
  18. package/dist/nip/x509/oids.js.map +1 -1
  19. package/dist/nwp/anchor-client.d.ts +109 -0
  20. package/dist/nwp/anchor-client.d.ts.map +1 -0
  21. package/dist/nwp/anchor-client.js +279 -0
  22. package/dist/nwp/anchor-client.js.map +1 -0
  23. package/dist/nwp/index.d.ts +1 -1
  24. package/dist/nwp/index.d.ts.map +1 -1
  25. package/dist/nwp/index.js +1 -1
  26. package/dist/nwp/index.js.map +1 -1
  27. package/doc/nps-sdk.core.cn.md +0 -0
  28. package/doc/nps-sdk.core.md +0 -0
  29. package/doc/nps-sdk.ncp.cn.md +0 -0
  30. package/doc/nps-sdk.ncp.md +0 -0
  31. package/doc/nps-sdk.ndp.cn.md +0 -0
  32. package/doc/nps-sdk.ndp.md +0 -0
  33. package/doc/nps-sdk.nop.cn.md +0 -0
  34. package/doc/nps-sdk.nop.md +0 -0
  35. package/doc/overview.cn.md +0 -0
  36. package/doc/overview.md +0 -0
  37. package/package.json +12 -1
  38. package/CONTRIBUTING.cn.md +0 -35
  39. package/CONTRIBUTING.md +0 -35
  40. package/dist/nwp/error-codes.d.ts +0 -42
  41. package/dist/nwp/error-codes.d.ts.map +0 -1
  42. package/dist/nwp/error-codes.js +0 -53
  43. package/dist/nwp/error-codes.js.map +0 -1
  44. package/nip-ca-server/Dockerfile +0 -27
  45. package/nip-ca-server/README.md +0 -45
  46. package/nip-ca-server/db/001_init.sql +0 -25
  47. package/nip-ca-server/docker-compose.yml +0 -29
  48. package/nip-ca-server/package.json +0 -23
  49. package/nip-ca-server/src/ca.ts +0 -155
  50. package/nip-ca-server/src/db.ts +0 -104
  51. package/nip-ca-server/src/index.ts +0 -157
  52. package/nip-ca-server/tsconfig.json +0 -13
  53. package/src/core/anchor-cache.ts +0 -129
  54. package/src/core/cache.ts +0 -93
  55. package/src/core/canonical-json.ts +0 -50
  56. package/src/core/codec.ts +0 -158
  57. package/src/core/codecs/index.ts +0 -5
  58. package/src/core/codecs/ncp-codec.ts +0 -170
  59. package/src/core/codecs/tier1-json-codec.ts +0 -33
  60. package/src/core/codecs/tier2-msgpack-codec.ts +0 -30
  61. package/src/core/crypto-provider.ts +0 -47
  62. package/src/core/exceptions.ts +0 -57
  63. package/src/core/frame-header.ts +0 -282
  64. package/src/core/frame-registry.ts +0 -91
  65. package/src/core/frames.ts +0 -184
  66. package/src/core/index.ts +0 -42
  67. package/src/core/registry.ts +0 -28
  68. package/src/core/status-codes.ts +0 -47
  69. package/src/index.ts +0 -10
  70. package/src/ncp/frames/anchor-frame.ts +0 -87
  71. package/src/ncp/frames/caps-frame.ts +0 -59
  72. package/src/ncp/frames/diff-frame.ts +0 -69
  73. package/src/ncp/frames/error-frame.ts +0 -26
  74. package/src/ncp/frames/hello-frame.ts +0 -50
  75. package/src/ncp/frames/stream-frame.ts +0 -35
  76. package/src/ncp/frames.ts +0 -251
  77. package/src/ncp/handshake.ts +0 -95
  78. package/src/ncp/index.ts +0 -13
  79. package/src/ncp/ncp-error-codes.ts +0 -36
  80. package/src/ncp/ncp-patch-format.ts +0 -16
  81. package/src/ncp/preamble.ts +0 -79
  82. package/src/ncp/registry.ts +0 -15
  83. package/src/ncp/stream-manager.ts +0 -212
  84. package/src/ndp/dns-txt.ts +0 -86
  85. package/src/ndp/frames.ts +0 -124
  86. package/src/ndp/index.ts +0 -8
  87. package/src/ndp/ndp-registry.ts +0 -116
  88. package/src/ndp/registry.ts +0 -12
  89. package/src/ndp/validator.ts +0 -64
  90. package/src/nip/acme/client.ts +0 -185
  91. package/src/nip/acme/index.ts +0 -8
  92. package/src/nip/acme/jws.ts +0 -109
  93. package/src/nip/acme/messages.ts +0 -85
  94. package/src/nip/acme/server.ts +0 -480
  95. package/src/nip/acme/wire.ts +0 -24
  96. package/src/nip/assurance-level.ts +0 -40
  97. package/src/nip/cert-format.ts +0 -9
  98. package/src/nip/error-codes.ts +0 -38
  99. package/src/nip/frames.ts +0 -138
  100. package/src/nip/identity.ts +0 -113
  101. package/src/nip/index.ts +0 -14
  102. package/src/nip/registry.ts +0 -12
  103. package/src/nip/verifier.ts +0 -122
  104. package/src/nip/x509/builder.ts +0 -91
  105. package/src/nip/x509/index.ts +0 -6
  106. package/src/nip/x509/oids.ts +0 -28
  107. package/src/nip/x509/verifier.ts +0 -214
  108. package/src/nop/client.ts +0 -103
  109. package/src/nop/frames.ts +0 -181
  110. package/src/nop/index.ts +0 -7
  111. package/src/nop/models.ts +0 -79
  112. package/src/nop/nop-types.ts +0 -208
  113. package/src/nop/registry.ts +0 -13
  114. package/src/nwp/client.ts +0 -114
  115. package/src/nwp/error-codes.ts +0 -62
  116. package/src/nwp/frames.ts +0 -116
  117. package/src/nwp/index.ts +0 -7
  118. package/src/nwp/registry.ts +0 -11
  119. package/src/setup.ts +0 -32
  120. package/tests/_rfc0002-keys.ts +0 -57
  121. package/tests/core/anchor-cache.test.ts +0 -242
  122. package/tests/core/codec.test.ts +0 -205
  123. package/tests/core/frame-registry.test.ts +0 -46
  124. package/tests/core.test.ts +0 -327
  125. package/tests/ncp/diff-binary-bitset.test.ts +0 -107
  126. package/tests/ncp/e2e-enc-reject.test.ts +0 -93
  127. package/tests/ncp/err-error-frame.test.ts +0 -152
  128. package/tests/ncp/frames.test.ts +0 -359
  129. package/tests/ncp/framing.test.ts +0 -233
  130. package/tests/ncp/hello-frame.test.ts +0 -122
  131. package/tests/ncp/inline-anchor.test.ts +0 -88
  132. package/tests/ncp/preamble.test.ts +0 -93
  133. package/tests/ncp/security.test.ts +0 -184
  134. package/tests/ncp/stream-window.test.ts +0 -167
  135. package/tests/ncp/stream.test.ts +0 -242
  136. package/tests/ncp/version-negotiation.test.ts +0 -123
  137. package/tests/ndp.test.ts +0 -377
  138. package/tests/nip-acme-agent01.test.ts +0 -192
  139. package/tests/nip-x509.test.ts +0 -280
  140. package/tests/nip.test.ts +0 -184
  141. package/tests/nop.test.ts +0 -344
  142. package/tests/nwp.test.ts +0 -237
  143. package/tsconfig.json +0 -20
  144. package/tsup.config.ts +0 -20
  145. package/vitest.config.ts +0 -10
package/CHANGELOG.cn.md CHANGED
@@ -8,6 +8,32 @@
8
8
 
9
9
  ---
10
10
 
11
+ ## [1.0.0-alpha.7] —— 2026-05-17
12
+
13
+ ### 新增
14
+
15
+ - **`nip/reputation-client.ts` — `ReputationLogClient`(NPS-RFC-0004 Phase 2)**:基于 fetch 的声誉日志 operator 完整客户端。`submitEntry`、`queryEntries`、`getSth`、`getProof`、`getGossipSth`。`verifyInclusion` 使用 `@noble/hashes/sha256` 在本地执行 RFC 9162 §2.1.3.2 Merkle audit-path 验证。`signEntry` / `verifyEntry` 使用 `@noble/ed25519` 签名验证条目。Wire 类型:`ReputationLogEntry`、`SignedTreeHead`、`InclusionProof`、`ObservationWindow`。`AnchorTopologyError` 携带 `nwpErrorCode` + `npsStatus`。30 条回归测试。从 `@labacacia/nps-sdk/nip` 重新导出。
16
+
17
+ - **`nwp/anchor-client.ts` — `AnchorNodeClient`(NPS-CR-0002)**:基于 fetch 的 Anchor Node 拓扑查询客户端。`getSnapshot`(topology.snapshot)和 `subscribe` async generator(topology.stream NDJSON)。判别联合类型 `TopologyEvent`,包含 `member_joined`、`member_left`、`member_updated`、`anchor_state`、`resync_required` 五种 kind。`AnchorTopologyError` 处理协议错误。24 条回归测试。
18
+
19
+ ### 跟随套件
20
+
21
+ 本次跟随 NPS 套件 `v1.0.0-alpha.7`。
22
+
23
+ ---
24
+
25
+ ## [1.0.0-alpha.6] —— 2026-05-14
26
+
27
+ ### 变更
28
+
29
+ - **`nip/x509/oids.ts` — IANA PEN 65715(Breaking,CR-0004)**:`LAB_ACACIA_PEN_ARC` 从 `"1.3.6.1.4.1.99999"` 更新为 `"1.3.6.1.4.1.65715"`。在临时弧下签发的证书必须吊销并重新签发。
30
+
31
+ - **`nwp/index.ts` — 移除 `NwpErrorCodes` 重导出(Breaking)**:从桶文件中移除了 `export * as NwpErrorCodes from "./error-codes.js"`。如需使用,请直接从 `@labacacia/nps-sdk/nwp/error-codes` 导入。
32
+
33
+ - **版本升级至 `1.0.0-alpha.6`** —— 与 NPS 套件 alpha.6 版本同步。
34
+
35
+ ---
36
+
11
37
  ## [1.0.0-alpha.5] —— 2026-05-01
12
38
 
13
39
  ### 新增
@@ -123,8 +149,6 @@
123
149
 
124
150
  作为 NPS 套件 `v1.0.0-alpha.1` 的一部分首次公开 alpha。
125
151
 
126
- [1.0.0-alpha.5]: https://github.com/labacacia/NPS-sdk-ts/releases/tag/v1.0.0-alpha.5
127
- [1.0.0-alpha.4]: https://gitee.com/labacacia/NPS-sdk-ts/releases/tag/v1.0.0-alpha.4
128
- [1.0.0-alpha.3]: https://github.com/LabAcacia/NPS-Dev/releases/tag/v1.0.0-alpha.3
129
- [1.0.0-alpha.2]: https://github.com/LabAcacia/NPS-Dev/releases/tag/v1.0.0-alpha.2
130
- [1.0.0-alpha.1]: https://github.com/LabAcacia/NPS-Dev/releases/tag/v1.0.0-alpha.1
152
+ [1.0.0-alpha.7]: https://github.com/labacacia/NPS-sdk-ts/releases/tag/v1.0.0-alpha.7
153
+ [1.0.0-alpha.2]: https://github.com/LabAcacia/nps/releases/tag/v1.0.0-alpha.2
154
+ [1.0.0-alpha.1]: https://github.com/LabAcacia/nps/releases/tag/v1.0.0-alpha.1
package/CHANGELOG.md CHANGED
@@ -8,6 +8,32 @@ Until NPS reaches v1.0 stable, every repository in the suite is synchronized to
8
8
 
9
9
  ---
10
10
 
11
+ ## [1.0.0-alpha.7] — 2026-05-17
12
+
13
+ ### Added
14
+
15
+ - **`nip/reputation-client.ts` — `ReputationLogClient` (NPS-RFC-0004 Phase 2)**: Full fetch-based client for the reputation-log operator API. `submitEntry`, `queryEntries`, `getSth`, `getProof`, `getGossipSth`. `verifyInclusion` performs RFC 9162 §2.1.3.2 Merkle audit-path verification locally using `@noble/hashes/sha256`. `signEntry` / `verifyEntry` sign and verify entries with `@noble/ed25519`. Wire types: `ReputationLogEntry`, `SignedTreeHead`, `InclusionProof`, `ObservationWindow`. `AnchorTopologyError` carries `nwpErrorCode` + `npsStatus`. 30 regression tests. Re-exported from `@labacacia/nps-sdk/nip`.
16
+
17
+ - **`nwp/anchor-client.ts` — `AnchorNodeClient` (NPS-CR-0002)**: Fetch-based client for Anchor Node topology queries. `getSnapshot` (topology.snapshot) and `subscribe` async generator (topology.stream NDJSON). Discriminated-union `TopologyEvent` with kinds: `member_joined`, `member_left`, `member_updated`, `anchor_state`, `resync_required`. `AnchorTopologyError` for protocol errors. 24 regression tests.
18
+
19
+ ### Tracking the suite
20
+
21
+ This release tracks NPS suite `v1.0.0-alpha.7`.
22
+
23
+ ---
24
+
25
+ ## [1.0.0-alpha.6] — 2026-05-14
26
+
27
+ ### Changed
28
+
29
+ - **`nip/x509/oids.ts` — IANA PEN 65715 (Breaking, CR-0004)**: `LAB_ACACIA_PEN_ARC` updated from `"1.3.6.1.4.1.99999"` to `"1.3.6.1.4.1.65715"`. Certificates issued under the provisional arc must be revoked and re-issued.
30
+
31
+ - **`nwp/index.ts` — `NwpErrorCodes` re-export removed (Breaking)**: `export * as NwpErrorCodes from "./error-codes.js"` removed from the barrel. Import directly from `@labacacia/nps-sdk/nwp/error-codes` if needed.
32
+
33
+ - **Version bump to `1.0.0-alpha.6`** — synchronized with NPS suite alpha.6 release.
34
+
35
+ ---
36
+
11
37
  ## [1.0.0-alpha.5] — 2026-05-01
12
38
 
13
39
  ### Added
@@ -132,8 +158,6 @@ Until NPS reaches v1.0 stable, every repository in the suite is synchronized to
132
158
 
133
159
  First public alpha as part of the NPS suite `v1.0.0-alpha.1` release.
134
160
 
135
- [1.0.0-alpha.5]: https://github.com/labacacia/NPS-sdk-ts/releases/tag/v1.0.0-alpha.5
136
- [1.0.0-alpha.4]: https://github.com/labacacia/NPS-sdk-ts/releases/tag/v1.0.0-alpha.4
137
- [1.0.0-alpha.3]: https://github.com/LabAcacia/NPS-Dev/releases/tag/v1.0.0-alpha.3
138
- [1.0.0-alpha.2]: https://github.com/LabAcacia/NPS-Dev/releases/tag/v1.0.0-alpha.2
139
- [1.0.0-alpha.1]: https://github.com/LabAcacia/NPS-Dev/releases/tag/v1.0.0-alpha.1
161
+ [1.0.0-alpha.7]: https://github.com/labacacia/NPS-sdk-ts/releases/tag/v1.0.0-alpha.7
162
+ [1.0.0-alpha.2]: https://github.com/LabAcacia/nps/releases/tag/v1.0.0-alpha.2
163
+ [1.0.0-alpha.1]: https://github.com/LabAcacia/nps/releases/tag/v1.0.0-alpha.1
package/LICENSE CHANGED
File without changes
package/NOTICE CHANGED
File without changes
package/README.cn.md CHANGED
@@ -7,24 +7,19 @@
7
7
 
8
8
  ## 状态
9
9
 
10
- **v1.0.0-alpha.5 —— NWP 错误码 + NPS 状态码扩展** · 5 个协议 · 284 个测试 · 覆盖率 ≥ 98%
10
+ **v1.0.0-alpha.6 RFC-0002 SDK 端口波(第三棒)** · 5 个协议 · 271 个测试 · 覆盖率 ≥ 98%
11
+
12
+ > npm registry 说明:`@labacacia/nps-sdk@1.0.0-alpha.6` 已 deprecated,因为发布到 npm 的 tarball 缺少 `dist/`。当前 `alpha` dist-tag 临时指向 `1.0.0-alpha.5`;需要 alpha.6 源码时请使用 GitHub `v1.0.0-alpha.6` tag,等待下一个 npm 预发布。
11
13
 
12
14
  | 协议 | 类 | 状态 |
13
15
  |------|----|------|
14
16
  | NCP — Neural Communication Protocol | 帧、编解码器 | ✅ |
15
- | NWP — Neural Web Protocol | `NwpClient`、`NwpErrorCodes` | ✅ |
17
+ | NWP — Neural Web Protocol | `NwpClient` | ✅ |
16
18
  | NIP — Neural Identity Protocol | `NipIdentity`、`NipIdentVerifier`(RFC-0002 §8.1 双信任)、`AssuranceLevel`(RFC-0003)、`nip.x509` + `nip.acme` | ✅ |
17
- | NDP — Neural Discovery Protocol | `InMemoryNdpRegistry`、`NdpAnnounceValidator`、`resolveWithDns`(DNS TXT 回退)、`DnsTxtLookup`、`SystemDnsTxtLookup`、`parseNpsTxtRecord` | ✅ |
19
+ | NDP — Neural Discovery Protocol | `InMemoryNdpRegistry`、`NdpAnnounceValidator` | ✅ |
18
20
  | NOP — Neural Orchestration Protocol | `NopClient` | ✅ |
19
21
 
20
- **alpha.5 新增:**
21
-
22
- - `NwpErrorCodes` —— 从 `@labacacia/nps-sdk/nwp` 导出,包含 30 个 NWP wire 错误码字符串常量(`NWP-AUTH-*`、`NWP-QUERY-*`、`NWP-TOPOLOGY-*`、`NWP-RESERVED-TYPE-UNSUPPORTED` 等)。
23
- - `NpsStatusCodes.NPS_SERVER_UNSUPPORTED` —— 新状态码 `"NPS-SERVER-UNSUPPORTED"`(HTTP 501)。
24
- - `NipErrorCodes.REPUTATION_GOSSIP_FORK` / `.REPUTATION_GOSSIP_SIG_INVALID` —— RFC-0004 Phase 3 gossip 错误码。
25
- - `AssuranceLevel.fromWire("")` 改为返回 `Anonymous`(spec §5.1.1 修复)。
26
-
27
- **alpha.4 新增** —— 完整的 NPS-RFC-0002 X.509 + ACME `agent-01` NID 证书原语:
22
+ **早期新增** —— 完整的 NPS-RFC-0002 X.509 + ACME `agent-01` NID 证书原语:
28
23
 
29
24
  - `nip.x509` —— `issueLeaf` / `issueRoot` / `verify`(基于 `@peculiar/x509` + 原生 Web Crypto Ed25519)。
30
25
  - `nip.acme` —— `AcmeClient` + 进程内 `AcmeServer` + JWS / messages helpers(RFC 8555 + RFC 8037 EdDSA)。
@@ -33,7 +28,7 @@
33
28
  ## 安装
34
29
 
35
30
  ```bash
36
- npm install @labacacia/nps-sdk
31
+ npm install @labacacia/nps-sdk@alpha
37
32
  ```
38
33
 
39
34
  > **对等依赖:** Node.js 22+
@@ -165,4 +160,4 @@ npm run build
165
160
 
166
161
  ## 许可证
167
162
 
168
- Apache 2.0 —— 详见 [LICENSE](../../LICENSE)。
163
+ Apache 2.0 —— 详见 [LICENSE](https://github.com/labacacia/NPS-Dev/blob/main/LICENSE)。
package/README.md CHANGED
@@ -7,24 +7,19 @@ Part of the [LabAcacia](https://github.com/LabAcacia) / INNO LOTUS PTY LTD open-
7
7
 
8
8
  ## Status
9
9
 
10
- **v1.0.0-alpha.5NWP error codes + NPS status code extension** · 5 protocols · 284 tests · ≥ 98% coverage
10
+ **v1.0.0-alpha.6RFC-0002 cross-SDK port (third language)** · 5 protocols · 271 tests · ≥ 98% coverage
11
+
12
+ > npm registry note: `@labacacia/nps-sdk@1.0.0-alpha.6` is deprecated because the published tarball omitted `dist/`. The `alpha` dist-tag currently resolves to `1.0.0-alpha.5`; use the GitHub `v1.0.0-alpha.6` tag for source until the next npm prerelease.
11
13
 
12
14
  | Protocol | Class | Status |
13
15
  |----------|-------|--------|
14
16
  | NCP — Neural Communication Protocol | Framing, codec | ✅ |
15
- | NWP — Neural Web Protocol | `NwpClient`, `NwpErrorCodes` | ✅ |
17
+ | NWP — Neural Web Protocol | `NwpClient` | ✅ |
16
18
  | NIP — Neural Identity Protocol | `NipIdentity`, `NipIdentVerifier` (RFC-0002 §8.1 dual-trust), `AssuranceLevel` (RFC-0003), `nip.x509` + `nip.acme` | ✅ |
17
- | NDP — Neural Discovery Protocol | `InMemoryNdpRegistry`, `NdpAnnounceValidator`, `resolveWithDns` (DNS TXT fallback), `DnsTxtLookup`, `SystemDnsTxtLookup`, `parseNpsTxtRecord` | ✅ |
19
+ | NDP — Neural Discovery Protocol | `InMemoryNdpRegistry`, `NdpAnnounceValidator` | ✅ |
18
20
  | NOP — Neural Orchestration Protocol | `NopClient` | ✅ |
19
21
 
20
- **alpha.5 additions:**
21
-
22
- - `NwpErrorCodes` — exported from `@labacacia/nps-sdk/nwp`; 30 NWP wire error code constants (`NWP-AUTH-*`, `NWP-QUERY-*`, `NWP-TOPOLOGY-*`, `NWP-RESERVED-TYPE-UNSUPPORTED`, …).
23
- - `NpsStatusCodes.NPS_SERVER_UNSUPPORTED` — new `"NPS-SERVER-UNSUPPORTED"` status code (HTTP 501) in `src/core/status-codes.ts`.
24
- - `NipErrorCodes.REPUTATION_GOSSIP_FORK` / `.REPUTATION_GOSSIP_SIG_INVALID` — RFC-0004 Phase 3 gossip error codes.
25
- - `AssuranceLevel.fromWire("")` returns `Anonymous` instead of `Unknown` (spec §5.1.1 fix).
26
-
27
- **alpha.4 additions** — Full NPS-RFC-0002 X.509 + ACME `agent-01` NID certificate primitives:
22
+ **Earlier additions** — Full NPS-RFC-0002 X.509 + ACME `agent-01` NID certificate primitives:
28
23
 
29
24
  - `nip.x509` — `issueLeaf` / `issueRoot` / `verify` (built on `@peculiar/x509` + native Web Crypto Ed25519).
30
25
  - `nip.acme` — `AcmeClient` + in-process `AcmeServer` + JWS / message helpers (RFC 8555 + EdDSA per RFC 8037).
@@ -33,7 +28,7 @@ Part of the [LabAcacia](https://github.com/LabAcacia) / INNO LOTUS PTY LTD open-
33
28
  ## Installation
34
29
 
35
30
  ```bash
36
- npm install @labacacia/nps-sdk
31
+ npm install @labacacia/nps-sdk@alpha
37
32
  ```
38
33
 
39
34
  > **Peer requirement:** Node.js 22+
@@ -165,4 +160,4 @@ node node_modules/tsup/dist/cli-default.js
165
160
 
166
161
  ## License
167
162
 
168
- Apache 2.0 — see [LICENSE](../../LICENSE)
163
+ Apache 2.0 — see [LICENSE](https://github.com/labacacia/NPS-Dev/blob/main/LICENSE)
@@ -7,4 +7,5 @@ export * from "./error-codes.js";
7
7
  export * from "./verifier.js";
8
8
  export * as x509 from "./x509/index.js";
9
9
  export * as acme from "./acme/index.js";
10
+ export * from "./reputation-client.js";
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nip/index.ts"],"names":[],"mappings":"AAGA,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nip/index.ts"],"names":[],"mappings":"AAGA,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AAGxC,cAAc,wBAAwB,CAAC"}
package/dist/nip/index.js CHANGED
@@ -10,4 +10,6 @@ export * from "./error-codes.js";
10
10
  export * from "./verifier.js";
11
11
  export * as x509 from "./x509/index.js";
12
12
  export * as acme from "./acme/index.js";
13
+ // RFC-0004 — Reputation log
14
+ export * from "./reputation-client.js";
13
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nip/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,sCAAsC;AAEtC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,2DAA2D;AAC3D,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nip/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,sCAAsC;AAEtC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,2DAA2D;AAC3D,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AAExC,4BAA4B;AAC5B,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,116 @@
1
+ export interface ObservationWindow {
2
+ start: string;
3
+ end: string;
4
+ }
5
+ export declare const IncidentType: {
6
+ readonly Other: "other";
7
+ readonly CertRevoked: "cert-revoked";
8
+ readonly RateLimitViolation: "rate-limit-violation";
9
+ readonly TosViolation: "tos-violation";
10
+ readonly ScrapingPattern: "scraping-pattern";
11
+ readonly PaymentDefault: "payment-default";
12
+ readonly ContractDispute: "contract-dispute";
13
+ readonly ImpersonationClaim: "impersonation-claim";
14
+ readonly PositiveAttestation: "positive-attestation";
15
+ };
16
+ export type IncidentType = typeof IncidentType[keyof typeof IncidentType];
17
+ export declare const Severity: {
18
+ readonly Info: 0;
19
+ readonly Minor: 1;
20
+ readonly Moderate: 2;
21
+ readonly Major: 3;
22
+ readonly Critical: 4;
23
+ };
24
+ export type Severity = typeof Severity[keyof typeof Severity];
25
+ export interface ReputationLogEntry {
26
+ v: number;
27
+ log_id: string;
28
+ seq: number;
29
+ timestamp: string;
30
+ subject_nid: string;
31
+ incident: string;
32
+ incidentRaw?: string;
33
+ severity: string;
34
+ window?: ObservationWindow;
35
+ observation?: unknown;
36
+ evidence_ref?: string;
37
+ evidence_sha256?: string;
38
+ issuer_nid: string;
39
+ signature: string;
40
+ }
41
+ export interface SignedTreeHead {
42
+ log_id: string;
43
+ tree_size: number;
44
+ timestamp: string;
45
+ sha256_root_hash: string;
46
+ signature: string;
47
+ }
48
+ export interface InclusionProof {
49
+ seq: number;
50
+ leaf_index: number;
51
+ tree_size: number;
52
+ leaf_hash: string;
53
+ audit_path: string[];
54
+ }
55
+ /**
56
+ * Sign a ReputationLogEntry and return a new entry with `signature` set.
57
+ * The private key must be a 32-byte raw Ed25519 private key.
58
+ */
59
+ export declare function signEntry(privKey: Uint8Array, entry: ReputationLogEntry): ReputationLogEntry;
60
+ /**
61
+ * Verify the `signature` field of a ReputationLogEntry against the given
62
+ * Ed25519 public key (32-byte raw).
63
+ */
64
+ export declare function verifyEntry(pubKey: Uint8Array, entry: ReputationLogEntry): boolean;
65
+ /**
66
+ * Parse a wire severity string. Throws an Error for unknown values
67
+ * (no forward-compat — callers must upgrade to handle new severity levels).
68
+ */
69
+ export declare function parseSeverity(wire: string): Severity;
70
+ /**
71
+ * Parse a wire incident string. Unknown values map to `IncidentType.Other`
72
+ * (forward-compat); the original string is returned as `incidentRaw`.
73
+ */
74
+ export declare function parseIncident(wire: string): {
75
+ incident: IncidentType;
76
+ incidentRaw?: string;
77
+ };
78
+ export declare class ReputationLogException extends Error {
79
+ readonly nipErrorCode: string;
80
+ readonly npsStatus: string;
81
+ constructor(nipErrorCode: string, npsStatus: string, message?: string);
82
+ }
83
+ export declare class ReputationLogClient {
84
+ private readonly baseUrl;
85
+ constructor(baseUrl: string);
86
+ /**
87
+ * POST /v1/log/entries — submit a signed entry.
88
+ * Returns the server-echoed entry with seq/timestamp/log_id filled in.
89
+ */
90
+ submit(entry: ReputationLogEntry): Promise<ReputationLogEntry>;
91
+ /**
92
+ * GET /v1/log/entries — query entries.
93
+ * @param options.nid Filter by subject NID.
94
+ * @param options.sinceSeq Return only entries with seq > sinceSeq.
95
+ */
96
+ query(options?: {
97
+ nid?: string;
98
+ sinceSeq?: number;
99
+ }): Promise<ReputationLogEntry[]>;
100
+ /** GET /v1/log/sth — current SignedTreeHead. */
101
+ getSth(): Promise<SignedTreeHead>;
102
+ /** GET /v1/log/proof?seq=<seq> — InclusionProof for a log entry. */
103
+ getProof(seq: number): Promise<InclusionProof>;
104
+ /** GET /v1/log/gossip/sth — gossip SignedTreeHead. */
105
+ getGossipSth(): Promise<SignedTreeHead>;
106
+ /**
107
+ * Verify that `entry` is included in the log at the position described by
108
+ * `proof`, under the given `sth`.
109
+ *
110
+ * Merkle construction (RFC 9162):
111
+ * leaf_hash = SHA256(0x00 || utf8(canonical_all_sorted_json_of_entry))
112
+ * node_hash = SHA256(0x01 || left_bytes || right_bytes)
113
+ */
114
+ static verifyInclusion(proof: InclusionProof, sth: SignedTreeHead, entry: ReputationLogEntry): boolean;
115
+ }
116
+ //# sourceMappingURL=reputation-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reputation-client.d.ts","sourceRoot":"","sources":["../../src/nip/reputation-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,261 @@
1
+ // Copyright 2026 INNO LOTUS PTY LTD
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * ReputationLogClient — NPS-RFC-0004 reputation log HTTP client, signing
5
+ * helpers, and Merkle inclusion verification.
6
+ */
7
+ import * as ed25519 from "@noble/ed25519";
8
+ import { sha512 } from "@noble/hashes/sha512";
9
+ import { sha256 } from "@noble/hashes/sha256";
10
+ // noble/ed25519 requires sha512 to be set explicitly in Node environments
11
+ ed25519.etc.sha512Sync = (...m) => sha512(ed25519.etc.concatBytes(...m));
12
+ // ── Base64url helpers ────────────────────────────────────────────────────────
13
+ function base64urlEncode(bytes) {
14
+ return Buffer.from(bytes)
15
+ .toString("base64")
16
+ .replace(/\+/g, "-")
17
+ .replace(/\//g, "_")
18
+ .replace(/=/g, "");
19
+ }
20
+ function base64urlDecode(s) {
21
+ // Re-pad to a multiple of 4
22
+ const padded = s.replace(/-/g, "+").replace(/_/g, "/");
23
+ const pad = (4 - (padded.length % 4)) % 4;
24
+ return new Uint8Array(Buffer.from(padded + "=".repeat(pad), "base64"));
25
+ }
26
+ // ── Sorted-key canonical JSON ────────────────────────────────────────────────
27
+ /**
28
+ * Returns a value where every object in the tree has its keys sorted
29
+ * alphabetically (deeply). Arrays and primitives pass through unchanged.
30
+ */
31
+ function sortedValue(v) {
32
+ if (v === null || typeof v !== "object")
33
+ return v;
34
+ if (Array.isArray(v))
35
+ return v.map(sortedValue);
36
+ const obj = v;
37
+ const sorted = {};
38
+ for (const k of Object.keys(obj).sort()) {
39
+ sorted[k] = sortedValue(obj[k]);
40
+ }
41
+ return sorted;
42
+ }
43
+ /** Canonical JSON with all object keys sorted recursively. */
44
+ function sortedJson(obj) {
45
+ return JSON.stringify(sortedValue(obj));
46
+ }
47
+ export const IncidentType = {
48
+ Other: "other",
49
+ CertRevoked: "cert-revoked",
50
+ RateLimitViolation: "rate-limit-violation",
51
+ TosViolation: "tos-violation",
52
+ ScrapingPattern: "scraping-pattern",
53
+ PaymentDefault: "payment-default",
54
+ ContractDispute: "contract-dispute",
55
+ ImpersonationClaim: "impersonation-claim",
56
+ PositiveAttestation: "positive-attestation",
57
+ };
58
+ export const Severity = {
59
+ Info: 0,
60
+ Minor: 1,
61
+ Moderate: 2,
62
+ Major: 3,
63
+ Critical: 4,
64
+ };
65
+ /** Maps wire severity strings to numeric values. Throws on unknown values. */
66
+ const SEVERITY_WIRE = {
67
+ info: Severity.Info,
68
+ minor: Severity.Minor,
69
+ moderate: Severity.Moderate,
70
+ major: Severity.Major,
71
+ critical: Severity.Critical,
72
+ };
73
+ /** Known incident wire strings for forward-compat mapping. */
74
+ const KNOWN_INCIDENTS = new Set(Object.values(IncidentType).filter(v => v !== "other"));
75
+ // ── Signing helpers ──────────────────────────────────────────────────────────
76
+ /**
77
+ * Build the canonical bytes to sign for a ReputationLogEntry.
78
+ * The `signature` field is excluded; all remaining keys are sorted recursively.
79
+ */
80
+ function entrySigningBytes(entry) {
81
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
82
+ const { signature, ...rest } = entry;
83
+ return new TextEncoder().encode(sortedJson(rest));
84
+ }
85
+ /**
86
+ * Sign a ReputationLogEntry and return a new entry with `signature` set.
87
+ * The private key must be a 32-byte raw Ed25519 private key.
88
+ */
89
+ export function signEntry(privKey, entry) {
90
+ const bytes = entrySigningBytes(entry);
91
+ const sig = ed25519.sign(bytes, privKey);
92
+ return { ...entry, signature: `ed25519:${base64urlEncode(sig)}` };
93
+ }
94
+ /**
95
+ * Verify the `signature` field of a ReputationLogEntry against the given
96
+ * Ed25519 public key (32-byte raw).
97
+ */
98
+ export function verifyEntry(pubKey, entry) {
99
+ if (!entry.signature.startsWith("ed25519:"))
100
+ return false;
101
+ try {
102
+ const sigBytes = base64urlDecode(entry.signature.slice("ed25519:".length));
103
+ const bytes = entrySigningBytes(entry);
104
+ return ed25519.verify(sigBytes, bytes, pubKey);
105
+ }
106
+ catch {
107
+ return false;
108
+ }
109
+ }
110
+ // ── Severity / incident parsing ──────────────────────────────────────────────
111
+ /**
112
+ * Parse a wire severity string. Throws an Error for unknown values
113
+ * (no forward-compat — callers must upgrade to handle new severity levels).
114
+ */
115
+ export function parseSeverity(wire) {
116
+ const v = SEVERITY_WIRE[wire.toLowerCase()];
117
+ if (v === undefined)
118
+ throw new Error(`Unknown NPS severity value: "${wire}"`);
119
+ return v;
120
+ }
121
+ /**
122
+ * Parse a wire incident string. Unknown values map to `IncidentType.Other`
123
+ * (forward-compat); the original string is returned as `incidentRaw`.
124
+ */
125
+ export function parseIncident(wire) {
126
+ if (KNOWN_INCIDENTS.has(wire))
127
+ return { incident: wire };
128
+ return { incident: IncidentType.Other, incidentRaw: wire };
129
+ }
130
+ // ── Merkle verification ──────────────────────────────────────────────────────
131
+ function bytesEqual(a, b) {
132
+ if (a.length !== b.length)
133
+ return false;
134
+ for (let i = 0; i < a.length; i++)
135
+ if (a[i] !== b[i])
136
+ return false;
137
+ return true;
138
+ }
139
+ // ── HTTP client ──────────────────────────────────────────────────────────────
140
+ export class ReputationLogException extends Error {
141
+ nipErrorCode;
142
+ npsStatus;
143
+ constructor(nipErrorCode, npsStatus, message) {
144
+ super(message);
145
+ this.nipErrorCode = nipErrorCode;
146
+ this.npsStatus = npsStatus;
147
+ this.name = "ReputationLogException";
148
+ }
149
+ }
150
+ /** Throw a ReputationLogException for non-ok HTTP responses. */
151
+ async function ensureOk(resp) {
152
+ if (resp.ok)
153
+ return;
154
+ let nipCode = "NIP-UNKNOWN";
155
+ let npsStatus = String(resp.status);
156
+ let message = resp.statusText;
157
+ try {
158
+ const body = await resp.json();
159
+ if (body.error)
160
+ nipCode = body.error;
161
+ if (body.status)
162
+ npsStatus = body.status;
163
+ if (body.message)
164
+ message = body.message;
165
+ }
166
+ catch { /* ignore parse failures */ }
167
+ throw new ReputationLogException(nipCode, npsStatus, message);
168
+ }
169
+ export class ReputationLogClient {
170
+ baseUrl;
171
+ constructor(baseUrl) {
172
+ // Strip trailing slash for consistent path construction
173
+ this.baseUrl = baseUrl.replace(/\/+$/, "");
174
+ }
175
+ /**
176
+ * POST /v1/log/entries — submit a signed entry.
177
+ * Returns the server-echoed entry with seq/timestamp/log_id filled in.
178
+ */
179
+ async submit(entry) {
180
+ const resp = await fetch(`${this.baseUrl}/v1/log/entries`, {
181
+ method: "POST",
182
+ headers: { "Content-Type": "application/json" },
183
+ body: JSON.stringify(entry),
184
+ });
185
+ await ensureOk(resp);
186
+ return resp.json();
187
+ }
188
+ /**
189
+ * GET /v1/log/entries — query entries.
190
+ * @param options.nid Filter by subject NID.
191
+ * @param options.sinceSeq Return only entries with seq > sinceSeq.
192
+ */
193
+ async query(options) {
194
+ const params = new URLSearchParams();
195
+ if (options?.nid !== undefined)
196
+ params.set("nid", options.nid);
197
+ if (options?.sinceSeq !== undefined)
198
+ params.set("since", String(options.sinceSeq));
199
+ const qs = params.size > 0 ? `?${params.toString()}` : "";
200
+ const resp = await fetch(`${this.baseUrl}/v1/log/entries${qs}`);
201
+ await ensureOk(resp);
202
+ const body = await resp.json();
203
+ return body.entries;
204
+ }
205
+ /** GET /v1/log/sth — current SignedTreeHead. */
206
+ async getSth() {
207
+ const resp = await fetch(`${this.baseUrl}/v1/log/sth`);
208
+ await ensureOk(resp);
209
+ return resp.json();
210
+ }
211
+ /** GET /v1/log/proof?seq=<seq> — InclusionProof for a log entry. */
212
+ async getProof(seq) {
213
+ const resp = await fetch(`${this.baseUrl}/v1/log/proof?seq=${seq}`);
214
+ await ensureOk(resp);
215
+ return resp.json();
216
+ }
217
+ /** GET /v1/log/gossip/sth — gossip SignedTreeHead. */
218
+ async getGossipSth() {
219
+ const resp = await fetch(`${this.baseUrl}/v1/log/gossip/sth`);
220
+ await ensureOk(resp);
221
+ return resp.json();
222
+ }
223
+ /**
224
+ * Verify that `entry` is included in the log at the position described by
225
+ * `proof`, under the given `sth`.
226
+ *
227
+ * Merkle construction (RFC 9162):
228
+ * leaf_hash = SHA256(0x00 || utf8(canonical_all_sorted_json_of_entry))
229
+ * node_hash = SHA256(0x01 || left_bytes || right_bytes)
230
+ */
231
+ static verifyInclusion(proof, sth, entry) {
232
+ // Leaf hash includes the signature field
233
+ const leafBytes = new TextEncoder().encode(sortedJson(entry));
234
+ const leafBuf = new Uint8Array(1 + leafBytes.length);
235
+ leafBuf[0] = 0x00;
236
+ leafBuf.set(leafBytes, 1);
237
+ const computedLeafHash = sha256(leafBuf);
238
+ // Verify that the computed leaf hash matches the proof's leaf_hash
239
+ const proofLeafHash = base64urlDecode(proof.leaf_hash);
240
+ if (!bytesEqual(computedLeafHash, proofLeafHash))
241
+ return false;
242
+ // RFC 9162 fold up the audit path
243
+ let nodeHash = computedLeafHash;
244
+ for (let i = 0; i < proof.audit_path.length; i++) {
245
+ const sibling = base64urlDecode(proof.audit_path[i]);
246
+ const buf = new Uint8Array(65);
247
+ buf[0] = 0x01;
248
+ if (((BigInt(proof.leaf_index) >> BigInt(i)) & 1n) === 0n) {
249
+ buf.set(nodeHash, 1);
250
+ buf.set(sibling, 33);
251
+ }
252
+ else {
253
+ buf.set(sibling, 1);
254
+ buf.set(nodeHash, 33);
255
+ }
256
+ nodeHash = sha256(buf);
257
+ }
258
+ return bytesEqual(nodeHash, base64urlDecode(sth.sha256_root_hash));
259
+ }
260
+ }
261
+ //# sourceMappingURL=reputation-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reputation-client.js","sourceRoot":"","sources":["../../src/nip/reputation-client.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,16 @@
1
1
  /**
2
2
  * OID constants for NPS X.509 certificates per NPS-RFC-0002 §4.
3
3
  *
4
- * The 1.3.6.1.4.1.99999 arc is provisional pending IANA Private Enterprise
5
- * Number assignment (RFC-0002 §10 OQ-2). All implementations MUST update
6
- * these constants when the official PEN is granted.
4
+ * The 1.3.6.1.4.1.65715 arc is the LabAcacia IANA-assigned Private Enterprise
5
+ * Number (PEN 65715, NPS-CR-0004, 2026-05-08).
7
6
  */
8
- export declare const LAB_ACACIA_PEN_ARC = "1.3.6.1.4.1.99999";
9
- export declare const EKU_ARC = "1.3.6.1.4.1.99999.1";
10
- export declare const EXTENSION_ARC = "1.3.6.1.4.1.99999.2";
11
- export declare const EKU_AGENT_IDENTITY = "1.3.6.1.4.1.99999.1.1";
12
- export declare const EKU_NODE_IDENTITY = "1.3.6.1.4.1.99999.1.2";
13
- export declare const EKU_CA_INTERMEDIATE_AGENT = "1.3.6.1.4.1.99999.1.3";
14
- export declare const NID_ASSURANCE_LEVEL = "1.3.6.1.4.1.99999.2.1";
7
+ export declare const LAB_ACACIA_PEN_ARC = "1.3.6.1.4.1.65715";
8
+ export declare const EKU_ARC = "1.3.6.1.4.1.65715.1";
9
+ export declare const EXTENSION_ARC = "1.3.6.1.4.1.65715.2";
10
+ export declare const EKU_AGENT_IDENTITY = "1.3.6.1.4.1.65715.1.1";
11
+ export declare const EKU_NODE_IDENTITY = "1.3.6.1.4.1.65715.1.2";
12
+ export declare const EKU_CA_INTERMEDIATE_AGENT = "1.3.6.1.4.1.65715.1.3";
13
+ export declare const NID_ASSURANCE_LEVEL = "1.3.6.1.4.1.65715.2.1";
15
14
  export declare const ED25519 = "1.3.101.112";
16
15
  export declare const OID_EXTENDED_KEY_USAGE = "2.5.29.37";
17
16
  //# sourceMappingURL=oids.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oids.d.ts","sourceRoot":"","sources":["../../../src/nip/x509/oids.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AAEH,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AACtD,eAAO,MAAM,OAAO,wBAAuC,CAAC;AAC5D,eAAO,MAAM,aAAa,wBAAiC,CAAC;AAG5D,eAAO,MAAM,kBAAkB,0BAAwB,CAAC;AACxD,eAAO,MAAM,iBAAiB,0BAAyB,CAAC;AACxD,eAAO,MAAM,yBAAyB,0BAAiB,CAAC;AAGxD,eAAO,MAAM,mBAAmB,0BAAuB,CAAC;AAGxD,eAAO,MAAM,OAAO,gBAAgB,CAAC;AAGrC,eAAO,MAAM,sBAAsB,cAAc,CAAC"}
1
+ {"version":3,"file":"oids.d.ts","sourceRoot":"","sources":["../../../src/nip/x509/oids.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AACtD,eAAO,MAAM,OAAO,wBAAuC,CAAC;AAC5D,eAAO,MAAM,aAAa,wBAAiC,CAAC;AAG5D,eAAO,MAAM,kBAAkB,0BAAwB,CAAC;AACxD,eAAO,MAAM,iBAAiB,0BAAyB,CAAC;AACxD,eAAO,MAAM,yBAAyB,0BAAiB,CAAC;AAGxD,eAAO,MAAM,mBAAmB,0BAAuB,CAAC;AAGxD,eAAO,MAAM,OAAO,gBAAgB,CAAC;AAGrC,eAAO,MAAM,sBAAsB,cAAc,CAAC"}