dexterm-cli 0.0.0-stage → 0.1.1

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 (349) hide show
  1. package/LICENSE +661 -0
  2. package/dist/packages/agents/src/audit.js +122 -0
  3. package/dist/packages/agents/src/bus.js +379 -0
  4. package/dist/packages/agents/src/executor.js +177 -0
  5. package/dist/packages/agents/src/gate.js +176 -0
  6. package/dist/packages/agents/src/identity.js +179 -0
  7. package/dist/packages/agents/src/index.js +15 -0
  8. package/dist/packages/agents/src/proposals.js +153 -0
  9. package/dist/packages/agents/src/schema.js +87 -0
  10. package/dist/packages/agents/src/sdk.js +140 -0
  11. package/dist/packages/agents/src/tiers.js +114 -0
  12. package/dist/packages/agents/src/tools.js +69 -0
  13. package/dist/packages/agents/src/ws.js +158 -0
  14. package/dist/packages/cli/assets/claude/analyst-system.md +76 -0
  15. package/dist/packages/cli/assets/claude/plugin/.claude-plugin/plugin.json +5 -0
  16. package/dist/packages/cli/assets/claude/plugin/skills/REGISTRY.json +16 -0
  17. package/dist/packages/cli/assets/claude/plugin/skills/larp-check/SKILL.md +67 -0
  18. package/dist/packages/cli/assets/claude/plugin/skills/rug-check/SKILL.md +64 -0
  19. package/dist/packages/cli/assets/claude/plugin/skills/token-dossier/SKILL.md +63 -0
  20. package/dist/packages/cli/assets/claude/plugin/skills/trench-scan/SKILL.md +44 -0
  21. package/dist/packages/cli/assets/claude/schemas/larp.schema.json +117 -0
  22. package/dist/packages/cli/assets/claude/schemas/trench-scan.schema.json +71 -0
  23. package/dist/packages/cli/assets/claude/schemas/verdict.schema.json +115 -0
  24. package/dist/packages/cli/bin/dexterm.mjs +11 -0
  25. package/dist/packages/cli/src/agent-cmd.js +303 -0
  26. package/dist/packages/cli/src/agent-roster.js +26 -0
  27. package/dist/packages/cli/src/analyst/backend.js +526 -0
  28. package/dist/packages/cli/src/analyst/results.js +38 -0
  29. package/dist/packages/cli/src/analyst/session.js +319 -0
  30. package/dist/packages/cli/src/audit.js +51 -0
  31. package/dist/packages/cli/src/backtest-cmd.js +149 -0
  32. package/dist/packages/cli/src/boot-state.js +62 -0
  33. package/dist/packages/cli/src/custom.js +261 -0
  34. package/dist/packages/cli/src/display.js +191 -0
  35. package/dist/packages/cli/src/doctor.js +361 -0
  36. package/dist/packages/cli/src/feed.js +634 -0
  37. package/dist/packages/cli/src/fixtures.js +275 -0
  38. package/dist/packages/cli/src/follow-cmd.js +221 -0
  39. package/dist/packages/cli/src/images-config.js +59 -0
  40. package/dist/packages/cli/src/index.js +31 -0
  41. package/dist/packages/cli/src/kb-skill-cmd.js +240 -0
  42. package/dist/packages/cli/src/larp-record.js +21 -0
  43. package/dist/packages/cli/src/live/copy.js +80 -0
  44. package/dist/packages/cli/src/live/flow.js +233 -0
  45. package/dist/packages/cli/src/live/index.js +509 -0
  46. package/dist/packages/cli/src/live/intel.js +227 -0
  47. package/dist/packages/cli/src/live/newpairs.js +334 -0
  48. package/dist/packages/cli/src/live/screens/newpairs-live.js +219 -0
  49. package/dist/packages/cli/src/live/screens/token-live.js +459 -0
  50. package/dist/packages/cli/src/live/screens/watchlist-live.js +149 -0
  51. package/dist/packages/cli/src/live/token.js +585 -0
  52. package/dist/packages/cli/src/live/trade.js +929 -0
  53. package/dist/packages/cli/src/live/watchlist.js +178 -0
  54. package/dist/packages/cli/src/main.js +5583 -0
  55. package/dist/packages/cli/src/narrative-cmd.js +76 -0
  56. package/dist/packages/cli/src/pack-cmd.js +323 -0
  57. package/dist/packages/cli/src/plan-cmd.js +278 -0
  58. package/dist/packages/cli/src/popup.js +810 -0
  59. package/dist/packages/cli/src/rules-cmd.js +131 -0
  60. package/dist/packages/cli/src/rules.js +339 -0
  61. package/dist/packages/cli/src/scan/command.js +57 -0
  62. package/dist/packages/cli/src/scan/engine.js +419 -0
  63. package/dist/packages/cli/src/scan/observe.js +64 -0
  64. package/dist/packages/cli/src/scan/ui.js +98 -0
  65. package/dist/packages/cli/src/screener/filter.js +241 -0
  66. package/dist/packages/cli/src/screener/presets.js +80 -0
  67. package/dist/packages/cli/src/screener/rows.js +146 -0
  68. package/dist/packages/cli/src/screener/rug.js +50 -0
  69. package/dist/packages/cli/src/screener/sort.js +52 -0
  70. package/dist/packages/cli/src/screener/view.js +183 -0
  71. package/dist/packages/cli/src/screens/analyst-session.js +343 -0
  72. package/dist/packages/cli/src/screens/analyst.js +326 -0
  73. package/dist/packages/cli/src/screens/boot.js +74 -0
  74. package/dist/packages/cli/src/screens/bubbles.js +255 -0
  75. package/dist/packages/cli/src/screens/coin.js +33 -0
  76. package/dist/packages/cli/src/screens/follows.js +201 -0
  77. package/dist/packages/cli/src/screens/kol.js +90 -0
  78. package/dist/packages/cli/src/screens/narrative.js +90 -0
  79. package/dist/packages/cli/src/screens/newpairs.js +150 -0
  80. package/dist/packages/cli/src/screens/overlay.js +257 -0
  81. package/dist/packages/cli/src/screens/plans.js +126 -0
  82. package/dist/packages/cli/src/screens/positions.js +176 -0
  83. package/dist/packages/cli/src/screens/rules.js +170 -0
  84. package/dist/packages/cli/src/screens/screener.js +459 -0
  85. package/dist/packages/cli/src/screens/social-panel.js +107 -0
  86. package/dist/packages/cli/src/screens/ticket.js +342 -0
  87. package/dist/packages/cli/src/screens/token.js +312 -0
  88. package/dist/packages/cli/src/screens/trending.js +181 -0
  89. package/dist/packages/cli/src/screens/watchlist.js +104 -0
  90. package/dist/packages/cli/src/social/demo.js +96 -0
  91. package/dist/packages/cli/src/social/view.js +250 -0
  92. package/dist/packages/cli/src/state.js +463 -0
  93. package/dist/packages/cli/src/theme-cmd.js +126 -0
  94. package/dist/packages/cli/src/trade.js +319 -0
  95. package/dist/packages/cli/src/voice-hud.js +42 -0
  96. package/dist/packages/cli/src/wallet-cmd.js +440 -0
  97. package/dist/packages/cli/src/wallet-command.js +31 -0
  98. package/dist/packages/cli/src/widgets.js +208 -0
  99. package/dist/packages/cli/src/workspace-cmd.js +68 -0
  100. package/dist/packages/cli/src/x-cmd.js +154 -0
  101. package/dist/packages/custom/src/config.js +213 -0
  102. package/dist/packages/custom/src/index.js +10 -0
  103. package/dist/packages/custom/src/keymap.js +107 -0
  104. package/dist/packages/custom/src/layout.js +235 -0
  105. package/dist/packages/custom/src/packs.js +633 -0
  106. package/dist/packages/custom/src/rules.js +704 -0
  107. package/dist/packages/custom/src/schema.js +515 -0
  108. package/dist/packages/custom/src/themes.js +176 -0
  109. package/dist/packages/custom/src/widget-html.js +222 -0
  110. package/dist/packages/custom/src/workspace.js +141 -0
  111. package/dist/packages/data/src/analyst-actions.js +133 -0
  112. package/dist/packages/data/src/budget.js +88 -0
  113. package/dist/packages/data/src/cache.js +142 -0
  114. package/dist/packages/data/src/candles.js +168 -0
  115. package/dist/packages/data/src/clock.js +64 -0
  116. package/dist/packages/data/src/credits.js +137 -0
  117. package/dist/packages/data/src/detail.js +97 -0
  118. package/dist/packages/data/src/fast-lane.js +321 -0
  119. package/dist/packages/data/src/fixtures.js +135 -0
  120. package/dist/packages/data/src/health.js +245 -0
  121. package/dist/packages/data/src/http.js +277 -0
  122. package/dist/packages/data/src/images/cache.js +141 -0
  123. package/dist/packages/data/src/images/decode-worker.js +28 -0
  124. package/dist/packages/data/src/images/decode.js +81 -0
  125. package/dist/packages/data/src/images/fetch.js +162 -0
  126. package/dist/packages/data/src/images/gif.js +214 -0
  127. package/dist/packages/data/src/images/index.js +10 -0
  128. package/dist/packages/data/src/images/jpeg.js +544 -0
  129. package/dist/packages/data/src/images/png.js +310 -0
  130. package/dist/packages/data/src/images/service.js +334 -0
  131. package/dist/packages/data/src/images/types.js +27 -0
  132. package/dist/packages/data/src/index.js +208 -0
  133. package/dist/packages/data/src/intel/helius-history.js +59 -0
  134. package/dist/packages/data/src/intel/holder-class.js +125 -0
  135. package/dist/packages/data/src/intel/rules.js +421 -0
  136. package/dist/packages/data/src/intel/scan.js +170 -0
  137. package/dist/packages/data/src/larp/evidence.js +288 -0
  138. package/dist/packages/data/src/larp/links.js +137 -0
  139. package/dist/packages/data/src/larp/robots.js +90 -0
  140. package/dist/packages/data/src/larp/safe-fetch.js +389 -0
  141. package/dist/packages/data/src/limiter.js +341 -0
  142. package/dist/packages/data/src/model.js +12 -0
  143. package/dist/packages/data/src/paper.js +331 -0
  144. package/dist/packages/data/src/rpc-config.js +126 -0
  145. package/dist/packages/data/src/rpc-pool.js +166 -0
  146. package/dist/packages/data/src/social/chain.js +83 -0
  147. package/dist/packages/data/src/social/dedupe.js +205 -0
  148. package/dist/packages/data/src/social/feed.js +462 -0
  149. package/dist/packages/data/src/social/firewall.js +110 -0
  150. package/dist/packages/data/src/social/index.js +11 -0
  151. package/dist/packages/data/src/social/kol.js +269 -0
  152. package/dist/packages/data/src/social/model.js +11 -0
  153. package/dist/packages/data/src/social/rank.js +184 -0
  154. package/dist/packages/data/src/social/rss.js +113 -0
  155. package/dist/packages/data/src/social/summary.js +104 -0
  156. package/dist/packages/data/src/social/venues.js +186 -0
  157. package/dist/packages/data/src/sources/dexscreener.js +170 -0
  158. package/dist/packages/data/src/sources/geckoterminal.js +133 -0
  159. package/dist/packages/data/src/sources/goplus.js +161 -0
  160. package/dist/packages/data/src/sources/jupiter-swap.js +236 -0
  161. package/dist/packages/data/src/sources/jupiter.js +198 -0
  162. package/dist/packages/data/src/sources/pda.js +113 -0
  163. package/dist/packages/data/src/sources/pump-curve.js +58 -0
  164. package/dist/packages/data/src/sources/pumpportal.js +247 -0
  165. package/dist/packages/data/src/sources/rugcheck.js +71 -0
  166. package/dist/packages/data/src/sources/solana-rpc.js +299 -0
  167. package/dist/packages/data/src/sources/solana-ws.js +287 -0
  168. package/dist/packages/data/src/store.js +289 -0
  169. package/dist/packages/data/src/trade/bridge.js +464 -0
  170. package/dist/packages/data/src/trade/caps.js +323 -0
  171. package/dist/packages/data/src/trade/copy/auto.js +385 -0
  172. package/dist/packages/data/src/trade/copy/follows.js +103 -0
  173. package/dist/packages/data/src/trade/copy/index.js +9 -0
  174. package/dist/packages/data/src/trade/copy/mirror.js +91 -0
  175. package/dist/packages/data/src/trade/copy/stats.js +120 -0
  176. package/dist/packages/data/src/trade/copy/tracker.js +158 -0
  177. package/dist/packages/data/src/trade/copy/trades.js +87 -0
  178. package/dist/packages/data/src/trade/copy/types.js +6 -0
  179. package/dist/packages/data/src/trade/executor.js +933 -0
  180. package/dist/packages/data/src/trade/kill-switch.js +47 -0
  181. package/dist/packages/data/src/trade/link-store.js +52 -0
  182. package/dist/packages/data/src/trade/plans/confirm.js +157 -0
  183. package/dist/packages/data/src/trade/plans/engine.js +784 -0
  184. package/dist/packages/data/src/trade/plans/executor-live.js +220 -0
  185. package/dist/packages/data/src/trade/plans/executor-paper.js +44 -0
  186. package/dist/packages/data/src/trade/plans/executor.js +11 -0
  187. package/dist/packages/data/src/trade/plans/index.js +12 -0
  188. package/dist/packages/data/src/trade/plans/journal.js +77 -0
  189. package/dist/packages/data/src/trade/plans/mandate.js +129 -0
  190. package/dist/packages/data/src/trade/plans/plan.js +179 -0
  191. package/dist/packages/data/src/trade/plans/service.js +168 -0
  192. package/dist/packages/data/src/trade/plans/types.js +6 -0
  193. package/dist/packages/data/src/trade/rpc-exec.js +229 -0
  194. package/dist/packages/data/src/trade/signer/client.js +197 -0
  195. package/dist/packages/data/src/trade/signer/fast-wallet.js +154 -0
  196. package/dist/packages/data/src/trade/signer/host.js +97 -0
  197. package/dist/packages/data/src/trade/signer/main.js +121 -0
  198. package/dist/packages/data/src/trade/signer/probe-builder.js +85 -0
  199. package/dist/packages/data/src/trade/signer/protocol.js +92 -0
  200. package/dist/packages/data/src/trade/signer/service.js +400 -0
  201. package/dist/packages/data/src/trade/signer/sol-usd-feed.js +98 -0
  202. package/dist/packages/data/src/trade/sol-usd.js +86 -0
  203. package/dist/packages/data/src/trade/swap-build.js +108 -0
  204. package/dist/packages/data/src/trade/token-delta.js +201 -0
  205. package/dist/packages/data/src/trade/tx-decode.js +632 -0
  206. package/dist/packages/data/src/util.js +24 -0
  207. package/dist/packages/data/src/watchlist.js +176 -0
  208. package/dist/packages/data/src/x/api.js +256 -0
  209. package/dist/packages/data/src/x/budget.js +66 -0
  210. package/dist/packages/data/src/x/config.js +49 -0
  211. package/dist/packages/data/src/x/index.js +10 -0
  212. package/dist/packages/data/src/x/mock-server.js +217 -0
  213. package/dist/packages/data/src/x/oauth.js +242 -0
  214. package/dist/packages/data/src/x/pkce.js +21 -0
  215. package/dist/packages/data/src/x/source.js +285 -0
  216. package/dist/packages/data/src/x/token-store.js +134 -0
  217. package/dist/packages/data/src/x/transport.js +71 -0
  218. package/dist/packages/data/vendor/solana-web3/LICENSE +20 -0
  219. package/dist/packages/data/vendor/solana-web3/NOTICE.md +13 -0
  220. package/dist/packages/data/vendor/solana-web3/index.iife.min.js +20 -0
  221. package/dist/packages/mcp/assets/cases.json +1194 -0
  222. package/dist/packages/mcp/assets/kb/entries/cabal-and-coordinated-launches.md +28 -0
  223. package/dist/packages/mcp/assets/kb/entries/common-rug-patterns.md +40 -0
  224. package/dist/packages/mcp/assets/kb/entries/dbc-mechanics.md +30 -0
  225. package/dist/packages/mcp/assets/kb/entries/dev-wallet-behaviour.md +33 -0
  226. package/dist/packages/mcp/assets/kb/entries/glossary.md +35 -0
  227. package/dist/packages/mcp/assets/kb/entries/holder-concentration.md +30 -0
  228. package/dist/packages/mcp/assets/kb/entries/jito-bundles.md +29 -0
  229. package/dist/packages/mcp/assets/kb/entries/launchlab-curve.md +31 -0
  230. package/dist/packages/mcp/assets/kb/entries/lp-burn-vs-lock.md +31 -0
  231. package/dist/packages/mcp/assets/kb/entries/metadata-and-copycats.md +29 -0
  232. package/dist/packages/mcp/assets/kb/entries/mint-freeze-authority.md +31 -0
  233. package/dist/packages/mcp/assets/kb/entries/narrative-lifecycle.md +32 -0
  234. package/dist/packages/mcp/assets/kb/entries/pump-bonding-curve.md +33 -0
  235. package/dist/packages/mcp/assets/kb/entries/pumpswap-migration.md +29 -0
  236. package/dist/packages/mcp/assets/kb/entries/sniping-and-snipers.md +29 -0
  237. package/dist/packages/mcp/assets/kb/entries/token2022-extensions-risk.md +32 -0
  238. package/dist/packages/mcp/assets/kb/entries/wash-trading-fake-volume.md +33 -0
  239. package/dist/packages/mcp/assets/skills/rug-check.md +52 -0
  240. package/dist/packages/mcp/assets/skills/token-dossier.md +57 -0
  241. package/dist/packages/mcp/assets/skills/trench-scan.md +40 -0
  242. package/dist/packages/mcp/bin/dexterm-mcp.mjs +16 -0
  243. package/dist/packages/mcp/src/dossier.js +78 -0
  244. package/dist/packages/mcp/src/firewall.js +21 -0
  245. package/dist/packages/mcp/src/index.js +22 -0
  246. package/dist/packages/mcp/src/server.js +849 -0
  247. package/dist/packages/mcp/src/user-content.js +434 -0
  248. package/dist/packages/packs/src/backtest.js +183 -0
  249. package/dist/packages/packs/src/digest.js +95 -0
  250. package/dist/packages/packs/src/firewall.js +57 -0
  251. package/dist/packages/packs/src/index.js +19 -0
  252. package/dist/packages/packs/src/larp-eval.js +100 -0
  253. package/dist/packages/packs/src/narrative.js +309 -0
  254. package/dist/packages/packs/src/reason.js +135 -0
  255. package/dist/packages/packs/src/rug-model.js +137 -0
  256. package/dist/packages/packs/src/schema.js +54 -0
  257. package/dist/packages/packs/src/token-dossier.js +174 -0
  258. package/dist/packages/packs/src/verdicts.js +17 -0
  259. package/dist/packages/packs/src/wallet-dossier.js +105 -0
  260. package/dist/packages/popup/src/config.js +71 -0
  261. package/dist/packages/popup/src/dock.js +271 -0
  262. package/dist/packages/popup/src/host.js +210 -0
  263. package/dist/packages/popup/src/index.js +12 -0
  264. package/dist/packages/popup/src/loopback.js +53 -0
  265. package/dist/packages/popup/src/open.js +183 -0
  266. package/dist/packages/popup/src/pages/bubbles-lib.js +160 -0
  267. package/dist/packages/popup/src/pages/bubbles.css +23 -0
  268. package/dist/packages/popup/src/pages/bubbles.html +36 -0
  269. package/dist/packages/popup/src/pages/bubbles.js +214 -0
  270. package/dist/packages/popup/src/pages/chart-lib.js +262 -0
  271. package/dist/packages/popup/src/pages/chart.css +50 -0
  272. package/dist/packages/popup/src/pages/chart.html +56 -0
  273. package/dist/packages/popup/src/pages/chart.js +554 -0
  274. package/dist/packages/popup/src/pages/common.css +34 -0
  275. package/dist/packages/popup/src/pages/common.js +187 -0
  276. package/dist/packages/popup/src/pages/feeds.html +20 -0
  277. package/dist/packages/popup/src/pages/feeds.js +77 -0
  278. package/dist/packages/popup/src/pages/narrative.html +20 -0
  279. package/dist/packages/popup/src/pages/narrative.js +61 -0
  280. package/dist/packages/popup/src/pages/plans.css +30 -0
  281. package/dist/packages/popup/src/pages/plans.html +26 -0
  282. package/dist/packages/popup/src/pages/plans.js +82 -0
  283. package/dist/packages/popup/src/pages/roster.css +41 -0
  284. package/dist/packages/popup/src/pages/roster.html +25 -0
  285. package/dist/packages/popup/src/pages/roster.js +75 -0
  286. package/dist/packages/popup/src/pages/token.html +20 -0
  287. package/dist/packages/popup/src/pages/token.js +112 -0
  288. package/dist/packages/popup/src/pages/widget-sdk.js +224 -0
  289. package/dist/packages/popup/src/pages/widget.css +5 -0
  290. package/dist/packages/popup/src/pages/widget.html +21 -0
  291. package/dist/packages/popup/src/pages/widget.js +85 -0
  292. package/dist/packages/popup/src/protocol.js +31 -0
  293. package/dist/packages/popup/src/selftest.js +156 -0
  294. package/dist/packages/popup/src/server.js +582 -0
  295. package/dist/packages/popup/src/sinkproxy.js +167 -0
  296. package/dist/packages/popup/src/widget-html.js +231 -0
  297. package/dist/packages/popup/vendor/lightweight-charts/LICENSE +201 -0
  298. package/dist/packages/popup/vendor/lightweight-charts/NOTICE +2 -0
  299. package/dist/packages/popup/vendor/lightweight-charts/README.md +30 -0
  300. package/dist/packages/popup/vendor/lightweight-charts/VERSION +1 -0
  301. package/dist/packages/popup/vendor/lightweight-charts/lightweight-charts.standalone.production.js +7 -0
  302. package/dist/packages/recorder/bin/dexterm-recorder.mjs +11 -0
  303. package/dist/packages/recorder/src/cli.js +113 -0
  304. package/dist/packages/recorder/src/export.js +71 -0
  305. package/dist/packages/recorder/src/index.js +20 -0
  306. package/dist/packages/recorder/src/labels.js +151 -0
  307. package/dist/packages/recorder/src/open.js +29 -0
  308. package/dist/packages/recorder/src/recorder.js +553 -0
  309. package/dist/packages/recorder/src/schedule.js +43 -0
  310. package/dist/packages/recorder/src/schema.js +135 -0
  311. package/dist/packages/recorder/src/snapshot.js +191 -0
  312. package/dist/packages/recorder/src/sweep.js +52 -0
  313. package/dist/packages/recorder/src/verdicts.js +52 -0
  314. package/dist/packages/tui/src/bubbles.js +415 -0
  315. package/dist/packages/tui/src/canvas.js +370 -0
  316. package/dist/packages/tui/src/chrome.js +85 -0
  317. package/dist/packages/tui/src/color.js +133 -0
  318. package/dist/packages/tui/src/flush.js +62 -0
  319. package/dist/packages/tui/src/fmt.js +188 -0
  320. package/dist/packages/tui/src/fx-trade.js +278 -0
  321. package/dist/packages/tui/src/fx.js +527 -0
  322. package/dist/packages/tui/src/images/blocks.js +141 -0
  323. package/dist/packages/tui/src/images/coin.js +22 -0
  324. package/dist/packages/tui/src/images/detect.js +140 -0
  325. package/dist/packages/tui/src/images/index.js +7 -0
  326. package/dist/packages/tui/src/images/layer.js +146 -0
  327. package/dist/packages/tui/src/images/pixels.js +157 -0
  328. package/dist/packages/tui/src/images/protocols.js +87 -0
  329. package/dist/packages/tui/src/index.js +15 -0
  330. package/dist/packages/tui/src/keymap.js +355 -0
  331. package/dist/packages/tui/src/layout.js +11 -0
  332. package/dist/packages/tui/src/sound.js +177 -0
  333. package/dist/packages/tui/src/theme.js +182 -0
  334. package/dist/packages/tui/src/widgets.js +598 -0
  335. package/dist/packages/voice/src/controller.js +395 -0
  336. package/dist/packages/voice/src/doctor.js +63 -0
  337. package/dist/packages/voice/src/engines.js +44 -0
  338. package/dist/packages/voice/src/index.js +16 -0
  339. package/dist/packages/voice/src/router.js +502 -0
  340. package/dist/packages/voice/src/stt/apple-helper.swift.js +103 -0
  341. package/dist/packages/voice/src/stt/apple.js +179 -0
  342. package/dist/packages/voice/src/stt/fake.js +34 -0
  343. package/dist/packages/voice/src/stt/whisper.js +102 -0
  344. package/dist/packages/voice/src/summary.js +44 -0
  345. package/dist/packages/voice/src/tts/fake.js +30 -0
  346. package/dist/packages/voice/src/tts/say.js +96 -0
  347. package/dist/packages/voice/src/types.js +3 -0
  348. package/package.json +42 -4
  349. package/README.md +0 -3
