@nano133/nanoterra 0.0.0-stage → 0.2.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.
Files changed (187) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/LICENSE +21 -0
  3. package/README.md +548 -2
  4. package/ai/PROMPT.md +16 -0
  5. package/ai/SPEC.md +111 -0
  6. package/dist/admin/adapters/d1.d.ts +27 -0
  7. package/dist/admin/adapters/d1.js +73 -0
  8. package/dist/admin/adapters/firestore.d.ts +40 -0
  9. package/dist/admin/adapters/firestore.js +53 -0
  10. package/dist/admin/amount.d.ts +5 -0
  11. package/dist/admin/amount.js +11 -0
  12. package/dist/admin/conformance.d.ts +132 -0
  13. package/dist/admin/conformance.js +467 -0
  14. package/dist/admin/guard.d.ts +38 -0
  15. package/dist/admin/guard.js +57 -0
  16. package/dist/admin/handler.d.ts +63 -0
  17. package/dist/admin/handler.js +170 -0
  18. package/dist/admin/http.d.ts +17 -0
  19. package/dist/admin/http.js +76 -0
  20. package/dist/admin/index.d.ts +13 -0
  21. package/dist/admin/index.js +14 -0
  22. package/dist/admin/memory.d.ts +32 -0
  23. package/dist/admin/memory.js +40 -0
  24. package/dist/admin/panel/api.d.ts +11 -0
  25. package/dist/admin/panel/api.js +33 -0
  26. package/dist/admin/panel/dom.d.ts +7 -0
  27. package/dist/admin/panel/dom.js +33 -0
  28. package/dist/admin/panel/gameCard.d.ts +4 -0
  29. package/dist/admin/panel/gameCard.js +56 -0
  30. package/dist/admin/panel/index.d.ts +10 -0
  31. package/dist/admin/panel/index.js +13 -0
  32. package/dist/admin/panel/mount.d.ts +30 -0
  33. package/dist/admin/panel/mount.js +147 -0
  34. package/dist/admin/panel/shelf.d.ts +17 -0
  35. package/dist/admin/panel/shelf.js +247 -0
  36. package/dist/admin/panel/shelfData.d.ts +37 -0
  37. package/dist/admin/panel/shelfData.js +68 -0
  38. package/dist/admin/panel/signins.d.ts +6 -0
  39. package/dist/admin/panel/signins.js +69 -0
  40. package/dist/admin/store.d.ts +121 -0
  41. package/dist/admin/store.js +3 -0
  42. package/dist/admin/summary.d.ts +39 -0
  43. package/dist/admin/summary.js +85 -0
  44. package/dist/admin/switches.d.ts +58 -0
  45. package/dist/admin/switches.js +61 -0
  46. package/dist/character/assemble.d.ts +17 -0
  47. package/dist/character/assemble.js +39 -0
  48. package/dist/character/bases/bee.d.ts +2 -0
  49. package/dist/character/bases/bee.js +39 -0
  50. package/dist/character/bases/classic.d.ts +4 -0
  51. package/dist/character/bases/classic.js +28 -0
  52. package/dist/character/bases/critter.d.ts +2 -0
  53. package/dist/character/bases/critter.js +43 -0
  54. package/dist/character/bases/index.d.ts +5 -0
  55. package/dist/character/bases/index.js +8 -0
  56. package/dist/character/bases/pineapple.d.ts +2 -0
  57. package/dist/character/bases/pineapple.js +43 -0
  58. package/dist/character/bases/robot.d.ts +2 -0
  59. package/dist/character/bases/robot.js +33 -0
  60. package/dist/character/bases/round.d.ts +2 -0
  61. package/dist/character/bases/round.js +65 -0
  62. package/dist/character/bases/shared.d.ts +17 -0
  63. package/dist/character/bases/shared.js +17 -0
  64. package/dist/character/bases/spec.d.ts +17 -0
  65. package/dist/character/bases/spec.js +1 -0
  66. package/dist/character/build.d.ts +65 -0
  67. package/dist/character/build.js +223 -0
  68. package/dist/character/clothes.d.ts +21 -0
  69. package/dist/character/clothes.js +193 -0
  70. package/dist/character/color.d.ts +2 -0
  71. package/dist/character/color.js +9 -0
  72. package/dist/character/create.d.ts +58 -0
  73. package/dist/character/create.js +164 -0
  74. package/dist/character/ctx.d.ts +97 -0
  75. package/dist/character/ctx.js +1 -0
  76. package/dist/character/edit.d.ts +11 -0
  77. package/dist/character/edit.js +73 -0
  78. package/dist/character/face.d.ts +15 -0
  79. package/dist/character/face.js +181 -0
  80. package/dist/character/fit.d.ts +12 -0
  81. package/dist/character/fit.js +66 -0
  82. package/dist/character/hair.d.ts +4 -0
  83. package/dist/character/hair.js +139 -0
  84. package/dist/character/index.d.ts +36 -0
  85. package/dist/character/index.js +25 -0
  86. package/dist/character/kit.d.ts +16 -0
  87. package/dist/character/kit.js +47 -0
  88. package/dist/character/limbs.d.ts +30 -0
  89. package/dist/character/limbs.js +45 -0
  90. package/dist/character/lists.d.ts +63 -0
  91. package/dist/character/lists.js +59 -0
  92. package/dist/character/look.d.ts +27 -0
  93. package/dist/character/look.js +75 -0
  94. package/dist/character/make.d.ts +53 -0
  95. package/dist/character/make.js +64 -0
  96. package/dist/character/motion.d.ts +7 -0
  97. package/dist/character/motion.js +95 -0
  98. package/dist/character/pose.d.ts +42 -0
  99. package/dist/character/pose.js +98 -0
  100. package/dist/character/pure.d.ts +4 -0
  101. package/dist/character/pure.js +7 -0
  102. package/dist/character/record.d.ts +137 -0
  103. package/dist/character/record.js +190 -0
  104. package/dist/character/skeleton.d.ts +15 -0
  105. package/dist/character/skeleton.js +77 -0
  106. package/dist/character/solver.d.ts +36 -0
  107. package/dist/character/solver.js +145 -0
  108. package/dist/character/toon.d.ts +16 -0
  109. package/dist/character/toon.js +95 -0
  110. package/dist/character/torso.d.ts +8 -0
  111. package/dist/character/torso.js +9 -0
  112. package/dist/index.d.ts +4 -0
  113. package/dist/index.js +8 -0
  114. package/dist/looks/change.d.ts +24 -0
  115. package/dist/looks/change.js +63 -0
  116. package/dist/looks/index.d.ts +7 -0
  117. package/dist/looks/index.js +4 -0
  118. package/dist/looks/json.d.ts +8 -0
  119. package/dist/looks/json.js +37 -0
  120. package/dist/looks/ladder.d.ts +14 -0
  121. package/dist/looks/ladder.js +24 -0
  122. package/dist/looks/look.d.ts +62 -0
  123. package/dist/looks/look.js +113 -0
  124. package/dist/ticket/index.d.ts +99 -0
  125. package/dist/ticket/index.js +191 -0
  126. package/package.json +46 -4
  127. package/src/admin/adapters/d1.ts +94 -0
  128. package/src/admin/adapters/firestore.ts +78 -0
  129. package/src/admin/amount.ts +14 -0
  130. package/src/admin/conformance.ts +605 -0
  131. package/src/admin/guard.ts +86 -0
  132. package/src/admin/handler.ts +200 -0
  133. package/src/admin/http.ts +74 -0
  134. package/src/admin/index.ts +21 -0
  135. package/src/admin/memory.ts +59 -0
  136. package/src/admin/panel/api.ts +37 -0
  137. package/src/admin/panel/dom.ts +31 -0
  138. package/src/admin/panel/gameCard.ts +63 -0
  139. package/src/admin/panel/index.ts +18 -0
  140. package/src/admin/panel/mount.ts +227 -0
  141. package/src/admin/panel/shelf.ts +337 -0
  142. package/src/admin/panel/shelfData.ts +87 -0
  143. package/src/admin/panel/signins.ts +68 -0
  144. package/src/admin/panel/style.css +542 -0
  145. package/src/admin/store.ts +98 -0
  146. package/src/admin/summary.ts +103 -0
  147. package/src/admin/switches.ts +74 -0
  148. package/src/character/assemble.ts +44 -0
  149. package/src/character/bases/bee.ts +42 -0
  150. package/src/character/bases/classic.ts +30 -0
  151. package/src/character/bases/critter.ts +44 -0
  152. package/src/character/bases/index.ts +12 -0
  153. package/src/character/bases/pineapple.ts +45 -0
  154. package/src/character/bases/robot.ts +34 -0
  155. package/src/character/bases/round.ts +69 -0
  156. package/src/character/bases/shared.ts +25 -0
  157. package/src/character/bases/spec.ts +18 -0
  158. package/src/character/build.ts +244 -0
  159. package/src/character/clothes.ts +204 -0
  160. package/src/character/color.ts +10 -0
  161. package/src/character/create.ts +214 -0
  162. package/src/character/ctx.ts +95 -0
  163. package/src/character/edit.ts +78 -0
  164. package/src/character/face.ts +176 -0
  165. package/src/character/fit.ts +78 -0
  166. package/src/character/hair.ts +142 -0
  167. package/src/character/index.ts +29 -0
  168. package/src/character/kit.ts +51 -0
  169. package/src/character/limbs.ts +78 -0
  170. package/src/character/lists.ts +77 -0
  171. package/src/character/look.ts +85 -0
  172. package/src/character/make.ts +82 -0
  173. package/src/character/motion.ts +100 -0
  174. package/src/character/pose.ts +132 -0
  175. package/src/character/pure.ts +7 -0
  176. package/src/character/record.ts +265 -0
  177. package/src/character/skeleton.ts +82 -0
  178. package/src/character/solver.ts +160 -0
  179. package/src/character/toon.ts +104 -0
  180. package/src/character/torso.ts +13 -0
  181. package/src/index.ts +12 -0
  182. package/src/looks/change.ts +65 -0
  183. package/src/looks/index.ts +7 -0
  184. package/src/looks/json.ts +36 -0
  185. package/src/looks/ladder.ts +35 -0
  186. package/src/looks/look.ts +131 -0
  187. package/src/ticket/index.ts +241 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,92 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 (2026-10-27)
