@deck.gl-community/graph-layers 9.1.1 → 9.2.0-beta.3

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 (354) hide show
  1. package/dist/_deprecated/old-constants.d.ts +107 -0
  2. package/dist/_deprecated/old-constants.d.ts.map +1 -0
  3. package/dist/_deprecated/old-constants.js +111 -0
  4. package/dist/_deprecated/old-constants.js.map +1 -0
  5. package/dist/core/cache.d.ts +0 -1
  6. package/dist/core/cache.js +0 -1
  7. package/dist/core/constants.d.ts +12 -100
  8. package/dist/core/constants.d.ts.map +1 -1
  9. package/dist/core/constants.js +3 -44
  10. package/dist/core/constants.js.map +1 -1
  11. package/dist/core/graph-engine.d.ts +63 -20
  12. package/dist/core/graph-engine.d.ts.map +1 -1
  13. package/dist/core/graph-engine.js +163 -72
  14. package/dist/core/graph-engine.js.map +1 -1
  15. package/dist/core/graph-layout.d.ts +63 -32
  16. package/dist/core/graph-layout.d.ts.map +1 -1
  17. package/dist/core/graph-layout.js +118 -36
  18. package/dist/core/graph-layout.js.map +1 -1
  19. package/dist/core/interaction-manager.d.ts +7 -5
  20. package/dist/core/interaction-manager.d.ts.map +1 -1
  21. package/dist/core/interaction-manager.js +64 -20
  22. package/dist/core/interaction-manager.js.map +1 -1
  23. package/dist/graph/arrow-graph.d.ts +69 -0
  24. package/dist/graph/arrow-graph.d.ts.map +1 -0
  25. package/dist/graph/arrow-graph.js +513 -0
  26. package/dist/graph/arrow-graph.js.map +1 -0
  27. package/dist/graph/classic-graph.d.ts +169 -0
  28. package/dist/graph/classic-graph.d.ts.map +1 -0
  29. package/dist/graph/classic-graph.js +390 -0
  30. package/dist/graph/classic-graph.js.map +1 -0
  31. package/dist/graph/edge.d.ts +12 -12
  32. package/dist/graph/edge.d.ts.map +1 -1
  33. package/dist/graph/edge.js +3 -6
  34. package/dist/graph/edge.js.map +1 -1
  35. package/dist/graph/functions/arrow-utils.d.ts +6 -0
  36. package/dist/graph/functions/arrow-utils.d.ts.map +1 -0
  37. package/dist/graph/functions/arrow-utils.js +67 -0
  38. package/dist/graph/functions/arrow-utils.js.map +1 -0
  39. package/dist/graph/functions/create-graph-from-data.d.ts +3 -0
  40. package/dist/graph/functions/create-graph-from-data.d.ts.map +1 -0
  41. package/dist/graph/functions/create-graph-from-data.js +12 -0
  42. package/dist/graph/functions/create-graph-from-data.js.map +1 -0
  43. package/dist/graph/graph-normalization.d.ts +10 -0
  44. package/dist/graph/graph-normalization.d.ts.map +1 -0
  45. package/dist/graph/graph-normalization.js +65 -0
  46. package/dist/graph/graph-normalization.js.map +1 -0
  47. package/dist/graph/graph.d.ts +62 -156
  48. package/dist/graph/graph.d.ts.map +1 -1
  49. package/dist/graph/graph.js +11 -301
  50. package/dist/graph/graph.js.map +1 -1
  51. package/dist/graph/node.d.ts +12 -13
  52. package/dist/graph/node.d.ts.map +1 -1
  53. package/dist/graph/node.js +5 -7
  54. package/dist/graph/node.js.map +1 -1
  55. package/dist/graph-data/arrow-graph-data-builder.d.ts +21 -0
  56. package/dist/graph-data/arrow-graph-data-builder.d.ts.map +1 -0
  57. package/dist/graph-data/arrow-graph-data-builder.js +105 -0
  58. package/dist/graph-data/arrow-graph-data-builder.js.map +1 -0
  59. package/dist/graph-data/graph-data-builder.d.ts +6 -0
  60. package/dist/graph-data/graph-data-builder.d.ts.map +1 -0
  61. package/dist/graph-data/graph-data-builder.js +1 -0
  62. package/dist/graph-data/graph-data-builder.js.map +1 -0
  63. package/dist/graph-data/graph-data.d.ts +40 -0
  64. package/dist/graph-data/graph-data.d.ts.map +1 -0
  65. package/dist/graph-data/graph-data.js +11 -0
  66. package/dist/graph-data/graph-data.js.map +1 -0
  67. package/dist/graph-data/plain-graph-data-builder.d.ts +20 -0
  68. package/dist/graph-data/plain-graph-data-builder.d.ts.map +1 -0
  69. package/dist/graph-data/plain-graph-data-builder.js +105 -0
  70. package/dist/graph-data/plain-graph-data-builder.js.map +1 -0
  71. package/dist/graph-style-schema.cdn.d.ts +2 -0
  72. package/dist/graph-style-schema.cdn.js +2 -0
  73. package/dist/graph-style-schema.json +12 -0
  74. package/dist/index.cjs +7851 -3250
  75. package/dist/index.cjs.map +4 -4
  76. package/dist/index.d.ts +35 -22
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +42 -25
  79. package/dist/index.js.map +1 -1
  80. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.d.ts +0 -1
  81. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-fragment.glsl.js +0 -1
  82. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.d.ts +0 -1
  83. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex-tf.glsl.js +0 -1
  84. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.d.ts +0 -1
  85. package/dist/layers/common-layers/flow-path-layer/flow-path-layer-vertex.glsl.js +0 -1
  86. package/dist/layers/common-layers/flow-path-layer/flow-path-layer.d.ts +0 -1
  87. package/dist/layers/common-layers/flow-path-layer/flow-path-layer.d.ts.map +1 -1
  88. package/dist/layers/common-layers/flow-path-layer/flow-path-layer.js +1 -3
  89. package/dist/layers/common-layers/flow-path-layer/flow-path-layer.js.map +1 -1
  90. package/dist/layers/common-layers/grid-layer/grid-layer.d.ts +83 -0
  91. package/dist/layers/common-layers/grid-layer/grid-layer.d.ts.map +1 -0
  92. package/dist/layers/common-layers/grid-layer/grid-layer.js +133 -0
  93. package/dist/layers/common-layers/grid-layer/grid-layer.js.map +1 -0
  94. package/dist/layers/common-layers/marker-layer/atlas-data-url.d.ts +0 -1
  95. package/dist/layers/common-layers/marker-layer/atlas-data-url.js +0 -1
  96. package/dist/layers/common-layers/marker-layer/marker-layer.d.ts +0 -1
  97. package/dist/layers/common-layers/marker-layer/marker-layer.js +2 -3
  98. package/dist/layers/common-layers/marker-layer/marker-list.d.ts +2 -63
  99. package/dist/layers/common-layers/marker-layer/marker-list.d.ts.map +1 -1
  100. package/dist/layers/common-layers/marker-layer/marker-list.js +1 -65
  101. package/dist/layers/common-layers/marker-layer/marker-list.js.map +1 -1
  102. package/dist/layers/common-layers/marker-layer/marker-mapping.d.ts +0 -1
  103. package/dist/layers/common-layers/marker-layer/marker-mapping.js +0 -1
  104. package/dist/layers/common-layers/spline-layer/spline-layer.d.ts +0 -1
  105. package/dist/layers/common-layers/spline-layer/spline-layer.js +0 -1
  106. package/dist/layers/common-layers/zoomable-text-layer/zoomable-text-layer.d.ts +0 -1
  107. package/dist/layers/common-layers/zoomable-text-layer/zoomable-text-layer.js +0 -1
  108. package/dist/layers/edge-attachment-helper.d.ts +15 -0
  109. package/dist/layers/edge-attachment-helper.d.ts.map +1 -0
  110. package/dist/layers/edge-attachment-helper.js +229 -0
  111. package/dist/layers/edge-attachment-helper.js.map +1 -0
  112. package/dist/layers/edge-layer.d.ts +1 -5
  113. package/dist/layers/edge-layer.d.ts.map +1 -1
  114. package/dist/layers/edge-layer.js +9 -11
  115. package/dist/layers/edge-layer.js.map +1 -1
  116. package/dist/layers/edge-layers/arrow-2d-geometry.d.ts +4 -0
  117. package/dist/layers/edge-layers/arrow-2d-geometry.d.ts.map +1 -0
  118. package/dist/layers/edge-layers/arrow-2d-geometry.js +42 -0
  119. package/dist/layers/edge-layers/arrow-2d-geometry.js.map +1 -0
  120. package/dist/layers/edge-layers/curved-edge-layer.d.ts +1 -2
  121. package/dist/layers/edge-layers/curved-edge-layer.js +1 -2
  122. package/dist/layers/edge-layers/edge-arrow-layer.d.ts +21 -0
  123. package/dist/layers/edge-layers/edge-arrow-layer.d.ts.map +1 -0
  124. package/dist/layers/edge-layers/edge-arrow-layer.js +131 -0
  125. package/dist/layers/edge-layers/edge-arrow-layer.js.map +1 -0
  126. package/dist/layers/edge-layers/edge-label-layer.d.ts +1 -2
  127. package/dist/layers/edge-layers/edge-label-layer.js +1 -2
  128. package/dist/layers/edge-layers/flow-layer.d.ts +1 -2
  129. package/dist/layers/edge-layers/flow-layer.js +1 -2
  130. package/dist/layers/edge-layers/path-edge-layer.d.ts +0 -1
  131. package/dist/layers/edge-layers/path-edge-layer.js +0 -1
  132. package/dist/layers/edge-layers/straight-line-edge-layer.d.ts +0 -1
  133. package/dist/layers/edge-layers/straight-line-edge-layer.js +0 -1
  134. package/dist/layers/graph-layer.d.ts +85 -29
  135. package/dist/layers/graph-layer.d.ts.map +1 -1
  136. package/dist/layers/graph-layer.js +635 -94
  137. package/dist/layers/graph-layer.js.map +1 -1
  138. package/dist/layers/node-layers/circle-layer.d.ts +0 -1
  139. package/dist/layers/node-layers/circle-layer.js +0 -1
  140. package/dist/layers/node-layers/image-layer.d.ts +0 -1
  141. package/dist/layers/node-layers/image-layer.js +0 -1
  142. package/dist/layers/node-layers/label-layer.d.ts +1 -2
  143. package/dist/layers/node-layers/label-layer.js +1 -2
  144. package/dist/layers/node-layers/path-rounded-rectangle-layer.d.ts +0 -1
  145. package/dist/layers/node-layers/path-rounded-rectangle-layer.js +1 -2
  146. package/dist/layers/node-layers/rectangle-layer.d.ts +0 -1
  147. package/dist/layers/node-layers/rectangle-layer.js +0 -1
  148. package/dist/layers/node-layers/rounded-rectangle-layer-fragment.d.ts +0 -1
  149. package/dist/layers/node-layers/rounded-rectangle-layer-fragment.js +0 -1
  150. package/dist/layers/node-layers/rounded-rectangle-layer.d.ts +1 -2
  151. package/dist/layers/node-layers/rounded-rectangle-layer.js +2 -3
  152. package/dist/layers/node-layers/zoomable-marker-layer.d.ts +1 -2
  153. package/dist/layers/node-layers/zoomable-marker-layer.js +1 -2
  154. package/dist/layouts/d3-dag/collapsable-d3-dag-layout.d.ts +24 -0
  155. package/dist/layouts/d3-dag/collapsable-d3-dag-layout.d.ts.map +1 -0
  156. package/dist/layouts/d3-dag/collapsable-d3-dag-layout.js +251 -0
  157. package/dist/layouts/d3-dag/collapsable-d3-dag-layout.js.map +1 -0
  158. package/dist/layouts/d3-dag/d3-dag-layout.d.ts +102 -0
  159. package/dist/layouts/d3-dag/d3-dag-layout.d.ts.map +1 -0
  160. package/dist/layouts/d3-dag/d3-dag-layout.js +531 -0
  161. package/dist/layouts/d3-dag/d3-dag-layout.js.map +1 -0
  162. package/dist/layouts/d3-force/d3-force-layout.d.ts +23 -11
  163. package/dist/layouts/d3-force/d3-force-layout.d.ts.map +1 -1
  164. package/dist/layouts/d3-force/d3-force-layout.js +63 -29
  165. package/dist/layouts/d3-force/d3-force-layout.js.map +1 -1
  166. package/dist/layouts/d3-force/worker.d.ts +0 -1
  167. package/dist/layouts/d3-force/worker.js +0 -1
  168. package/dist/layouts/experimental/force-multi-graph-layout.d.ts +25 -20
  169. package/dist/layouts/experimental/force-multi-graph-layout.d.ts.map +1 -1
  170. package/dist/layouts/experimental/force-multi-graph-layout.js +60 -47
  171. package/dist/layouts/experimental/force-multi-graph-layout.js.map +1 -1
  172. package/dist/layouts/experimental/hive-plot-layout.d.ts +26 -20
  173. package/dist/layouts/experimental/hive-plot-layout.d.ts.map +1 -1
  174. package/dist/layouts/experimental/hive-plot-layout.js +43 -39
  175. package/dist/layouts/experimental/hive-plot-layout.js.map +1 -1
  176. package/dist/layouts/experimental/radial-layout.d.ts +20 -12
  177. package/dist/layouts/experimental/radial-layout.d.ts.map +1 -1
  178. package/dist/layouts/experimental/radial-layout.js +41 -19
  179. package/dist/layouts/experimental/radial-layout.js.map +1 -1
  180. package/dist/layouts/gpu-force/gpu-force-layout.d.ts +15 -12
  181. package/dist/layouts/gpu-force/gpu-force-layout.d.ts.map +1 -1
  182. package/dist/layouts/gpu-force/gpu-force-layout.js +71 -59
  183. package/dist/layouts/gpu-force/gpu-force-layout.js.map +1 -1
  184. package/dist/layouts/gpu-force/worker.d.ts +0 -1
  185. package/dist/layouts/gpu-force/worker.js +0 -1
  186. package/dist/layouts/simple-layout.d.ts +21 -31
  187. package/dist/layouts/simple-layout.d.ts.map +1 -1
  188. package/dist/layouts/simple-layout.js +33 -26
  189. package/dist/layouts/simple-layout.js.map +1 -1
  190. package/dist/loaders/dot-graph-loader.d.ts +25 -0
  191. package/dist/loaders/dot-graph-loader.d.ts.map +1 -0
  192. package/dist/loaders/dot-graph-loader.js +668 -0
  193. package/dist/loaders/dot-graph-loader.js.map +1 -0
  194. package/dist/loaders/json-graph-loader.d.ts +6 -0
  195. package/dist/loaders/json-graph-loader.d.ts.map +1 -0
  196. package/dist/loaders/json-graph-loader.js +31 -0
  197. package/dist/loaders/json-graph-loader.js.map +1 -0
  198. package/dist/loaders/parsers/edge-parsers.d.ts +2 -0
  199. package/dist/loaders/parsers/edge-parsers.d.ts.map +1 -0
  200. package/dist/loaders/{edge-parsers.js → parsers/edge-parsers.js} +2 -3
  201. package/dist/loaders/parsers/edge-parsers.js.map +1 -0
  202. package/dist/loaders/parsers/node-parsers.d.ts +2 -0
  203. package/dist/loaders/parsers/node-parsers.d.ts.map +1 -0
  204. package/dist/loaders/{node-parsers.js → parsers/node-parsers.js} +2 -3
  205. package/dist/loaders/parsers/node-parsers.js.map +1 -0
  206. package/dist/loaders/parsers/parse-json-graph.d.ts +29 -0
  207. package/dist/loaders/parsers/parse-json-graph.d.ts.map +1 -0
  208. package/dist/loaders/parsers/parse-json-graph.js +78 -0
  209. package/dist/loaders/parsers/parse-json-graph.js.map +1 -0
  210. package/dist/style/graph-layer-stylesheet.d.ts +34 -0
  211. package/dist/style/graph-layer-stylesheet.d.ts.map +1 -0
  212. package/dist/style/graph-layer-stylesheet.js +39 -0
  213. package/dist/style/graph-layer-stylesheet.js.map +1 -0
  214. package/dist/style/graph-style-accessor-map.d.ts +93 -0
  215. package/dist/style/graph-style-accessor-map.d.ts.map +1 -0
  216. package/dist/style/graph-style-accessor-map.js +93 -0
  217. package/dist/style/graph-style-accessor-map.js.map +1 -0
  218. package/dist/style/graph-style-engine.d.ts +12 -0
  219. package/dist/style/graph-style-engine.d.ts.map +1 -0
  220. package/dist/style/graph-style-engine.js +164 -0
  221. package/dist/style/graph-style-engine.js.map +1 -0
  222. package/dist/style/graph-stylesheet.schema.d.ts +310 -0
  223. package/dist/style/graph-stylesheet.schema.d.ts.map +1 -0
  224. package/dist/style/graph-stylesheet.schema.js +237 -0
  225. package/dist/style/graph-stylesheet.schema.js.map +1 -0
  226. package/dist/style/style-property.d.ts +2 -3
  227. package/dist/style/style-property.d.ts.map +1 -1
  228. package/dist/style/style-property.js +224 -48
  229. package/dist/style/style-property.js.map +1 -1
  230. package/dist/style/stylesheet-engine.d.ts +33 -0
  231. package/dist/style/stylesheet-engine.d.ts.map +1 -0
  232. package/dist/style/stylesheet-engine.js +121 -0
  233. package/dist/style/stylesheet-engine.js.map +1 -0
  234. package/dist/utils/collapsed-chains.d.ts +17 -0
  235. package/dist/utils/collapsed-chains.d.ts.map +1 -0
  236. package/dist/utils/collapsed-chains.js +192 -0
  237. package/dist/utils/collapsed-chains.js.map +1 -0
  238. package/dist/utils/layer-utils.d.ts +0 -1
  239. package/dist/utils/layer-utils.d.ts.map +1 -1
  240. package/dist/utils/layer-utils.js +0 -1
  241. package/dist/utils/log.d.ts +2 -1
  242. package/dist/utils/log.d.ts.map +1 -1
  243. package/dist/utils/log.js +12 -2
  244. package/dist/utils/log.js.map +1 -1
  245. package/dist/utils/node-boundary.d.ts +10 -0
  246. package/dist/utils/node-boundary.d.ts.map +1 -0
  247. package/dist/utils/node-boundary.js +130 -0
  248. package/dist/utils/node-boundary.js.map +1 -0
  249. package/dist/utils/polygon-calculations.d.ts +0 -1
  250. package/dist/utils/polygon-calculations.js +0 -1
  251. package/dist/utils/rank-grid.d.ts +30 -0
  252. package/dist/utils/rank-grid.d.ts.map +1 -0
  253. package/dist/utils/rank-grid.js +306 -0
  254. package/dist/utils/rank-grid.js.map +1 -0
  255. package/package.json +25 -13
  256. package/src/_deprecated/old-constants.ts +122 -0
  257. package/src/_disabled/arrow-graph-data.ts.disabled +18 -0
  258. package/src/_disabled/columnar-graph-data-builder.ts.disabled +250 -0
  259. package/src/_disabled/graph-runtime-layout.ts.disabled +29 -0
  260. package/src/core/constants.ts +21 -43
  261. package/src/core/graph-engine.ts +212 -80
  262. package/src/core/graph-layout.ts +175 -47
  263. package/src/core/interaction-manager.ts +93 -33
  264. package/src/graph/arrow-graph.ts +648 -0
  265. package/src/graph/classic-graph.ts +447 -0
  266. package/src/graph/edge.ts +13 -13
  267. package/src/graph/functions/arrow-utils.ts +72 -0
  268. package/src/graph/functions/convert-arrow-graph-to-classic-graph.ts.disabled +47 -0
  269. package/src/graph/functions/convert-plain-graph-to-arrow-graph.ts.disabled +119 -0
  270. package/src/graph/functions/create-graph-from-data.ts +16 -0
  271. package/src/graph/functions/create-plain-graph-from-data.ts.disabled +176 -0
  272. package/src/graph/graph-normalization.ts +87 -0
  273. package/src/graph/graph.ts +68 -339
  274. package/src/graph/node.ts +15 -15
  275. package/src/graph/tabular-graph.ts.disabled +761 -0
  276. package/src/graph-data/arrow-graph-data-builder.ts +165 -0
  277. package/src/graph-data/graph-data-builder.ts +7 -0
  278. package/src/graph-data/graph-data.ts +57 -0
  279. package/src/graph-data/plain-graph-data-builder.ts +132 -0
  280. package/src/index.ts +82 -17
  281. package/src/layers/common-layers/flow-path-layer/flow-path-layer.ts +1 -2
  282. package/src/layers/common-layers/grid-layer/grid-layer.ts +237 -0
  283. package/src/layers/common-layers/marker-layer/marker-list.ts +62 -64
  284. package/src/layers/edge-attachment-helper.ts +361 -0
  285. package/src/layers/edge-layer.ts +6 -7
  286. package/src/layers/edge-layers/arrow-2d-geometry.ts +51 -0
  287. package/src/layers/edge-layers/edge-arrow-layer.ts +171 -0
  288. package/src/layers/graph-layer.ts +928 -130
  289. package/src/layouts/d3-dag/collapsable-d3-dag-layout.ts +330 -0
  290. package/src/layouts/d3-dag/d3-dag-layout.ts +739 -0
  291. package/src/layouts/d3-force/d3-force-layout.ts +83 -39
  292. package/src/layouts/experimental/force-multi-graph-layout.ts +72 -57
  293. package/src/layouts/experimental/hive-plot-layout.ts +60 -49
  294. package/src/layouts/experimental/radial-layout.ts +57 -26
  295. package/src/layouts/gpu-force/gpu-force-layout.ts +86 -72
  296. package/src/layouts/simple-layout.ts +51 -52
  297. package/src/loaders/{create-graph.ts → deprecated/create-graph.ts.disabled} +6 -6
  298. package/src/loaders/deprecated/json-classic-graph-loader.ts.disabled +33 -0
  299. package/src/loaders/{simple-json-graph-loader.ts → deprecated/simple-json-graph-loader.ts.disabled} +4 -4
  300. package/src/loaders/{table-graph-loader.ts → deprecated/table-graph-loader.ts.disabled} +9 -9
  301. package/src/loaders/dot-graph-loader.ts +860 -0
  302. package/src/loaders/json-graph-loader.ts +48 -0
  303. package/src/loaders/parsers/create-graph-data.ts.disabled +45 -0
  304. package/src/loaders/{edge-parsers.ts → parsers/edge-parsers.ts} +3 -3
  305. package/src/loaders/{node-parsers.ts → parsers/node-parsers.ts} +3 -3
  306. package/src/loaders/parsers/parse-json-graph.ts +134 -0
  307. package/src/style/graph-layer-stylesheet.ts +99 -0
  308. package/src/style/graph-style-accessor-map.ts +103 -0
  309. package/src/style/graph-style-engine.ts +232 -0
  310. package/src/style/graph-stylesheet.schema.ts +344 -0
  311. package/src/style/style-property.ts +314 -51
  312. package/src/style/stylesheet-engine.ts +168 -0
  313. package/src/utils/collapsed-chains.ts +255 -0
  314. package/src/utils/log.ts +15 -1
  315. package/src/utils/node-boundary.ts +238 -0
  316. package/src/utils/rank-grid.ts +426 -0
  317. package/dist/loaders/create-graph.d.ts +0 -13
  318. package/dist/loaders/create-graph.d.ts.map +0 -1
  319. package/dist/loaders/create-graph.js +0 -39
  320. package/dist/loaders/create-graph.js.map +0 -1
  321. package/dist/loaders/edge-parsers.d.ts +0 -3
  322. package/dist/loaders/edge-parsers.d.ts.map +0 -1
  323. package/dist/loaders/edge-parsers.js.map +0 -1
  324. package/dist/loaders/json-loader.d.ts +0 -8
  325. package/dist/loaders/json-loader.d.ts.map +0 -1
  326. package/dist/loaders/json-loader.js +0 -17
  327. package/dist/loaders/json-loader.js.map +0 -1
  328. package/dist/loaders/node-parsers.d.ts +0 -3
  329. package/dist/loaders/node-parsers.d.ts.map +0 -1
  330. package/dist/loaders/node-parsers.js.map +0 -1
  331. package/dist/loaders/simple-json-graph-loader.d.ts +0 -12
  332. package/dist/loaders/simple-json-graph-loader.d.ts.map +0 -1
  333. package/dist/loaders/simple-json-graph-loader.js +0 -21
  334. package/dist/loaders/simple-json-graph-loader.js.map +0 -1
  335. package/dist/loaders/table-graph-loader.d.ts +0 -17
  336. package/dist/loaders/table-graph-loader.d.ts.map +0 -1
  337. package/dist/loaders/table-graph-loader.js +0 -92
  338. package/dist/loaders/table-graph-loader.js.map +0 -1
  339. package/dist/style/style-sheet.d.ts +0 -11
  340. package/dist/style/style-sheet.d.ts.map +0 -1
  341. package/dist/style/style-sheet.js +0 -253
  342. package/dist/style/style-sheet.js.map +0 -1
  343. package/dist/widgets/long-press-button.d.ts +0 -13
  344. package/dist/widgets/long-press-button.d.ts.map +0 -1
  345. package/dist/widgets/long-press-button.js +0 -32
  346. package/dist/widgets/long-press-button.js.map +0 -1
  347. package/dist/widgets/view-control-widget.d.ts +0 -78
  348. package/dist/widgets/view-control-widget.d.ts.map +0 -1
  349. package/dist/widgets/view-control-widget.js +0 -195
  350. package/dist/widgets/view-control-widget.js.map +0 -1
  351. package/src/loaders/json-loader.ts +0 -19
  352. package/src/style/style-sheet.ts +0 -277
  353. package/src/widgets/long-press-button.tsx +0 -50
  354. package/src/widgets/view-control-widget.tsx +0 -337