@@ -0,0 +1,188 @@
1
+ // @dexterm/tui — number/time formatting helpers (SPEC §7.6: compact currency, ages, subscript zeros).
2
+ const SUB = '₀₁₂₃₄₅₆₇₈₉';
3
+ export function fmtUsd(n, { digits = 2 } = {}) {
4
+ if (n == null || Number.isNaN(n))
5
+ return '—';
6
+ const a = Math.abs(n);
7
+ const sign = n < 0 ? '-' : '';
8
+ if (a >= 1e9)
9
+ return `${sign}$${(a / 1e9).toFixed(digits)}B`;
10
+ if (a >= 1e6)
11
+ return `${sign}$${(a / 1e6).toFixed(digits)}M`;
12
+ if (a >= 1e3)
13
+ return `${sign}$${(a / 1e3).toFixed(digits > 1 ? 1 : 0)}K`;
14
+ return `${sign}$${a.toFixed(0)}`;
15
+ }
16
+ export function fmtNum(n) {
17
+ if (n == null)
18
+ return '—';
19
+ const a = Math.abs(n);
20
+ if (a >= 1e9)
21
+ return `${(n / 1e9).toFixed(2)}B`;
22
+ if (a >= 1e6)
23
+ return `${(n / 1e6).toFixed(2)}M`;
24
+ if (a >= 1e4)
25
+ return `${(n / 1e3).toFixed(1)}K`;
26
+ if (a >= 1e3)
27
+ return `${(n / 1e3).toFixed(2)}K`;
28
+ return String(Math.round(n));
29
+ }
30
+ /**
31
+ * A TOKEN QUANTITY (what you pay / receive / hold): compact above 10 000 like fmtNum, otherwise up to four
32
+ * decimals with trailing zeros trimmed, and subscript-compressed below 0.01 (0.0000123 → 0.0₄123). task-1368:
33
+ * `fmtNum` rounds to a whole number, so a $4.33 buy of a $300 token showed `You receive 0 AVGOx` — never again.
34
+ * A true zero is "0"; null is a dash. Decimals unknown? Do not call this — say so (the ticket does).
35
+ */
36
+ export function fmtAmount(n) {
37
+ if (n == null || Number.isNaN(n))
38
+ return '—';
39
+ if (n === 0)
40
+ return '0';
41
+ const a = Math.abs(n);
42
+ const sign = n < 0 ? '-' : '';
43
+ if (a >= 1e4)
44
+ return `${sign}${fmtNum(a)}`;
45
+ if (a >= 1) {
46
+ const d = a >= 1000 ? 2 : 4;
47
+ return `${sign}${trimZeros(a.toFixed(d))}`;
48
+ }
49
+ if (a >= 0.01)
50
+ return `${sign}${trimZeros(a.toFixed(4))}`;
51
+ return `${sign}${fmtPriceBare(a)}`;
52
+ }
53
+ function trimZeros(s) {
54
+ return s.includes('.') ? s.replace(/0+$/, '').replace(/\.$/, '') : s;
55
+ }
56
+ /**
57
+ * Price magnitude with subscript zero-compression, WITHOUT a currency symbol: 0.0000123 -> 0.0₄123.
58
+ * Use this for amounts whose unit is written out separately (e.g. SOL per token); `fmtPrice` is the
59
+ * USD-prefixed form. Mixing them is the task-1310 "$…​ SOL" bug: a `$` glued to a SOL amount.
60
+ */
61
+ export function fmtPriceBare(p) {
62
+ if (p == null)
63
+ return '—';
64
+ if (p >= 1000)
65
+ return p.toLocaleString('en-US', { maximumFractionDigits: 0 });
66
+ if (p >= 1)
67
+ return p.toFixed(p >= 100 ? 2 : 3);
68
+ if (p >= 0.01)
69
+ return p.toFixed(4);
70
+ const s = p.toFixed(12);
71
+ const m = s.match(/^0\.(0*)(\d+)/);
72
+ if (!m)
73
+ return `${p}`;
74
+ const zeros = m[1].length;
75
+ const digits = m[2].replace(/0+$/, '').slice(0, 4) || '0';
76
+ if (zeros < 3)
77
+ return `0.${m[1]}${digits}`;
78
+ const sub = String(zeros).split('').map((c) => SUB[Number(c)]).join('');
79
+ return `0.0${sub}${digits}`;
80
+ }
81
+ /** USD price with subscript zero-compression: 0.0000123 -> $0.0₄123 */
82
+ export function fmtPrice(p) {
83
+ const bare = fmtPriceBare(p);
84
+ return bare === '—' ? bare : `$${bare}`;
85
+ }
86
+ /**
87
+ * task-1366: market cap (or any large USD amount) on an axis / in a cell, compact K/M/B/T with at most three
88
+ * significant digits and no currency symbol: 300000 → 300K, 1234567 → 1.23M, 1.2e9 → 1.2B, 950 → 950,
89
+ * 0.42 → 0.42. The unit is rounded FIRST so 999 999 reads 1M, never 1000K. Non-finite → '—'.
90
+ */
91
+ export function fmtMcapBare(n) {
92
+ if (n == null || !Number.isFinite(n))
93
+ return '—';
94
+ const sign = n < 0 ? '-' : '';
95
+ let a = Math.abs(n);
96
+ if (a === 0)
97
+ return '0';
98
+ if (a < 1)
99
+ return sign + String(Number(a.toPrecision(2)));
100
+ const units = ['', 'K', 'M', 'B', 'T'];
101
+ let u = 0;
102
+ while (u < units.length - 1 && a >= 1000) {
103
+ a /= 1000;
104
+ u++;
105
+ }
106
+ let r = Number(a.toPrecision(3));
107
+ if (r >= 1000 && u < units.length - 1) {
108
+ r = Number((r / 1000).toPrecision(3));
109
+ u++;
110
+ }
111
+ // three significant digits, trailing zeros dropped (1.20M → 1.2M); T stays plain digits beyond 999T
112
+ const digits = r >= 1000 ? String(Math.round(r)) : String(r);
113
+ return `${sign}${digits}${units[u]}`;
114
+ }
115
+ /** USD market cap, compact: `$1.2M`. See fmtMcapBare. */
116
+ export function fmtMcap(n) {
117
+ const bare = fmtMcapBare(n);
118
+ if (bare === '—')
119
+ return bare;
120
+ return bare.startsWith('-') ? `-$${bare.slice(1)}` : `$${bare}`;
121
+ }
122
+ export function fmtPct(n, { sign = true, digits = 1 } = {}) {
123
+ if (n == null || Number.isNaN(n))
124
+ return '—';
125
+ const a = Math.abs(n);
126
+ const d = a >= 1000 ? 0 : digits;
127
+ const s = `${a.toFixed(d)}%`;
128
+ if (!sign)
129
+ return s;
130
+ return n > 0 ? `+${s}` : n < 0 ? `-${s}` : ` ${s}`;
131
+ }
132
+ export function fmtAge(minutes) {
133
+ if (minutes < 1)
134
+ return `${Math.max(1, Math.round(minutes * 60))}s`;
135
+ if (minutes < 60)
136
+ return `${Math.round(minutes)}m`;
137
+ if (minutes < 60 * 24)
138
+ return `${(minutes / 60).toFixed(minutes < 600 ? 1 : 0)}h`;
139
+ if (minutes < 60 * 24 * 30)
140
+ return `${Math.round(minutes / 1440)}d`;
141
+ return `${Math.round(minutes / 43200)}mo`;
142
+ }
143
+ export function fmtAgeSec(seconds) {
144
+ if (seconds < 60)
145
+ return `${Math.round(seconds)}s`;
146
+ return fmtAge(seconds / 60);
147
+ }
148
+ export function shortAddr(a, n = 4) {
149
+ if (!a)
150
+ return '';
151
+ return `${a.slice(0, n)}…${a.slice(-n)}`;
152
+ }
153
+ export function pad(s, w, align = 'left') {
154
+ let str = String(s);
155
+ if (str.length >= w)
156
+ return str.slice(0, w);
157
+ const sp = ' '.repeat(w - str.length);
158
+ return align === 'right' ? sp + str : str + sp;
159
+ }
160
+ export function clamp(n, lo, hi) {
161
+ return Math.max(lo, Math.min(hi, n));
162
+ }
163
+ /**
164
+ * HH:MM:SS clock. `timeZone` pins the zone (fixtures and snapshot tests use
165
+ * 'America/New_York' so renders are identical on every machine); omit for local time.
166
+ */
167
+ export function clock(d = new Date(), timeZone) {
168
+ if (!timeZone)
169
+ return d.toTimeString().slice(0, 8);
170
+ return new Intl.DateTimeFormat('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, timeZone }).format(d);
171
+ }
172
+ /** Greedy word wrap; words longer than `width` are kept whole on their own line. */
173
+ export function wrap(s, width) {
174
+ const words = s.split(' ');
175
+ const out = [];
176
+ let cur = '';
177
+ for (const wd of words) {
178
+ if ((cur + ' ' + wd).trim().length > width) {
179
+ out.push(cur);
180
+ cur = wd;
181
+ }
182
+ else
183
+ cur = (cur + ' ' + wd).trim();
184
+ }
185
+ if (cur)
186
+ out.push(cur);
187
+ return out;
188
+ }
@@ -0,0 +1,278 @@
1
+ import { mix } from "./color.js";
2
+ import { hash3, CODE } from "./fx.js";
3
+ const unit = (a, b, c) => hash3(a, b, c) / 4294967296;
4
+ const COINS = '$◆●¢◇✦∘';
5
+ const BURST = '✦✧◆·∗⟡';
6
+ const STATIC = '░▒▓▒░';
7
+ /** Durations in seconds per kind; fever runs longer and denser. */
8
+ export const MOMENT_SECONDS = { buy: 1.8, profit: 2.1, loss: 1.8, failed: 1.2, runner: 2.0 };
9
+ export function momentFrames(kind, intensity, fps) {
10
+ if (kind === 'inflight')
11
+ return 0;
12
+ const s = MOMENT_SECONDS[kind];
13
+ const k = intensity === 'fever' ? 1.45 : 1;
14
+ return Math.max(2, Math.round(s * k * fps));
15
+ }
16
+ /** Progress of the current moment in [0, 1], null when none (or finished). Inflight is always 0. */
17
+ export function momentP(v) {
18
+ const m = v.moment;
19
+ if (!m)
20
+ return null;
21
+ if (m.kind === 'inflight')
22
+ return 0;
23
+ const p = (v.frame - m.t0) / Math.max(1, m.dur);
24
+ return p > 1 ? null : p;
25
+ }
26
+ /** Classify a settled outcome: buy → 'buy'; sell → 'profit' | 'loss' by realized PnL; failed → 'failed'. */
27
+ export function momentKindFor(tx) {
28
+ if (tx.status === 'failed')
29
+ return 'failed';
30
+ if (tx.side === 'buy')
31
+ return 'buy';
32
+ return (tx.pnlSol ?? 0) >= 0 ? 'profit' : 'loss';
33
+ }
34
+ /**
35
+ * Fire the moment for a SETTLED outcome. Throws unless `tx.status` is confirmed or failed — the same guard the
36
+ * prototype's settle() had — so a quote, a plan or an in-flight send cannot reach the effects. Returns the moment
37
+ * (or null when effects are off). Side effects on the vfx: mood ramp swap and a glitch for loss / failed; the
38
+ * shake is never used while a shielded ticket is on screen (shake() refuses shields anyway).
39
+ */
40
+ export function fireMoment(v, tx, opts = {}) {
41
+ if (!tx || (tx.status !== 'confirmed' && tx.status !== 'failed'))
42
+ throw new Error('fireMoment needs a settled chain outcome (confirmed | failed), not a quote');
43
+ const kind = momentKindFor(tx);
44
+ if (v.intensity === 'off') {
45
+ v.moment = null;
46
+ return null;
47
+ }
48
+ const fps = opts.fps ?? 30;
49
+ const milestone = opts.milestone ?? null;
50
+ const m = {
51
+ kind, milestone, t0: v.frame, dur: momentFrames(kind, v.intensity, fps), origin: opts.origin ?? null,
52
+ symbol: tx.symbol, pnl: tx.pnlSol ?? 0, pct: tx.pnlPct ?? 0, tx, seed: hash3(v.seed, v.frame, 77),
53
+ };
54
+ if (milestone)
55
+ m.dur = Math.round(m.dur * 1.35);
56
+ v.moment = m;
57
+ const fever = v.intensity === 'fever';
58
+ if (kind === 'buy') {
59
+ v.activity = Math.max(v.activity, fever ? 1 : 0.8);
60
+ }
61
+ else if (kind === 'profit') {
62
+ v.mood = 'pump';
63
+ v.moodUntil = v.frame + Math.round(fps * (fever ? 4 : 3));
64
+ v.activity = 1;
65
+ }
66
+ else if (kind === 'loss') {
67
+ v.mood = 'dump';
68
+ v.moodUntil = v.frame + Math.round(fps * 3);
69
+ v.glitch = Math.max(v.glitch, fever ? 0.7 : 0.45);
70
+ v.stutter = 0;
71
+ }
72
+ else if (kind === 'failed') {
73
+ v.glitch = Math.max(v.glitch, 0.25);
74
+ }
75
+ if (milestone === 'rug') {
76
+ v.glitch = 1;
77
+ v.mood = 'dump';
78
+ v.moodUntil = v.frame + Math.round(fps * 4);
79
+ }
80
+ return m;
81
+ }
82
+ /** The pending state: a neutral scanning sweep while a send is in flight. Never a verdict; replaced by fireMoment. */
83
+ export function fireInflight(v, symbol, origin = null) {
84
+ if (v.intensity === 'off') {
85
+ v.moment = null;
86
+ return null;
87
+ }
88
+ const m = { kind: 'inflight', milestone: null, t0: v.frame, dur: 0, origin, symbol, pnl: 0, pct: 0, tx: null, seed: hash3(v.seed, v.frame, 78) };
89
+ v.moment = m;
90
+ return m;
91
+ }
92
+ /** Called by stepVfx every frame: drops a finished moment and lets a mood swap expire. */
93
+ export function stepMoment(v) {
94
+ if (v.moodUntil != null && v.frame >= v.moodUntil) {
95
+ v.mood = 'neutral';
96
+ v.moodUntil = null;
97
+ }
98
+ if (v.moment && v.moment.kind !== 'inflight' && momentP(v) == null)
99
+ v.moment = null;
100
+ }
101
+ /** Any key: the moment is dropped (the result card stays: it is content, not an effect). Inflight stays. */
102
+ export function skipMoment(v) {
103
+ if (v.moment && v.moment.kind !== 'inflight')
104
+ v.moment = null;
105
+ if (v.moodUntil != null) {
106
+ v.mood = 'neutral';
107
+ v.moodUntil = null;
108
+ }
109
+ v.glitch = 0;
110
+ v.shake = 0;
111
+ v.stutter = 0;
112
+ }
113
+ /** Clear the inflight sweep (the send settled or was cancelled). */
114
+ export function clearInflight(v) {
115
+ if (v.moment?.kind === 'inflight')
116
+ v.moment = null;
117
+ }
118
+ function center(o, c) {
119
+ if (!o)
120
+ return { cx: Math.floor(c.w / 2), cy: Math.floor(c.h / 2) };
121
+ return { cx: o.x + Math.floor(o.w / 2), cy: o.y + Math.floor(o.h / 2) };
122
+ }
123
+ /** Theme-derived palettes: gold from the pump ramp, a green "buy" ramp from `up`. */
124
+ function palettes(c) {
125
+ const t = c.theme;
126
+ return { gold: t.rainPump[2], goldHot: t.rainPump[3], buy: [mix(t.bg, t.up, 0.3), mix(t.bg, t.up, 0.6), t.up, mix(t.up, '#ffffff', 0.6)] };
127
+ }
128
+ /** The post-pass. No-op without a live moment or when effects are off. */
129
+ export function tradeFx(c, v) {
130
+ if (!v || v.intensity === 'off')
131
+ return;
132
+ const m = v.moment;
133
+ if (!m)
134
+ return;
135
+ const p = momentP(v);
136
+ if (p == null)
137
+ return;
138
+ const t = c.theme;
139
+ const { gold, goldHot, buy: rainBuy } = palettes(c);
140
+ const fever = v.intensity === 'fever';
141
+ const f = v.frame;
142
+ const W = c.w, H = c.h;
143
+ const fps = 30;
144
+ const { cx, cy } = center(m.origin, c);
145
+ const dist = (x, y) => Math.sqrt((x - cx) * (x - cx) + (2 * (y - cy)) * (2 * (y - cy)));
146
+ if (m.kind === 'inflight') {
147
+ // scanning sweep: one bright row sweeping down every 0.7 s, bg tint on soft cells + a faint trail
148
+ const per = Math.max(6, Math.round(0.7 * fps));
149
+ const ys = Math.floor(((f - m.t0) % per) / per * H);
150
+ for (let k = 0; k < 3; k++) {
151
+ const y = ys - k;
152
+ if (y < 0 || y >= H)
153
+ continue;
154
+ const amt = k === 0 ? 0.28 : k === 1 ? 0.14 : 0.06;
155
+ for (let x = 0; x < W; x++) {
156
+ c.tintFx(x, y, t.cyan, amt);
157
+ if (k === 0 && c.zone[c.idx(x, y)] && unit(x, y, f) < 0.35)
158
+ c.putFx(x, y, '╌', { fg: mix(t.bg, t.cyan, 0.7) });
159
+ }
160
+ }
161
+ return;
162
+ }
163
+ if (m.kind === 'buy') {
164
+ // shockwave ring from the origin, 0–0.6; inside the ring the bg lifts toward green and fades
165
+ const R = Math.max(W, H * 2) * 0.75;
166
+ const pr = Math.min(1, p / 0.6);
167
+ const r = pr * R;
168
+ const fade = 1 - pr;
169
+ if (pr < 1) {
170
+ for (let y = 0; y < H; y++)
171
+ for (let x = 0; x < W; x++) {
172
+ const d = dist(x, y);
173
+ const dd = Math.abs(d - r);
174
+ if (dd < 1.4) {
175
+ if (c.zone[c.idx(x, y)])
176
+ c.putFx(x, y, dd < 0.6 ? '○' : '∘', { fg: mix(rainBuy[2], rainBuy[3], fade), b: dd < 0.6 });
177
+ c.tintFx(x, y, t.up, (dd < 0.6 ? 0.3 : 0.2) * fade);
178
+ }
179
+ else if (d < r && d > r - 6)
180
+ c.tintFx(x, y, t.up, 0.10 * fade * (1 - (r - d) / 6));
181
+ }
182
+ }
183
+ // coins / glyphs streaming up from the origin row
184
+ const N = (fever ? 90 : 46) * Math.max(1, Math.floor(W / 120));
185
+ const ox = m.origin ? m.origin.x : 0, ow = m.origin ? m.origin.w : W, oy = m.origin ? m.origin.y : cy;
186
+ for (let i = 0; i < N; i++) {
187
+ const born = unit(m.seed, i, 1) * 0.55;
188
+ const age = p - born;
189
+ if (age < 0 || age > 0.55)
190
+ continue;
191
+ const x = ox + Math.floor(unit(m.seed, i, 2) * ow);
192
+ const speed = (0.6 + unit(m.seed, i, 3) * 0.9) * H * 1.3;
193
+ const y = Math.round(oy - age * speed);
194
+ const wobble = Math.round(Math.sin((age * 9 + i) * 1.7) * 1);
195
+ if (y < 0 || y >= H)
196
+ continue;
197
+ const sym = m.symbol || '';
198
+ const ch = unit(m.seed, i, 4) < 0.35 && sym ? sym[i % sym.length] : COINS[hash3(m.seed, i, 5) % COINS.length];
199
+ const life = 1 - age / 0.55;
200
+ const fg = life > 0.7 ? rainBuy[3] : life > 0.35 ? rainBuy[2] : rainBuy[1];
201
+ c.putFx(x + wobble, y, ch, { fg, b: life > 0.7 });
202
+ if (fever && life > 0.5)
203
+ c.putFx(x + wobble, y + 1, '·', { fg: rainBuy[1] });
204
+ }
205
+ return;
206
+ }
207
+ if (m.kind === 'profit' || m.kind === 'runner') {
208
+ // gold burst: particles radiate from the centre, slow down, drift down a little
209
+ const N = (fever ? 140 : 70) * Math.max(1, Math.floor(W / 120));
210
+ const R = Math.max(W, H * 2) * 0.5;
211
+ for (let i = 0; i < N; i++) {
212
+ const born = unit(m.seed, i, 1) * 0.18;
213
+ const age = p - born;
214
+ if (age < 0 || age > 0.75)
215
+ continue;
216
+ const a = unit(m.seed, i, 2) * Math.PI * 2;
217
+ const sp = 0.4 + unit(m.seed, i, 3) * 0.9;
218
+ const d = (1 - Math.pow(1 - age / 0.75, 2)) * sp * R * 0.9;
219
+ const x = Math.round(cx + Math.cos(a) * d);
220
+ const y = Math.round(cy + Math.sin(a) * d * 0.5 + age * age * 6);
221
+ if (x < 0 || x >= W || y < 0 || y >= H)
222
+ continue;
223
+ const life = 1 - age / 0.75;
224
+ const ch = BURST[hash3(m.seed, i, 6 + (f >> 2)) % BURST.length];
225
+ const fg = life > 0.75 ? goldHot : life > 0.4 ? gold : mix(t.bg, gold, 0.55);
226
+ if (!c.putFx(x, y, ch, { fg, b: life > 0.75 }))
227
+ c.tintFx(x, y, gold, 0.25 * life);
228
+ if (fever)
229
+ c.tintFx(x, y, gold, 0.12 * life);
230
+ }
231
+ if (p < 0.4)
232
+ for (let y = cy - 1; y <= cy + 1; y++)
233
+ for (let x = cx - 10; x <= cx + 10; x++)
234
+ c.tintFx(x, y, gold, 0.18 * (1 - p / 0.4) * (1 - Math.abs(x - cx) / 11));
235
+ return;
236
+ }
237
+ if (m.kind === 'loss') {
238
+ // red static that collapses: 0–0.35 density rises everywhere; 0.35–1 a line falls and clears the screen above it
239
+ const dens = (fever ? 0.5 : 0.36) * Math.min(1, p / 0.35);
240
+ const yl = p < 0.35 ? -1 : Math.floor((p - 0.35) / 0.55 * (H + 1));
241
+ for (let y = 0; y < H; y++) {
242
+ if (y < yl)
243
+ continue;
244
+ const rowDens = dens * (yl >= 0 ? Math.min(1, (y - yl) / 4 + 0.3) : 1);
245
+ for (let x = 0; x < W; x++) {
246
+ if (unit(x, y, f) >= rowDens)
247
+ continue;
248
+ const ch = unit(x, y, f + 9) < 0.7 ? STATIC[hash3(x, y, f) % STATIC.length] : CODE[hash3(x, y, f + 1) % CODE.length];
249
+ const tier = unit(x, y, f + 3);
250
+ const fg = tier < 0.1 ? t.rainDump[2] : tier < 0.5 ? t.rainDump[1] : t.rainDump[0];
251
+ if (!c.putFx(x, y, ch, { fg }))
252
+ c.tintFx(x, y, t.down, 0.08);
253
+ }
254
+ if (y === yl || y === yl + 1)
255
+ for (let x = 0; x < W; x++)
256
+ c.tintFx(x, y, t.down, y === yl ? 0.2 : 0.1);
257
+ }
258
+ return;
259
+ }
260
+ if (m.kind === 'failed') {
261
+ // lockout flicker: header band + footer row tint red every other 4 frames for 0.8 s; sparse static near the bands
262
+ const on = Math.floor((f - m.t0) / 4) % 2 === 0 && p < 0.7;
263
+ if (on)
264
+ for (let x = 0; x < W; x++) {
265
+ c.tintFx(x, 1, t.down, 0.35);
266
+ c.tintFx(x, 0, t.down, 0.18);
267
+ c.tintFx(x, H - 1, t.down, 0.18);
268
+ c.tintFx(x, H - 2, t.down, 0.12);
269
+ }
270
+ if (p < 0.5)
271
+ for (let y = 0; y < H; y++)
272
+ for (let x = 0; x < W; x++) {
273
+ if (!c.zone[c.idx(x, y)] || unit(x, y, f) >= 0.06 * (1 - p / 0.5))
274
+ continue;
275
+ c.putFx(x, y, STATIC[hash3(x, y, f) % STATIC.length], { fg: t.rainDump[1] });
276
+ }
277
+ }
278
+ }