@mindexec/cli 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 (232) hide show
  1. package/README.md +275 -0
  2. package/codex-runtime.js +960 -0
  3. package/launch-bridge.cjs +162 -0
  4. package/package.json +61 -0
  5. package/port-guard.cjs +232 -0
  6. package/scripts/setup-tree-sitter-grammars.mjs +59 -0
  7. package/server.js +8422 -0
  8. package/start-bridge.bat +32 -0
  9. package/start-bridge.sh +81 -0
  10. package/tree-sitter-grammars/README.md +18 -0
  11. package/tree-sitter-grammars/tree-sitter-c_sharp.wasm +0 -0
  12. package/tree-sitter-grammars/tree-sitter-go.wasm +0 -0
  13. package/tree-sitter-grammars/tree-sitter-java.wasm +0 -0
  14. package/tree-sitter-grammars/tree-sitter-javascript.wasm +0 -0
  15. package/tree-sitter-grammars/tree-sitter-python.wasm +0 -0
  16. package/tree-sitter-grammars/tree-sitter-rust.wasm +0 -0
  17. package/tree-sitter-grammars/tree-sitter-tsx.wasm +0 -0
  18. package/tree-sitter-grammars/tree-sitter-typescript.wasm +0 -0
  19. package/wwwroot/MindExecution.Web.styles.css +3 -0
  20. package/wwwroot/_content/MindExecution.Plugins.Admin/css/admin-dashboard.css +546 -0
  21. package/wwwroot/_content/MindExecution.Plugins.Directory/MindExecution.Plugins.Directory.u7utcng611.bundle.scp.css +7 -0
  22. package/wwwroot/_content/MindExecution.Plugins.Directory/background.png +0 -0
  23. package/wwwroot/_content/MindExecution.Plugins.Directory/directory-manager.js +202 -0
  24. package/wwwroot/_content/MindExecution.Plugins.Directory/exampleJsInterop.js +6 -0
  25. package/wwwroot/_content/MindExecution.Plugins.YouTube/css/youtube-search.css +251 -0
  26. package/wwwroot/_content/MindExecution.Shared/MindExecution.Shared.wsano1j4wp.bundle.scp.css +4 -0
  27. package/wwwroot/_content/MindExecution.Shared/css/admin-dashboard.css +559 -0
  28. package/wwwroot/_content/MindExecution.Shared/css/app.css +1 -0
  29. package/wwwroot/_content/MindExecution.Shared/css/mind-map-overrides.css +2936 -0
  30. package/wwwroot/_content/MindExecution.Shared/fonts/NotoSansKR-Bold.ttf +0 -0
  31. package/wwwroot/_content/MindExecution.Shared/fonts/NotoSansKR-Regular.ttf +0 -0
  32. package/wwwroot/_content/MindExecution.Shared/js/agent-visualization.js +359 -0
  33. package/wwwroot/_content/MindExecution.Shared/js/background-themes.js +1721 -0
  34. package/wwwroot/_content/MindExecution.Shared/js/code-master.js +8316 -0
  35. package/wwwroot/_content/MindExecution.Shared/js/file-system-helper.js +639 -0
  36. package/wwwroot/_content/MindExecution.Shared/js/helpers/InfiniteGridHelper.js +109 -0
  37. package/wwwroot/_content/MindExecution.Shared/js/marked.min.js +69 -0
  38. package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js +7982 -0
  39. package/wwwroot/_content/MindExecution.Shared/js/mind-map-core.js.backup +1059 -0
  40. package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +15803 -0
  41. package/wwwroot/_content/MindExecution.Shared/js/mind-map-dev-guards.js +325 -0
  42. package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js +1430 -0
  43. package/wwwroot/_content/MindExecution.Shared/js/mind-map-dnd.js.bak +434 -0
  44. package/wwwroot/_content/MindExecution.Shared/js/mind-map-glow-shader.js +260 -0
  45. package/wwwroot/_content/MindExecution.Shared/js/mind-map-interactions.js +7640 -0
  46. package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-plan-worker.js +160 -0
  47. package/wwwroot/_content/MindExecution.Shared/js/mind-map-lod-renderer.js +9923 -0
  48. package/wwwroot/_content/MindExecution.Shared/js/mind-map-logic-workers.js +977 -0
  49. package/wwwroot/_content/MindExecution.Shared/js/mind-map-menu-manager.js +1431 -0
  50. package/wwwroot/_content/MindExecution.Shared/js/mind-map-multi-select.js +1716 -0
  51. package/wwwroot/_content/MindExecution.Shared/js/mind-map-node-search-worker.js +553 -0
  52. package/wwwroot/_content/MindExecution.Shared/js/mind-map-nodes.js +4541 -0
  53. package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js +489 -0
  54. package/wwwroot/_content/MindExecution.Shared/js/mind-map-object-manager.js.backup +372 -0
  55. package/wwwroot/_content/MindExecution.Shared/js/mind-map-pipeline.js +2075 -0
  56. package/wwwroot/_content/MindExecution.Shared/js/mind-map-text-lod-system.js +646 -0
  57. package/wwwroot/_content/MindExecution.Shared/js/mind-map-text-overlay-v2.js +4323 -0
  58. package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js +2260 -0
  59. package/wwwroot/_content/MindExecution.Shared/js/mind-map-texture-factory.js.backup +1258 -0
  60. package/wwwroot/_content/MindExecution.Shared/js/mind-map-visibility-worker.js +890 -0
  61. package/wwwroot/_content/MindExecution.Shared/js/mindmap-toolbar.js +594 -0
  62. package/wwwroot/_content/MindExecution.Shared/js/native-drop-handler.js +170 -0
  63. package/wwwroot/_content/MindExecution.Shared/js/plan-master.js +788 -0
  64. package/wwwroot/_content/MindExecution.Shared/js/renderers/CSS3DRenderer.js +50 -0
  65. package/wwwroot/_content/MindExecution.Shared/js/texture-worker-manager.js +188 -0
  66. package/wwwroot/_content/MindExecution.Shared/js/texture-worker.js +208 -0
  67. package/wwwroot/_content/MindExecution.Shared/js/three.min.js +6 -0
  68. package/wwwroot/_content/MindExecution.Shared/js/titlebar-handler.js +191 -0
  69. package/wwwroot/_content/MindExecution.Shared/js/token-manager.js +37 -0
  70. package/wwwroot/_content/MindExecution.Shared/js/token-worker.js +28 -0
  71. package/wwwroot/_content/MindExecution.Shared/js/troika-bundle.js +5626 -0
  72. package/wwwroot/_content/MindExecution.Shared/js/troika-bundle.js.map +7 -0
  73. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/css/all.min.css +9 -0
  74. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-brands-400.ttf +0 -0
  75. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-brands-400.woff2 +0 -0
  76. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-regular-400.ttf +0 -0
  77. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-regular-400.woff2 +0 -0
  78. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-solid-900.ttf +0 -0
  79. package/wwwroot/_content/MindExecution.Shared/lib/font-awesome/webfonts/fa-solid-900.woff2 +0 -0
  80. package/wwwroot/_content/MindExecution.Shared/models/all-MiniLM-L6-v2-quantized.onnx +0 -0
  81. package/wwwroot/_content/MindExecution.Shared/models/vocab.txt +30522 -0
  82. package/wwwroot/_framework/Google.Protobuf.9h59ukbel7.dll +0 -0
  83. package/wwwroot/_framework/Markdig.d1j7v41cl1.dll +0 -0
  84. package/wwwroot/_framework/MessagePack.Annotations.l6qv48kgpt.dll +0 -0
  85. package/wwwroot/_framework/MessagePack.eqoptzx9d5.dll +0 -0
  86. package/wwwroot/_framework/Microsoft.AspNetCore.Authorization.k7dsih5y5g.dll +0 -0
  87. package/wwwroot/_framework/Microsoft.AspNetCore.Components.6nyje9sa0g.dll +0 -0
  88. package/wwwroot/_framework/Microsoft.AspNetCore.Components.Authorization.iycd6unprw.dll +0 -0
  89. package/wwwroot/_framework/Microsoft.AspNetCore.Components.Web.487u3twia4.dll +0 -0
  90. package/wwwroot/_framework/Microsoft.AspNetCore.Components.WebAssembly.d0gcnmlxxz.dll +0 -0
  91. package/wwwroot/_framework/Microsoft.AspNetCore.Metadata.h4yevl9adi.dll +0 -0
  92. package/wwwroot/_framework/Microsoft.CSharp.qrvp77qmhs.dll +0 -0
  93. package/wwwroot/_framework/Microsoft.Data.Sqlite.jdlxgv2jtg.dll +0 -0
  94. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.4gjazp7kjf.dll +0 -0
  95. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Abstractions.gocudnvz7b.dll +0 -0
  96. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Relational.lt4rsvinuo.dll +0 -0
  97. package/wwwroot/_framework/Microsoft.EntityFrameworkCore.Sqlite.69luj0fa9r.dll +0 -0
  98. package/wwwroot/_framework/Microsoft.Extensions.Caching.Abstractions.364t4jh3zz.dll +0 -0
  99. package/wwwroot/_framework/Microsoft.Extensions.Caching.Memory.izlxhpzosu.dll +0 -0
  100. package/wwwroot/_framework/Microsoft.Extensions.Configuration.8zq7hh41o7.dll +0 -0
  101. package/wwwroot/_framework/Microsoft.Extensions.Configuration.Abstractions.8if74zs6ea.dll +0 -0
  102. package/wwwroot/_framework/Microsoft.Extensions.Configuration.Json.duvlngw8i0.dll +0 -0
  103. package/wwwroot/_framework/Microsoft.Extensions.DependencyInjection.Abstractions.t2hh9kvx0o.dll +0 -0
  104. package/wwwroot/_framework/Microsoft.Extensions.DependencyInjection.n4tg99oy8l.dll +0 -0
  105. package/wwwroot/_framework/Microsoft.Extensions.DependencyModel.h0d06ixk3e.dll +0 -0
  106. package/wwwroot/_framework/Microsoft.Extensions.Logging.Abstractions.rl32bkx2sd.dll +0 -0
  107. package/wwwroot/_framework/Microsoft.Extensions.Logging.dlht1xei0t.dll +0 -0
  108. package/wwwroot/_framework/Microsoft.Extensions.Options.qeunebioml.dll +0 -0
  109. package/wwwroot/_framework/Microsoft.Extensions.Primitives.18cr6vnuuz.dll +0 -0
  110. package/wwwroot/_framework/Microsoft.IO.RecyclableMemoryStream.r915vovvw4.dll +0 -0
  111. package/wwwroot/_framework/Microsoft.IdentityModel.Abstractions.1ejljk3erv.dll +0 -0
  112. package/wwwroot/_framework/Microsoft.IdentityModel.JsonWebTokens.1596zr8gne.dll +0 -0
  113. package/wwwroot/_framework/Microsoft.IdentityModel.Logging.229uyvpgio.dll +0 -0
  114. package/wwwroot/_framework/Microsoft.IdentityModel.Tokens.9sibtajc9f.dll +0 -0
  115. package/wwwroot/_framework/Microsoft.JSInterop.17lq4j1j7g.dll +0 -0
  116. package/wwwroot/_framework/Microsoft.JSInterop.WebAssembly.ryia5gxiad.dll +0 -0
  117. package/wwwroot/_framework/Microsoft.ML.OnnxRuntime.w9deo1m5ss.dll +0 -0
  118. package/wwwroot/_framework/Microsoft.ML.Tokenizers.cm2vuv2z61.dll +0 -0
  119. package/wwwroot/_framework/Microsoft.NET.StringTools.3qbrf4v2ki.dll +0 -0
  120. package/wwwroot/_framework/MimeMapping.og9ys58ylm.dll +0 -0
  121. package/wwwroot/_framework/MindExecution.Core.1q1trifbuu.dll +0 -0
  122. package/wwwroot/_framework/MindExecution.Kernel.gwwc40sc45.dll +0 -0
  123. package/wwwroot/_framework/MindExecution.Plugins.Admin.0jgrn1sckv.dll +0 -0
  124. package/wwwroot/_framework/MindExecution.Plugins.Business.13mme2qcag.dll +0 -0
  125. package/wwwroot/_framework/MindExecution.Plugins.Concept.dfp2mdt45q.dll +0 -0
  126. package/wwwroot/_framework/MindExecution.Plugins.Directory.3w4t6n3se0.dll +0 -0
  127. package/wwwroot/_framework/MindExecution.Plugins.PlanMaster.s0qpntz420.dll +0 -0
  128. package/wwwroot/_framework/MindExecution.Plugins.YouTube.iu11fq8d16.dll +0 -0
  129. package/wwwroot/_framework/MindExecution.Shared.7j27dcqnrc.dll +0 -0
  130. package/wwwroot/_framework/MindExecution.Web.pq1ty8ov2v.dll +0 -0
  131. package/wwwroot/_framework/Newtonsoft.Json.a56zs13vug.dll +0 -0
  132. package/wwwroot/_framework/SQLitePCLRaw.batteries_v2.rrd1nzawpp.dll +0 -0
  133. package/wwwroot/_framework/SQLitePCLRaw.core.1dxloztpfz.dll +0 -0
  134. package/wwwroot/_framework/SQLitePCLRaw.provider.e_sqlite3.oekyzl53i1.dll +0 -0
  135. package/wwwroot/_framework/Supabase.Core.s1pkj4aj0l.dll +0 -0
  136. package/wwwroot/_framework/Supabase.Functions.qz4nu782sg.dll +0 -0
  137. package/wwwroot/_framework/Supabase.Gotrue.twah27pkik.dll +0 -0
  138. package/wwwroot/_framework/Supabase.Postgrest.gmuuv369ih.dll +0 -0
  139. package/wwwroot/_framework/Supabase.Realtime.ox3kchdy3w.dll +0 -0
  140. package/wwwroot/_framework/Supabase.Storage.fnjnepaowr.dll +0 -0
  141. package/wwwroot/_framework/Supabase.azmaw5pgcz.dll +0 -0
  142. package/wwwroot/_framework/System.Collections.Concurrent.y1zmvuyipi.dll +0 -0
  143. package/wwwroot/_framework/System.Collections.Immutable.ug3j698qms.dll +0 -0
  144. package/wwwroot/_framework/System.Collections.NonGeneric.h66hj3863h.dll +0 -0
  145. package/wwwroot/_framework/System.Collections.Specialized.umr3y27ntj.dll +0 -0
  146. package/wwwroot/_framework/System.Collections.x53e19vfsj.dll +0 -0
  147. package/wwwroot/_framework/System.ComponentModel.Annotations.tz6gnt4ebt.dll +0 -0
  148. package/wwwroot/_framework/System.ComponentModel.Primitives.j7tiphu4rg.dll +0 -0
  149. package/wwwroot/_framework/System.ComponentModel.TypeConverter.ujlztox1gx.dll +0 -0
  150. package/wwwroot/_framework/System.ComponentModel.x9xz0ojfb6.dll +0 -0
  151. package/wwwroot/_framework/System.Console.ijzpqmj7ne.dll +0 -0
  152. package/wwwroot/_framework/System.Data.Common.1r0sqffq1p.dll +0 -0
  153. package/wwwroot/_framework/System.Diagnostics.DiagnosticSource.9upoqwq09o.dll +0 -0
  154. package/wwwroot/_framework/System.Diagnostics.Process.m99azzntjm.dll +0 -0
  155. package/wwwroot/_framework/System.Diagnostics.TraceSource.pl7wv26myr.dll +0 -0
  156. package/wwwroot/_framework/System.Diagnostics.Tracing.crlhfx6tut.dll +0 -0
  157. package/wwwroot/_framework/System.Drawing.Primitives.22e4y9ikq9.dll +0 -0
  158. package/wwwroot/_framework/System.Drawing.mi7d8hwowb.dll +0 -0
  159. package/wwwroot/_framework/System.Formats.Asn1.jx23sjiqnn.dll +0 -0
  160. package/wwwroot/_framework/System.IO.Compression.6fyoii3uej.dll +0 -0
  161. package/wwwroot/_framework/System.IO.Pipelines.vg77t4cd4d.dll +0 -0
  162. package/wwwroot/_framework/System.IdentityModel.Tokens.Jwt.t67es60z5b.dll +0 -0
  163. package/wwwroot/_framework/System.Linq.1bkoxlqgmq.dll +0 -0
  164. package/wwwroot/_framework/System.Linq.Expressions.24xqiypwdt.dll +0 -0
  165. package/wwwroot/_framework/System.Linq.Queryable.hvd01d6rsa.dll +0 -0
  166. package/wwwroot/_framework/System.Memory.8dx3lwgym4.dll +0 -0
  167. package/wwwroot/_framework/System.Net.Http.Json.3mhdm9l1rf.dll +0 -0
  168. package/wwwroot/_framework/System.Net.Http.eitrz660my.dll +0 -0
  169. package/wwwroot/_framework/System.Net.NetworkInformation.3pkuofcv9r.dll +0 -0
  170. package/wwwroot/_framework/System.Net.Ping.8clj5pklrp.dll +0 -0
  171. package/wwwroot/_framework/System.Net.Primitives.qrp4wcjz1p.dll +0 -0
  172. package/wwwroot/_framework/System.Net.WebSockets.Client.2u6pv01g69.dll +0 -0
  173. package/wwwroot/_framework/System.Net.WebSockets.qp6u31zvm5.dll +0 -0
  174. package/wwwroot/_framework/System.Numerics.Tensors.0c7z4mt3on.dll +0 -0
  175. package/wwwroot/_framework/System.Numerics.Vectors.kc7ufp2j4l.dll +0 -0
  176. package/wwwroot/_framework/System.ObjectModel.qv82fot1ib.dll +0 -0
  177. package/wwwroot/_framework/System.Private.CoreLib.rkafq04oma.dll +0 -0
  178. package/wwwroot/_framework/System.Private.Uri.t9542hmr6j.dll +0 -0
  179. package/wwwroot/_framework/System.Private.Xml.Linq.n8n3ptrbwu.dll +0 -0
  180. package/wwwroot/_framework/System.Private.Xml.rxd3tytisn.dll +0 -0
  181. package/wwwroot/_framework/System.Reactive.t3fuon548l.dll +0 -0
  182. package/wwwroot/_framework/System.Reflection.Emit.9tjhp6y0j3.dll +0 -0
  183. package/wwwroot/_framework/System.Reflection.Emit.ILGeneration.stxyk8zoo1.dll +0 -0
  184. package/wwwroot/_framework/System.Reflection.Emit.Lightweight.6xrd5v8vg0.dll +0 -0
  185. package/wwwroot/_framework/System.Reflection.Primitives.wgn8fpwwvv.dll +0 -0
  186. package/wwwroot/_framework/System.Runtime.InteropServices.JavaScript.sliym526xh.dll +0 -0
  187. package/wwwroot/_framework/System.Runtime.InteropServices.RuntimeInformation.oji7zut14z.dll +0 -0
  188. package/wwwroot/_framework/System.Runtime.InteropServices.te07xr2we9.dll +0 -0
  189. package/wwwroot/_framework/System.Runtime.Intrinsics.507y4h8nzq.dll +0 -0
  190. package/wwwroot/_framework/System.Runtime.Loader.v7gk4bse0k.dll +0 -0
  191. package/wwwroot/_framework/System.Runtime.Numerics.eqy5xjv3nd.dll +0 -0
  192. package/wwwroot/_framework/System.Runtime.Serialization.Formatters.zpkrub8lab.dll +0 -0
  193. package/wwwroot/_framework/System.Runtime.Serialization.Primitives.vhkpnbxjip.dll +0 -0
  194. package/wwwroot/_framework/System.Runtime.jn319d5nyg.dll +0 -0
  195. package/wwwroot/_framework/System.Security.Claims.0ztig1q9vo.dll +0 -0
  196. package/wwwroot/_framework/System.Security.Cryptography.vttizqc9ho.dll +0 -0
  197. package/wwwroot/_framework/System.Text.Encoding.Extensions.utdd47ny8f.dll +0 -0
  198. package/wwwroot/_framework/System.Text.Encodings.Web.wah8r1zoe0.dll +0 -0
  199. package/wwwroot/_framework/System.Text.Json.kxlfxj0wrs.dll +0 -0
  200. package/wwwroot/_framework/System.Text.RegularExpressions.dbqn58klox.dll +0 -0
  201. package/wwwroot/_framework/System.Threading.42ao9vi047.dll +0 -0
  202. package/wwwroot/_framework/System.Threading.Channels.hfa7j0uv2w.dll +0 -0
  203. package/wwwroot/_framework/System.Threading.Thread.caul0pdqul.dll +0 -0
  204. package/wwwroot/_framework/System.Transactions.Local.fimi2hamzo.dll +0 -0
  205. package/wwwroot/_framework/System.Web.HttpUtility.gq8yz50p2e.dll +0 -0
  206. package/wwwroot/_framework/System.Xml.Linq.kitin4zjoj.dll +0 -0
  207. package/wwwroot/_framework/System.Xml.ReaderWriter.kzvw3qgxb0.dll +0 -0
  208. package/wwwroot/_framework/System.Xml.XDocument.c539ki6cuq.dll +0 -0
  209. package/wwwroot/_framework/System.m05i39uvk9.dll +0 -0
  210. package/wwwroot/_framework/Websocket.Client.vapounvmnl.dll +0 -0
  211. package/wwwroot/_framework/blazor.boot.json +305 -0
  212. package/wwwroot/_framework/blazor.webassembly.js +1 -0
  213. package/wwwroot/_framework/dotnet.js +4 -0
  214. package/wwwroot/_framework/dotnet.native.vz0adxojrz.wasm +0 -0
  215. package/wwwroot/_framework/dotnet.native.xsn1d6x2kd.js +16 -0
  216. package/wwwroot/_framework/dotnet.runtime.dstopyvqzi.js +4 -0
  217. package/wwwroot/_framework/icudt_CJK.tjcz0u77k5.dat +0 -0
  218. package/wwwroot/_framework/icudt_EFIGS.tptq2av103.dat +0 -0
  219. package/wwwroot/_framework/icudt_no_CJK.lfu7j35m59.dat +0 -0
  220. package/wwwroot/_framework/netstandard.0xet7jg7ky.dll +0 -0
  221. package/wwwroot/_headers +40 -0
  222. package/wwwroot/_redirects +1 -0
  223. package/wwwroot/appsettings.json +71 -0
  224. package/wwwroot/icon-192.png +0 -0
  225. package/wwwroot/icon-512.png +0 -0
  226. package/wwwroot/index.html +710 -0
  227. package/wwwroot/js/marketing-tool.js +180 -0
  228. package/wwwroot/manifest.webmanifest +22 -0
  229. package/wwwroot/robots.txt +4 -0
  230. package/wwwroot/service-worker-assets.js +857 -0
  231. package/wwwroot/service-worker.js +33 -0
  232. package/wwwroot/sitemap.xml +27 -0