@@ -0,0 +1,860 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
6
+ import type {ArrowGraphData} from '../graph-data/graph-data';
7
+ import {ArrowGraphDataBuilder} from '../graph-data/arrow-graph-data-builder';
8
+
9
+ // __VERSION__ is injected by babel-plugin-version-inline
10
+ // @ts-ignore TS2304: Cannot find name '__VERSION__'.
11
+ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
12
+
13
+ type DOTAttributeMap = Record<string, unknown>;
14
+
15
+ type ParsedNode = {
16
+ id: string;
17
+ attributes: DOTAttributeMap;
18
+ subgraphs: Set<string>;
19
+ };
20
+
21
+ type ParsedEdge = {
22
+ id: string;
23
+ sourceId: string;
24
+ targetId: string;
25
+ directed: boolean;
26
+ attributes: DOTAttributeMap;
27
+ subgraphs: string[];
28
+ };
29
+
30
+ type ParsedSubgraph = {
31
+ id: string;
32
+ attributes: DOTAttributeMap;
33
+ parentId?: string | null;
34
+ };
35
+
36
+ type DOTParseResult = {
37
+ id?: string;
38
+ directed: boolean;
39
+ strict: boolean;
40
+ graphAttributes: DOTAttributeMap;
41
+ nodes: Map<string, ParsedNode>;
42
+ edges: ParsedEdge[];
43
+ subgraphs: Map<string, ParsedSubgraph>;
44
+ };
45
+
46
+ export type DOTGraphLoaderMetadata = {
47
+ id?: string;
48
+ directed: boolean;
49
+ strict: boolean;
50
+ attributes: DOTAttributeMap;
51
+ subgraphs: ParsedSubgraph[];
52
+ };
53
+
54
+ // Loader definition
55
+
56
+ export type DOTGraphLoaderOptions = LoaderOptions & {
57
+ dot?: {
58
+ version?: number;
59
+ };
60
+ };
61
+
62
+ export type DOTGraphParserOptions = NonNullable<DOTGraphLoaderOptions['dot']>;
63
+
64
+
65
+ export const DOTGraphLoader = {
66
+ dataType: null as unknown as ArrowGraphData,
67
+ batchType: null as never,
68
+
69
+ name: 'DOT Graph',
70
+ id: 'dot-graph',
71
+ module: 'graph-layers',
72
+ version: VERSION,
73
+ worker: false,
74
+ extensions: ['dot'],
75
+ mimeTypes: ['text/vnd.graphviz', 'text/x-graphviz', 'application/vnd.graphviz'],
76
+ text: true,
77
+ options: {
78
+ dot: {
79
+ version: 0
80
+ }
81
+ },
82
+ parse: (arrayBuffer: ArrayBuffer, options?: DOTGraphLoaderOptions) => {
83
+ const text = new TextDecoder().decode(arrayBuffer);
84
+ return Promise.resolve(DOTGraphLoader.parseTextSync(text, options));
85
+ },
86
+ parseTextSync: (text: string, options?: DOTGraphLoaderOptions) => {
87
+ const parseOptions = {...DOTGraphLoader.options.dot, ...options?.dot};
88
+ return loadDOTGraph(text, parseOptions);
89
+ }
90
+ } as const satisfies LoaderWithParser<ArrowGraphData, never, DOTGraphLoaderOptions>;
91
+
92
+
93
+ export function loadDOTGraph(dot: string, options: DOTGraphParserOptions = {}): ArrowGraphData {
94
+ const parsed = parseDOT(dot);
95
+ return buildArrowGraphData(parsed, options);
96
+ }
97
+
98
+ export function parseDOTToArrowGraphData(
99
+ dot: string,
100
+ options: DOTGraphParserOptions = {}
101
+ ): ArrowGraphData {
102
+ const parsed = parseDOT(dot);
103
+ return buildArrowGraphData(parsed, options);
104
+ }
105
+
106
+ function buildArrowGraphData(
107
+ parsed: DOTParseResult,
108
+ options: DOTGraphParserOptions
109
+ ): ArrowGraphData {
110
+ const builder = new ArrowGraphDataBuilder({version: options.version});
111
+
112
+ const subgraphDescriptors = new Map<string, ParsedSubgraph>();
113
+ for (const [id, subgraph] of parsed.subgraphs.entries()) {
114
+ subgraphDescriptors.set(id, {
115
+ id,
116
+ attributes: {...subgraph.attributes},
117
+ parentId: subgraph.parentId
118
+ });
119
+ }
120
+
121
+ for (const node of parsed.nodes.values()) {
122
+ const attributes: DOTAttributeMap = {...node.attributes};
123
+ if (node.subgraphs.size > 0) {
124
+ attributes.subgraphs = Array.from(node.subgraphs, (id) => describeSubgraph(id, subgraphDescriptors));
125
+ }
126
+ builder.addNode({
127
+ id: node.id,
128
+ attributes
129
+ });
130
+ }
131
+
132
+ parsed.edges.forEach((edge) => {
133
+ const attributes: DOTAttributeMap = {...edge.attributes};
134
+ if (edge.subgraphs.length > 0) {
135
+ attributes.subgraphs = edge.subgraphs.map((id) => describeSubgraph(id, subgraphDescriptors));
136
+ }
137
+ builder.addEdge({
138
+ id: edge.id,
139
+ sourceId: edge.sourceId,
140
+ targetId: edge.targetId,
141
+ directed: edge.directed,
142
+ attributes
143
+ });
144
+ });
145
+
146
+ const metadata: DOTGraphLoaderMetadata = {
147
+ id: parsed.id,
148
+ directed: parsed.directed,
149
+ strict: parsed.strict,
150
+ attributes: {...parsed.graphAttributes},
151
+ subgraphs: Array.from(parsed.subgraphs.values(), (subgraph) => ({
152
+ id: subgraph.id,
153
+ attributes: {...subgraph.attributes},
154
+ parentId: subgraph.parentId
155
+ }))
156
+ };
157
+
158
+ const data = builder.finish();
159
+ data.metadata = metadata;
160
+ return data;
161
+ }
162
+
163
+ function describeSubgraph(
164
+ id: string,
165
+ descriptors: Map<string, ParsedSubgraph>
166
+ ): {id: string; attributes: DOTAttributeMap; parentId?: string | null} {
167
+ const subgraph = descriptors.get(id);
168
+ if (!subgraph) {
169
+ return {id, attributes: {}};
170
+ }
171
+ return {
172
+ id,
173
+ attributes: {...subgraph.attributes},
174
+ parentId: subgraph.parentId
175
+ };
176
+ }
177
+
178
+ type TokenType =
179
+ | 'identifier'
180
+ | 'string'
181
+ | 'html'
182
+ | 'arrow'
183
+ | 'lbrace'
184
+ | 'rbrace'
185
+ | 'lbrack'
186
+ | 'rbrack'
187
+ | 'equals'
188
+ | 'comma'
189
+ | 'semicolon';
190
+
191
+ type Token = {
192
+ type: TokenType;
193
+ value: string;
194
+ };
195
+
196
+ type ScopeContext = {
197
+ id?: string;
198
+ nodeDefaults: DOTAttributeMap;
199
+ edgeDefaults: DOTAttributeMap;
200
+ graphAttributes: DOTAttributeMap;
201
+ };
202
+
203
+ class DOTParser {
204
+ private readonly tokens: Token[];
205
+ private position = 0;
206
+ private readonly result: DOTParseResult = {
207
+ directed: false,
208
+ strict: false,
209
+ graphAttributes: {},
210
+ nodes: new Map(),
211
+ edges: [],
212
+ subgraphs: new Map()
213
+ };
214
+
215
+ private readonly scopes: ScopeContext[] = [
216
+ {nodeDefaults: {}, edgeDefaults: {}, graphAttributes: {}}
217
+ ];
218
+
219
+ private subgraphCounter = 0;
220
+ private edgeCounter = 0;
221
+
222
+ constructor(tokens: Token[]) {
223
+ this.tokens = tokens;
224
+ }
225
+
226
+ parse(): DOTParseResult {
227
+ this.parseGraph();
228
+ return this.result;
229
+ }
230
+
231
+ private parseGraph(): void {
232
+ const strictToken = this.peek();
233
+ if (strictToken && isKeyword(strictToken, 'strict')) {
234
+ this.consume();
235
+ this.result.strict = true;
236
+ }
237
+
238
+ const typeToken = this.peek();
239
+ if (!typeToken || !isGraphType(typeToken)) {
240
+ throw new Error('DOT graph must start with graph or digraph keyword.');
241
+ }
242
+ this.consume();
243
+ this.result.directed = isKeyword(typeToken, 'digraph');
244
+
245
+ const idToken = this.peek();
246
+ if (idToken && isIdentifierLike(idToken)) {
247
+ if (!isStructuralToken(idToken)) {
248
+ this.result.id = parseIdentifierValue(this.consume());
249
+ }
250
+ }
251
+
252
+ this.expect('lbrace');
253
+ while (!this.match('rbrace')) {
254
+ if (!this.parseStatement()) {
255
+ break;
256
+ }
257
+ }
258
+ this.result.graphAttributes = {...this.scopes[0].graphAttributes};
259
+ }
260
+
261
+ private parseStatement(): boolean {
262
+ if (this.consumeSemicolonIfPresent()) {
263
+ return true;
264
+ }
265
+
266
+ const token = this.peek();
267
+ if (!token) {
268
+ return false;
269
+ }
270
+
271
+ if (this.tryParseSubgraphStatement(token)) {
272
+ return true;
273
+ }
274
+
275
+ if (this.tryParseKeywordStatement(token)) {
276
+ return true;
277
+ }
278
+
279
+ if (this.tryParseAssignmentStatement(token)) {
280
+ return true;
281
+ }
282
+
283
+ if (isIdentifierLike(token)) {
284
+ this.parseNodeOrEdgeStatement();
285
+ this.consumeOptionalSemicolon();
286
+ return true;
287
+ }
288
+
289
+ throw new Error(`Unexpected token: ${token.value}`);
290
+ }
291
+
292
+ private consumeSemicolonIfPresent(): boolean {
293
+ const next = this.peek();
294
+ if (next?.type === 'semicolon') {
295
+ this.consume();
296
+ return true;
297
+ }
298
+ return false;
299
+ }
300
+
301
+ private tryParseSubgraphStatement(token: Token): boolean {
302
+ if (token.type !== 'lbrace' && !isKeyword(token, 'subgraph')) {
303
+ return false;
304
+ }
305
+ this.parseSubgraph();
306
+ return true;
307
+ }
308
+
309
+ private tryParseKeywordStatement(token: Token): boolean {
310
+ if (!(isKeyword(token, 'graph') || isKeyword(token, 'node') || isKeyword(token, 'edge'))) {
311
+ return false;
312
+ }
313
+
314
+ this.consume();
315
+ const attrs = this.parseAttributeList();
316
+
317
+ if (isKeyword(token, 'graph')) {
318
+ Object.assign(this.currentScope().graphAttributes, attrs);
319
+ } else if (isKeyword(token, 'node')) {
320
+ Object.assign(this.currentScope().nodeDefaults, attrs);
321
+ } else {
322
+ Object.assign(this.currentScope().edgeDefaults, attrs);
323
+ }
324
+
325
+ this.consumeOptionalSemicolon();
326
+ return true;
327
+ }
328
+
329
+ private tryParseAssignmentStatement(token: Token): boolean {
330
+ if (!isIdentifierLike(token)) {
331
+ return false;
332
+ }
333
+ const next = this.peek(1);
334
+ if (next?.type !== 'equals') {
335
+ return false;
336
+ }
337
+
338
+ const key = parseIdentifierValue(this.consume());
339
+ this.consume();
340
+ const valueToken = this.consume();
341
+ const value = parseAttributeValue(valueToken);
342
+ this.currentScope().graphAttributes[key] = value;
343
+ this.consumeOptionalSemicolon();
344
+ return true;
345
+ }
346
+
347
+ private parseNodeOrEdgeStatement(): void {
348
+ const first = parseIdentifierValue(this.consume());
349
+ const references: string[] = [first];
350
+ const operators: string[] = [];
351
+
352
+ let operatorToken = this.match('arrow');
353
+ while (operatorToken) {
354
+ operators.push(operatorToken.value);
355
+ const referenceToken = this.consume();
356
+ if (!isIdentifierLike(referenceToken)) {
357
+ throw new Error('Expected node identifier in edge statement.');
358
+ }
359
+ references.push(parseIdentifierValue(referenceToken));
360
+ operatorToken = this.match('arrow');
361
+ }
362
+
363
+ if (operators.length === 0) {
364
+ const attrs = this.parseAttributeList();
365
+ this.addNode(first, attrs);
366
+ return;
367
+ }
368
+
369
+ const attrs = this.parseAttributeList();
370
+ this.addEdgeChain(references, operators, attrs);
371
+ }
372
+
373
+ private addNode(id: string, attrs: DOTAttributeMap): void {
374
+ const membership = this.getCurrentSubgraphChain();
375
+ const node = this.ensureNode(id, membership);
376
+ node.attributes = {...node.attributes, ...attrs};
377
+ }
378
+
379
+ private addEdgeChain(nodes: string[], operators: string[], attrs: DOTAttributeMap): void {
380
+ const membership = this.getCurrentSubgraphChain();
381
+ const defaults = this.currentScope().edgeDefaults;
382
+ const attributes = {...defaults, ...attrs};
383
+
384
+ for (let index = 0; index < nodes.length - 1; index++) {
385
+ const sourceId = nodes[index];
386
+ const targetId = nodes[index + 1];
387
+ const operator = operators[index];
388
+ const directed = operator === '->';
389
+
390
+ const edgeId = deriveEdgeId(attributes, sourceId, targetId, ++this.edgeCounter);
391
+ const edgeAttributes = {...attributes};
392
+ this.ensureNode(sourceId, membership);
393
+ this.ensureNode(targetId, membership);
394
+
395
+ const directedOverride = deriveDirectedFlag(edgeAttributes, directed);
396
+ this.result.edges.push({
397
+ id: edgeId,
398
+ sourceId,
399
+ targetId,
400
+ directed: directedOverride,
401
+ attributes: edgeAttributes,
402
+ subgraphs: membership
403
+ });
404
+ }
405
+ }
406
+
407
+ private parseSubgraph(): void {
408
+ let idToken = this.peek();
409
+ let subgraphId: string;
410
+
411
+ if (idToken && isKeyword(idToken, 'subgraph')) {
412
+ this.consume();
413
+ idToken = this.peek();
414
+ }
415
+
416
+ if (idToken && isIdentifierLike(idToken) && idToken.type !== 'lbrace') {
417
+ subgraphId = parseIdentifierValue(this.consume());
418
+ } else {
419
+ subgraphId = `subgraph_${++this.subgraphCounter}`;
420
+ }
421
+
422
+ this.expect('lbrace');
423
+ const parentId = this.findCurrentSubgraphId();
424
+ const context: ScopeContext = {
425
+ id: subgraphId,
426
+ nodeDefaults: {...this.currentScope().nodeDefaults},
427
+ edgeDefaults: {...this.currentScope().edgeDefaults},
428
+ graphAttributes: {}
429
+ };
430
+ this.scopes.push(context);
431
+ this.result.subgraphs.set(subgraphId, {id: subgraphId, attributes: context.graphAttributes, parentId});
432
+
433
+ let shouldContinue = true;
434
+ while (shouldContinue) {
435
+ if (this.match('rbrace')) {
436
+ break;
437
+ }
438
+ shouldContinue = this.parseStatement();
439
+ }
440
+
441
+ this.scopes.pop();
442
+ }
443
+
444
+ private parseAttributeList(): DOTAttributeMap {
445
+ const attributes: DOTAttributeMap = {};
446
+ while (this.match('lbrack')) {
447
+ while (!this.match('rbrack')) {
448
+ const keyToken = this.consume();
449
+ if (!isIdentifierLike(keyToken)) {
450
+ throw new Error('Expected attribute name.');
451
+ }
452
+ const key = parseIdentifierValue(keyToken);
453
+ let value: unknown = true;
454
+ if (this.match('equals')) {
455
+ const valueToken = this.consume();
456
+ value = parseAttributeValue(valueToken);
457
+ }
458
+ attributes[key] = value;
459
+ if (this.peek()?.type === 'comma' || this.peek()?.type === 'semicolon') {
460
+ this.consume();
461
+ }
462
+ }
463
+ }
464
+ return attributes;
465
+ }
466
+
467
+ private ensureNode(id: string, membership: string[]): ParsedNode {
468
+ let node = this.result.nodes.get(id);
469
+ if (!node) {
470
+ const defaults = this.currentScope().nodeDefaults;
471
+ node = {id, attributes: {...defaults}, subgraphs: new Set()};
472
+ this.result.nodes.set(id, node);
473
+ }
474
+ if (node) {
475
+ membership.forEach((subgraphId) => node.subgraphs.add(subgraphId));
476
+ }
477
+ return node;
478
+ }
479
+
480
+ private getCurrentSubgraphChain(): string[] {
481
+ const chain: string[] = [];
482
+ for (const scope of this.scopes) {
483
+ if (scope.id) {
484
+ chain.push(scope.id);
485
+ }
486
+ }
487
+ return chain;
488
+ }
489
+
490
+ private findCurrentSubgraphId(): string | undefined {
491
+ for (let index = this.scopes.length - 1; index >= 0; index--) {
492
+ const scope = this.scopes[index];
493
+ if (scope.id) {
494
+ return scope.id;
495
+ }
496
+ }
497
+ return undefined;
498
+ }
499
+
500
+ private currentScope(): ScopeContext {
501
+ return this.scopes[this.scopes.length - 1];
502
+ }
503
+
504
+ private consumeOptionalSemicolon(): void {
505
+ const next = this.peek();
506
+ if (next?.type === 'semicolon') {
507
+ this.consume();
508
+ }
509
+ }
510
+
511
+ private expect(type: TokenType): Token {
512
+ const token = this.consume();
513
+ if (!token || token.type !== type) {
514
+ throw new Error(`Expected token ${type}.`);
515
+ }
516
+ return token;
517
+ }
518
+
519
+ private consume(): Token {
520
+ const token = this.tokens[this.position];
521
+ if (!token) {
522
+ throw new Error('Unexpected end of DOT input.');
523
+ }
524
+ this.position++;
525
+ return token;
526
+ }
527
+
528
+ private match(type: TokenType): Token | null {
529
+ const token = this.peek();
530
+ if (token && token.type === type) {
531
+ this.position++;
532
+ return token;
533
+ }
534
+ return null;
535
+ }
536
+
537
+ private peek(offset = 0): Token | null {
538
+ return this.tokens[this.position + offset] ?? null;
539
+ }
540
+ }
541
+
542
+ function parseDOT(input: string): DOTParseResult {
543
+ const parser = new DOTParser(tokenize(input));
544
+ return parser.parse();
545
+ }
546
+
547
+ const IDENTIFIER_TERMINATORS = new Set(['{', '}', '[', ']', '=', ';', ',', '"', '<', '#']);
548
+
549
+ function tokenize(input: string): Token[] {
550
+ const tokens: Token[] = [];
551
+ let index = 0;
552
+
553
+ while (index < input.length) {
554
+ const {token, nextIndex} = readNextToken(input, index);
555
+ if (nextIndex <= index) {
556
+ throw new Error(`Tokenizer did not advance at position ${index}.`);
557
+ }
558
+ if (token) {
559
+ tokens.push(token);
560
+ }
561
+ index = nextIndex;
562
+ }
563
+
564
+ return tokens;
565
+ }
566
+
567
+ function readNextToken(input: string, index: number): {token: Token | null; nextIndex: number} {
568
+ if (index >= input.length) {
569
+ return {token: null, nextIndex: input.length};
570
+ }
571
+
572
+ const char = input[index];
573
+
574
+ if (isWhitespace(char)) {
575
+ return {token: null, nextIndex: index + 1};
576
+ }
577
+
578
+ const commentEnd = skipComment(input, index);
579
+ if (commentEnd !== null) {
580
+ return {token: null, nextIndex: commentEnd};
581
+ }
582
+
583
+ const arrowToken = readArrowToken(input, index);
584
+ if (arrowToken) {
585
+ return arrowToken;
586
+ }
587
+
588
+ const punctuation = readPunctuationToken(char);
589
+ if (punctuation) {
590
+ return {token: punctuation, nextIndex: index + 1};
591
+ }
592
+
593
+ if (char === '"') {
594
+ const {value, nextIndex} = readQuotedString(input, index + 1);
595
+ return {token: {type: 'string', value}, nextIndex};
596
+ }
597
+
598
+ if (char === '<') {
599
+ const {value, nextIndex} = readHtmlString(input, index + 1);
600
+ return {token: {type: 'html', value}, nextIndex};
601
+ }
602
+
603
+ const identifier = readIdentifier(input, index);
604
+ if (identifier.value) {
605
+ return {
606
+ token: {type: 'identifier', value: identifier.value},
607
+ nextIndex: identifier.nextIndex
608
+ };
609
+ }
610
+
611
+ throw new Error(`Unexpected token at position ${index}.`);
612
+ }
613
+
614
+ function skipComment(input: string, index: number): number | null {
615
+ const char = input[index];
616
+ if (char === '/') {
617
+ const next = input[index + 1];
618
+ if (next === '/') {
619
+ return skipLineComment(input, index + 2);
620
+ }
621
+ if (next === '*') {
622
+ return skipBlockComment(input, index + 2);
623
+ }
624
+ return null;
625
+ }
626
+
627
+ if (char === '#') {
628
+ return skipLineComment(input, index + 1);
629
+ }
630
+
631
+ return null;
632
+ }
633
+
634
+ function skipLineComment(input: string, startIndex: number): number {
635
+ let cursor = startIndex;
636
+ while (cursor < input.length && !isLineBreak(input[cursor])) {
637
+ cursor++;
638
+ }
639
+ return cursor;
640
+ }
641
+
642
+ function skipBlockComment(input: string, startIndex: number): number {
643
+ let cursor = startIndex;
644
+ while (cursor < input.length) {
645
+ if (input[cursor] === '*' && input[cursor + 1] === '/') {
646
+ return cursor + 2;
647
+ }
648
+ cursor++;
649
+ }
650
+ throw new Error('Unterminated block comment in DOT source.');
651
+ }
652
+
653
+ function readArrowToken(input: string, index: number): {token: Token; nextIndex: number} | null {
654
+ const next = input[index + 1];
655
+ if (input[index] === '-' && next === '-') {
656
+ return {token: {type: 'arrow', value: '--'}, nextIndex: index + 2};
657
+ }
658
+ if (input[index] === '-' && next === '>') {
659
+ return {token: {type: 'arrow', value: '->'}, nextIndex: index + 2};
660
+ }
661
+ return null;
662
+ }
663
+
664
+ function readPunctuationToken(char: string): Token | null {
665
+ switch (char) {
666
+ case '{':
667
+ return {type: 'lbrace', value: char};
668
+ case '}':
669
+ return {type: 'rbrace', value: char};
670
+ case '[':
671
+ return {type: 'lbrack', value: char};
672
+ case ']':
673
+ return {type: 'rbrack', value: char};
674
+ case '=':
675
+ return {type: 'equals', value: char};
676
+ case ',':
677
+ return {type: 'comma', value: char};
678
+ case ';':
679
+ return {type: 'semicolon', value: char};
680
+ default:
681
+ return null;
682
+ }
683
+ }
684
+
685
+ function readQuotedString(input: string, startIndex: number): {value: string; nextIndex: number} {
686
+ let value = '';
687
+ let index = startIndex;
688
+ while (index < input.length) {
689
+ const char = input[index];
690
+ if (char === '"') {
691
+ return {value, nextIndex: index + 1};
692
+ }
693
+ if (char === '\\') {
694
+ const escape = readEscapedCharacter(input, index + 1);
695
+ value += escape.value;
696
+ index = escape.nextIndex;
697
+ } else {
698
+ value += char;
699
+ index++;
700
+ }
701
+ }
702
+ throw new Error('Unterminated string literal in DOT source.');
703
+ }
704
+
705
+ function readEscapedCharacter(input: string, startIndex: number): {value: string; nextIndex: number} {
706
+ const next = input[startIndex];
707
+ switch (next) {
708
+ case 'n':
709
+ case 'l':
710
+ case 'L':
711
+ return {value: '\n', nextIndex: startIndex + 1};
712
+ case 't':
713
+ return {value: '\t', nextIndex: startIndex + 1};
714
+ case 'r':
715
+ return {value: '\r', nextIndex: startIndex + 1};
716
+ case '"':
717
+ return {value: '"', nextIndex: startIndex + 1};
718
+ case '\\':
719
+ return {value: '\\', nextIndex: startIndex + 1};
720
+ default: {
721
+ if (typeof next === 'undefined') {
722
+ throw new Error('Unterminated escape sequence in DOT source.');
723
+ }
724
+ return {value: next, nextIndex: startIndex + 1};
725
+ }
726
+ }
727
+ }
728
+
729
+ function readHtmlString(input: string, startIndex: number): {value: string; nextIndex: number} {
730
+ let value = '<';
731
+ let depth = 1;
732
+ let index = startIndex;
733
+ while (index < input.length) {
734
+ const char = input[index];
735
+ value += char;
736
+ if (char === '<') {
737
+ depth++;
738
+ } else if (char === '>') {
739
+ depth--;
740
+ if (depth === 0) {
741
+ return {value, nextIndex: index + 1};
742
+ }
743
+ }
744
+ index++;
745
+ }
746
+ throw new Error('Unterminated HTML-like string literal in DOT source.');
747
+ }
748
+
749
+ function readIdentifier(input: string, startIndex: number): {value: string; nextIndex: number} {
750
+ let index = startIndex;
751
+ let value = '';
752
+ while (index < input.length && !isIdentifierTerminator(input, index)) {
753
+ value += input[index];
754
+ index++;
755
+ }
756
+ return {value, nextIndex: index};
757
+ }
758
+
759
+ function isIdentifierTerminator(input: string, index: number): boolean {
760
+ const char = input[index];
761
+ if (isWhitespace(char) || IDENTIFIER_TERMINATORS.has(char)) {
762
+ return true;
763
+ }
764
+ if (isArrowOperatorStart(input, index)) {
765
+ return true;
766
+ }
767
+ if (isCommentStart(input, index)) {
768
+ return true;
769
+ }
770
+ return false;
771
+ }
772
+
773
+ function isArrowOperatorStart(input: string, index: number): boolean {
774
+ if (input[index] !== '-') {
775
+ return false;
776
+ }
777
+ const next = input[index + 1];
778
+ return next === '-' || next === '>';
779
+ }
780
+
781
+ function isCommentStart(input: string, index: number): boolean {
782
+ if (input[index] !== '/') {
783
+ return false;
784
+ }
785
+ const next = input[index + 1];
786
+ return next === '/' || next === '*';
787
+ }
788
+
789
+ function isWhitespace(char: string): boolean {
790
+ return char === ' ' || char === '\n' || char === '\r' || char === '\t' || char === '\f';
791
+ }
792
+
793
+ function isLineBreak(char: string): boolean {
794
+ return char === '\n' || char === '\r';
795
+ }
796
+
797
+ function isKeyword(token: Token, keyword: string): boolean {
798
+ return token.type === 'identifier' && token.value.toLowerCase() === keyword.toLowerCase();
799
+ }
800
+
801
+ function isGraphType(token: Token): boolean {
802
+ return isKeyword(token, 'graph') || isKeyword(token, 'digraph');
803
+ }
804
+
805
+ function isIdentifierLike(token: Token): boolean {
806
+ return token.type === 'identifier' || token.type === 'string' || token.type === 'html';
807
+ }
808
+
809
+ function isStructuralToken(token: Token): boolean {
810
+ return token.type === 'lbrace' || token.type === 'rbrace' || token.type === 'lbrack' || token.type === 'rbrack';
811
+ }
812
+
813
+ function parseIdentifierValue(token: Token): string {
814
+ return token.value;
815
+ }
816
+
817
+ function parseAttributeValue(token: Token): unknown {
818
+ if (token.type === 'string' || token.type === 'html') {
819
+ return token.value;
820
+ }
821
+ if (token.type === 'identifier') {
822
+ const numeric = Number(token.value);
823
+ if (!Number.isNaN(numeric)) {
824
+ return numeric;
825
+ }
826
+ return token.value;
827
+ }
828
+ throw new Error('Invalid attribute value in DOT input.');
829
+ }
830
+
831
+ function deriveEdgeId(
832
+ attributes: DOTAttributeMap,
833
+ sourceId: string,
834
+ targetId: string,
835
+ counter: number
836
+ ): string {
837
+ const candidate = attributes.id ?? attributes.Id ?? attributes.ID;
838
+ if (typeof candidate === 'string' || typeof candidate === 'number') {
839
+ return String(candidate);
840
+ }
841
+ return `${String(sourceId)}-${String(targetId)}-${counter}`;
842
+ }
843
+
844
+ function deriveDirectedFlag(attributes: DOTAttributeMap, defaultDirected: boolean): boolean {
845
+ const candidate = attributes.directed;
846
+ if (typeof candidate === 'boolean') {
847
+ return candidate;
848
+ }
849
+
850
+ const dirAttr = attributes.dir;
851
+ if (typeof dirAttr === 'string') {
852
+ const normalized = dirAttr.toLowerCase();
853
+ if (normalized === 'none') {
854
+ return false;
855
+ }
856
+ return true;
857
+ }
858
+
859
+ return defaultDirected;
860
+ }