4
+
5
+ - **Slots** on a look (`@nano133/nanoterra/looks`, and the Shelf of `/admin/panel`): `slots?: Record<string, string>`, what a game defines for itself (a pair of wings, a trail colour). Names are 1 to 24
6
+ lowercase letters, digits or dashes starting with a letter; values are words (1 to 40 lowercase letters, digits or dashes) or `#rrggbb` colours; at most 8 on a look. `lookProblems` checks them
7
+ (`slots`, `slots.<name>`), `checkLooks` keeps them, `looksJson` writes them after `change`, `diffLooks` lists a change as the field `"slots"` (order and the case of a colour are not changes), and
8
+ `removalProblems` reports a changed slot on a look that a player owns (players own a look by its id; a price, a name, a colour or a hat of an owned look stays allowed). New: `sameSlots`,
9
+ `cleanSlots`, `slotValueOk`, `SLOTS_MAX`, `SLOT_NAME_PATTERN`, `SLOT_WORD_PATTERN`, the type `Slots`. A file from before slots reads and writes exactly as it did. The Shelf keeps the slots in its
10
+ draft and has a Slots editor. This is a minor change (0.2.0); a game on 0.1.0 drops slots, so it must move to the new version.
11
+ - **`@nano133/nanoterra/admin`** (step 1 of the admin panel): the admin of a game, in the package, with no Three.js, no database and no cookie. The game gives a session and a store.
12
+ - `adminAccess(input)`: the guard, ONE pure function. The same five checks as the game starter's `adminGuard`, in the same order (owner set, session present, wallet login,
13
+ same address, not older than one day). It only refuses MORE than the starter does: a bad owner address, a time that is not a number or lies more than five minutes in the
14
+ future, a login word that is not exactly "wallet", and a limit above one day are all refusals. A fault inside it is a refusal.
15
+ - `createAdminHandler(options)`: the routes (summary, the two game switches, the payment check) on Web `Request` and `Response`. Every path under the base goes through the
16
+ guard first, so a visitor learns nothing about the routes. A POST must come from the game's own page. No CORS header, always `no-store`, a body limit, a rate limit.
17
+ - `AdminStore`: what a game gives (read the two settings, save a checked patch, the summary). The only writes are the two `setting:` values.
18
+ - `loadGameSettings(store, defaults)`: the two switches for the game's own routes (the listing file, the character); the defaults when the store fails.
19
+ - `createMemoryStore()`: a store in memory, for tests.
20
+ - **`@nano133/nanoterra/admin/panel`** (step 2): `mountAdmin(element, options)`, the admin page in plain DOM with no framework: the Game card, the status warnings, the totals, the Shelf (the
21
+ starter's, moved here: it edits a draft and gives text to copy, and sends no request), the orders with "Paid late" and an optional "Check payments now", the looks that players own,
22
+ and the screens for a visitor who is signed out, a wrong wallet, a Nanoterra sign-in and a missing owner address. The game gives `signIn`, `signOut` and its `looks`.
23
+ `@nano133/nanoterra/admin/style.css`: its stylesheet, every rule under `.n133-admin`. The summary of the handler now says `canCheck`.
24
+ - **`@nano133/nanoterra/admin/d1`** and **`/admin/firestore`** (step 3): `createD1Store(db)` (the game starter's tables, with the starter's own queries) and `createFirestoreStore(db, names?)` (a small interface; no
25
+ Firebase dependency). Both write ONLY the two settings. `adminStoreConformance(make)` (in `/admin/conformance`) is the store contract that every adapter passes: the memory store, D1 on SQLite and Firestore on a fake.
26
+ The summary's numbers come from one file (`summarize`, `moneyOf`, `shapeOrders`), so every adapter says the same thing. The memory store now takes orders with a raw `amountRaw`, like a real database.
27
+ - **The Game card's words for sign-in Off** (Wes, "off means off"): "Sign-in from Nanoterra is Off, so every player plays as the island's first character, a player who signed in from Nanoterra before
28
+ included." The card only says it: the game's own page must draw no Nanoterra character while sign-in is Off (the game starter's `src/client/ui/player.ts` does).
29
+ - **Who signed in, and "Sign out everywhere"** (optional, Wes's security ideas): `AdminLogin` (time, country, short browser name) and the optional store calls `recentLogins(limit)` and
30
+ `signOutEverywhere()`. With them the summary has `logins` (the last 10, only those three things, whatever the store gives) and `canSignOutEverywhere`, the handler has `POST {base}/signout-all`
31
+ (guarded, same origin, 5 a minute, deletes the admin sessions and no player session), and the panel has a Sign-ins card with a two-press "Sign out everywhere". `createD1Store(db, { logins: true })`
32
+ reads `admin_logins` and deletes `sessions WHERE scope = 'admin'`. Memory store: `createMemoryStore({ logins: true })`. The store contract has cases for both. The panel option `loginsNote` says what
33
+ the game keeps and for how long (30 days suggested).
34
+ - **`@nano133/nanoterra/admin/conformance`**: `adminConformance(host)` gives test cases that a game runs against its OWN session code and store: every route refuses a visitor
35
+ who is signed out, a login made for the game's players (also its token in the admin cookie), a Nanoterra sign-in, a login made some way the game does not know, another wallet, a missing
36
+ owner address, an expired login and a login that is old but still valid in the store; OPTIONS and HEAD are refused with no preflight answer; other spellings of an admin path open nothing with
37
+ any method; the game's other routes under the base (`otherRoutes`) refuse a visitor; a POST from another site is refused; a body that is too big is refused; every answer is `no-store` with
38
+ no CORS header. (The first version of this suite passed four wirings that leak everything; a security read found them, and each is a test now.)
39
+ - **A fourth security read** (the same fresh agent as the third, 2026-10-27, on the third-read fixes) found that `adminSigninConformance` still passed wrong chains: one with no binding of a request to its
40
+ browser inside one scope, one whose cross-scope ask gave a login in the STORED scope, one whose `sign()` stopped landing (the checks then ran on an unsigned request), one that checked the scope only
41
+ while the request was fresh, one whose Sign out everywhere left a request that was still waiting for a signature, and one with no `signOutEverywhere` at all (the case was skipped). Fixed: `sign()` must
42
+ throw on a refusal; a cross-scope ask must give no login of either kind and the request must still sign in afterwards (the signature is proven to have landed); a same-scope ask from another browser gives
43
+ none; the host may give `advance(ms)` to repeat the asks after the admin's request life; `adminSigninConformance(host, { signOutEverywhere: true })` fails a host that has no call; the store contract
44
+ REQUIRES `seedRequests` and `pendingRequests` when the store has `signOutEverywhere`. `createD1Store(db, { logins: true })`'s `signOutEverywhere` also ends the pending admin requests
45
+ (`expires_at = 0`). Eight fake chains (one good, seven wrong) run against the contract.
46
+ A fifth read of these fixes (same agent) found four small gaps, fixed: `adminSigninConformance(host, { advance: true })` fails a host that cannot move its clock (the time case could be skipped);
47
+ the late asks are made at 10 and at 55 minutes (a scope check that holds for 30 minutes passed); a collected request must give another browser no login either; and the kit's `dist` must be
48
+ built before `npm pack` (a packed tarball of an unbuilt change tested the old code). Ten fake chains (one good, nine wrong).
49
+ - **A third security read** (another new fresh agent, 2026-10-27) found that the suite still passed four wirings that leak: a game that caches 200 answers by URL, one that keeps the sessions it has read
50
+ in memory (a login that sign-out or Sign out everywhere ended still opens), one that also reads a player's token from a Bearer header, and one that reads it from the query. Fixed: the suite sends every
51
+ refused visitor again right after the owner was served; `host.endLogin` and the login that used Sign out everywhere are used again and must be refused; `req.tokenAt` sends a player's token in other
52
+ places than the cookie; and `adminSigninConformance(host)` is a contract for the code that MAKES the logins (a game request never makes an admin login and the other way round, for the browser that
53
+ started it, another browser and retyped credentials; once; and a signed admin request makes no login after Sign out everywhere). `createD1Store(db, { logins: true })`'s `signOutEverywhere` also marks
54
+ the admin sign-in requests that were not delivered as delivered (needs `signin_requests.scope` and `.delivered`). The list shows a browser name only when it is words. Four tests run the four wirings
55
+ against the suite, and three fake sign-in chains run against the contract (one good, three wrong).
56
+ - **A second security read** (new fresh agent, 2026-10-27) found that the second conformance suite still passed some wirings that leak or act. Fixed: the suite sends a foreign Origin (another site,
57
+ `"null"`, a sibling subdomain) and Sec-Fetch-Site cross-site and same-site on every route with every method, for the owner too; it sends an old login that is still valid THREE times (the last two
58
+ with `req.again`) so a rolling session fails; `expired_login` is now made less than a day ago so only the game's own store can refuse it; new kind `signed_out_login`; the spelling tricks run on
59
+ every route and method; the game's other routes must refuse with a refusal that carries no data. **The handler now refuses a read that says it comes from another page**, as it refused a write.
60
+ Looks: `wholeCents` is exact (`0.300000001` and `1e-9` no longer pass); a slot colour is written in lower case (a change of only its case is no change); the names `constructor` and
61
+ `prototype` are reserved; `checkLooks` checks and copies one snapshot; the Shelf never gives an id that a player owns to a new look.
62
+ - **Fixes from a security read of the first admin code:** odd spellings of the base path (a bad percent code, backslashes, many levels of encoding) now reach the guard instead of falling through;
63
+ a fault in the game's `now()` or `onError()` can no longer reject `handle()` with the raw error; the default limiter is keyed by base path and owner, so two games in one process do not share a
64
+ count; the message for an AI assistant takes only valid look ids, written as JSON strings (an id from a database cannot write a line into it); the summary counts only the four statuses it knows
65
+ and reads a dollar text only when it is plain dollars.
66
+
67
+ ## 0.1.0
68
+
69
+ First version (Pre-alpha). **One package for Nanoterra.** It replaces `@nano133/character` 0.1.0, `@nano133/ticket` 0.1.0 and
70
+ `@nano133/looks` 0.1.0 (their npm versions stay; they are deprecated and point here).
71
+
72
+ - **`@nano133/nanoterra/character`**: the character is now the one that nano133.com's island and 3D room draw, from the same code. Six bases
73
+ (Classic, Round, Critter, Bee, Robot, Pineapple), faces, hair, clothes, sizes and colours, from a **record** of whole numbers on closed lists.
74
+ `createCharacter({ record, look, colors, quality, reducedMotion })` gives `object`, `update(dt, { speed, airborne, verticalSpeed })`,
75
+ `wave()`, `setLook(recordOrFiveColours)`, `setColors(colors)`, `record`, `look`, `reducedMotion` and `dispose()`. `setLook` to another body builds new
76
+ geometry and frees the old; a new colour only repaints. The default Classic is the old package's character, vertex for vertex.
77
+ Also exported: `buildCharacter` and `assemble` (the geometry and the skinned meshes on the island's 28-bone skeleton), the lists, `WornAdapter`.
78
+ - **Changed from `@nano133/character` 0.1.0:** the blob shadow is a disc in the body (on the skeleton's shadow bone), so there is no `c.shadow` and one
79
+ `scene.add(c.object)` is enough; it stays on the ground under a jump. A colour that is not on the island's lists (a shop dye) goes through `setColors`
80
+ (`setLook` takes a record or the five colours of the lists). `HEIGHT` and `RADIUS` are the default Classic's.
81
+ - **`@nano133/nanoterra/character/record`**: the record with no Three.js and no package at all: `packRecord` and `unpackRecord` (two whole numbers; `null` for
82
+ anything off a list), `recordProblem`, `clean`, `fromLegacy` and `toLegacy` (the five colours; all 8,192 old looks come back whole), `withLegacy`, `withBase`,
83
+ `diceRecord`, `fromBlob` and `toBlob` (the room's blob), the lists, `defaultLook`, `isLook`, `lookProblem`, `assertLook`, `LOOK_PARTS`.
84
+ - **`@nano133/nanoterra/ticket`**: `readTicket`, `verifyTicket`, `fetchKeys`, `ticketFromHash`, `hashWithoutTicket`, as in `@nano133/ticket` 0.1.0, and the
85
+ ticket's **`record`** when it carries one (read with care; absent for a ticket from before it, and then the answer reads exactly as it did). The same pinned
86
+ ticket is checked byte for byte here and in nano133.com's own test.
87
+ - **`@nano133/nanoterra/looks`**: `@nano133/looks` 0.1.0 as it was (`checkLooks`, `lookProblems`, `removalProblems`, `diffLooks`, `looksJson`, `slugId`,
88
+ `PRICE_LADDER`, `rungOf`, `priceText`, `usdText`, `wholeCents`, `HATS`).
89
+ - **`@nano133/nanoterra`**: the types `Look` and `LookRecord`, and nothing that runs. Importing the record, the ticket, the looks or this path loads no Three.js
90
+ (a test reads the built files and proves it). `three` is an optional peer dependency (`>=0.174.0`).
91
+ - Body only. The island's 14 worn items are not in this package: the builder takes them through the `WornAdapter` interface, and a later version (0.2.0) adds
92
+ the item art. A player's item ids are in the sign-in answer.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 nano133.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.