@@ -0,0 +1,890 @@
1
+ 'use strict';
2
+
3
+ const FULL_RES_VISIBILITY_EXIT_MARGIN_SCALE = 1.8;
4
+ const MAX_DIRECT_GRID_LOOKUPS = 4096;
5
+ const DEFAULT_HIT_TEST_CELL_RADIUS = 1;
6
+ const MAX_HIT_TEST_CELL_RADIUS = 3;
7
+
8
+ function createState() {
9
+ return {
10
+ boardId: '',
11
+ cellSize: 500,
12
+ nodes: new Map(),
13
+ spatialGrid: new Map(),
14
+ lastVisibleIds: new Set(),
15
+ lastPriorityIds: [],
16
+ lastVisibilityRect: null,
17
+ lastNodeCount: 0,
18
+ lastResultSeq: 0
19
+ };
20
+ }
21
+
22
+ let runtime = createState();
23
+
24
+ function normalizeBoardId(boardId) {
25
+ return String(boardId ?? '').trim();
26
+ }
27
+
28
+ function normalizeNodeSnapshot(node) {
29
+ if (!node || typeof node !== 'object') {
30
+ return null;
31
+ }
32
+
33
+ const id = String(node.id || '').trim();
34
+ if (!id) {
35
+ return null;
36
+ }
37
+
38
+ const minX = Number(node.minX || 0);
39
+ const maxX = Number(node.maxX || minX);
40
+ const minY = Number(node.minY || 0);
41
+ const maxY = Number(node.maxY || minY);
42
+
43
+ return {
44
+ id,
45
+ contentType: String(node.contentType || '').trim().toLowerCase(),
46
+ textLike: node.textLike === true,
47
+ x: Number(node.x || minX),
48
+ y: Number(node.y || maxY),
49
+ z: Number(node.z || 0),
50
+ width: Math.max(1, Number(node.width || (maxX - minX) || 1)),
51
+ height: Math.max(1, Number(node.height || (maxY - minY) || 1)),
52
+ minX,
53
+ maxX,
54
+ minY,
55
+ maxY,
56
+ cellKeys: Array.isArray(node.cellKeys)
57
+ ? node.cellKeys.map((key) => String(key || '').trim()).filter(Boolean)
58
+ : []
59
+ };
60
+ }
61
+
62
+ function clearState(boardId, cellSize) {
63
+ runtime = createState();
64
+ runtime.boardId = normalizeBoardId(boardId);
65
+ runtime.cellSize = Math.max(1, Number(cellSize || 500));
66
+ }
67
+
68
+ function removeNodeFromGrid(nodeId, node) {
69
+ const normalizedId = String(nodeId || '').trim();
70
+ if (!normalizedId || !node?.cellKeys) {
71
+ return;
72
+ }
73
+
74
+ for (let i = 0; i < node.cellKeys.length; i++) {
75
+ const key = node.cellKeys[i];
76
+ const cell = runtime.spatialGrid.get(key);
77
+ if (!cell) {
78
+ continue;
79
+ }
80
+
81
+ cell.delete(normalizedId);
82
+ if (cell.size === 0) {
83
+ runtime.spatialGrid.delete(key);
84
+ }
85
+ }
86
+ }
87
+
88
+ function upsertNode(node) {
89
+ const normalizedNode = normalizeNodeSnapshot(node);
90
+ if (!normalizedNode) {
91
+ return;
92
+ }
93
+
94
+ const existing = runtime.nodes.get(normalizedNode.id);
95
+ if (existing) {
96
+ removeNodeFromGrid(normalizedNode.id, existing);
97
+ }
98
+
99
+ runtime.nodes.set(normalizedNode.id, normalizedNode);
100
+ for (let i = 0; i < normalizedNode.cellKeys.length; i++) {
101
+ const key = normalizedNode.cellKeys[i];
102
+ let cell = runtime.spatialGrid.get(key);
103
+ if (!cell) {
104
+ cell = new Set();
105
+ runtime.spatialGrid.set(key, cell);
106
+ }
107
+ cell.add(normalizedNode.id);
108
+ }
109
+ }
110
+
111
+ function removeNode(nodeId) {
112
+ const normalizedId = String(nodeId || '').trim();
113
+ if (!normalizedId) {
114
+ return;
115
+ }
116
+
117
+ const existing = runtime.nodes.get(normalizedId);
118
+ if (!existing) {
119
+ return;
120
+ }
121
+
122
+ removeNodeFromGrid(normalizedId, existing);
123
+ runtime.nodes.delete(normalizedId);
124
+ runtime.lastVisibleIds.delete(normalizedId);
125
+ }
126
+
127
+ function rebuildBoard(boardId, cellSize, nodes) {
128
+ clearState(boardId, cellSize);
129
+ const sourceNodes = Array.isArray(nodes) ? nodes : [];
130
+ for (let i = 0; i < sourceNodes.length; i++) {
131
+ upsertNode(sourceNodes[i]);
132
+ }
133
+ }
134
+
135
+ function getVisibilityMarginPolicy(cameraZ, isPanning = false, isCtrlWheelVerticalScrolling = false) {
136
+ let cullingMarginPx = 3000;
137
+ let maxMarginCells = 6;
138
+ let useCoarseVisibility = false;
139
+
140
+ if (cameraZ < 4500) {
141
+ cullingMarginPx = 1000;
142
+ maxMarginCells = 4;
143
+ } else if (cameraZ < 12000) {
144
+ cullingMarginPx = 2200;
145
+ maxMarginCells = 5;
146
+ } else if (cameraZ < 30000) {
147
+ cullingMarginPx = 900;
148
+ maxMarginCells = 2;
149
+ } else {
150
+ cullingMarginPx = 240;
151
+ maxMarginCells = 1;
152
+ useCoarseVisibility = isPanning !== true;
153
+ }
154
+
155
+ if (isPanning === true) {
156
+ if (cameraZ < 4500) {
157
+ cullingMarginPx += 500;
158
+ maxMarginCells += 1;
159
+ } else if (cameraZ < 12000) {
160
+ cullingMarginPx += 700;
161
+ maxMarginCells += 1;
162
+ } else if (cameraZ < 30000) {
163
+ cullingMarginPx += 600;
164
+ maxMarginCells += 1;
165
+ } else {
166
+ cullingMarginPx += 320;
167
+ maxMarginCells += 1;
168
+ }
169
+ }
170
+
171
+ if (isCtrlWheelVerticalScrolling && cameraZ < 12000) {
172
+ cullingMarginPx += (cameraZ < 4500) ? 700 : 900;
173
+ maxMarginCells += 2;
174
+ }
175
+
176
+ return {
177
+ cullingMarginPx,
178
+ maxMarginCells,
179
+ useCoarseVisibility
180
+ };
181
+ }
182
+
183
+ function describeCellRange(rect, cellSize) {
184
+ if (!rect) {
185
+ return null;
186
+ }
187
+
188
+ const left = Number(rect.left);
189
+ const right = Number(rect.right);
190
+ const bottom = Number(rect.bottom);
191
+ const top = Number(rect.top);
192
+ if (!Number.isFinite(left) || !Number.isFinite(right) || !Number.isFinite(bottom) || !Number.isFinite(top)) {
193
+ return null;
194
+ }
195
+ if (right < left || top < bottom) {
196
+ return null;
197
+ }
198
+
199
+ const startCellX = Math.floor(left / cellSize);
200
+ const endCellX = Math.floor(right / cellSize);
201
+ const startCellY = Math.floor(bottom / cellSize);
202
+ const endCellY = Math.floor(top / cellSize);
203
+ const spanX = Math.max(0, endCellX - startCellX + 1);
204
+ const spanY = Math.max(0, endCellY - startCellY + 1);
205
+
206
+ return {
207
+ startCellX,
208
+ endCellX,
209
+ startCellY,
210
+ endCellY,
211
+ spanX,
212
+ spanY,
213
+ directGridLookups: spanX * spanY
214
+ };
215
+ }
216
+
217
+ function intersectsRect(node, rect) {
218
+ if (!node || !rect) {
219
+ return false;
220
+ }
221
+
222
+ return !(
223
+ node.maxX < rect.left ||
224
+ node.minX > rect.right ||
225
+ node.maxY < rect.bottom ||
226
+ node.minY > rect.top
227
+ );
228
+ }
229
+
230
+ function collectCandidates(range) {
231
+ const candidateIds = new Set();
232
+ let usedPopulatedCellScan = false;
233
+
234
+ if (!range) {
235
+ runtime.nodes.forEach((_, nodeId) => candidateIds.add(nodeId));
236
+ return {
237
+ candidateIds,
238
+ usedPopulatedCellScan,
239
+ directGridLookups: 0,
240
+ gridSpanX: 0,
241
+ gridSpanY: 0
242
+ };
243
+ }
244
+
245
+ if (range.directGridLookups > MAX_DIRECT_GRID_LOOKUPS) {
246
+ usedPopulatedCellScan = true;
247
+ runtime.spatialGrid.forEach((nodeIds, key) => {
248
+ const separatorIndex = key.indexOf(':');
249
+ if (separatorIndex <= 0) {
250
+ return;
251
+ }
252
+
253
+ const cx = Number(key.slice(0, separatorIndex));
254
+ const cy = Number(key.slice(separatorIndex + 1));
255
+ if (!Number.isFinite(cx) || !Number.isFinite(cy)) {
256
+ return;
257
+ }
258
+
259
+ if (cx >= range.startCellX && cx <= range.endCellX && cy >= range.startCellY && cy <= range.endCellY) {
260
+ nodeIds.forEach((nodeId) => candidateIds.add(nodeId));
261
+ }
262
+ });
263
+ } else {
264
+ for (let cx = range.startCellX; cx <= range.endCellX; cx++) {
265
+ for (let cy = range.startCellY; cy <= range.endCellY; cy++) {
266
+ const cell = runtime.spatialGrid.get(`${cx}:${cy}`);
267
+ if (!cell) {
268
+ continue;
269
+ }
270
+ cell.forEach((nodeId) => candidateIds.add(nodeId));
271
+ }
272
+ }
273
+ }
274
+
275
+ runtime.lastVisibleIds.forEach((nodeId) => {
276
+ if (runtime.nodes.has(nodeId)) {
277
+ candidateIds.add(nodeId);
278
+ }
279
+ });
280
+
281
+ return {
282
+ candidateIds,
283
+ usedPopulatedCellScan,
284
+ directGridLookups: range.directGridLookups,
285
+ gridSpanX: range.spanX,
286
+ gridSpanY: range.spanY
287
+ };
288
+ }
289
+
290
+ function buildCellKeySetFromRange(range, targetSet) {
291
+ if (!range || !targetSet) {
292
+ return;
293
+ }
294
+
295
+ for (let cx = range.startCellX; cx <= range.endCellX; cx++) {
296
+ for (let cy = range.startCellY; cy <= range.endCellY; cy++) {
297
+ targetSet.add(`${cx}:${cy}`);
298
+ }
299
+ }
300
+ }
301
+
302
+ function addCandidatesFromCellKeySet(cellKeys, candidateIds, skipPreviouslyVisible = false) {
303
+ if (!cellKeys || !candidateIds || cellKeys.size === 0) {
304
+ return;
305
+ }
306
+
307
+ cellKeys.forEach((key) => {
308
+ const nodeIds = runtime.spatialGrid.get(key);
309
+ if (!nodeIds) {
310
+ return;
311
+ }
312
+
313
+ nodeIds.forEach((nodeId) => {
314
+ if (skipPreviouslyVisible && runtime.lastVisibleIds.has(nodeId)) {
315
+ return;
316
+ }
317
+
318
+ candidateIds.add(nodeId);
319
+ });
320
+ });
321
+ }
322
+
323
+ function normalizeHitTestCellRadius(cellRadius) {
324
+ const normalized = Math.round(Number(cellRadius || DEFAULT_HIT_TEST_CELL_RADIUS));
325
+ if (!Number.isFinite(normalized)) {
326
+ return DEFAULT_HIT_TEST_CELL_RADIUS;
327
+ }
328
+
329
+ return Math.max(0, Math.min(MAX_HIT_TEST_CELL_RADIUS, normalized));
330
+ }
331
+
332
+ function collectHitTestCandidateIds(centerCellX, centerCellY, cellRadius) {
333
+ const candidateIds = new Set();
334
+ const normalizedCellRadius = normalizeHitTestCellRadius(cellRadius);
335
+ let cellLookups = 0;
336
+
337
+ for (let offsetX = -normalizedCellRadius; offsetX <= normalizedCellRadius; offsetX++) {
338
+ for (let offsetY = -normalizedCellRadius; offsetY <= normalizedCellRadius; offsetY++) {
339
+ cellLookups++;
340
+ const cell = runtime.spatialGrid.get(`${centerCellX + offsetX}:${centerCellY + offsetY}`);
341
+ if (!cell) {
342
+ continue;
343
+ }
344
+
345
+ cell.forEach((nodeId) => candidateIds.add(nodeId));
346
+ }
347
+ }
348
+
349
+ return {
350
+ candidateIds,
351
+ cellLookups,
352
+ cellRadius: normalizedCellRadius
353
+ };
354
+ }
355
+
356
+ function normalizeSelectionRect(rect) {
357
+ if (!rect || typeof rect !== 'object') {
358
+ return null;
359
+ }
360
+
361
+ const left = Number(rect.left);
362
+ const right = Number(rect.right);
363
+ const bottom = Number(rect.bottom);
364
+ const top = Number(rect.top);
365
+ if (!Number.isFinite(left) || !Number.isFinite(right) || !Number.isFinite(bottom) || !Number.isFinite(top)) {
366
+ return null;
367
+ }
368
+
369
+ return {
370
+ left: Math.min(left, right),
371
+ right: Math.max(left, right),
372
+ bottom: Math.min(bottom, top),
373
+ top: Math.max(bottom, top)
374
+ };
375
+ }
376
+
377
+ function buildPriorityIds(visibleIds, camX, camY) {
378
+ const buffer = [];
379
+ visibleIds.forEach((nodeId) => {
380
+ const node = runtime.nodes.get(nodeId);
381
+ if (!node) {
382
+ return;
383
+ }
384
+
385
+ const dx = Number(node.x || 0) - camX;
386
+ const dy = Number(node.y || 0) - camY;
387
+ const distSq = (dx * dx) + (dy * dy);
388
+ const textPriority = node.textLike === true ? 0 : 1;
389
+ const mediaPriority = node.contentType === 'image' ? 0 : 1;
390
+ buffer.push({ nodeId, textPriority, mediaPriority, distSq });
391
+ });
392
+
393
+ buffer.sort((a, b) => {
394
+ if (a.textPriority !== b.textPriority) {
395
+ return a.textPriority - b.textPriority;
396
+ }
397
+ if (a.mediaPriority !== b.mediaPriority) {
398
+ return a.mediaPriority - b.mediaPriority;
399
+ }
400
+ return a.distSq - b.distSq;
401
+ });
402
+
403
+ return buffer.map((entry) => entry.nodeId);
404
+ }
405
+
406
+ function buildIncrementalPriorityIds(nextVisibleIds, enteredIds, camX, camY) {
407
+ const priorityIds = [];
408
+ const used = new Set();
409
+
410
+ if (Array.isArray(runtime.lastPriorityIds)) {
411
+ for (let i = 0; i < runtime.lastPriorityIds.length; i++) {
412
+ const nodeId = String(runtime.lastPriorityIds[i] || '').trim();
413
+ if (!nodeId || used.has(nodeId) || !nextVisibleIds.has(nodeId)) {
414
+ continue;
415
+ }
416
+
417
+ priorityIds.push(nodeId);
418
+ used.add(nodeId);
419
+ }
420
+ }
421
+
422
+ const enteredSet = new Set();
423
+ if (Array.isArray(enteredIds)) {
424
+ for (let i = 0; i < enteredIds.length; i++) {
425
+ const nodeId = String(enteredIds[i] || '').trim();
426
+ if (nodeId && nextVisibleIds.has(nodeId) && !used.has(nodeId)) {
427
+ enteredSet.add(nodeId);
428
+ }
429
+ }
430
+ }
431
+
432
+ if (enteredSet.size > 0) {
433
+ const enteredPriorityIds = buildPriorityIds(enteredSet, camX, camY);
434
+ for (let i = 0; i < enteredPriorityIds.length; i++) {
435
+ const nodeId = enteredPriorityIds[i];
436
+ if (!used.has(nodeId)) {
437
+ priorityIds.push(nodeId);
438
+ used.add(nodeId);
439
+ }
440
+ }
441
+ }
442
+
443
+ if (priorityIds.length !== nextVisibleIds.size) {
444
+ return buildPriorityIds(nextVisibleIds, camX, camY);
445
+ }
446
+
447
+ return priorityIds;
448
+ }
449
+
450
+ function handleVisibilityQuery(message) {
451
+ const boardId = normalizeBoardId(message.boardId);
452
+ if (!boardId || boardId !== runtime.boardId) {
453
+ return;
454
+ }
455
+
456
+ const t0 = (typeof performance !== 'undefined' && typeof performance.now === 'function')
457
+ ? performance.now()
458
+ : Date.now();
459
+
460
+ const camera = message.camera || {};
461
+ const state = message.state || {};
462
+ const seq = Number(message.seq || 0);
463
+ const previousResultSeq = Math.max(0, Math.floor(Number(runtime.lastResultSeq || 0)));
464
+ const mainLastAppliedSeq = Math.max(0, Math.floor(Number(message.mainLastAppliedSeq || 0)));
465
+ const cellSize = Math.max(1, Number(message.cellSize || runtime.cellSize || 500));
466
+ const camX = Number(camera.x || 0);
467
+ const camY = Number(camera.y || 0);
468
+ const camZ = Number(camera.z || 0);
469
+ const camNear = Number(camera.near || 0);
470
+ const camFar = Number(camera.far || Number.MAX_SAFE_INTEGER);
471
+ const viewportW = Math.max(1, Number(camera.viewportW || 1));
472
+ const viewportH = Math.max(1, Number(camera.viewportH || 1));
473
+ const aspect = Math.max(0.1, Number(camera.aspect || 1));
474
+ const fov = Number(camera.fov || 45);
475
+ const isPanning = state.isPanning === true;
476
+ const isZooming = state.isZooming === true;
477
+ const isFullResMode = state.isFullResMode === true;
478
+ const isCtrlWheelVerticalScrolling = state.isCtrlWheelVerticalScrolling === true;
479
+
480
+ const marginPolicy = getVisibilityMarginPolicy(camZ, isPanning, isCtrlWheelVerticalScrolling);
481
+ let marginWorld = 0;
482
+ let verticalLeadMarginTopWorld = 0;
483
+ let verticalLeadMarginBottomWorld = 0;
484
+ let horizontalLeadMarginLeftWorld = 0;
485
+ let horizontalLeadMarginRightWorld = 0;
486
+
487
+ const vfov = (fov * Math.PI) / 180;
488
+ const viewHeight = 2 * Math.tan(vfov / 2) * Math.max(1, camZ);
489
+ const viewWidth = viewHeight * aspect;
490
+ const worldPerPxX = viewWidth / viewportW;
491
+ const worldPerPxY = viewHeight / viewportH;
492
+ const rawMarginWorld = marginPolicy.cullingMarginPx * Math.max(worldPerPxX, worldPerPxY);
493
+ marginWorld = Math.min(rawMarginWorld, cellSize * marginPolicy.maxMarginCells);
494
+
495
+ if (isCtrlWheelVerticalScrolling && camZ < 12000) {
496
+ const directionalLeadWorld = Math.min(
497
+ rawMarginWorld * 0.8,
498
+ cellSize * Math.max(1, marginPolicy.maxMarginCells - 1)
499
+ );
500
+ const lastCtrlWheelDeltaY = Number(state.lastCtrlWheelDeltaY || 0);
501
+ if (lastCtrlWheelDeltaY < -0.01) {
502
+ verticalLeadMarginTopWorld = directionalLeadWorld;
503
+ } else if (lastCtrlWheelDeltaY > 0.01) {
504
+ verticalLeadMarginBottomWorld = directionalLeadWorld;
505
+ } else {
506
+ verticalLeadMarginTopWorld = directionalLeadWorld * 0.5;
507
+ verticalLeadMarginBottomWorld = directionalLeadWorld * 0.5;
508
+ }
509
+ }
510
+
511
+ if (isPanning && camZ < 12000) {
512
+ const panLeadWorld = Math.min(
513
+ rawMarginWorld * (camZ < 4500 ? 1.35 : 1.1),
514
+ cellSize * Math.max(1, marginPolicy.maxMarginCells)
515
+ );
516
+ const panDx = Number(state.lastPanWorldDeltaX || 0);
517
+ const panDy = Number(state.lastPanWorldDeltaY || 0);
518
+ if (panDx > 0.01) {
519
+ horizontalLeadMarginRightWorld = panLeadWorld;
520
+ } else if (panDx < -0.01) {
521
+ horizontalLeadMarginLeftWorld = panLeadWorld;
522
+ }
523
+ if (panDy > 0.01) {
524
+ verticalLeadMarginTopWorld = Math.max(verticalLeadMarginTopWorld, panLeadWorld);
525
+ } else if (panDy < -0.01) {
526
+ verticalLeadMarginBottomWorld = Math.max(verticalLeadMarginBottomWorld, panLeadWorld);
527
+ }
528
+ }
529
+
530
+ const halfVisibleW = viewWidth / 2;
531
+ const halfVisibleH = viewHeight / 2;
532
+ const viewportLeft = camX - halfVisibleW;
533
+ const viewportRight = camX + halfVisibleW;
534
+ const viewportBottom = camY - halfVisibleH;
535
+ const viewportTop = camY + halfVisibleH;
536
+ const enterMarginWorld = marginWorld;
537
+ const exitMarginWorld = marginWorld * FULL_RES_VISIBILITY_EXIT_MARGIN_SCALE;
538
+
539
+ const currentEnterRect = {
540
+ left: viewportLeft - (enterMarginWorld + horizontalLeadMarginLeftWorld),
541
+ right: viewportRight + (enterMarginWorld + horizontalLeadMarginRightWorld),
542
+ bottom: viewportBottom - (enterMarginWorld + verticalLeadMarginBottomWorld),
543
+ top: viewportTop + (enterMarginWorld + verticalLeadMarginTopWorld)
544
+ };
545
+ const currentPreserveRect = {
546
+ left: viewportLeft - (exitMarginWorld + horizontalLeadMarginLeftWorld),
547
+ right: viewportRight + (exitMarginWorld + horizontalLeadMarginRightWorld),
548
+ bottom: viewportBottom - (exitMarginWorld + verticalLeadMarginBottomWorld),
549
+ top: viewportTop + (exitMarginWorld + verticalLeadMarginTopWorld)
550
+ };
551
+
552
+ const previousVisibilityRect = runtime.lastVisibilityRect || null;
553
+ const currentRange = describeCellRange(currentEnterRect, cellSize);
554
+ let candidateIds = new Set();
555
+ let usedPopulatedCellScan = false;
556
+ let directGridLookups = Number(currentRange?.directGridLookups || 0);
557
+ let gridSpanX = Number(currentRange?.spanX || 0);
558
+ let gridSpanY = Number(currentRange?.spanY || 0);
559
+ const previousVisibleCount = runtime.lastVisibleIds.size;
560
+ const nextVisibleIds = new Set();
561
+ let usedIncrementalPanVisibility = false;
562
+ let incrementalPanBandCount = 0;
563
+ let incrementalPanCellLookups = 0;
564
+ const canAttemptIncrementalFullResPan =
565
+ isFullResMode === true &&
566
+ isPanning === true &&
567
+ isZooming !== true &&
568
+ state.isWindowResizing !== true &&
569
+ state.isResizing !== true &&
570
+ previousVisibilityRect?.mode === 'full-res' &&
571
+ runtime.lastNodeCount === runtime.nodes.size &&
572
+ Math.abs(Number(previousVisibilityRect?.cameraZ || 0) - camZ) < 0.01 &&
573
+ runtime.lastVisibleIds.size > 0;
574
+
575
+ if (canAttemptIncrementalFullResPan && currentRange) {
576
+ const prevRect = previousVisibilityRect;
577
+ const epsilon = 0.01;
578
+ const incrementalBands = [];
579
+
580
+ if (currentEnterRect.left < Number(prevRect.left) - epsilon) {
581
+ incrementalBands.push({
582
+ left: currentEnterRect.left,
583
+ right: Math.min(currentEnterRect.right, Number(prevRect.left)),
584
+ bottom: currentEnterRect.bottom,
585
+ top: currentEnterRect.top
586
+ });
587
+ }
588
+ if (currentEnterRect.right > Number(prevRect.right) + epsilon) {
589
+ incrementalBands.push({
590
+ left: Math.max(currentEnterRect.left, Number(prevRect.right)),
591
+ right: currentEnterRect.right,
592
+ bottom: currentEnterRect.bottom,
593
+ top: currentEnterRect.top
594
+ });
595
+ }
596
+ if (currentEnterRect.bottom < Number(prevRect.bottom) - epsilon) {
597
+ incrementalBands.push({
598
+ left: currentEnterRect.left,
599
+ right: currentEnterRect.right,
600
+ bottom: currentEnterRect.bottom,
601
+ top: Math.min(currentEnterRect.top, Number(prevRect.bottom))
602
+ });
603
+ }
604
+ if (currentEnterRect.top > Number(prevRect.top) + epsilon) {
605
+ incrementalBands.push({
606
+ left: currentEnterRect.left,
607
+ right: currentEnterRect.right,
608
+ bottom: Math.max(currentEnterRect.bottom, Number(prevRect.top)),
609
+ top: currentEnterRect.top
610
+ });
611
+ }
612
+
613
+ const incrementalCellKeys = new Set();
614
+ for (let i = 0; i < incrementalBands.length; i++) {
615
+ const bandRange = describeCellRange(incrementalBands[i], cellSize);
616
+ if (!bandRange || bandRange.directGridLookups <= 0) {
617
+ continue;
618
+ }
619
+
620
+ incrementalPanBandCount++;
621
+ buildCellKeySetFromRange(bandRange, incrementalCellKeys);
622
+ }
623
+
624
+ if (incrementalPanBandCount > 0 &&
625
+ incrementalCellKeys.size > 0 &&
626
+ incrementalCellKeys.size < directGridLookups) {
627
+ usedIncrementalPanVisibility = true;
628
+ incrementalPanCellLookups = incrementalCellKeys.size;
629
+
630
+ runtime.lastVisibleIds.forEach((nodeId) => {
631
+ if (runtime.nodes.has(nodeId)) {
632
+ nextVisibleIds.add(nodeId);
633
+ }
634
+ });
635
+ addCandidatesFromCellKeySet(incrementalCellKeys, candidateIds, true);
636
+ }
637
+ }
638
+
639
+ if (!usedIncrementalPanVisibility) {
640
+ const result = collectCandidates(currentRange);
641
+ candidateIds = result.candidateIds;
642
+ usedPopulatedCellScan = result.usedPopulatedCellScan;
643
+ directGridLookups = result.directGridLookups;
644
+ gridSpanX = result.gridSpanX;
645
+ gridSpanY = result.gridSpanY;
646
+ }
647
+
648
+ candidateIds.forEach((nodeId) => {
649
+ const node = runtime.nodes.get(nodeId);
650
+ if (!node) {
651
+ return;
652
+ }
653
+
654
+ const depth = camZ - node.z;
655
+ if (depth <= camNear || depth >= camFar) {
656
+ return;
657
+ }
658
+
659
+ const baseMarginWorld = runtime.lastVisibleIds.has(nodeId)
660
+ ? exitMarginWorld
661
+ : enterMarginWorld;
662
+ const leftBound = viewportLeft - (baseMarginWorld + horizontalLeadMarginLeftWorld);
663
+ const rightBound = viewportRight + (baseMarginWorld + horizontalLeadMarginRightWorld);
664
+ const bottomBound = viewportBottom - (baseMarginWorld + verticalLeadMarginBottomWorld);
665
+ const topBound = viewportTop + (baseMarginWorld + verticalLeadMarginTopWorld);
666
+
667
+ const isVisible = !(
668
+ node.maxX < leftBound ||
669
+ node.minX > rightBound ||
670
+ node.maxY < bottomBound ||
671
+ node.minY > topBound
672
+ );
673
+
674
+ if (isVisible) {
675
+ nextVisibleIds.add(nodeId);
676
+ }
677
+ });
678
+
679
+ const enteredIds = [];
680
+ nextVisibleIds.forEach((nodeId) => {
681
+ if (!runtime.lastVisibleIds.has(nodeId)) {
682
+ enteredIds.push(nodeId);
683
+ }
684
+ });
685
+
686
+ const exitedIds = [];
687
+ runtime.lastVisibleIds.forEach((nodeId) => {
688
+ if (!usedIncrementalPanVisibility && !nextVisibleIds.has(nodeId)) {
689
+ exitedIds.push(nodeId);
690
+ }
691
+ });
692
+
693
+ const priorityIds = usedIncrementalPanVisibility
694
+ ? buildIncrementalPriorityIds(nextVisibleIds, enteredIds, camX, camY)
695
+ : buildPriorityIds(nextVisibleIds, camX, camY);
696
+ const visibilityChanged = enteredIds.length > 0 || exitedIds.length > 0;
697
+
698
+ runtime.lastVisibleIds = nextVisibleIds;
699
+ runtime.lastPriorityIds = priorityIds;
700
+ runtime.lastVisibilityRect = {
701
+ left: currentEnterRect.left,
702
+ right: currentEnterRect.right,
703
+ bottom: currentEnterRect.bottom,
704
+ top: currentEnterRect.top,
705
+ mode: isFullResMode === true ? 'full-res' : 'lod',
706
+ cameraZ: camZ
707
+ };
708
+ runtime.lastNodeCount = runtime.nodes.size;
709
+ runtime.lastResultSeq = seq;
710
+
711
+ const t1 = (typeof performance !== 'undefined' && typeof performance.now === 'function')
712
+ ? performance.now()
713
+ : Date.now();
714
+
715
+ const canOmitFullVisibleIds =
716
+ usedIncrementalPanVisibility === true &&
717
+ mainLastAppliedSeq > 0 &&
718
+ mainLastAppliedSeq === previousResultSeq &&
719
+ seq === previousResultSeq + 1;
720
+
721
+ self.postMessage({
722
+ type: 'VISIBILITY_RESULT',
723
+ boardId,
724
+ seq,
725
+ visibleIds: canOmitFullVisibleIds ? undefined : Array.from(nextVisibleIds),
726
+ visibleCount: Number(nextVisibleIds.size || 0),
727
+ enteredIds,
728
+ exitedIds,
729
+ priorityIds,
730
+ visibilityChanged,
731
+ viewportRect: runtime.lastVisibilityRect,
732
+ lastVisibilityNodeCount: runtime.lastNodeCount,
733
+ fullResVisibilityReconcilePending: usedIncrementalPanVisibility === true,
734
+ profile: {
735
+ durationMs: Number(Math.max(0, t1 - t0).toFixed(2)),
736
+ cameraZ: Number((camZ || 0).toFixed(2)),
737
+ useCoarseVisibility: marginPolicy.useCoarseVisibility === true,
738
+ marginWorld: Number((marginWorld || 0).toFixed(2)),
739
+ gridSpanX: Number(gridSpanX || 0),
740
+ gridSpanY: Number(gridSpanY || 0),
741
+ directGridLookups: Number(directGridLookups || 0),
742
+ usedPopulatedCellScan: usedPopulatedCellScan === true,
743
+ incrementalPanMode: usedIncrementalPanVisibility === true,
744
+ incrementalPanBandCount,
745
+ incrementalPanCellLookups,
746
+ omittedFullVisibleIds: canOmitFullVisibleIds === true,
747
+ candidateCount: Number(candidateIds.size || 0),
748
+ processedCount: Number(candidateIds.size || 0),
749
+ prevVisibleCount: Number(previousVisibleCount || 0),
750
+ nextVisibleCount: Number(nextVisibleIds.size || 0),
751
+ visibilityChanged: visibilityChanged === true
752
+ }
753
+ });
754
+ }
755
+
756
+ function handleHitTestQuery(message) {
757
+ const boardId = normalizeBoardId(message.boardId);
758
+ if (!boardId || boardId !== runtime.boardId) {
759
+ return;
760
+ }
761
+
762
+ const seq = Number(message.seq || 0);
763
+ const cellX = Math.floor(Number(message.cellX || 0));
764
+ const cellY = Math.floor(Number(message.cellY || 0));
765
+ const t0 = (typeof performance !== 'undefined' && typeof performance.now === 'function')
766
+ ? performance.now()
767
+ : Date.now();
768
+ const { candidateIds, cellLookups, cellRadius } = collectHitTestCandidateIds(
769
+ cellX,
770
+ cellY,
771
+ message.cellRadius
772
+ );
773
+ const t1 = (typeof performance !== 'undefined' && typeof performance.now === 'function')
774
+ ? performance.now()
775
+ : Date.now();
776
+
777
+ self.postMessage({
778
+ type: 'HIT_TEST_RESULT',
779
+ boardId,
780
+ seq,
781
+ cellX,
782
+ cellY,
783
+ cellRadius,
784
+ rangeKey: `${cellX}:${cellY}:${cellRadius}`,
785
+ candidateIds: Array.from(candidateIds),
786
+ profile: {
787
+ durationMs: Number(Math.max(0, t1 - t0).toFixed(2)),
788
+ cellLookups,
789
+ candidateCount: Number(candidateIds.size || 0),
790
+ spatialGridCellCount: Number(runtime.spatialGrid.size || 0)
791
+ }
792
+ });
793
+ }
794
+
795
+ function handleSelectionQuery(message) {
796
+ const boardId = normalizeBoardId(message.boardId);
797
+ if (!boardId || boardId !== runtime.boardId) {
798
+ return;
799
+ }
800
+
801
+ const rect = normalizeSelectionRect(message.selectionRect);
802
+ if (!rect) {
803
+ return;
804
+ }
805
+
806
+ const seq = Number(message.seq || 0);
807
+ const t0 = (typeof performance !== 'undefined' && typeof performance.now === 'function')
808
+ ? performance.now()
809
+ : Date.now();
810
+ const range = describeCellRange(rect, Math.max(1, Number(message.cellSize || runtime.cellSize || 500)));
811
+ const { candidateIds, usedPopulatedCellScan, directGridLookups, gridSpanX, gridSpanY } = collectCandidates(range);
812
+ const selectedIds = [];
813
+
814
+ candidateIds.forEach((nodeId) => {
815
+ const node = runtime.nodes.get(nodeId);
816
+ if (!node) {
817
+ return;
818
+ }
819
+
820
+ if (node.minX >= rect.left &&
821
+ node.maxX <= rect.right &&
822
+ node.minY >= rect.bottom &&
823
+ node.maxY <= rect.top) {
824
+ selectedIds.push(nodeId);
825
+ }
826
+ });
827
+
828
+ const t1 = (typeof performance !== 'undefined' && typeof performance.now === 'function')
829
+ ? performance.now()
830
+ : Date.now();
831
+
832
+ self.postMessage({
833
+ type: 'SELECTION_QUERY_RESULT',
834
+ boardId,
835
+ seq,
836
+ selectedIds,
837
+ selectionRect: rect,
838
+ profile: {
839
+ durationMs: Number(Math.max(0, t1 - t0).toFixed(2)),
840
+ candidateCount: Number(candidateIds.size || 0),
841
+ selectedCount: Number(selectedIds.length || 0),
842
+ gridSpanX: Number(gridSpanX || 0),
843
+ gridSpanY: Number(gridSpanY || 0),
844
+ directGridLookups: Number(directGridLookups || 0),
845
+ usedPopulatedCellScan: usedPopulatedCellScan === true
846
+ }
847
+ });
848
+ }
849
+
850
+ self.onmessage = function (event) {
851
+ const message = event?.data || null;
852
+ if (!message || typeof message !== 'object') {
853
+ return;
854
+ }
855
+
856
+ switch (message.type) {
857
+ case 'RESET_BOARD':
858
+ clearState(message.boardId, message.cellSize);
859
+ break;
860
+ case 'REBUILD_BOARD':
861
+ rebuildBoard(message.boardId, message.cellSize, message.nodes);
862
+ break;
863
+ case 'UPSERT_NODE':
864
+ if (normalizeBoardId(message.boardId) === runtime.boardId) {
865
+ upsertNode(message.node);
866
+ }
867
+ break;
868
+ case 'REMOVE_NODE':
869
+ if (normalizeBoardId(message.boardId) === runtime.boardId) {
870
+ removeNode(message.nodeId);
871
+ }
872
+ break;
873
+ case 'VISIBILITY_QUERY':
874
+ handleVisibilityQuery(message);
875
+ break;
876
+ case 'HIT_TEST_QUERY':
877
+ handleHitTestQuery(message);
878
+ break;
879
+ case 'SELECTION_QUERY':
880
+ handleSelectionQuery(message);
881
+ break;
882
+ default:
883
+ break;
884
+ }
885
+ };
886
+
887
+ self.postMessage({
888
+ type: 'READY',
889
+ worker: 'visibility'
890
+ });