@ixfx/components 0.3.1 → 0.4.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 (256) hide show
  1. package/bundle/index.d.ts +1086 -603
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +16527 -14258
  4. package/bundle/index.js.map +1 -1
  5. package/bundle/style.css +14 -4
  6. package/dist/ac-text.d.ts.map +1 -1
  7. package/dist/ac-text.js +11 -6
  8. package/dist/ac-text.js.map +1 -1
  9. package/dist/{button-DMt5XWUK.js → button-C3fLMKUv.js} +4 -4
  10. package/dist/{button-DMt5XWUK.js.map → button-C3fLMKUv.js.map} +1 -1
  11. package/dist/button.d.ts.map +1 -1
  12. package/dist/button.js +1 -1
  13. package/dist/checkbox.d.ts +2 -2
  14. package/dist/checkbox.d.ts.map +1 -1
  15. package/dist/checkbox.js +14 -8
  16. package/dist/checkbox.js.map +1 -1
  17. package/dist/{colour-C3MQIjFJ-BLXg8W3U.js → colour-C3MQIjFJ-vRCdr8W-.js} +146 -552
  18. package/dist/colour-C3MQIjFJ-vRCdr8W-.js.map +1 -0
  19. package/dist/{colour-picker-K6zu82lm.js → colour-picker-0sgAha1T.js} +14 -9
  20. package/dist/colour-picker-0sgAha1T.js.map +1 -0
  21. package/dist/colour-picker.d.ts +1 -1
  22. package/dist/colour-picker.js +1 -1
  23. package/dist/crumbs.d.ts +1 -1
  24. package/dist/crumbs.d.ts.map +1 -1
  25. package/dist/crumbs.js +11 -6
  26. package/dist/crumbs.js.map +1 -1
  27. package/dist/data-display.d.ts +9 -4
  28. package/dist/data-display.d.ts.map +1 -1
  29. package/dist/data-display.js +270 -43
  30. package/dist/data-display.js.map +1 -1
  31. package/dist/data-provider-DgI909FP.js +23 -0
  32. package/dist/data-provider-DgI909FP.js.map +1 -0
  33. package/dist/{decorate-D7rC1gLP.js → decorate-DdjvVHS-.js} +2 -2
  34. package/dist/{decorate-D7rC1gLP.js.map → decorate-DdjvVHS-.js.map} +1 -1
  35. package/dist/{defaults-C7elhuyJ.js → defaults-C3b9OWJD.js} +2 -2
  36. package/dist/{defaults-C7elhuyJ.js.map → defaults-C3b9OWJD.js.map} +1 -1
  37. package/dist/{dist-TAGYwaju.js → dist-CA13FvMn.js} +7 -66
  38. package/dist/dist-CA13FvMn.js.map +1 -0
  39. package/dist/editable-label.d.ts.map +1 -1
  40. package/dist/editable-label.js +3 -2
  41. package/dist/editable-label.js.map +1 -1
  42. package/dist/fallbacks-pNMOMx38.js +168 -0
  43. package/dist/fallbacks-pNMOMx38.js.map +1 -0
  44. package/dist/{hex-editor-DlfoA65y.d.ts → hex-editor-CMIxtNgT.d.ts} +1 -1
  45. package/dist/hex-editor-CMIxtNgT.d.ts.map +1 -0
  46. package/dist/{hex-editor-CsN_ySkH.js → hex-editor-WZrjRtvL.js} +3 -3
  47. package/dist/{hex-editor-CsN_ySkH.js.map → hex-editor-WZrjRtvL.js.map} +1 -1
  48. package/dist/hex.d.ts +1 -1
  49. package/dist/hex.js +1 -1
  50. package/dist/{highlight-TPbSHruI.js → highlight-B-eQrhhb.js} +1 -1
  51. package/dist/{highlight-TPbSHruI.js.map → highlight-B-eQrhhb.js.map} +1 -1
  52. package/dist/{icon-CeTDJhC7.d.ts → icon-Bd5BiU4b.d.ts} +2 -2
  53. package/dist/icon-Bd5BiU4b.d.ts.map +1 -0
  54. package/dist/{icon-9NWTXtE1.js → icon-Ndo40kNO.js} +6 -5
  55. package/dist/icon-Ndo40kNO.js.map +1 -0
  56. package/dist/icons.d.ts +2 -2
  57. package/dist/icons.js +3 -3
  58. package/dist/{incr-search-DSKKsk6w.js → incr-search-CeERfijK.js} +2 -2
  59. package/dist/{incr-search-DSKKsk6w.js.map → incr-search-CeERfijK.js.map} +1 -1
  60. package/dist/incr-search.d.ts +1 -1
  61. package/dist/incr-search.js +2 -2
  62. package/dist/{index-hXFn14tM.d.ts → index-BMjri2-S.d.ts} +2 -2
  63. package/dist/{index-hXFn14tM.d.ts.map → index-BMjri2-S.d.ts.map} +1 -1
  64. package/dist/{index-DSlPeWLK.d.ts → index-CWpNcQKE.d.ts} +5 -5
  65. package/dist/index-CWpNcQKE.d.ts.map +1 -0
  66. package/dist/{index--hrxPBkQ.d.ts → index-CowKi2mo.d.ts} +2 -1
  67. package/dist/index-CowKi2mo.d.ts.map +1 -0
  68. package/dist/{index-B1hNR7Z9.d.ts → index-D87kRcEs.d.ts} +1 -1
  69. package/dist/{index-B1hNR7Z9.d.ts.map → index-D87kRcEs.d.ts.map} +1 -1
  70. package/dist/{index-CnL9krsH.d.ts → index-DgXpCg_G.d.ts} +32 -26
  71. package/dist/index-DgXpCg_G.d.ts.map +1 -0
  72. package/dist/{index-DrQjA8Gs.d.ts → index-s_IhSnwc.d.ts} +2 -2
  73. package/dist/index-s_IhSnwc.d.ts.map +1 -0
  74. package/dist/index.d.ts +432 -121
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +2370 -1707
  77. package/dist/index.js.map +1 -1
  78. package/dist/interaction-D6efrBLo.js +1 -0
  79. package/dist/{keyboard-De_vOHLg.js → keyboard-CimiEskD.js} +1 -1
  80. package/dist/{keyboard-De_vOHLg.js.map → keyboard-CimiEskD.js.map} +1 -1
  81. package/dist/{labelled-input-base-CqPL5rKm.js → labelled-input-base-9K_w3oLj.js} +2 -2
  82. package/dist/{labelled-input-base-CqPL5rKm.js.map → labelled-input-base-9K_w3oLj.js.map} +1 -1
  83. package/dist/{labelled-input-base-D-Y7agky.d.ts → labelled-input-base-ORb1rGq6.d.ts} +1 -1
  84. package/dist/labelled-input-base-ORb1rGq6.d.ts.map +1 -0
  85. package/dist/labelled-radial-input.d.ts +2 -2
  86. package/dist/labelled-radial-input.d.ts.map +1 -1
  87. package/dist/labelled-radial-input.js +7 -6
  88. package/dist/labelled-radial-input.js.map +1 -1
  89. package/dist/labelled-range-input.d.ts +1 -1
  90. package/dist/labelled-range-input.js +2 -2
  91. package/dist/led.d.ts +1 -1
  92. package/dist/led.d.ts.map +1 -1
  93. package/dist/led.js +2 -2
  94. package/dist/led.js.map +1 -1
  95. package/dist/{menu-item-CKRfP0pN.js → menu-item-BrIuORYD.js} +20 -10
  96. package/dist/menu-item-BrIuORYD.js.map +1 -0
  97. package/dist/{menu-item-ClQF2DKN.d.ts → menu-item-COx-Azgj.d.ts} +1 -1
  98. package/dist/menu-item-COx-Azgj.d.ts.map +1 -0
  99. package/dist/{menu-DJJuCm-5.js → menu-vjoiHZ13.js} +30 -17
  100. package/dist/menu-vjoiHZ13.js.map +1 -0
  101. package/dist/menu.d.ts +2 -2
  102. package/dist/menu.js +2 -2
  103. package/dist/miller.d.ts +2 -2
  104. package/dist/miller.d.ts.map +1 -1
  105. package/dist/miller.js +18 -11
  106. package/dist/miller.js.map +1 -1
  107. package/dist/narrowed-text.d.ts.map +1 -1
  108. package/dist/narrowed-text.js +7 -5
  109. package/dist/narrowed-text.js.map +1 -1
  110. package/dist/panel.d.ts +1 -1
  111. package/dist/panel.d.ts.map +1 -1
  112. package/dist/panel.js +5 -4
  113. package/dist/panel.js.map +1 -1
  114. package/dist/plots.d.ts +2 -2
  115. package/dist/plots.js +2 -2
  116. package/dist/polar-pad.d.ts +1 -1
  117. package/dist/polar-pad.d.ts.map +1 -1
  118. package/dist/polar-pad.js +10 -4
  119. package/dist/polar-pad.js.map +1 -1
  120. package/dist/{popup-ImtS9KnS.js → popup-DiWMxsWj.js} +1 -1
  121. package/dist/{popup-ImtS9KnS.js.map → popup-DiWMxsWj.js.map} +1 -1
  122. package/dist/prominence-DlFShic3.js +104 -0
  123. package/dist/prominence-DlFShic3.js.map +1 -0
  124. package/dist/{radial-input-LUSBEycd.d.ts → radial-input-CpQPs1Mp.d.ts} +1 -1
  125. package/dist/radial-input-CpQPs1Mp.d.ts.map +1 -0
  126. package/dist/{radial-input-DZA6WaFu.js → radial-input-DZ7eQCcM.js} +11 -6
  127. package/dist/radial-input-DZ7eQCcM.js.map +1 -0
  128. package/dist/radial-input.d.ts +1 -1
  129. package/dist/radial-input.js +1 -1
  130. package/dist/range-input.d.ts +1 -1
  131. package/dist/range-input.d.ts.map +1 -1
  132. package/dist/range-input.js +9 -4
  133. package/dist/range-input.js.map +1 -1
  134. package/dist/range.d.ts +1 -1
  135. package/dist/range.d.ts.map +1 -1
  136. package/dist/range.js +5 -3
  137. package/dist/range.js.map +1 -1
  138. package/dist/{registry-Q2gYQCHM.js → registry-CkW7q09Q.js} +1 -1
  139. package/dist/{registry-Q2gYQCHM.js.map → registry-CkW7q09Q.js.map} +1 -1
  140. package/dist/selecthorizontal.d.ts +1 -1
  141. package/dist/selecthorizontal.d.ts.map +1 -1
  142. package/dist/selecthorizontal.js +4 -3
  143. package/dist/selecthorizontal.js.map +1 -1
  144. package/dist/snap-container.d.ts.map +1 -1
  145. package/dist/snap-container.js +1 -1
  146. package/dist/split-layout.d.ts +1 -1
  147. package/dist/split-layout.d.ts.map +1 -1
  148. package/dist/split-layout.js +6 -5
  149. package/dist/split-layout.js.map +1 -1
  150. package/dist/style.css +14 -4
  151. package/dist/swipe.d.ts.map +1 -1
  152. package/dist/swipe.js +9 -4
  153. package/dist/swipe.js.map +1 -1
  154. package/dist/{tab-list-BnqISNvO.d.ts → tab-list-DLzb-m-I.d.ts} +2 -2
  155. package/dist/tab-list-DLzb-m-I.d.ts.map +1 -0
  156. package/dist/tabs.d.ts +1 -1
  157. package/dist/tabs.js +10 -4
  158. package/dist/tabs.js.map +1 -1
  159. package/dist/{tickled-controller-Cq1Va0rR.d.ts → tickled-controller-BjYCzGrU.d.ts} +2 -2
  160. package/dist/tickled-controller-BjYCzGrU.d.ts.map +1 -0
  161. package/dist/{tickled-styles-Bg3QbcrD.js → tickled-styles-fNDdqf6l.js} +1 -17
  162. package/dist/{tickled-styles-Bg3QbcrD.js.map → tickled-styles-fNDdqf6l.js.map} +1 -1
  163. package/dist/{timeline-Cv75Th2U.js → timeline-2OFtN4Ta.js} +1437 -36
  164. package/dist/timeline-2OFtN4Ta.js.map +1 -0
  165. package/dist/timeline.d.ts +1 -1
  166. package/dist/timeline.js +1 -1
  167. package/dist/{tooltip-DMxmBNky.js → tooltip-CJt3WLmN.js} +1 -1
  168. package/dist/{tooltip-DMxmBNky.js.map → tooltip-CJt3WLmN.js.map} +1 -1
  169. package/dist/{tooltip-CwGfb4lp.d.ts → tooltip-RGVIwHrZ.d.ts} +1 -1
  170. package/dist/{tooltip-CwGfb4lp.d.ts.map → tooltip-RGVIwHrZ.d.ts.map} +1 -1
  171. package/dist/{tree-CvvKbO-f.js → tree-CJWpMUvD.js} +113 -103
  172. package/dist/tree-CJWpMUvD.js.map +1 -0
  173. package/dist/{tree-component-D8Bg48tt.d.ts → tree-component-BcO26Xvt.d.ts} +65 -3
  174. package/dist/tree-component-BcO26Xvt.d.ts.map +1 -0
  175. package/dist/tree.d.ts +15 -15
  176. package/dist/tree.d.ts.map +1 -1
  177. package/dist/tree.js +1 -1
  178. package/dist/{types-BKaqnpwx.d.ts → types-DSfbtHs3.d.ts} +1 -1
  179. package/dist/types-DSfbtHs3.d.ts.map +1 -0
  180. package/dist/{xy-axis-DL0tfJDr.js → xy-axis-CK64haaK.js} +1831 -359
  181. package/dist/xy-axis-CK64haaK.js.map +1 -0
  182. package/dist/{xy-axis-D9uwpGTT.d.ts → xy-axis-McdUpcYr.d.ts} +102 -3
  183. package/dist/xy-axis-McdUpcYr.d.ts.map +1 -0
  184. package/dist/xy-pad.d.ts +1 -1
  185. package/dist/xy-pad.d.ts.map +1 -1
  186. package/dist/xy-pad.js +11 -6
  187. package/dist/xy-pad.js.map +1 -1
  188. package/docs-user/README.md +45 -0
  189. package/docs-user/ac-text.md +67 -0
  190. package/docs-user/ac-token.md +187 -0
  191. package/docs-user/button.md +355 -0
  192. package/docs-user/checkbox.md +62 -0
  193. package/docs-user/colour-picker.md +237 -0
  194. package/docs-user/crumbs.md +66 -0
  195. package/docs-user/data-display.md +98 -0
  196. package/docs-user/editable-label.md +244 -0
  197. package/docs-user/grouped-item-lister.md +424 -0
  198. package/docs-user/icons.md +191 -0
  199. package/docs-user/incr-search.md +94 -0
  200. package/docs-user/labelled-radial-input.md +204 -0
  201. package/docs-user/labelled-range-input.md +194 -0
  202. package/docs-user/led.md +40 -0
  203. package/docs-user/menu.md +319 -0
  204. package/docs-user/miller.md +453 -0
  205. package/docs-user/narrowed-text.md +72 -0
  206. package/docs-user/panel.md +250 -0
  207. package/docs-user/plots.md +361 -0
  208. package/docs-user/polar-pad.md +228 -0
  209. package/docs-user/radial-input.md +559 -0
  210. package/docs-user/range-input.md +264 -0
  211. package/docs-user/range.md +12 -0
  212. package/docs-user/selecthorizontal.md +32 -0
  213. package/docs-user/snap-container.md +132 -0
  214. package/docs-user/split-layout.md +232 -0
  215. package/docs-user/swipe.md +44 -0
  216. package/docs-user/tabs.md +217 -0
  217. package/docs-user/timeline.md +116 -0
  218. package/docs-user/transitory-label.md +120 -0
  219. package/docs-user/tree.md +592 -0
  220. package/docs-user/user-catalog.md +165 -0
  221. package/docs-user/user-theming.md +379 -0
  222. package/docs-user/util.md +122 -0
  223. package/docs-user/vertical-list.md +351 -0
  224. package/docs-user/xy-pad.md +94 -0
  225. package/package.json +19 -18
  226. package/dist/colour-C3MQIjFJ-BLXg8W3U.js.map +0 -1
  227. package/dist/colour-picker-K6zu82lm.js.map +0 -1
  228. package/dist/dist-BX0OVIm7.js +0 -1290
  229. package/dist/dist-BX0OVIm7.js.map +0 -1
  230. package/dist/dist-TAGYwaju.js.map +0 -1
  231. package/dist/hex-editor-DlfoA65y.d.ts.map +0 -1
  232. package/dist/icon-9NWTXtE1.js.map +0 -1
  233. package/dist/icon-CeTDJhC7.d.ts.map +0 -1
  234. package/dist/index--hrxPBkQ.d.ts.map +0 -1
  235. package/dist/index-CnL9krsH.d.ts.map +0 -1
  236. package/dist/index-DSlPeWLK.d.ts.map +0 -1
  237. package/dist/index-DrQjA8Gs.d.ts.map +0 -1
  238. package/dist/interaction-DG7X1rhI.js +0 -1
  239. package/dist/labelled-input-base-D-Y7agky.d.ts.map +0 -1
  240. package/dist/menu-DJJuCm-5.js.map +0 -1
  241. package/dist/menu-item-CKRfP0pN.js.map +0 -1
  242. package/dist/menu-item-ClQF2DKN.d.ts.map +0 -1
  243. package/dist/prominence--ic9uWBl.js +0 -98
  244. package/dist/prominence--ic9uWBl.js.map +0 -1
  245. package/dist/radial-input-DZA6WaFu.js.map +0 -1
  246. package/dist/radial-input-LUSBEycd.d.ts.map +0 -1
  247. package/dist/tab-list-BnqISNvO.d.ts.map +0 -1
  248. package/dist/tickled-controller-Cq1Va0rR.d.ts.map +0 -1
  249. package/dist/timeline-Cv75Th2U.js.map +0 -1
  250. package/dist/tree-CvvKbO-f.js.map +0 -1
  251. package/dist/tree-component-D8Bg48tt.d.ts.map +0 -1
  252. package/dist/types-BKaqnpwx.d.ts.map +0 -1
  253. package/dist/xy-axis-D9uwpGTT.d.ts.map +0 -1
  254. package/dist/xy-axis-DL0tfJDr.js.map +0 -1
  255. /package/bundle/{chunk-pbuEa-1d.js → chunk-D7D4PA-g.js} +0 -0
  256. /package/dist/{chunk-pbuEa-1d.js → chunk-D7D4PA-g.js} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"dist-BX0OVIm7.js","names":[],"sources":["../node_modules/.pnpm/@ixfx+core@0.56.12/node_modules/@ixfx/core/dist/chunk-pbuEa-1d.js","../node_modules/.pnpm/@ixfx+core@0.56.12/node_modules/@ixfx/core/dist/maps-BqikhSVo.js","../node_modules/.pnpm/@ixfx+core@0.56.12/node_modules/@ixfx/core/dist/text.js","../node_modules/.pnpm/@ixfx+core@0.56.12/node_modules/@ixfx/core/dist/src-rzH1dhIm.js"],"sourcesContent":["//#region \\0rolldown/runtime.js\nvar __defProp = Object.defineProperty;\nvar __exportAll = (all, no_symbols) => {\n\tlet target = {};\n\tfor (var name in all) __defProp(target, name, {\n\t\tget: all[name],\n\t\tenumerable: true\n\t});\n\tif (!no_symbols) __defProp(target, Symbol.toStringTag, { value: \"Module\" });\n\treturn target;\n};\n//#endregion\nexport { __exportAll as t };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\n//#region src/records/circular.ts\nconst removeCircularReferences = (value, replaceWith = null, seen = /* @__PURE__ */ new WeakSet(), path = ``) => {\n\tif (value === null) return value;\n\tif (typeof value !== `object`) throw new TypeError(`Param 'value' must be an object. Got type: ${typeof value}`);\n\tseen.add(value);\n\tconst entries = Object.entries(value);\n\tfor (const entry of entries) {\n\t\tif (entry[1] === null) continue;\n\t\tif (typeof entry[1] !== `object`) continue;\n\t\tif (seen.has(entry[1])) {\n\t\t\tentry[1] = replaceWith;\n\t\t\tcontinue;\n\t\t}\n\t\tentry[1] = removeCircularReferences(entry[1], replaceWith, seen, `${entry[0]}.`);\n\t}\n\treturn Object.fromEntries(entries);\n};\n//#endregion\n//#region src/to-string.ts\nconst objectToString = Object.prototype.toString;\nconst toTypeString = (value) => objectToString.call(value);\n/**\n* Returns _true_ if `value` is a Map type\n* @param value\n* @returns \n*/\nconst isMap = (value) => toTypeString(value) === `[object Map]`;\n/**\n* Returns _true_ if `value` is a Set type\n* @param value \n* @returns \n*/\nconst isSet = (value) => toTypeString(value) === `[object Set]`;\n/**\n* A default converter to string that uses JSON.stringify if its an object, or the thing itself if it's a string\n*/\nconst toStringDefault = (itemToMakeStringFor) => typeof itemToMakeStringFor === `string` ? itemToMakeStringFor : JSON.stringify(itemToMakeStringFor);\n/**\n* Converts a value to string form.\n* For simple objects, .toString() is used, other JSON.stringify is used.\n* It is meant for creating debugging output or 'hash' versions of objects, and does\n* not necessarily maintain full fidelity of the input\n* @param value \n* @returns \n*/\nconst defaultToString = (value) => {\n\tif (value === null) return `null`;\n\tif (typeof value === `boolean` || typeof value === `number`) return value.toString();\n\tif (typeof value === `string`) return value;\n\tif (typeof value === `symbol`) throw new TypeError(`Symbol cannot be converted to string`);\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch (error) {\n\t\tif (typeof value === `object`) return JSON.stringify(removeCircularReferences(value, `(circular)`));\n\t\telse throw error;\n\t}\n};\n//#endregion\n//#region src/comparers.ts\n/**\n* Sort numbers in ascending order.\n*\n* ```js\n* [10, 4, 5, 0].sort(numericComparer);\n* // Yields: [0, 4, 5, 10]\n* [10, 4, 5, 0].sort(comparerInverse(numericComparer));\n* // Yields: [ 10, 5, 4, 0]\n* ```\n* \n* Returns:\n* * 0: values are equal\n* * negative: `a` should be before `b`\n* * positive: `a` should come after `b`\n* @param a\n* @param b\n* @returns\n*/\nconst numericComparer = (a, b) => {\n\tif (a === b) return 0;\n\tif (a > b) return 1;\n\treturn -1;\n};\n/**\n* Default sort comparer, following same sematics as Array.sort.\n* Consider using {@link defaultComparer} to get more logical sorting of numbers.\n*\n* Note: numbers are sorted in alphabetical order, eg:\n* ```js\n* [ 10, 20, 5, 100 ].sort(jsComparer); // same as .sort()\n* // Yields: [10, 100, 20, 5]\n* ```\n* \n* Returns -1 if x is less than y\n* Returns 1 if x is greater than y\n* Returns 0 if x is the same as y\n* @param x\n* @param y\n* @returns\n*/\nconst jsComparer = (x, y) => {\n\tif (x === void 0 && y === void 0) return 0;\n\tif (x === void 0) return 1;\n\tif (y === void 0) return -1;\n\tconst xString = defaultToString(x);\n\tconst yString = defaultToString(y);\n\tif (xString < yString) return -1;\n\tif (xString > yString) return 1;\n\treturn 0;\n};\n/**\n* Inverts the source comparer.\n* @param comparer\n* @returns\n*/\nconst comparerInverse = (comparer) => {\n\treturn (x, y) => {\n\t\treturn comparer(x, y) * -1;\n\t};\n};\n/**\n* Compares numbers by numeric value, otherwise uses the default\n* logic of string comparison.\n*\n* Is an ascending sort:\n* * b, a, c -> a, b, c\n* * 10, 5, 100 -> 5, 10, 100\n* \n* Returns -1 if x is less than y\n* Returns 1 if x is greater than y\n* Returns 0 if x is the same as y\n* @param x\n* @param y\n* @see {@link comparerInverse} Inverted order\n* @returns\n*/\nconst defaultComparer = (x, y) => {\n\tif (typeof x === `number` && typeof y === `number`) return numericComparer(x, y);\n\treturn jsComparer(x, y);\n};\n//#endregion\n//#region src/is-equal.ts\n/**\n* If input is a string, it is returned.\n* Otherwise, it returns the result of JSON.stringify() with fields ordered.\n* \n* This allows for more consistent comparisons when object field orders are different but values the same.\n* @param itemToMakeStringFor \n* @returns \n*/\nconst toStringOrdered = (itemToMakeStringFor) => {\n\tif (typeof itemToMakeStringFor === `string`) return itemToMakeStringFor;\n\tconst allKeys = /* @__PURE__ */ new Set();\n\tJSON.stringify(itemToMakeStringFor, (key, value) => (allKeys.add(key), value));\n\treturn JSON.stringify(itemToMakeStringFor, [...allKeys].sort());\n};\n/**\n* Default comparer function is equiv to checking `a === b`.\n* Use {@link isEqualValueDefault} to compare by value, via comparing JSON string representation.\n*/\nconst isEqualDefault = (a, b) => a === b;\n/**\n* Comparer returns true if string representation of `a` and `b` are equal.\n* Use {@link isEqualDefault} to compare using === semantics\n* Uses `toStringDefault` to generate a string representation (via `JSON.stringify`).\n* \n* Returns _false_ if the ordering of fields is different, even though values are identical:\n* ```js\n* isEqualValueDefault({ a: 10, b: 20}, { b: 20, a: 10 }); // false\n* ```\n* \n* Use {@link isEqualValueIgnoreOrder} to ignore order (with an overhead of additional processing).\n* ```js\n* isEqualValueIgnoreOrder({ a: 10, b: 20}, { b: 20, a: 10 }); // true\n* ```\n* \n* Use {@link isEqualValuePartial} to partially match `b` against `a`.\n* @returns True if the contents of `a` and `b` are equal\n*/\nconst isEqualValueDefault = (a, b) => {\n\tif (a === b) return true;\n\treturn toStringDefault(a) === toStringDefault(b);\n};\n/**\n* Returns _true_ if `a` contains the values of `b`. `a` may contain other values, but we\n* only check against what is in `b`. `a` and `b` must both be simple objects.\n* \n* ```js\n* const obj = {\n* name: `Elle`,\n* size: 100,\n* colour: {\n* red: 0.5,\n* green: 0.1,\n* blue: 0.2\n* }\n* }\n* \n* isEqualValuePartial(obj, { name: `Elle` }); // true\n* isEqualValuePartial(obj, { name: { colour: red: { 0.5, green: 0.1 }} }); // true\n* \n* isEqualValuePartial(obj, { name: `Ellen` }); // false\n* isEqualValuePartial(obj, { lastname: `Elle` }); // false\n* ```\n* @param a \n* @param b \n* @param fieldComparer \n* @returns \n*/\nconst isEqualValuePartial = (a, b, fieldComparer) => {\n\tif (typeof a !== `object`) throw new Error(`Param 'a' expected to be object`);\n\tif (typeof b !== `object`) throw new Error(`Param 'b' expected to be object`);\n\tif (Object.is(a, b)) return true;\n\tconst comparer = fieldComparer ?? isEqualValuePartial;\n\tfor (const entryB of Object.entries(b)) {\n\t\tconst valueOnAKeyFromB = a[entryB[0]];\n\t\tconst valueB = entryB[1];\n\t\tif (typeof valueOnAKeyFromB === `object` && typeof valueB === `object`) {\n\t\t\tif (!comparer(valueOnAKeyFromB, valueB)) return false;\n\t\t} else if (valueOnAKeyFromB !== valueB) return false;\n\t}\n\treturn true;\n};\n/**\n* Comparer returns true if string representation of `a` and `b` are equal, regardless of field ordering.\n* Uses `toStringOrdered` to generate a string representation (via JSON.stringify`).\n* \n* ```js\n* isEqualValueIgnoreOrder({ a: 10, b: 20}, { b: 20, a: 10 }); // true\n* isEqualValue({ a: 10, b: 20}, { b: 20, a: 10 }); // false, fields are different order\n* ```\n* \n* There is an overhead to ordering fields. Use {@link isEqualValueDefault} if it's not possible that field ordering will change.\n* @returns True if the contents of `a` and `b` are equal\n* @typeParam T - Type of objects being compared\n*/\nconst isEqualValueIgnoreOrder = (a, b) => {\n\tif (a === b) return true;\n\treturn toStringOrdered(a) === toStringOrdered(b);\n};\n/**\n* Returns _true_ if Object.entries() is empty for `value`\n* @param value \n* @returns \n*/\nconst isEmptyEntries = (value) => [...Object.entries(value)].length === 0;\n/**\n* Returns _true_ if `a` and `b` are equal based on their JSON representations.\n* `path` is ignored.\n* @param a \n* @param b \n* @param path \n* @returns \n*/\nconst isEqualContextString = (a, b, _path) => {\n\treturn JSON.stringify(a) === JSON.stringify(b);\n};\n//#endregion\n//#region src/maps.ts\nvar maps_exports = /* @__PURE__ */ __exportAll({\n\taddObjectEntriesMutate: () => addObjectEntriesMutate,\n\taddValue: () => addValue,\n\taddValueMutate: () => addValueMutate,\n\taddValueMutator: () => addValueMutator,\n\tdeleteByValueCompareMutate: () => deleteByValueCompareMutate,\n\tfilterValues: () => filterValues,\n\tfindBySomeKey: () => findBySomeKey,\n\tfindEntryByPredicate: () => findEntryByPredicate,\n\tfindEntryByValue: () => findEntryByValue,\n\tfindValue: () => findValue,\n\tfromIterable: () => fromIterable,\n\tfromObject: () => fromObject,\n\tgetClosestIntegerKey: () => getClosestIntegerKey,\n\tgetOrGenerate: () => getOrGenerate,\n\tgetOrGenerateSync: () => getOrGenerateSync,\n\thasAnyValue: () => hasAnyValue,\n\thasKeyValue: () => hasKeyValue,\n\tmapToArray: () => mapToArray,\n\tmapToObjectTransform: () => mapToObjectTransform,\n\tmergeByKey: () => mergeByKey,\n\tsome: () => some,\n\tsortByValue: () => sortByValue,\n\tsortByValueProperty: () => sortByValueProperty,\n\ttoArray: () => toArray,\n\ttoObject: () => toObject,\n\ttransformMap: () => transformMap,\n\tzipKeyValue: () => zipKeyValue\n});\n/**\n* Gets the closest integer key to `target` in `data`.\n* * Requires map to have numbers as keys, not strings\n* * Math.round is used for rounding `target`.\n*\n* Examples:\n* ```js\n* // Assuming numeric keys 1, 2, 3, 4 exist:\n* getClosestIntegerKey(map, 3); // 3\n* getClosestIntegerKey(map, 3.1); // 3\n* getClosestIntegerKey(map, 3.5); // 4\n* getClosestIntegerKey(map, 3.6); // 4\n* getClosestIntegerKey(map, 100); // 4\n* getClosestIntegerKey(map, -100); // 1\n* ```\n* @param data Map\n* @param target Target value\n* @returns\n*/\nconst getClosestIntegerKey = (data, target) => {\n\ttarget = Math.round(target);\n\tif (data.has(target)) return target;\n\telse {\n\t\tlet offset = 1;\n\t\twhile (offset < 1e3) {\n\t\t\tif (data.has(target - offset)) return target - offset;\n\t\t\telse if (data.has(target + offset)) return target + offset;\n\t\t\toffset++;\n\t\t}\n\t\tthrow new Error(`Could not find target ${target.toString()}`);\n\t}\n};\n/**\n* Returns the first value in `data` that matches a key from `keys`.\n* ```js\n* // Iterate, yielding: `a.b.c.d`, `b.c.d`, `c.d`, `d`\n* const keys = Text.segmentsFromEnd(`a.b.c.d`);\n* // Gets first value that matches a key (starting from most precise)\n* const value = findBySomeKey(data, keys);\n* ```\n* @param data \n* @param keys \n* @returns \n*/\nconst findBySomeKey = (data, keys) => {\n\tfor (const key of keys) if (data.has(key)) return data.get(key);\n};\n/**\n* Returns true if map contains `value` under `key`, using `comparer` function. Use {@link hasAnyValue} if you don't care\n* what key value might be under.\n*\n* Having a comparer function is useful to check by value rather than object reference.\n*\n* @example Find key value based on string equality\n* ```js\n* hasKeyValue(map,`hello`, `samantha`, (a, b) => a === b);\n* ```\n* @param map Map to search\n* @param key Key to search\n* @param value Value to search\n* @param comparer Function to determine match. By default uses === comparison.\n* @returns True if key is found\n*/\nconst hasKeyValue = (map, key, value, comparer = isEqualDefault) => {\n\tif (!map.has(key)) return false;\n\treturn [...map.values()].some((v) => comparer(v, value));\n};\n/**\n* Deletes all key/values from map where value matches `value`,\n* with optional comparer. Mutates map.\n*\n* ```js\n* // Compare fruits based on their colour property\n* const colourComparer = (a, b) => a.colour === b.colour;\n*\n* // Deletes all values where .colour = `red`\n* deleteByValueCompareMutate(map, { colour: `red` }, colourComparer);\n* ```\n* @param map\n* @param value\n* @param comparer Uses === equality by default. Use isEqualValueDefault to compare by value\n*/\nconst deleteByValueCompareMutate = (map, value, comparer = isEqualDefault) => {\n\tfor (const entry of map.entries()) if (comparer(entry[1], value)) map.delete(entry[0]);\n};\n/**\n* Finds first entry by iterable value. Expects a map with an iterable as values.\n*\n* ```js\n* const map = new Map();\n* map.set('hello', 'a');\n* map.set('there', 'b');\n*\n* const entry = findEntryByPredicate(map, (value, key) => {\n* return (value === 'b');\n* });\n* // Entry is: ['there', 'b']\n* ```\n*\n* An alternative is {@link findEntryByValue} to search by value.\n* @param map Map to search\n* @param predicate Filter function returns true when there is a match of value\n* @returns Entry, or _undefined_ if `filter` function never returns _true_\n*/\nconst findEntryByPredicate = (map, predicate) => {\n\tfor (const entry of map.entries()) if (predicate(entry[1], entry[0])) return entry;\n};\n/**\n* Finds first entry by value.\n*\n* ```js\n* const map = new Map();\n* map.set('hello', 'a');\n* map.set('there', 'b');\n*\n* const entry = findEntryByValue(map, 'b');\n* // Entry is: ['there', 'b']\n* ```\n*\n* Uses JS's === comparison by default. Consider using `isEqualValueDefault` to match by value.\n* An alternative is {@link findEntryByValue} to search by predicate function.\n* @param map Map to search\n* @param value Value to seek\n* @param isEqual Filter function which checks equality. Uses JS comparer by default.\n* @returns Entry, or _undefined_ if `value` not found.\n*/\nconst findEntryByValue = (map, value, isEqual = isEqualDefault) => {\n\tfor (const entry of map.entries()) if (isEqual(entry[1], value)) return entry;\n};\n/**\n* Adds items to a map only if their key doesn't already exist\n*\n* Uses provided {@link ToString} function to create keys for items. Item is only added if it doesn't already exist.\n* Thus the older item wins out, versus normal `Map.set` where the newest wins.\n*\n* Returns a copy of the input map.\n* @example\n* ```js\n* const map = new Map();\n* const peopleArray = [ _some people objects..._];\n* addKeepingExisting(map, p => p.name, ...peopleArray);\n* ```\n* @param set\n* @param hasher\n* @param values\n* @returns\n*/\n/**\n* Mutates `map`, adding each value to it using a\n* function to produce a key. Use {@link addValue} for an immutable version.\n* ```\n* const map = new Map();\n* addValueMutate(map, v=>v.name, { name:`Jane`, size:10 }, { name:`Bob`, size: 9 });\n* // Map consists of entries:\n* // [ `Jane`, { name:`Jane`, size:10 } ],\n* // [ `Bob` { name:`Bob`, size: 9 } ]\n* ```\n* \n* Uses {@link addValueMutator} under the hood.\n* @param map Map to modify. If _undefined_, a new map is created\n* @param hasher Function to generate a string key for a given object value\n* @param values Values to add\n* @param collisionPolicy What to do if the key already exists\n* @returns Map instance\n*/\nconst addValueMutate = (map, hasher, collisionPolicy, ...values) => {\n\tconst m = map ?? /* @__PURE__ */ new Map();\n\taddValueMutator(m, hasher, collisionPolicy)(...values);\n\treturn m;\n};\n/**\n* Adds values to a map, returning a new, modified copy and leaving the original\n* intact.\n* \n* Use {@link addValueMutate} for a mutable \n* @param map Map to start with, or _undefined_ to automatically create a map \n* @param hasher Function to create keys for values\n* @param collisionPolicy What to do if a key already exists\n* @param values Values to add\n* @returns A new map containing values\n*/\nconst addValue = (map, hasher, collisionPolicy, ...values) => {\n\tconst m = map === void 0 ? /* @__PURE__ */ new Map() : new Map(map);\n\tfor (const v of values) {\n\t\tconst hashResult = hasher(v);\n\t\tif (collisionPolicy !== `overwrite`) {\n\t\t\tif (m.has(hashResult)) {\n\t\t\t\tif (collisionPolicy === `throw`) throw new Error(`Key '${hashResult}' already in map`);\n\t\t\t\tif (collisionPolicy === `skip`) continue;\n\t\t\t}\n\t\t}\n\t\tm.set(hashResult, v);\n\t}\n\treturn m;\n};\n/**\n* Returns a function that adds values to a map, using a hashing function to produce a key.\n* Use {@link addValueMutate} if you don't need a reusable function.\n* \n* ```js\n* const map = new Map(); // Create map\n* const mutate = addValueMutator(map, v=>v.name); // Create a mutator using default 'overwrite' policy\n* mutate( { name:`Bob`, size:10 }, { name: `Alice`, size: 2 }); // Add values to map\n* mutate( {name: `Bob`, size: 11 }); // Change the value stored under key `Bob`.\n* map.get(`Bob`); // { name: `Bob`, size: 11 }\n* ```\n* \n* The 'collision policy' determines what to do if the key already exists. The default behaviour\n* is to overwrite the key, just as Map.set would.\n* ```js\n* const map = new Map();\n* const mutate = addValueMutator(map, v=>v.name, `skip`);\n* mutate( { name:`Bob`,size:10 }, { name: `Alice`, size: 2 }); // Add values to map\n* mutate( { name:`Bob`, size: 20 }); // This value would be skipped because map already contains 'Bob'\n* map.get(`Bob`); // { name: `Bob`, size: 10 }\n* ``` \n*\n* @param map Map to modify\n* @param hasher Hashing function to make a key for a value\n* @param collisionPolicy What to do if a value is already stored under a key\n* @returns Function\n*/\nconst addValueMutator = (map, hasher, collisionPolicy = `overwrite`) => {\n\treturn (...values) => {\n\t\tfor (const v of values) {\n\t\t\tconst hashResult = hasher(v);\n\t\t\tif (collisionPolicy !== `overwrite`) {\n\t\t\t\tif (map.has(hashResult)) {\n\t\t\t\t\tif (collisionPolicy === `throw`) throw new Error(`Key '${hashResult}' already in map`);\n\t\t\t\t\tif (collisionPolicy === `skip`) continue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tmap.set(hashResult, v);\n\t\t}\n\t\treturn map;\n\t};\n};\n/**\n* Returns a array of entries from a map, sorted by value.\n*\n* ```js\n* const m = new Map();\n* m.set(`4491`, { name: `Bob` });\n* m.set(`2319`, { name: `Alice` });\n*\n* // Compare by name\n* const comparer = (a, b) => defaultComparer(a.name, b.name);\n*\n* // Get sorted values\n* const sorted = Maps.sortByValue(m, comparer);\n* ```\n*\n* `sortByValue` takes a comparison function that should return -1, 0 or 1 to indicate order of `a` to `b`.\n* @param map\n* @param comparer\n* @returns\n*/\nconst sortByValue = (map, comparer) => {\n\tconst f = comparer ?? defaultComparer;\n\treturn [...map.entries()].sort((a, b) => f(a[1], b[1]));\n};\n/**\n* Returns an array of entries from a map, sorted by a property of the value\n*\n* ```js\n* const m = new Map();\n* m.set(`4491`, { name: `Bob` });\n* m.set(`2319`, { name: `Alice` });\n* const sorted = sortByValueProperty(m, `name`);\n* ```\n* @param map Map to sort\n* @param property Property of value\n* @param compareFunction Comparer. If unspecified, uses a default.\n*/\nconst sortByValueProperty = (map, property, compareFunction) => {\n\tconst cfn = typeof compareFunction === `undefined` ? defaultComparer : compareFunction;\n\treturn [...map.entries()].sort((aE, bE) => {\n\t\tconst a = aE[1];\n\t\tconst b = bE[1];\n\t\treturn cfn(a[property], b[property]);\n\t});\n};\n/**\n* Returns _true_ if any key contains `value`, based on the provided `comparer` function. Use {@link hasKeyValue}\n* if you only want to find a value under a certain key.\n*\n* Having a comparer function is useful to check by value rather than object reference.\n* @example Finds value where name is 'samantha', regardless of other properties\n* ```js\n* hasAnyValue(map, {name:`samantha`}, (a, b) => a.name === b.name);\n* ```\n*\n* Works by comparing `value` against all values contained in `map` for equality using the provided `comparer`.\n*\n* @param map Map to search\n* @param value Value to find\n* @param comparer Function that determines matching. Should return true if `a` and `b` are considered equal.\n* @returns True if value is found\n*/\nconst hasAnyValue = (map, value, comparer) => {\n\treturn [...map.entries()].some((kv) => comparer(kv[1], value));\n};\n/**\n* Returns values where `predicate` returns true.\n*\n* If you just want the first match, use `find`\n*\n* @example All people over thirty\n* ```js\n* // for-of loop\n* for (const v of filterValues(people, person => person.age > 30)) {\n*\n* }\n* // If you want an array\n* const overThirty = Array.from(filterValues(people, person => person.age > 30));\n* ```\n* @param map Map\n* @param predicate Filtering predicate\n* @returns Values that match predicate\n*/\nfunction* filterValues(map, predicate) {\n\tfor (const v of map.values()) if (predicate(v)) yield v;\n}\n/**\n* Copies data to an array\n* @param map\n* @returns\n*/\nconst toArray = (map) => [...map.values()];\n/**\n* Returns a Map from an iterable. By default throws an exception\n* if iterable contains duplicate values.\n*\n* ```js\n* const data = [\n* { fruit: `granny-smith`, family: `apple`, colour: `green` },\n* { fruit: `mango`, family: `stone-fruit`, colour: `orange` }\n* ];\n* const map = fromIterable(data, v => v.fruit);\n* map.get(`granny-smith`); // { fruit: `granny-smith`, family: `apple`, colour: `green` }\n* ```\n* @param data Input data\n* @param keyFunction Function which returns a string id. By default uses the JSON value of the object.\n* @param collisionPolicy By default, values with same key overwrite previous (`overwrite`)\n* @returns\n*/\nconst fromIterable = (data, keyFunction = toStringDefault, collisionPolicy = `overwrite`) => {\n\tconst m = /* @__PURE__ */ new Map();\n\tfor (const d of data) {\n\t\tconst key = keyFunction(d);\n\t\tif (m.has(key)) {\n\t\t\tif (collisionPolicy === `throw`) throw new Error(`Key '${key}' is already used and new data will overwrite it. `);\n\t\t\tif (collisionPolicy === `skip`) continue;\n\t\t}\n\t\tm.set(key, d);\n\t}\n\treturn m;\n};\n/**\n* Returns a Map from an object, or array of objects.\n* Assumes the top-level properties of the object is the key.\n*\n* ```js\n* const data = {\n* Sally: { name: `Sally`, colour: `red` },\n* Bob: { name: `Bob`, colour: `pink` }\n* };\n* const map = fromObject(data);\n* map.get(`Sally`); // { name: `Sally`, colour: `red` }\n* ```\n*\n* To add an object to an existing map, use {@link addObjectEntriesMutate}.\n* @param data\n* @returns\n*/\nconst fromObject = (data) => {\n\tconst map = /* @__PURE__ */ new Map();\n\tif (Array.isArray(data)) for (const d of data) addObjectEntriesMutate(map, d);\n\telse addObjectEntriesMutate(map, data);\n\treturn map;\n};\n/**\n* Adds an object to an existing map, mutating it. \n* It assumes a structure where each top-level property is a key:\n*\n* ```js\n* const data = {\n* Sally: { colour: `red` },\n* Bob: { colour: `pink` }\n* };\n* const map = new Map();\n* addObjectEntriesMutate(map, data);\n*\n* map.get(`Sally`); // { name: `Sally`, colour: `red` }\n* ```\n*\n* To create a new map from an object, use {@link fromObject} instead.\n* @param map\n* @param data\n*/\nconst addObjectEntriesMutate = (map, data) => {\n\tconst entries = Object.entries(data);\n\tfor (const [key, value] of entries) map.set(key, value);\n};\n/**\n* Returns the first found value that matches `predicate` or _undefined_.\n* To get an entry see {@link findEntryByPredicate}\n*\n* Use {@link some} if you don't care about the value, just whether it appears.\n* Use {@link filterValues} to get all value(s) that match `predicate`.\n*\n* @example First person over thirty\n* ```js\n* const overThirty = findValue(people, person => person.age > 30);\n* ```\n* @param map Map to search\n* @param predicate Function that returns true for a matching value\n* @returns Found value or _undefined_\n*/\nconst findValue = (map, predicate) => [...map.values()].find((v) => predicate(v));\n/**\n* Returns _true_ if `predicate` yields _true_ for any value in `map`.\n* Use {@link findValue} if you want the matched value.\n* ```js\n* const map = new Map();\n* map.set(`fruit`, `apple`);\n* map.set(`colour`, `red`);\n* Maps.some(map, v => v === `red`); // true\n* Maps.some(map, v => v === `orange`); // false\n* ```\n* @param map \n* @param predicate \n* @returns \n*/\nconst some = (map, predicate) => [...map.values()].some((v) => predicate(v));\n/**\n* Converts a map to a simple object, transforming from type `T` to `K` as it does so. If no transforms are needed, use {@link toObject}.\n*\n* ```js\n* const map = new Map();\n* map.set(`name`, `Alice`);\n* map.set(`pet`, `dog`);\n*\n* const o = mapToObjectTransform(map, v => {\n* ...v,\n* registered: true\n* });\n*\n* // Yields: { name: `Alice`, pet: `dog`, registered: true }\n* ```\n*\n* If the goal is to create a new map with transformed values, use {@link transformMap}.\n* @param m\n* @param valueTransform\n* @typeParam T Value type of input map\n* @typeParam K Value type of destination map\n* @returns\n*/\nconst mapToObjectTransform = (m, valueTransform) => [...m].reduce((object, [key, value]) => {\n\tobject[key] = valueTransform(value);\n\treturn object;\n}, {});\n/**\n* Zips together an array of keys and values into an object. Requires that\n* `keys` and `values` are the same length.\n*\n* @example\n* ```js\n* const o = zipKeyValue([`a`, `b`, `c`], [0, 1, 2])\n* Yields: { a: 0, b: 1, c: 2}\n*```\n* @param keys String keys\n* @param values Values\n* @typeParam V Type of values\n* @return Object with keys and values\n*/\nconst zipKeyValue = (keys, values) => {\n\tif (keys.length !== values.length) throw new Error(`Keys and values arrays should be same length`);\n\treturn Object.fromEntries(keys.map((k, index) => [k, values[index]]));\n};\n/**\n* Like `Array.map`, but for a Map. Transforms from Map<K,V> to Map<K,R>, returning as a new Map.\n*\n* @example\n* ```js\n* const mapOfStrings = new Map();\n* mapOfStrings.set(`a`, `10`);\n* mapOfStrings.get(`a`); // Yields `10` (a string)\n*\n* // Convert a map of string->string to string->number\n* const mapOfInts = transformMap(mapOfStrings, (value, key) => parseInt(value));\n*\n* mapOfInts.get(`a`); // Yields 10 (a proper number)\n* ```\n*\n* If you want to combine values into a single object, consider instead {@link mapToObjectTransform}.\n* @param source\n* @param transformer\n* @typeParam K Type of keys (generally a string)\n* @typeParam V Type of input map values\n* @typeParam R Type of output map values\n* @returns\n*/\nconst transformMap = (source, transformer) => new Map(Array.from(source, (v) => [v[0], transformer(v[1], v[0])]));\n/**\n* Converts a `Map` to a plain object, useful for serializing to JSON.\n* To convert back to a map use {@link fromObject}.\n*\n* @example\n* ```js\n* const map = new Map();\n* map.set(`Sally`, { name: `Sally`, colour: `red` });\n* map.set(`Bob`, { name: `Bob`, colour: `pink });\n*\n* const objects = Maps.toObject(map);\n* // Yields: {\n* // Sally: { name: `Sally`, colour: `red` },\n* // Bob: { name: `Bob`, colour: `pink` }\n* // }\n* ```\n* @param m\n* @returns\n*/\nconst toObject = (m) => [...m].reduce((object, [key, value]) => {\n\tobject[key] = value;\n\treturn object;\n}, {});\n/**\n* Converts Map to Array with a provided `transformer` function. Useful for plucking out certain properties\n* from contained values and for creating a new map based on transformed values from an input map.\n*\n* @example Get an array of ages from a map of Person objects\n* ```js\n* const person = { age: 29, name: `John`};\n* map.set(person.name, person);\n*\n* const ages = mapToArray(map, (key, person) => person.age);\n* // [29, ...]\n* ```\n*\n* In the above example, the `transformer` function returns a number, but it could\n* just as well return a transformed version of the input:\n*\n* ```js\n* // Return with random heights and uppercased name\n* mapToArray(map, (key, person) => ({\n* ...person,\n* height: Math.random(),\n* name: person.name.toUpperCase();\n* }))\n* // Yields:\n* // [{height: 0.12, age: 29, name: \"JOHN\"}, ...]\n* ```\n* @param m\n* @param transformer A function that takes a key and item, returning a new item.\n* @returns\n*/\nconst mapToArray = (m, transformer) => [...m.entries()].map((x) => transformer(x[0], x[1]));\n/**\n* Merges maps left to right, using the provided\n* `reconcile` function to choose a winner when keys overlap.\n*\n* There's also @ixfx/arrays/mergeByKey if you don't already have a map.\n*\n* For example, if we have the map A:\n* 1 => `A-1`, 2 => `A-2`, 3 => `A-3`\n*\n* And map B:\n* 1 => `B-1`, 2 => `B-2`, 4 => `B-4`\n*\n* If they are merged with the reconile function:\n* ```js\n* const reconcile = (a, b) => b.replace(`-`, `!`);\n* const output = mergeByKey(reconcile, mapA, mapB);\n* ```\n*\n* The final result will be:\n*\n* 1 => `B!1`, 2 => `B!2`, 3 => `A-3`, 4 => `B-4`\n*\n* In this toy example, it's obvious how the reconciler transforms\n* data where the keys overlap. For the keys that do not overlap -\n* 3 and 4 in this example - they are copied unaltered.\n*\n* A practical use for `mergeByKey` has been in smoothing keypoints\n* from a TensorFlow pose. In this case, we want to smooth new keypoints\n* with older keypoints. But if a keypoint is not present, for it to be\n* passed through.\n*\n* @param reconcile\n* @param maps\n*/\nconst mergeByKey = (reconcile, ...maps) => {\n\tconst result = /* @__PURE__ */ new Map();\n\tfor (const m of maps) for (const [mk, mv] of m) {\n\t\tlet v = result.get(mk);\n\t\tv = v ? reconcile(v, mv) : mv;\n\t\tresult.set(mk, v);\n\t}\n\treturn result;\n};\n/**\n* @inheritDoc getOrGenerate\n* @param map\n* @param fn\n* @returns\n*/\nconst getOrGenerateSync = (map, fn) => (key, args) => {\n\tlet value = map.get(key);\n\tif (value !== void 0) return value;\n\tvalue = fn(key, args);\n\tmap.set(key, value);\n\treturn value;\n};\n/**\n* Returns a function that fetches a value from a map, or generates and sets it if not present.\n* Undefined is never returned, because if `fn` yields that, an error is thrown.\n*\n* See {@link getOrGenerateSync} for a synchronous version.\n*\n* ```\n* const m = getOrGenerate(new Map(), (key) => {\n* return key.toUppercase();\n* });\n*\n* // Not contained in map, so it will run the uppercase function,\n* // setting the value to the key 'hello'.\n* const v = await m(`hello`); // Yields 'HELLO'\n* const v1 = await m(`hello`); // Value exists, so it is returned ('HELLO')\n* ```\n*\n*/\nconst getOrGenerate = (map, fn) => async (key, args) => {\n\tlet value = map.get(key);\n\tif (value !== void 0) return value;\n\tvalue = await fn(key, args);\n\tif (value === void 0) throw new Error(`fn returned undefined`);\n\tmap.set(key, value);\n\treturn value;\n};\n//#endregion\nexport { isEqualContextString as A, defaultToString as B, sortByValue as C, transformMap as D, toObject as E, toStringOrdered as F, isSet as H, comparerInverse as I, defaultComparer as L, isEqualValueDefault as M, isEqualValueIgnoreOrder as N, zipKeyValue as O, isEqualValuePartial as P, jsComparer as R, some as S, toArray as T, toStringDefault as U, isMap as V, removeCircularReferences as W, hasKeyValue as _, deleteByValueCompareMutate as a, maps_exports as b, findEntryByPredicate as c, fromIterable as d, fromObject as f, hasAnyValue as g, getOrGenerateSync as h, addValueMutator as i, isEqualDefault as j, isEmptyEntries as k, findEntryByValue as l, getOrGenerate as m, addValue as n, filterValues as o, getClosestIntegerKey as p, addValueMutate as r, findBySomeKey as s, addObjectEntriesMutate as t, findValue as u, mapToArray as v, sortByValueProperty as w, mergeByKey as x, mapToObjectTransform as y, numericComparer as z };\n","import { integerTest, resultThrow } from \"@ixfx/guards\";\n//#region src/text.ts\n/**\n* Returns chunks of `source`, broken up by `delimiter` (default '.').\n* \n* Whittles down from whole string to last token.\n* \n* If `delimiter` is not found, no results are yielded.\n* \n* ```js\n* stringSegmentsWholeToEnd(`a.b.c.d`);\n* // Yields:\n* // `a.b.c.d`\n* // `b.c.d`\n* // `c.d`\n* // `d`\n* ```\n* @param source \n* @param delimiter \n*/\nfunction* stringSegmentsWholeToEnd(source, delimiter = `.`) {\n\twhile (source.length > 0) {\n\t\tyield source;\n\t\tconst trimmed = afterMatch(source, delimiter);\n\t\tif (trimmed === source) break;\n\t\tsource = trimmed;\n\t}\n}\n/**\n* Returns chunks of `source`, broken up by `delimiter` (default '.').\n* \n* Starts with last token, builds to whole.\n* \n* If `delimiter` is not found, no results are yielded.\n* \n* ````js\n* stringSegmentsLastToWhole(`a.b.c.d`);\n* // Yields:\n* // `d`\n* // `c.d`\n* // `b.c.d`\n* // `a.b.c.d`\n* ```\n* @param source \n* @param delimiter \n*/\nfunction* stringSegmentsLastToWhole(source, delimiter = `.`) {\n\tlet accumulator = ``;\n\tconst orig = source;\n\twhile (source.length > 0) {\n\t\tconst ba = beforeAfterMatch(source, delimiter, {\n\t\t\tfromEnd: true,\n\t\t\tifNoMatch: `original`\n\t\t});\n\t\tif (ba[0] === ba[1] && ba[1] === source) break;\n\t\tconst v = ba[1] + accumulator;\n\t\tyield v;\n\t\taccumulator = delimiter + v;\n\t\tsource = ba[0];\n\t}\n\tyield orig;\n}\n/**\n* Returns chunks of `source`, broken up by `delimiter` (default '.').\n* \n* We start with the first token and build up until end.\n* \n* If `delimiter` is not found, no results are yielded.\n* \n* ```js\n* stringSegmentsFirstToWhole(`a.b.c.d`);\n* // Yields:\n* // `a`\n* // `a.b`\n* // `a.b.c`\n* // `a.b.c.d`\n* ```\n* @param source \n* @param delimiter \n*/\nfunction* stringSegmentsFirstToWhole(source, delimiter = `.`) {\n\tlet accumulator = ``;\n\tconst orig = source;\n\twhile (source.length > 0) {\n\t\tconst ba = beforeAfterMatch(source, delimiter, { ifNoMatch: `original` });\n\t\tif (ba[0] === source && ba[1] === source) break;\n\t\taccumulator += ba[0];\n\t\tyield accumulator;\n\t\taccumulator += delimiter;\n\t\tsource = ba[1];\n\t}\n\tyield orig;\n}\n/**\n* Returns chunks of `source`, broken up by `delimiter` (default '.').\n* \n* We start with whole string and whittle down to starting token.\n* \n* If `delimiter` is not found, no results are yielded.\n* \n* ```js\n* stringSegmentsWholeToFirst(`a.b.c.d`);\n* // Yields:\n* // `a.b.c.d`\n* // `a.b.c`,\n* // `a.b`,\n* // `a`,\n* ```\n* @param source \n* @param delimiter \n*/\nfunction* stringSegmentsWholeToFirst(source, delimiter = `.`) {\n\twhile (source.length > 0) {\n\t\tyield source;\n\t\tconst b = beforeMatch(source, delimiter, {\n\t\t\tifNoMatch: `original`,\n\t\t\tfromEnd: true\n\t\t});\n\t\tif (b === source) break;\n\t\tsource = b;\n\t}\n}\n/**\n* Given a long string, abbreviates it with ...\n* ```js\n* abbreviate(`This is something`, 7); // `This is...`\n* ```\n* \n* If `source` is under `maxLength` the original is returned.\n* @param source \n* @param maxLength Maximum length. Defaults to 20\n* @returns \n*/\nconst abbreviate = (source, maxLength = 15) => {\n\tresultThrow(integerTest(maxLength, `aboveZero`, `maxLength`));\n\tif (typeof source !== `string`) throw new Error(`Parameter 'source' is not a string`);\n\tif (source.length > maxLength && source.length > 3) {\n\t\tif (maxLength > 15) {\n\t\t\tconst chunk = Math.round((maxLength - 2) / 2);\n\t\t\treturn source.slice(0, chunk) + `...` + source.slice(-chunk);\n\t\t}\n\t\treturn source.slice(0, maxLength) + `...`;\n\t}\n\treturn source;\n};\n/**\n* Uses JSON.toString() on `source`, but abbreviates result.\n* @param source Object to stringify\n* @param maxLength Default 20\n* @returns \n*/\nconst toStringAbbreviate = (source, maxLength = 20) => {\n\tif (source === void 0) return `(undefined)`;\n\tif (source === null) return `(null)`;\n\treturn abbreviate(JSON.stringify(source), maxLength);\n};\n/**\n* Returns source text that is between `start` and `end` match strings. Returns _undefined_ if start/end is not found.\n*\n* ```js\n* // Yields ` orange `;\n* between(`apple orange melon`, `apple`, `melon`);\n* ```\n* @param source Source text\n* @param start Start match\n* @param end If undefined, the `start` string will be looked for\n* @param lastEndMatch If true, looks for the last match of `end` (default). If false, looks for the first match.\n* @returns\n*/\nconst between = (source, start, end, lastEndMatch = true) => {\n\tconst startPos = source.indexOf(start);\n\tif (startPos < 0) return;\n\tif (typeof end === `undefined`) end = start;\n\tconst endPos = lastEndMatch ? source.lastIndexOf(end) : source.indexOf(end, startPos + 1);\n\tif (endPos < 0) return;\n\treturn source.slice(startPos + 1, endPos);\n};\n/**\n* Like {@link between}, but also returns the source string without the start/end match and what's between.\n* ```js\n* const [src,between] = betweenChomp('hello [there] friend', '[', ']');\n* // src: 'hello friend'\n* // between: 'there'\n* ```\n* @param source\n* @param start\n* @param end\n* @param lastEndMatch\n* @returns\n*/\nconst betweenChomp = (source, start, end, lastEndMatch = true) => {\n\tif (typeof source !== `string`) throw new Error(`Parameter 'source' is not a string`);\n\tif (typeof start !== `string`) throw new Error(`Parameter 'start' is not a string`);\n\tif (end !== void 0 && typeof end !== `string`) throw new Error(`Parameter 'end' is not a string`);\n\tconst startPos = source.indexOf(start);\n\tif (startPos < 0) return [source, void 0];\n\tif (typeof end === `undefined`) end = start;\n\tconst endPos = lastEndMatch ? source.lastIndexOf(end) : source.indexOf(end, startPos + 1);\n\tif (endPos < 0) return [source, void 0];\n\tconst between = source.slice(startPos + 1, endPos);\n\treturn [source.slice(0, startPos) + source.slice(endPos + 1), between];\n};\n/**\n* Returns first position of the given character code, or -1 if not found.\n* @param source Source string\n* @param code Code to seek\n* @param start Start index, 0 by default\n* @param end End index (inclusive), source.length-1 by default\n* @returns Found position, or -1 if not found\n*/\nconst indexOfCharCode = (source, code, start = 0, end = source.length - 1) => {\n\tfor (let index = start; index <= end; index++) if (source.codePointAt(index) === code) return index;\n\treturn -1;\n};\n/**\n* Returns `source` with a given number of characters removed from start position.\n*\n* ```js\n* // Remove three characters starting at position 1\n* omitChars(`hello there`, 1, 3); // ie. removes 'ell'\n* // Yields: `ho there`\n* ```\n* @param source\n* @param removeStart Start point to remove\n* @param removeLength Number of characters to remove\n* @returns\n*/\nconst omitChars = (source, removeStart, removeLength) => source.slice(0, removeStart) + source.slice(removeStart + removeLength);\n/**\n* Splits a string into `length`-size chunks.\n*\n* If `length` is greater than the length of `source`, a single element array is returned with source.\n* The final array element may be smaller if we ran out of characters.\n*\n* ```js\n* splitByLength(`hello there`, 2);\n* // Yields:\n* // [`he`, `ll`, `o `, `th`, `er`, `e`]\n* ```\n* @param source Source string\n* @param length Length of each chunk\n* @returns\n*/\nconst splitByLength = (source, length) => {\n\tresultThrow(integerTest(length, `aboveZero`, `length`));\n\tif (source === null) throw new Error(`source parameter null`);\n\tif (typeof source !== `string`) throw new TypeError(`source parameter not a string`);\n\tconst chunks = Math.ceil(source.length / length);\n\tconst returnValue = [];\n\tlet start = 0;\n\tfor (let c = 0; c < chunks; c++) {\n\t\treturnValue.push(source.slice(start, start + length));\n\t\tstart += length;\n\t}\n\treturn returnValue;\n};\n/**\n* Returns all the text in `source` that precedes (and does not include) `match`. If not found, `source` is returned.\n* \n* See also: {@link beforeMatch}, {@link beforeAfterMatch}.\n* \n* ```js\n* afterMatch(`Hello. There`, `.`); // ' There'\n* afterMatch(`Hello, there', `,`); // 'Hello, there'\n* ```\n* \n* If `source` is _undefined_, an error is thrown.\n* @param source\n* @param match\n* @param options\n* @returns\n*/\nconst beforeMatch = (source, match, options = {}) => {\n\treturn beforeAfterMatch(source, match, options)[0];\n};\n/**\n* Returns all the text in `source` that follows `match`. If not found, `source` is returned.\n* \n* See also: {@link beforeMatch}, {@link beforeAfterMatch}.\n* \n* ```js\n* afterMatch(`Hello. There`, `.`); // ' There'\n* afterMatch(`Hello, there', `,`); // 'Hello, there'\n* ```\n* \n* If `source` is _undefined_, an error is thrown.\n* @param source\n* @param match\n* @param options\n* @returns\n*/\nconst afterMatch = (source, match, options = {}) => {\n\treturn beforeAfterMatch(source, match, options)[1];\n};\n/**\n* Returns the text that is before and after `match`.\n* \n* See also: {@link beforeMatch}, {@link afterMatch}.\n* \n* If `match` is at the end of start of `source`, after or before might be an empty string.\n* @param source \n* @param match \n* @param options \n* @returns \n*/\nconst beforeAfterMatch = (source, match, options = {}) => {\n\tif (source === void 0) throw new Error(`Param 'source' is undefined`);\n\tlet fallback = options.fallback;\n\tconst ifNoMatch = options.ifNoMatch ?? (fallback ? `fallback` : `original`);\n\tif (ifNoMatch === `original`) fallback = source;\n\tif (ifNoMatch === `fallback` && fallback === void 0) throw new Error(`Fallback must be provided`);\n\tconst startPos = options.startPos ?? void 0;\n\tconst m = options.fromEnd ?? false ? source.lastIndexOf(match, startPos) : source.indexOf(match, startPos);\n\tif (m < 0 && ifNoMatch === `throw`) throw new Error(`Match '${match}' not found in source.`);\n\tif (m < 0 && ifNoMatch === `original`) return [source, source];\n\tif (m < 0 && ifNoMatch === `fallback`) return [fallback, fallback];\n\treturn [source.slice(0, m), source.slice(Math.max(0, m + match.length))];\n};\n/**\n* 'Unwraps' a string, removing one or more 'wrapper' strings that it starts and ends with.\n* Only removes when a matching end is found.\n* ```js\n* unwrap(\"'hello'\", \"'\"); // hello\n* // No mataching end 'a', so nothing happens\n* unwrap(\"apple\", \"a\"); // apple\n* unwrap(\"wow\", \"w\"); // o\n* unwrap(`\"'blah'\"`, '\"', \"'\"); // blah\n* ```\n* @param source\n* @param wrappers\n* @returns\n*/\nconst unwrap = (source, ...wrappers) => {\n\tlet matched = false;\n\tdo {\n\t\tmatched = false;\n\t\tfor (const w of wrappers) if (source.startsWith(w) && source.endsWith(w)) {\n\t\t\tsource = source.slice(w.length, source.length - w.length * 2 + 1);\n\t\t\tmatched = true;\n\t\t}\n\t} while (matched);\n\treturn source;\n};\n/**\n* Calculates the span, defined in {@link Range} indexes, that includes `start` through to `end` character positions.\n*\n* After using {@link splitRanges} to split text, `lineSpan` is used to associate some text coordinates with ranges.\n*\n* @param ranges Ranges\n* @param start Start character position, in source text reference\n* @param end End character position, in source text reference\n* @returns Span\n*/\nconst lineSpan = (ranges, start, end) => {\n\tlet s = -1;\n\tlet endPos = -1;\n\tfor (const [index, r] of ranges.entries()) {\n\t\ts = index;\n\t\tif (r.text.length === 0) continue;\n\t\tif (start < r.end) break;\n\t}\n\tfor (let index = s; index < ranges.length; index++) {\n\t\tconst r = ranges[index];\n\t\tendPos = index;\n\t\tif (end === r.end) {\n\t\t\tendPos = index + 1;\n\t\t\tbreak;\n\t\t}\n\t\tif (end < r.end) break;\n\t}\n\treturn {\n\t\tlength: endPos - s,\n\t\tstart: s,\n\t\tend: endPos\n\t};\n};\n/**\n* Splits a source string into ranges:\n* ```js\n* const ranges = splitRanges(\"hello;there;fella\", \";\");\n* ```\n*\n* Each range consists of:\n* ```js\n* {\n* text: string - the text of range\n* start: number - start pos of range, wrt to source\n* end: number - end pos of range, wrt to source\n* index: number - index of range (starting at 0)\n* }\n* ```\n* @param source\n* @param split\n* @returns\n*/\nconst splitRanges = (source, split) => {\n\tlet start = 0;\n\tlet text = ``;\n\tconst ranges = [];\n\tlet index = 0;\n\tfor (let index_ = 0; index_ < source.length; index_++) if (source.indexOf(split, index_) === index_) {\n\t\tconst end = index_;\n\t\tranges.push({\n\t\t\ttext,\n\t\t\tstart,\n\t\t\tend,\n\t\t\tindex\n\t\t});\n\t\tstart = end + 1;\n\t\ttext = ``;\n\t\tindex++;\n\t} else text += source.charAt(index_);\n\tif (start < source.length) ranges.push({\n\t\ttext,\n\t\tstart,\n\t\tindex,\n\t\tend: source.length\n\t});\n\treturn ranges;\n};\n/**\n* Counts the number of times one of `chars` appears at the front of\n* a string, contiguously.\n*\n* ```js\n* countCharsFromStart(` hi`, ` `); // 2\n* countCharsFromStart(`hi `, ` `); // 0\n* countCharsFromStart(` hi `, ` `); // 2\n* ```\n* @param source\n* @param chars\n* @returns\n*/\nconst countCharsFromStart = (source, ...chars) => {\n\tlet counted = 0;\n\tfor (let index = 0; index < source.length; index++) if (chars.includes(source.charAt(index))) counted++;\n\telse break;\n\treturn counted;\n};\n/**\n* Returns _true_ if `source` starts and ends with `start` and `end`. Case-sensitive.\n* If _end_ is omitted, the the `start` value will be used.\n*\n* ```js\n* startsEnds(`This is a string`, `This`, `string`); // True\n* startsEnds(`This is a string`, `is`, `a`); // False\n* starsEnds(`test`, `t`); // True, starts and ends with 't'\n* ```\n* @param source String to search within\n* @param start Start\n* @param end End (if omitted, start will be looked for at end as well)\n* @returns True if source starts and ends with provided values.\n*/\nconst startsEnds = (source, start, end = start) => source.startsWith(start) && source.endsWith(end);\nconst htmlEntities = (source) => source.replaceAll(/[&<>\\u00A0-\\u9999]/g, (index) => `&#${index.codePointAt(0)};`);\n/**\n* Simple wilcard matching. Use '*' in `pattern` to denote any number of characters.\n* ```js\n* // Must start with 'cat'\n* wildcard(`cat*`,`caterpillar`); // true\n* // Must end with 'cat'\n* wildcat(`*cat`, `bobcat`); // true\n* // 'cat' anywhere in string\n* wildcard(`*cat*`, `see cat run`); // true\n* ```\n* @param pattern \n* @returns \n*/\nconst wildcard = (pattern) => {\n\tconst escapeRegex = (value) => value.replaceAll(/([!$()*+./:=?[\\\\\\]^{|}])/g, `\\\\$1`);\n\tpattern = pattern.split(`*`).map((m) => escapeRegex(m)).join(`.*`);\n\tpattern = `^` + pattern + `$`;\n\tconst regex = new RegExp(pattern);\n\treturn (value) => {\n\t\treturn regex.test(value);\n\t};\n};\n//#endregion\nexport { abbreviate, afterMatch, beforeAfterMatch, beforeMatch, between, betweenChomp, countCharsFromStart, htmlEntities, indexOfCharCode, lineSpan, omitChars, splitByLength, splitRanges, startsEnds, stringSegmentsFirstToWhole, stringSegmentsLastToWhole, stringSegmentsWholeToEnd, stringSegmentsWholeToFirst, toStringAbbreviate, unwrap, wildcard };\n","import { t as __exportAll } from \"./chunk-pbuEa-1d.js\";\nimport { A as isEqualContextString, L as defaultComparer, U as toStringDefault, W as removeCircularReferences, j as isEqualDefault } from \"./maps-BqikhSVo.js\";\nimport { toStringAbbreviate } from \"./text.js\";\nimport { integerTest, nullUndefTest, numberTest, resultThrow, testPlainObjectOrPrimitive } from \"@ixfx/guards\";\nimport { getErrorMessage } from \"@ixfx/debug\";\n//#region src/records/clone-from-fields.ts\nconst cloneFromFields = (source) => {\n\tconst entries = [];\n\tfor (const field in source) {\n\t\tconst value = source[field];\n\t\tif (testPlainObjectOrPrimitive(value)) entries.push([field, value]);\n\t}\n\treturn Object.fromEntries(entries);\n};\n//#endregion\n//#region src/records/map-object-keys.ts\n/**\n* Maps the keys of an object, returning a transformed object.\n* ```js\n* const input = {\n* hello: `there`,\n* chap: `chappie`\n* }\n* \n* mapObjectKeys(input, key => key.toUppercase());\n* \n* // Yields: { HELLO: `there`, CHAP: `chappie` }\n* ```\n* @param object \n* @param mapFunction \n* @returns \n*/\nconst mapObjectKeys = (object, mapFunction) => {\n\tconst destinationObject = {};\n\tfor (const entries of Object.entries(object)) {\n\t\tconst key = mapFunction(entries[0]);\n\t\tdestinationObject[key] = entries[1];\n\t}\n\treturn destinationObject;\n};\n//#endregion\n//#region src/records/compare.ts\n/**\n* Compares the keys of two objects, returning a set of those in\n* common, and those in either A or B exclusively.\n* ```js\n* const a = { colour: `red`, intensity: 5 };\n* const b = { colour: `pink`, size: 10 };\n* const c = compareObjectKeys(a, b);\n* // c.shared = [ `colour` ]\n* // c.a = [ `intensity` ]\n* // c.b = [ `size` ]\n* ```\n* @param a \n* @param b \n* @returns \n*/\nconst compareObjectKeys = (a, b) => {\n\treturn compareIterableValuesShallow(Object.keys(a), Object.keys(b));\n};\n/**\n* Returns the changed fields from A -> B. It's assumed that A and B have the same shape.\n* ie. returns an object that only consists of fields which have changed in B compared to A.\n* \n* ```js\n* const a = { msg: `hi`, v: 10 };\n* \n* changedProperties(a, { msg: `hi`, v: 10 }); // {}\n* changedProperties(a, { msg: `hi!!`, v: 10 }); // { msg: `hi!!` }\n* changedProperties(a, { msg: `hi!!` }); // { msg: `hi!!`, v: undefined }\n* ```\n* \n* If B has additional or removed fields, this is considered an error.\n* \n* If a field is an array, the whole array is returned, rather than a diff.\n* @param a \n* @param b \n*/\nconst changedProperties = (a, b) => {\n\tconst r = compareObjectData(a, b, true);\n\tif (Object.entries(r.added).length > 0) throw new Error(`Shape of data has changed`);\n\tif (Object.entries(r.removed).length > 0) throw new Error(`Shape of data has changed`);\n\treturn compareResultToObject(r, b);\n};\nconst compareResultToObject = (r, b) => {\n\tconst output = {};\n\tif (r.isArray) return b;\n\tfor (const entry of Object.entries(r.changed)) output[entry[0]] = entry[1];\n\tfor (const entry of Object.entries(r.added)) output[entry[0]] = entry[1];\n\tfor (const childEntry of Object.entries(r.children)) {\n\t\tconst childResult = childEntry[1];\n\t\tif (childResult.hasChanged) output[childEntry[0]] = compareResultToObject(childResult, b[childEntry[0]]);\n\t}\n\treturn output;\n};\n/**\n* Produces a {@link CompareChangeSet} between two arrays.\n* \n* @param a Earlier array to compare\n* @param b Later array to compare\n* @param eq Equality comparison for values\n* @returns Change set.\n*/\nconst compareArrays = (a, b, eq = isEqualDefault) => {\n\tif (!Array.isArray(a)) throw new Error(`Param 'a' is not an array`);\n\tif (!Array.isArray(b)) throw new Error(`Param 'b' is not an array`);\n\tconst c = compareObjectData(a, b, false, eq);\n\tif (!c.isArray) throw new Error(`Change set does not have arrays as parameters`);\n\tconst convert = (key) => {\n\t\tif (key.startsWith(`_`)) return Number.parseInt(key.slice(1));\n\t\telse throw new Error(`Unexpected key '${key}'`);\n\t};\n\treturn {\n\t\t...c,\n\t\tadded: mapObjectKeys(c.added, convert),\n\t\tchanged: mapObjectKeys(c.changed, convert),\n\t\tremoved: c.removed.map((v) => convert(v)),\n\t\tsummary: c.summary.map((value) => {\n\t\t\treturn [\n\t\t\t\tvalue[0],\n\t\t\t\tconvert(value[1]),\n\t\t\t\tvalue[2]\n\t\t\t];\n\t\t})\n\t};\n};\n/**\n* Compares A to B. Assumes they are simple objects, essentially key-value pairs, where the \n* values are primitive values or other simple objects. It also works with arrays.\n* \n* Uses === equality semantics by default.\n* @param a \n* @param b \n*/\nconst compareObjectData = (a, b, assumeSameShape = false, eq = isEqualDefault) => {\n\ta ??= {};\n\tb ??= {};\n\tconst entriesA = Object.entries(a);\n\tconst entriesB = Object.entries(b);\n\tconst scannedKeys = /* @__PURE__ */ new Set();\n\tconst changed = {};\n\tconst added = {};\n\tconst children = {};\n\tconst removed = [];\n\tconst isArray = Array.isArray(a);\n\tconst summary = new Array();\n\tlet hasChanged = false;\n\tfor (const entry of entriesA) {\n\t\tconst outputKey = isArray ? `_${entry[0]}` : entry[0];\n\t\tconst aValue = entry[1];\n\t\tconst bValue = b[entry[0]];\n\t\tscannedKeys.add(entry[0]);\n\t\tif (bValue === void 0) {\n\t\t\thasChanged = true;\n\t\t\tif (assumeSameShape && !isArray) {\n\t\t\t\tchanged[outputKey] = bValue;\n\t\t\t\tsummary.push([\n\t\t\t\t\t`mutate`,\n\t\t\t\t\toutputKey,\n\t\t\t\t\tbValue\n\t\t\t\t]);\n\t\t\t} else {\n\t\t\t\tremoved.push(outputKey);\n\t\t\t\tsummary.push([\n\t\t\t\t\t`del`,\n\t\t\t\t\toutputKey,\n\t\t\t\t\taValue\n\t\t\t\t]);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof aValue === `object`) {\n\t\t\tconst r = compareObjectData(aValue, bValue, assumeSameShape, eq);\n\t\t\tif (r.hasChanged) hasChanged = true;\n\t\t\tchildren[outputKey] = r;\n\t\t\tconst childSummary = r.summary.map((sum) => {\n\t\t\t\treturn [\n\t\t\t\t\tsum[0],\n\t\t\t\t\toutputKey + `.` + sum[1],\n\t\t\t\t\tsum[2]\n\t\t\t\t];\n\t\t\t});\n\t\t\tsummary.push(...childSummary);\n\t\t} else if (!eq(aValue, bValue)) {\n\t\t\tchanged[outputKey] = bValue;\n\t\t\thasChanged = true;\n\t\t\tsummary.push([\n\t\t\t\t`mutate`,\n\t\t\t\toutputKey,\n\t\t\t\tbValue\n\t\t\t]);\n\t\t}\n\t}\n\tif (!assumeSameShape || isArray) for (const entry of entriesB) {\n\t\tconst key = isArray ? `_${entry[0]}` : entry[0];\n\t\tif (scannedKeys.has(entry[0])) continue;\n\t\tadded[key] = entry[1];\n\t\thasChanged = true;\n\t\tsummary.push([\n\t\t\t`add`,\n\t\t\tkey,\n\t\t\tentry[1]\n\t\t]);\n\t}\n\treturn {\n\t\tchanged,\n\t\tadded,\n\t\tremoved,\n\t\tchildren,\n\t\thasChanged,\n\t\tisArray,\n\t\tsummary\n\t};\n};\n//#endregion\n//#region src/records/keys-to-numbers.ts\n/**\n* Returns a copy of `object` with integer numbers as keys instead of whatever it has.\n* ```js\n* keysToNumbers({ '1': true }); // Yields: { 1: true }\n* ```\n* \n* The `onInvalidKey` sets how to handle keys that cannot be converted to integers.\n* * 'throw' (default): throws an exception\n* * 'ignore': that key & value is ignored\n* * 'keep': uses the string key instead\n* \n* \n* ```js\n* keysToNumber({ hello: 'there' }, `ignore`); // Yields: { }\n* keysToNumber({ hello: 'there' }, `throw`); // Exception\n* keysToNumber({ hello: 'there' }, `keep`); // Yields: { hello: 'there' }\n* ```\n* \n* Floating-point numbers will be converted to integer by rounding.\n* ```js\n* keysToNumbers({ '2.4': 'hello' }); // Yields: { 2: 'hello' }\n* ```\n* @param object \n* @param onInvalidKey \n* @returns \n*/\nconst keysToNumbers = (object, onInvalidKey = `throw`) => {\n\tconst returnObject = {};\n\tfor (const entry of Object.entries(object)) {\n\t\tconst asNumber = Number.parseInt(entry[0]);\n\t\tif (Number.isNaN(asNumber)) switch (onInvalidKey) {\n\t\t\tcase `throw`: throw new TypeError(`Cannot convert key '${entry[0]}' to an integer`);\n\t\t\tcase `ignore`: continue;\n\t\t\tcase `keep`:\n\t\t\t\treturnObject[entry[0]] = entry[1];\n\t\t\t\tcontinue;\n\t\t\tdefault: throw new Error(`Param 'onInvalidKey' should be: 'throw', 'ignore' or 'keep'.`);\n\t\t}\n\t\treturnObject[asNumber] = entry[1];\n\t}\n\treturn returnObject;\n};\n//#endregion\n//#region src/records/map-object.ts\n/**\n* Maps the top-level properties of an object through a map function.\n* That is, run each of the values of an object through a function,\n* setting the result onto the same key structure as original.\n* \n* It is NOT recursive.\n*\n* The mapping function gets a single args object, consisting of `{ value, field, index }`,\n* where 'value' is the value of the field, 'field' the name, and 'index' a numeric count.\n* @example Double the value of all fields\n* ```js\n* const rect = { width: 100, height: 250 };\n* const doubled = mapObjectShallow(rect, args => {\n* return args.value*2;\n* });\n* // Yields: { width: 200, height: 500 }\n* ```\n*\n* Since the map callback gets the name of the property, it can do context-dependent things.\n* ```js\n* const rect = { width: 100, height: 250, colour: 'red' }\n* const doubled = mapObjectShallow(rect, args => {\n* if (args.field === 'width') return args.value*3;\n* else if (typeof args.value === 'number') return args.value*2;\n* return args.value;\n* });\n* // Yields: { width: 300, height: 500, colour: 'red' }\n* ```\n* In addition to bulk processing, it allows remapping of property types.\n*\n* In terms of type-safety, the mapped properties are assumed to have the\n* same type.\n*\n* ```js\n* const o = {\n* x: 10,\n* y: 20,\n* width: 200,\n* height: 200\n* }\n*\n* // Make each property use an averager instead\n* const oAvg = mapObjectShallow(o, args => {\n* return movingAverage(10);\n* });\n*\n* // Instead of { x:number, y:number... }, we now have { x:movingAverage(), y:movingAverage()... }\n* // Add a value to the averager\n* oAvg.x.add(20);\n* ```\n*/\nconst mapObjectShallow = (object, mapFunction) => {\n\tconst mapped = Object.entries(object).map(([sourceField, sourceFieldValue], index) => [sourceField, mapFunction({\n\t\tvalue: sourceFieldValue,\n\t\tfield: sourceField,\n\t\tindex,\n\t\tpath: sourceField\n\t})]);\n\treturn Object.fromEntries(mapped);\n};\n/**\n* Maps the contents of `data` using `mapper` as a structured set of map functions.\n* ```js\n* const a = {\n* person: {\n* size: 20\n* }\n* hello: `there`\n* }\n* mapObjectByObject(a, {\n* person: {\n* size: (value, context) => {\n* return value * 2\n* }\n* }\n* });\n* // Yields: { person: { size: 40 }, hello: `there` }\n* ```\n* @param data \n* @param mapper \n* @returns \n*/\nfunction mapObjectByObject(data, mapper) {\n\tconst entries = Object.entries(data);\n\tfor (const entry of entries) if (entry[0] in mapper) {\n\t\tconst m = mapper[entry[0]];\n\t\tentry[1] = typeof m === `object` ? mapObjectByObject(entry[1], m) : m(entry[1], data);\n\t}\n\treturn Object.fromEntries(entries);\n}\n//#endregion\n//#region src/records/merge.ts\n/**\n* Merges objects together, the rightmost objects overriding properties of earlier objects.\n* \n* The return type is the intersection of all properties\n* ```js\n* const a = { name: `jane`, age: 30 };\n* const b = { name: `fred`, age: 31, colour: `blue` };\n* const c = merge(a, b);\n* // Yields:\n* // { name: `fred`, age: 31, colour: `blue` } \n* ```\n* \n* Alternatively, use {@link mergeSameShape} if the return shape\n* should be based on the first object.\n* @param a \n* @returns Merged object\n*/\nfunction merge(...a) {\n\treturn Object.assign({}, ...a);\n}\n/**\n* Merges objects together, conforming to the shape of the first object.\n* Properties contained on later objects are ignored if they aren't part of the first.\n* \n* If a single object is passed in, a copy is returned.\n* \n* Use {@link merge} for object shape to be a union\n* @param a Object arrays to merge\n* @returns \n*/\nfunction mergeSameShape(...a) {\n\tconst aEntries = Object.entries(a[0]);\n\tfor (let index = 1; index < a.length; index++) {\n\t\tconst bEntries = Object.entries(a[index]);\n\t\tfor (const [key, value] of bEntries) {\n\t\t\tconst aEntry = aEntries.find(([aKey]) => aKey === key);\n\t\t\tif (aEntry) aEntry[1] = value;\n\t\t}\n\t}\n\treturn Object.fromEntries(aEntries);\n}\n//#endregion\n//#region src/records/prefix.ts\n/**\n* Returns a new object based on `data` but with all\n* properties prefixed by `prefix`.\n* \n* ```js\n* prefixProperties({ name: `x`, size: 10 }, `test-`);\n* \n* // Yields:\n* // { test-name: `x`, test-size: 10 }\n* ```\n* @param data \n* @param prefix \n* @returns \n*/\nfunction prefixProperties(data, prefix) {\n\tconst changed = [];\n\tfor (const d of data) {\n\t\tconst entries = Object.entries(d);\n\t\tconst changedEntries = [];\n\t\tfor (const [key, value] of entries) changedEntries.push([prefix + key, value]);\n\t\tchanged.push(Object.fromEntries(changedEntries));\n\t}\n\treturn changed;\n}\n//#endregion\n//#region src/is-primitive.ts\n/**\n* Returns _true_ if `value` is number, string, bigint or boolean.\n* Returns _false_ if `value` is an object, null, undefined\n* \n* Use {@link isPrimitiveOrObject} to also return true if `value` is an object.\n* @param value Value to check\n* @returns _True_ if value is number, string, bigint or boolean.\n*/\nfunction isPrimitive(value) {\n\tif (typeof value === `number`) return true;\n\tif (typeof value === `string`) return true;\n\tif (typeof value === `bigint`) return true;\n\tif (typeof value === `boolean`) return true;\n\treturn false;\n}\n/**\n* Returns _true_ if `value` is number, string, bigint, boolean or an object\n* \n* Use {@link isPrimitive} to not include objects.\n* @param value\n* @returns \n*/\nfunction isPrimitiveOrObject(value) {\n\tif (isPrimitive(value)) return true;\n\tif (typeof value === `object`) return true;\n\treturn false;\n}\n//#endregion\n//#region src/records/traverse.ts\n/**\n* Helper function to get a 'friendly' string representation of an array of {@link RecordEntry}.\n* @param entries\n* @returns\n*/\nfunction prettyPrintEntries(entries) {\n\tif (entries.length === 0) return `(empty)`;\n\tlet t = ``;\n\tfor (const [index, entry] of entries.entries()) {\n\t\tt += ` `.repeat(index);\n\t\tt += `${entry.name} = ${JSON.stringify(entry.nodeValue)}\\n`;\n\t}\n\treturn t;\n}\n/**\n* Returns a human-friendly debug string for a tree-like structure\n* ```js\n* console.log(Trees.prettyPrint(obj));\n* ```\n* @param indent\n* @param node\n* @param options\n* @returns\n*/\nfunction recordEntryPrettyPrint(node, indent = 0, options = {}) {\n\tresultThrow(nullUndefTest(node, `node`));\n\tconst entry = getNamedRecordEntry(node, options.name ?? `node`);\n\tconst t = `${` `.repeat(indent)} + name: ${entry.name} value: ${JSON.stringify(entry.nodeValue)}`;\n\tconst childrenAsArray = [...recordChildren(node, options)];\n\treturn childrenAsArray.length > 0 ? `${t}\\n${childrenAsArray.map((d) => recordEntryPrettyPrint(d.nodeValue, indent + 1, {\n\t\t...options,\n\t\tname: d.name\n\t})).join(`\\n`)}` : t;\n}\n/**\n* Returns the direct children of a tree-like object as a pairing\n* of node name and value. Supports basic objects, Maps and arrays.\n*\n* Sub-children are included as an object blob.\n*\n* @example Simple object\n* ```js\n* const o = {\n* colour: {\n* r: 0.5, g: 0.5, b: 0.5\n* }\n* };\n*\n* const children = [ ...Trees.children(o) ];\n* // Children:\n* // [\n* // { name: \"colour\", value: { b: 0.5, g: 0.5, r: 0.5 } }\n* // ]\n* const subChildren = [ ...Trees.children(o.colour) ];\n* // [ { name: \"r\", value: 0.5 }, { name: \"g\", value: 0.5 }, { name: \"b\", value: 0.5 } ]\n* ```\n*\n* Arrays are assigned a name based on index.\n* @example Arrays\n* ```js\n* const colours = [ { r: 1, g: 0, b: 0 }, { r: 0, g: 1, b: 0 }, { r: 0, g: 0, b: 1 } ];\n* // Children:\n* // [\n* // { name: \"array[0]\", value: {r:1,g:0,b:0} },\n* // { name: \"array[1]\", value: {r:0,g:1,b:0} },\n* // { name: \"array[2]\", value: {r:0,g:0,b:1} },\n* // ]\n* ```\n*\n* Pass in `options.name` (eg 'colours') to have names generated as 'colours[0]', etc.\n* Options can also be used to filter children. By default all direct children are returned.\n* @param node\n* @param options\n*/\nfunction* recordChildren(node, options = {}) {\n\tresultThrow(nullUndefTest(node, `node`));\n\tconst filter = options.filter ?? `none`;\n\tconst filterByValue = (v) => {\n\t\tif (filter === `none`) return [true, isPrimitive(v)];\n\t\telse if (filter === `leaves` && isPrimitive(v)) return [true, true];\n\t\telse if (filter === `branches` && !isPrimitive(v)) return [true, false];\n\t\treturn [false, isPrimitive(v)];\n\t};\n\tif (Array.isArray(node)) for (const [index, element] of node.entries()) {\n\t\tconst f = filterByValue(element);\n\t\tif (f[0]) yield {\n\t\t\tname: index.toString(),\n\t\t\tsourceValue: element,\n\t\t\tnodeValue: f[1] ? element : void 0\n\t\t};\n\t}\n\telse if (typeof node === `object`) if (options.withPrototype) for (const name in node) {\n\t\tconst value = node[name];\n\t\tconst f = filterByValue(value);\n\t\tif (f[0]) yield {\n\t\t\tname,\n\t\t\tsourceValue: value,\n\t\t\tnodeValue: f[1] ? value : void 0\n\t\t};\n\t}\n\telse {\n\t\tconst entriesIter = `entries` in node ? node.entries() : Object.entries(node);\n\t\tfor (const [name, value] of entriesIter) {\n\t\t\tconst f = filterByValue(value);\n\t\t\tif (f[0]) yield {\n\t\t\t\tname,\n\t\t\t\tsourceValue: value,\n\t\t\t\tnodeValue: f[1] ? value : void 0\n\t\t\t};\n\t\t}\n\t}\n}\nfunction* recordEntriesDepthFirst(node, options = {}, ancestors = []) {\n\tif (node === null || node === void 0) return;\n\tconst opts = {\n\t\tfilter: options.filter ?? `none`,\n\t\tname: options.name ?? ``,\n\t\twithPrototype: options.withPrototype ?? false,\n\t\tseen: options.seen ?? /* @__PURE__ */ new WeakSet()\n\t};\n\tif (typeof node === `object`) {\n\t\tif (opts.seen.has(node)) return;\n\t\topts.seen.add(node);\n\t}\n\tfor (const c of recordChildren(node, opts)) {\n\t\tyield {\n\t\t\t...c,\n\t\t\tancestors: [...ancestors]\n\t\t};\n\t\tyield* recordEntriesDepthFirst(c.sourceValue, opts, [...ancestors, c.name]);\n\t}\n}\n/**\n* Finds a given direct child by name\n* @param name\n* @param node\n* @returns\n*/\nfunction recordEntryChildByName(name, node) {\n\tfor (const d of recordChildren(node)) if (d.name === name) return d;\n}\n/**\n* Returns the closest matching entry, tracing `path` in an array, Map or simple object.\n* Returns an entry with _undefined_ value at the point where tracing stopped.\n* Use {@link traceRecordEntryByPath} to step through all the segments.\n*\n* ```js\n* const people = {\n* jane: {\n* address: {\n* postcode: 1000,\n* street: 'West St',\n* city: 'Blahville'\n* },\n* colour: 'red'\n* }\n* }\n* Trees.getByPath('jane.address.postcode', people); // '.' default separator\n* // ['postcode', 1000]\n* Trees.getByPath('jane.address.country.state', people);\n* // ['country', undefined] - since full path could not be resolved.\n* ```\n* @param path Path, eg `jane.address.postcode`\n* @param node Node to look within\n* @param options Options for parsing path. By default '.' is used as a separator\n* @returns\n*/\nfunction getRecordEntryByPath(path, node, options = {}) {\n\tconst paths = [...traceRecordEntryByPath(path, node, options)];\n\tif (paths.length === 0) throw new Error(`Could not trace path: ${path} `);\n\treturn paths.at(-1);\n}\n/**\n* Enumerates over children of `node` towards the node named in `path`.\n* This is useful if you want to get the interim steps to the target node.\n*\n* Use {@link getRecordEntryByPath} if you don't care about interim steps.\n*\n* ```js\n* const people = {\n* jane: {\n* address: {\n* postcode: 1000,\n* street: 'West St',\n* city: 'Blahville'\n* },\n* colour: 'red'\n* }\n* }\n* for (const p of Trees.traceByPath('jane.address.street', people)) {\n* // { name: \"jane\", value: { address: { postcode: 1000,street: 'West St', city: 'Blahville' }, colour: 'red'} },\n* // { name: \"address\", value: { postcode: 1000, street: 'West St', city: 'Blahville' } },\n* // { name: \"street\", value: \"West St\" } }\n* }\n* ```\n*\n* Results stop when the path can't be followed any further.\n* The last entry will have a name of the last sought path segment, and _undefined_ as its value.\n*\n* @param path Path to traverse\n* @param node Starting node\n* @param options Options for path traversal logic\n* @returns\n*/\nfunction* traceRecordEntryByPath(path, node, options = {}) {\n\tresultThrow(nullUndefTest(path, `path`), nullUndefTest(node, `node`));\n\tconst separator = options.separator ?? `.`;\n\tconst pathSplit = path.split(separator);\n\tconst ancestors = [];\n\tfor (const p of pathSplit) {\n\t\tconst entry = recordEntryChildByName(p, node);\n\t\tif (!entry) {\n\t\t\tyield {\n\t\t\t\tname: p,\n\t\t\t\tsourceValue: void 0,\n\t\t\t\tnodeValue: void 0,\n\t\t\t\tancestors\n\t\t\t};\n\t\t\treturn;\n\t\t}\n\t\tnode = entry.sourceValue;\n\t\tyield {\n\t\t\t...entry,\n\t\t\tancestors: [...ancestors]\n\t\t};\n\t\tancestors.push(p);\n\t}\n}\n/**\n* Generates a name for a node.\n* Uses the 'name' property if it exists, otherwise uses `defaultName`\n* @param node\n* @param defaultName\n* @returns\n*/\nfunction getNamedRecordEntry(node, defaultName = ``) {\n\tif (`name` in node && `nodeValue` in node && `sourceValue` in node) return node;\n\tif (`name` in node) return {\n\t\tname: node.name,\n\t\tnodeValue: node,\n\t\tsourceValue: node\n\t};\n\treturn {\n\t\tname: defaultName,\n\t\tnodeValue: node,\n\t\tsourceValue: node\n\t};\n}\n//#endregion\n//#region src/records/values.ts\n/**\n* Yields numerical values based on the an input of objects and the property to use.\n* \n* ```js\n* const data = [\n* { size: 10 }, { size: 20 }, { size: 0 }\n* ]\n* [...enumerateNumericalValues(data, `size`)]; // [ 10, 20, 0 ]\n* ```\n* \n* If any of objects has a non numerical value for `propertyName`, a TypeError is thrown.\n* @param records \n* @param propertyName \n* @returns \n*/\nfunction* enumerateNumericalValues(records, propertyName) {\n\tfor (const rec of records) {\n\t\tconst fieldValue = rec[propertyName];\n\t\tif (typeof fieldValue !== `number`) throw new TypeError(`Property value was not a number. Property: ${propertyName} Value: ${fieldValue} Type: ${typeof fieldValue}`);\n\t\tyield fieldValue;\n\t}\n}\n//#endregion\n//#region src/records/zip.ts\n/**\n* Merge corresponding objects from arrays. This is assuming objects at the same array indices are connected.\n* \n* Arrays must be the same length. When merging objects, the properties of later objects override those of earlier objects.\n* \n* ```js\n* const a = [ { name: `jane`, age: 30 }, { name: `bob`, age: 40 } ];\n* const b = [ { name: `fred`, colour: `red` }, { name: `johanne` } ];\n* const c = [...zip(a, b)];\n* // Yields:\n* // [\n* // { name: `fred`, age: 30, colour: `red` },\n* // { name: `johanne`, age: 40 }\n* // ]\n* ```\n* @param toMerge Arrays to merge\n* @throws {TypeError} If either parameter is not an array\n* @throws {TypeError} If the arrays are not of the same length\n* @returns Generator of merged records \n*/\nfunction* zip$1(...toMerge) {\n\tlet len = -1;\n\tfor (let index = 0; index < toMerge.length; index++) {\n\t\tif (!Array.isArray(toMerge[index])) throw new TypeError(`Value at index ${index} is not an array as expected`);\n\t\tif (len === -1) len = toMerge[index].length;\n\t\telse if (toMerge[index].length !== len) throw new TypeError(`Array length mismatch. Expected: ${len} Actual: ${toMerge[index].length} Array: ${index}`);\n\t}\n\tfor (let index = 0; index < len; index++) yield merge(...toMerge.map((arr) => arr[index]));\n}\n//#endregion\n//#region src/records.ts\nvar records_exports = /* @__PURE__ */ __exportAll({\n\tchangedProperties: () => changedProperties,\n\tcloneFromFields: () => cloneFromFields,\n\tcompareArrays: () => compareArrays,\n\tcompareObjectData: () => compareObjectData,\n\tcompareObjectKeys: () => compareObjectKeys,\n\tenumerateNumericalValues: () => enumerateNumericalValues,\n\tgetRecordEntryByPath: () => getRecordEntryByPath,\n\tkeysToNumbers: () => keysToNumbers,\n\tmapObjectByObject: () => mapObjectByObject,\n\tmapObjectKeys: () => mapObjectKeys,\n\tmapObjectShallow: () => mapObjectShallow,\n\tmerge: () => merge,\n\tmergeSameShape: () => mergeSameShape,\n\tprefixProperties: () => prefixProperties,\n\tprettyPrintEntries: () => prettyPrintEntries,\n\trecordChildren: () => recordChildren,\n\trecordEntriesDepthFirst: () => recordEntriesDepthFirst,\n\trecordEntryPrettyPrint: () => recordEntryPrettyPrint,\n\tremoveCircularReferences: () => removeCircularReferences,\n\ttraceRecordEntryByPath: () => traceRecordEntryByPath,\n\tzip: () => zip$1\n});\n//#endregion\n//#region src/pathed.ts\nvar pathed_exports = /* @__PURE__ */ __exportAll({\n\tapplyChanges: () => applyChanges,\n\tcompareData: () => compareData,\n\tgetField: () => getField,\n\tgetPaths: () => getPaths,\n\tgetPathsAndData: () => getPathsAndData,\n\tupdateByPath: () => updateByPath\n});\n/**\n* Get the entries for `target`.\n* \n* 'deep probe' uses alternative means to get entries of object, since `Object.entries`\n* can fail for some objects.\n* @param target Object to get entries from\n* @param deepProbe If true\n* @returns \n*/\nconst getEntries = (target, deepProbe) => {\n\tif (target === void 0) throw new Error(`Param 'target' is undefined`);\n\tif (target === null) throw new Error(`Param 'target' is null`);\n\tif (typeof target !== `object`) throw new Error(`Param 'target' is not an object (got: ${typeof target})`);\n\tif (deepProbe) {\n\t\tconst entries = [];\n\t\tfor (const field in target) {\n\t\t\tconst value = target[field];\n\t\t\tif (testPlainObjectOrPrimitive(value)) entries.push([field, value]);\n\t\t}\n\t\treturn entries;\n\t} else return Object.entries(target);\n};\n/**\n* Scans object, producing a list of changed fields where B's value (newer) differs from A (older).\n* \n* Options:\n* - `deepEntries` (_false_): If _false_ Object.entries are used to scan the object. However this won't work for some objects, eg event args, thus _true_ is needed.\n* - `eq` (JSON.stringify): By-value comparison function\n* - `includeMissingFromA` (_false): If _true_ includes fields present on B but missing on A.\n* - `asPartial` (_false): If _true_, treats B as a partial update to B. This means that things missing from B are not considered removals.\n* @param a 'Old' value\n* @param b 'New' value\n* @param options Options for comparison\n* @returns \n*/\nfunction* compareData(a, b, options = {}) {\n\tif (typeof a === `undefined`) {\n\t\tyield {\n\t\t\tpath: options.pathPrefix ?? ``,\n\t\t\tvalue: b,\n\t\t\tstate: `added`\n\t\t};\n\t\treturn;\n\t}\n\tif (typeof b === `undefined`) {\n\t\tyield {\n\t\t\tpath: options.pathPrefix ?? ``,\n\t\t\tprevious: a,\n\t\t\tvalue: void 0,\n\t\t\tstate: `removed`\n\t\t};\n\t\treturn;\n\t}\n\tconst asPartial = options.asPartial ?? false;\n\tconst skipInstances = options.skipInstances ?? /* @__PURE__ */ new WeakSet();\n\tconst undefinedValueMeansRemoved = options.undefinedValueMeansRemoved ?? false;\n\tconst pathPrefix = options.pathPrefix ?? ``;\n\tconst deepEntries = options.deepEntries ?? false;\n\tconst eq = options.eq ?? isEqualContextString;\n\tconst includeMissingFromA = options.includeMissingFromA ?? false;\n\tconst includeParents = options.includeParents ?? false;\n\tif (isPrimitive(a) && isPrimitive(b)) {\n\t\tif (a !== b) yield {\n\t\t\tpath: pathPrefix,\n\t\t\tvalue: b,\n\t\t\tprevious: a,\n\t\t\tstate: `change`\n\t\t};\n\t\treturn;\n\t}\n\tif (isPrimitive(b)) {\n\t\tyield {\n\t\t\tpath: pathPrefix,\n\t\t\tvalue: b,\n\t\t\tprevious: a,\n\t\t\tstate: `change`\n\t\t};\n\t\treturn;\n\t}\n\tconst entriesA = getEntries(a, deepEntries);\n\tconst entriesAKeys = /* @__PURE__ */ new Set();\n\tfor (const [key, valueA] of entriesA) {\n\t\tentriesAKeys.add(key);\n\t\tconst keyOfAInB = key in b;\n\t\tconst valueOfKeyInB = b[key];\n\t\tif (typeof valueA === `object` && valueA !== null) {\n\t\t\tif (skipInstances.has(valueA)) continue;\n\t\t\tskipInstances.add(valueA);\n\t\t\tif (keyOfAInB) if (valueOfKeyInB === void 0) throw new Error(`Pathed.compareData Value for key ${key} is undefined`);\n\t\t\telse {\n\t\t\t\tconst sub = [...compareData(valueA, valueOfKeyInB, {\n\t\t\t\t\t...options,\n\t\t\t\t\tskipInstances,\n\t\t\t\t\tpathPrefix: pathPrefix + key + `.`\n\t\t\t\t})];\n\t\t\t\tif (sub.length > 0) {\n\t\t\t\t\tfor (const s of sub) yield s;\n\t\t\t\t\tif (includeParents) yield {\n\t\t\t\t\t\tpath: pathPrefix + key,\n\t\t\t\t\t\tvalue: b[key],\n\t\t\t\t\t\tprevious: valueA,\n\t\t\t\t\t\tstate: `change`\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (asPartial) continue;\n\t\t\t\tyield {\n\t\t\t\t\tpath: pathPrefix + key,\n\t\t\t\t\tvalue: void 0,\n\t\t\t\t\tprevious: valueA,\n\t\t\t\t\tstate: `removed`\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\tconst subPath = pathPrefix + key;\n\t\t\tif (keyOfAInB) {\n\t\t\t\tif (valueOfKeyInB === void 0 && undefinedValueMeansRemoved) yield {\n\t\t\t\t\tpath: subPath,\n\t\t\t\t\tprevious: valueA,\n\t\t\t\t\tvalue: void 0,\n\t\t\t\t\tstate: `removed`\n\t\t\t\t};\n\t\t\t\telse if (!eq(valueA, valueOfKeyInB, subPath)) yield {\n\t\t\t\t\tpath: subPath,\n\t\t\t\t\tprevious: valueA,\n\t\t\t\t\tvalue: valueOfKeyInB,\n\t\t\t\t\tstate: `change`\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tif (asPartial) continue;\n\t\t\t\tyield {\n\t\t\t\t\tpath: subPath,\n\t\t\t\t\tprevious: valueA,\n\t\t\t\t\tvalue: void 0,\n\t\t\t\t\tstate: `removed`\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\tif (includeMissingFromA) {\n\t\tconst entriesB = getEntries(b, deepEntries);\n\t\tfor (const [key, valueB] of entriesB) {\n\t\t\tif (entriesAKeys.has(key)) continue;\n\t\t\tyield {\n\t\t\t\tpath: pathPrefix + key,\n\t\t\t\tprevious: void 0,\n\t\t\t\tvalue: valueB,\n\t\t\t\tstate: `added`\n\t\t\t};\n\t\t}\n\t}\n}\n/**\n* Returns a copy of `source` with `changes` applied.\n* @param source \n* @param changes \n*/\nconst applyChanges = (source, changes) => {\n\tfor (const change of changes) source = updateByPath(source, change.path, change.value);\n\treturn source;\n};\n/**\n* Returns a copy of `target` object with a specified path changed to `value`.\n* \n* ```js\n* const a = {\n* message: `Hello`,\n* position: { x: 10, y: 20 }\n* }\n* \n* const a1 = updateByPath(a, `message`, `new message`);\n* // a1 = { message: `new message`, position: { x: 10, y: 20 }}\n* const a2 = updateByPath(a, `position.x`, 20);\n* // a2 = { message: `hello`, position: { x: 20, y: 20 }}\n* ```\n* \n* Paths can also be array indexes:\n* ```js\n* updateByPath([`a`,`b`,`c`], 2, `d`);\n* // Yields: [ `a`, `b`, `d` ]\n* ```\n* \n* By default, only existing array indexes can be updated. Use the `allowShapeChange` parameter \n* to allow setting arbitrary indexes.\n* ```js\n* // Throws because array index 3 is undefined\n* updateByPath([ `a`, `b`, `c` ], `3`, `d`);\n* \n* // With allowShapeChange flag\n* updateByPath([ `a`, `b`, `c` ], `3`, `d`, true);\n* // Returns: [ `a`, `b`, `c`, `d` ]\n* ```\n* \n* Throws an error if:\n* * `path` cannot be resolved (eg. `position.z` in the above example)\n* * `value` applied to `target` results in the object having a different shape (eg missing a field, field\n* changing type, or array index out of bounds). Use `allowShapeChange` to suppress this error.\n* * Path is undefined or not a string\n* * Target is undefined/null\n* @param target Object to update\n* @param path Path to set value\n* @param value Value to set\n* @param allowShapeChange By default _false_, throwing an error if an update change the shape of the original object.\n* @returns \n*/\nconst updateByPath = (target, path, value, allowShapeChange = false) => {\n\tif (path === void 0) throw new Error(`Parameter 'path' is undefined`);\n\tif (typeof path !== `string`) throw new Error(`Parameter 'path' should be a string. Got: ${typeof path}`);\n\tif (target === void 0) throw new Error(`Parameter 'target' is undefined`);\n\tif (target === null) throw new Error(`Parameter 'target' is null`);\n\treturn updateByPathImpl(target, path.split(`.`), value, allowShapeChange);\n};\nconst updateByPathImpl = (o, split, value, allowShapeChange) => {\n\tif (split.length === 0) {\n\t\tif (allowShapeChange) return value;\n\t\tif (Array.isArray(o) && !Array.isArray(value)) throw new Error(`Expected array value, got: '${JSON.stringify(value)}'. Set allowShapeChange=true to ignore.`);\n\t\tif (!Array.isArray(o) && Array.isArray(value)) throw new Error(`Unexpected array value, got: '${JSON.stringify(value)}'. Set allowShapeChange=true to ignore.`);\n\t\tif (typeof o !== typeof value) throw new Error(`Cannot reassign object type. (${typeof o} -> ${typeof value}). Set allowShapeChange=true to ignore.`);\n\t\tif (typeof o === `object` && !Array.isArray(o)) {\n\t\t\tconst c = compareObjectKeys(o, value);\n\t\t\tif (c.a.length > 0) throw new Error(`New value is missing key(s): ${c.a.join(`,`)}`);\n\t\t\tif (c.b.length > 0) throw new Error(`New value cannot add new key(s): ${c.b.join(`,`)}`);\n\t\t}\n\t\treturn value;\n\t}\n\tconst start = split.shift();\n\tif (!start) return value;\n\tif (isInteger(start) && Array.isArray(o)) {\n\t\tconst index = Number.parseInt(start);\n\t\tif (index >= o.length && !allowShapeChange) throw new Error(`Array index ${index.toString()} is outside of the existing length of ${o.length.toString()}. Use allowShapeChange=true to permit this.`);\n\t\tconst copy = [...o];\n\t\tcopy[index] = updateByPathImpl(copy[index], split, value, allowShapeChange);\n\t\treturn copy;\n\t} else if (start in o) {\n\t\tconst copy = { ...o };\n\t\tcopy[start] = updateByPathImpl(copy[start], split, value, allowShapeChange);\n\t\treturn copy;\n\t} else throw new Error(`Path ${start} not found in data`);\n};\n/**\n* Gets the data at `path` in `object`. Assumes '.' separates each segment of path.\n* \n* ```js\n* getField({ name: { first: `Thom`, last: `Yorke` }}, `name.first`); // { value: `Thom` success: true }\n* getField({ colours: [`red`, `green`, `blue` ]}, `colours.1`); // { value: `green` success: true }\n* ```\n* \n* Returns an error result with more details, eg `{ success: false, error: 'Path could not be found' }`\n* \n* Throws if:\n* * `path` is not a string or empty\n* * `object` is _undefined_ or null\n* @param object Object to query\n* @param path Path\n* @param separator Separator of chunks of path. Defaults to '.'\n* @returns \n*/\nconst getField = (object, path, separator = `.`) => {\n\tif (typeof path !== `string`) throw new Error(`Param 'path' ought to be a string. Got: '${typeof path}'`);\n\tif (path.length === 0) throw new Error(`Param string 'path' is empty`);\n\tif (object === void 0) throw new Error(`Param 'object' is undefined`);\n\tif (object === null) throw new Error(`Param 'object' is null`);\n\treturn getFieldImpl(object, path.split(separator), path);\n};\nconst getFieldImpl = (object, split, position) => {\n\tif (object === void 0) return {\n\t\tsuccess: false,\n\t\terror: `Param 'object' is undefined. Position: ${position}`\n\t};\n\tif (split.length === 0) return {\n\t\tsuccess: false,\n\t\terror: `Path has been exhausted. position: ${position}`\n\t};\n\tconst start = split.shift();\n\tif (!start) return {\n\t\tsuccess: false,\n\t\terror: `Unexpected empty split path. Position: ${position}`\n\t};\n\tif (isInteger(start) && Array.isArray(object)) {\n\t\tconst index = Number.parseInt(start);\n\t\tif (typeof object[index] === `undefined`) return {\n\t\t\tsuccess: false,\n\t\t\terror: `Index '${index}' does not exist. Length: ${object.length}. Position: ${position}`\n\t\t};\n\t\tif (split.length === 0) return {\n\t\t\tvalue: object[index],\n\t\t\tsuccess: true\n\t\t};\n\t\telse return getFieldImpl(object[index], split, split.join(`.`));\n\t} else if (typeof object === `object` && start in object) if (split.length === 0) return {\n\t\tvalue: object[start],\n\t\tsuccess: true\n\t};\n\telse return getFieldImpl(object[start], split, split.join(`.`));\n\telse return {\n\t\tsuccess: false,\n\t\terror: `Path '${start}' not found. Position: ${position}`\n\t};\n};\n/**\n* Iterates 'paths' for all the fields on `o`\n* ```\n* const d = {\n* accel: { x: 1, y: 2, z: 3 },\n* gyro: { x: 4, y: 5, z: 6 }\n* };\n* const paths = [...getFieldPaths(d)];\n* // Yields [ `accel`, `gyro`, `accel.x`, `accel.y`,`accel.z`,`gyro.x`,`gyro.y`,`gyro.z` ]\n* ```\n*\n* Use {@link getField} to fetch data based on a path\n*\n* If object is _null_ or _undefined_, no results are returned.\n* \n* If `onlyLeaves` is _true_ (default: _false_), only 'leaf' nodes are included. \n* Leaf nodes are those that contain a primitive value.\n* ```js\n* const paths = getFieldPaths(d, true);\n* // Yields [ `accel.x`, `accel.y`,`accel.z`,`gyro.x`,`gyro.y`,`gyro.z` ]\n* ```\n*\n* Options:\n* * onlyLeaves: If _true_, only paths to 'leaf' nodes are included. Leaf nodes are those that contain a primitive value. Default: _false_\n* * withPrototype: If _true_, includes prototype chain. Default: _false_\n* @param object Object to get paths for.\n* @param options Options\n* @returns\n*/\nfunction* getPaths(object, options = {}) {\n\tconst onlyLeaves = options.onlyLeaves ?? false;\n\tif (object === void 0 || object === null) return;\n\tconst iter = recordEntriesDepthFirst(object, {\n\t\tseen: /* @__PURE__ */ new WeakSet(),\n\t\twithPrototype: false,\n\t\tonlyLeaves: false,\n\t\tfilter: `none`,\n\t\tname: ``,\n\t\t...options\n\t});\n\tconst rootName = options.rootName ? options.rootName + `.` : ``;\n\tfor (const c of iter) {\n\t\tif (c.nodeValue === void 0 && onlyLeaves) continue;\n\t\tlet path = rootName + c.name;\n\t\tif (c.ancestors.length > 0) path = c.ancestors.join(`.`) + `.` + path;\n\t\tyield path;\n\t}\n}\n/**\n* Returns a representation of the object as a set of paths and data.\n* ```js\n* const o = { name: `hello`, size: 20, colour: { r:200, g:100, b:40 } }\n* const pd = [...getPathsAndData(o)];\n* // Yields:\n* // [ \n* // { path: `name`, value: `hello` },\n* // { path: `size`, value: `20` },\n* // { path: `colour.r`, value: `200` },\n* // { path: `colour.g`, value: `100` },\n* // { path: `colour.b`, value: `40` }\n* //]\n* ```\n* @param o Object to get paths and data for\n* @param maxDepth Set maximum recursion depth. By default unlimited.\n* @param prefix Manually set a path prefix if it's necessary\n* @returns \n*/\nfunction* getPathsAndData(o, onlyLeaves = false, maxDepth = Number.MAX_SAFE_INTEGER, prefix = ``) {\n\tif (o === null) return;\n\tif (o === void 0) return;\n\tyield* getPathsAndDataImpl(o, prefix, onlyLeaves, maxDepth);\n}\nfunction* getPathsAndDataImpl(o, prefix, onlyLeaves = false, maxDepth) {\n\tif (maxDepth <= 0) return;\n\tif (typeof o !== `object`) return;\n\tfor (const entries of Object.entries(o)) {\n\t\tconst sub = (prefix.length > 0 ? prefix + `.` : ``) + entries[0];\n\t\tconst value = entries[1];\n\t\tif (onlyLeaves && typeof value !== `object` || !onlyLeaves) yield {\n\t\t\tpath: sub,\n\t\t\tvalue\n\t\t};\n\t\tyield* getPathsAndDataImpl(value, sub, onlyLeaves, maxDepth - 1);\n\t}\n}\n//#endregion\n//#region src/trackers/track-unique.ts\n/**\n* Tracks unique values. Returns _true_ if value is unique.\n* Alternatively: {@link uniqueInstances}\n* \n* ```js\n* const t = unique();\n* t(`hello`); // true\n* t(`hello`); // false\n* ```\n* \n* Uses JSON.stringify to compare anything which is not a string.\n* \n* Provide a custom function to convert to string to track uniqueness\n* for more complicated objects.\n* \n* ```js\n* const t = unique(p => p.name);\n* t({ name:`John`, level:2 }); // true\n* \n* // Since we're judging uniques by name only\n* t({ name:`John`, level:3 }); // false\n* ```\n* \n* Return function throws an error if `value` is null or undefined.\n* @returns \n*/\nconst unique = (toString = toStringDefault) => {\n\tconst set = /* @__PURE__ */ new Set();\n\treturn (value) => {\n\t\tif (value === null) throw new TypeError(`Param 'value' cannot be null`);\n\t\tif (value === void 0) throw new TypeError(`Param 'value' cannot be undefined`);\n\t\tconst asString = typeof value === `string` ? value : toString(value);\n\t\tif (set.has(asString)) return false;\n\t\tset.add(asString);\n\t\treturn true;\n\t};\n};\n/**\n* Tracks unique object instances. Returns _true_ if value is unique.\n* Alternatively: {@link unique} to track by value.\n*/\nconst uniqueInstances = () => {\n\tconst set = /* @__PURE__ */ new Set();\n\treturn (value) => {\n\t\tif (value === null) throw new TypeError(`Param 'value' cannot be null`);\n\t\tif (value === void 0) throw new TypeError(`Param 'value' cannot be undefined`);\n\t\tif (set.has(value)) return false;\n\t\tset.add(value);\n\t\treturn true;\n\t};\n};\n//#endregion\n//#region src/trackers.ts\nvar trackers_exports = /* @__PURE__ */ __exportAll({\n\tunique: () => unique,\n\tuniqueInstances: () => uniqueInstances\n});\n//#endregion\n//#region src/continuously.ts\n/**\n* Returns a {@link Continuously} that continually executes `callback` at `interval` rate.\n* \n* By default, first the sleep period happens and then the callback happens.\n*\n* Call `start` to begin/reset loop. The looping stops when `cancel` is called, or when `callback` returns _false_.\n*\n* @example\n* Animation loop\n* ```js\n* const draw = () => {\n* // Draw on canvas\n* }\n*\n* // Run draw() synchronised with monitor refresh rate via `window.requestAnimationFrame`\n* continuously(draw).start();\n* ```\n*\n* @example\n* With delay\n* ```js\n* const fn = () => {\n* // Runs after one minute\n* }\n* const c = continuously(fn, { mins: 1 } );\n* c.start(); // Runs `fn` every minute\n* ```\n*\n* @example\n* Control a 'continuously'\n* ```js\n* c.cancel(); // Stop the loop, cancelling any up-coming calls to `fn`\n* c.elapsedMs; // How many milliseconds have elapsed since start\n* c.ticks; // How many iterations of loop since start\n* c.interval; // Get/set speed of loop. Change kicks-in at next loop.\n* // Use .start() to reset to new interval immediately\n* ```\n*\n* Asynchronous callback functions are supported too:\n* ```js\n* continuously(async () => { ..});\n* ```\n*\n* The `callback` function can receive a few arguments:\n* \n* ```js\n* continuously( (ticks, elapsedMs) => {\n* // ticks: how many times loop has run\n* // elapsedMs: how long since last loop\n* }).start();\n* ```\n*\n* If the callback explicitly returns _false_, the loop will be cancelled.\n* \n* ```js\n* continuously(ticks => {\n* // Stop after 100 iterations\n* if (ticks > 100) return false;\n* }).start();\n* ```\n*\n* You can intercept the logic for calls to `start()` with `onStartCalled`. It can determine\n* whether the `start()` proceeds, if the loop is cancelled, or the whole thing disposed,\n* so it can't run any longer.\n* \n* ```js\n* continuously(callback, intervalMs, {\n* onStartCalled:(ticks, elapsedMs) => {\n* // Cancel the loop after 1000ms has elapsed\n* if (elapsedMs > 1000) return `cancel`;\n* }\n* }).start();\n* ```\n*\n* To run `callback` *before* the sleep happens, set `fireBeforeWait`:\n* ```js\n* continuously(callback, intervalMs, { fireBeforeWait: true });\n* ```\n* @param callback - Function to run. If it returns _false_, loop exits.\n* @param options - {@link ContinuouslyOpts ContinuouslyOpts}\n* @param interval - Speed of loop (default: 0)\n* @returns Instance to control looping.\n* @see Flow.timeout if you want to trigger something once.\n*/\nconst continuously = (callback, interval = 0, options = {}) => {\n\tlet intervalMs = intervalToMs(interval, 0);\n\tresultThrow(integerTest(intervalMs, `positive`, `interval`));\n\tconst fireBeforeWait = options.fireBeforeWait ?? false;\n\tconst onStartCalled = options.onStartCalled;\n\tconst signal = options.signal;\n\tlet disposed = false;\n\tlet runState = `idle`;\n\tlet startCount = 0;\n\tlet startCountTotal = 0;\n\tlet startedAt = performance.now();\n\tlet intervalUsed = interval ?? 0;\n\tlet cancelled = false;\n\tlet currentTimer;\n\tconst deschedule = () => {\n\t\tif (currentTimer === void 0) return;\n\t\tglobalThis.clearTimeout(currentTimer);\n\t\tcurrentTimer = void 0;\n\t\tstartCount = 0;\n\t\tstartedAt = NaN;\n\t};\n\tconst schedule = (scheduledCallback) => {\n\t\tif (intervalMs === 0) if (typeof requestAnimationFrame === `undefined`) currentTimer = globalThis.setTimeout(scheduledCallback, 0);\n\t\telse {\n\t\t\tcurrentTimer = void 0;\n\t\t\trequestAnimationFrame(scheduledCallback);\n\t\t}\n\t\telse currentTimer = globalThis.setTimeout(scheduledCallback, intervalMs);\n\t};\n\tconst cancel = () => {\n\t\tif (cancelled) return;\n\t\tcancelled = true;\n\t\tif (runState === `idle`) return;\n\t\trunState = `idle`;\n\t\tdeschedule();\n\t};\n\tconst loop = async () => {\n\t\tif (signal?.aborted) runState = `idle`;\n\t\tif (runState === `idle`) return;\n\t\trunState = `running`;\n\t\tstartCount++;\n\t\tstartCountTotal++;\n\t\tconst valueOrPromise = callback(startCount, performance.now() - startedAt);\n\t\tconst value = typeof valueOrPromise === `object` ? await valueOrPromise : valueOrPromise;\n\t\tif (cancelled) return;\n\t\trunState = `scheduled`;\n\t\tif (value !== void 0 && !value) {\n\t\t\tcancel();\n\t\t\treturn;\n\t\t}\n\t\tif (cancelled) return;\n\t\tschedule(loop);\n\t};\n\tconst start = () => {\n\t\tif (disposed) throw new Error(`Disposed`);\n\t\tcancelled = false;\n\t\tif (onStartCalled !== void 0) switch (onStartCalled(startCount, performance.now() - startedAt)) {\n\t\t\tcase `cancel`:\n\t\t\t\tcancel();\n\t\t\t\treturn;\n\t\t\tcase `reset`:\n\t\t\t\treset();\n\t\t\t\treturn;\n\t\t\tcase `dispose`:\n\t\t\t\tdisposed = true;\n\t\t\t\tcancel();\n\t\t\t\treturn;\n\t\t}\n\t\tif (runState === `idle`) {\n\t\t\tstartCount = 0;\n\t\t\tstartedAt = performance.now();\n\t\t\trunState = `scheduled`;\n\t\t\tif (fireBeforeWait) loop();\n\t\t\telse schedule(loop);\n\t\t}\n\t};\n\tconst reset = () => {\n\t\tif (disposed) throw new Error(`Disposed`);\n\t\tcancelled = false;\n\t\tstartCount = 0;\n\t\tstartedAt = NaN;\n\t\tif (runState !== `idle`) cancel();\n\t\tstart();\n\t};\n\treturn {\n\t\tstart,\n\t\treset,\n\t\tcancel,\n\t\tget interval() {\n\t\t\treturn intervalUsed;\n\t\t},\n\t\tget runState() {\n\t\t\treturn runState;\n\t\t},\n\t\tget startCountTotal() {\n\t\t\treturn startCountTotal;\n\t\t},\n\t\tget startCount() {\n\t\t\treturn startCount;\n\t\t},\n\t\tset interval(interval) {\n\t\t\tconst ms = intervalToMs(interval, 0);\n\t\t\tresultThrow(integerTest(ms, `positive`, `interval`));\n\t\t\tintervalMs = ms;\n\t\t\tintervalUsed = interval;\n\t\t},\n\t\tget isDisposed() {\n\t\t\treturn disposed;\n\t\t},\n\t\tget elapsedMs() {\n\t\t\treturn performance.now() - startedAt;\n\t\t}\n\t};\n};\n//#endregion\n//#region src/correlate.ts\nconst orderScore = (a, b) => {\n\tif (a.score > b.score) return -1;\n\telse if (a.score < b.score) return 1;\n\treturn 0;\n};\n/**\n* Attempts to align prior data with new data, based on a provided similarity function.\n*\n* See also `alignById` for a version which encloses parameters.\n*\n* ```js\n* // Compare data based on x,y distance\n* const fn = (a, b) => {\n* return 1-Points.distance(a, b);\n* }\n* const lastData = [\n* { id:`1`, x:100, y:200 }\n* ...\n* ]\n* const newData = [\n* { id:`2`, x:101, y:200 }\n* ]\n* const aligned = Correlate.align(fn, lastdata, newData, opts);\n*\n* // Result:\n* [\n* { id:`1`, x:101, y:200 }\n* ]\n* ```\n* @param similarityFunction Function to compute similarity\n* @param lastData Old data\n* @param newData New data\n* @param options Options\n* @returns\n*/\nconst align = (similarityFunction, lastData, newData, options = {}) => {\n\tconst matchThreshold = options.matchThreshold ?? 0;\n\tconst debug = options.debug ?? false;\n\tconst results = /* @__PURE__ */ new Map();\n\tconst newThings = [];\n\tconst lastMap = /* @__PURE__ */ new Map();\n\tlastData?.forEach((d, index) => {\n\t\tif (typeof d === `undefined`) throw new Error(`'lastData' contains undefined (index: ${index.toString()})`);\n\t\tlastMap.set(d.id, d);\n\t});\n\tfor (const newD of newData) {\n\t\tif (!lastData || lastData.length === 0) {\n\t\t\tif (debug) console.debug(`Correlate.align() new id: ${newD.id}`);\n\t\t\tnewThings.push(newD);\n\t\t\tcontinue;\n\t\t}\n\t\tconst scoredLastValues = Array.from(lastMap.values()).map((last) => ({\n\t\t\tid: last.id,\n\t\t\tscore: last === null ? -1 : similarityFunction(last, newD),\n\t\t\tlast\n\t\t}));\n\t\tif (scoredLastValues.length === 0) {\n\t\t\tif (debug) console.debug(`Correlate.align() no valid last values id: ${newD.id}`);\n\t\t\tnewThings.push(newD);\n\t\t\tcontinue;\n\t\t}\n\t\tscoredLastValues.sort(orderScore);\n\t\tconst top = scoredLastValues[0];\n\t\tif (top.score < matchThreshold) {\n\t\t\tif (debug) console.debug(`Correlate.align() new item does not reach threshold. Top score: ${top.score.toString()} id: ${newD.id}`);\n\t\t\tnewThings.push(newD);\n\t\t\tcontinue;\n\t\t}\n\t\tif (debug && top.id !== newD.id) console.log(`Correlate.align() Remapped ${newD.id} -> ${top.id} (score: ${top.score.toString()})`);\n\t\tresults.set(top.id, {\n\t\t\t...newD,\n\t\t\tid: top.id\n\t\t});\n\t\tlastMap.delete(top.id);\n\t}\n\tnewThings.forEach((t) => results.set(t.id, t));\n\treturn Array.from(results.values());\n};\n/**\n* Returns a function that attempts to align a series of data by its id.\n* See also {@link align} for a version with no internal storage.\n*\n* ```js\n* // Compare data based on x,y distance\n* const fn = (a, b) => {\n* return 1-Points.distance(a, b);\n* }\n* const aligner = Correlate.alignById(fn, opts);\n*\n* const lastData = [\n* { id:`1`, x:100, y:200 }\n* ...\n* ]\n* const aligned = aligner(lastData);\n*\n* ```\n* @param fn Function to compute similarity\n* @param options Options\n* @returns\n*/\nconst alignById = (fn, options = {}) => {\n\tlet lastData = [];\n\tconst compute = (newData) => {\n\t\tlastData = align(fn, lastData, newData, options);\n\t\treturn [...lastData];\n\t};\n\treturn compute;\n};\n//#endregion\n//#region src/default-keyer.ts\n/**\n* If values are strings, uses that as the key.\n* Otherwise uses `JSON.stringify`.\n* @param a\n* @returns\n*/\nconst defaultKeyer = (a) => {\n\treturn typeof a === `string` ? a : JSON.stringify(a);\n};\n//#endregion\n//#region src/filters.ts\n/**\n* Returns `v` if `predicate` returns _true_,\n* alternatively returning `skipValue`.\n* \n* ```js\n* // Return true if value is less than 10\n* const p = v => v < 10;\n* \n* filterValue(5, p, 0); // 5\n* filterValue(20, p, 0); // 0\n* ```\n* @param v Value to test\n* @param predicate Predicate\n* @param skipValue Value to return if predicate returns false\n* @returns Input value if predicate is _true_, or `skipValue` if not.\n*/\nconst filterValue = (v, predicate, skipValue) => {\n\tif (predicate(v)) return v;\n\treturn skipValue;\n};\n//#endregion\n//#region src/is-equal-test.ts\n/**\n* Wraps the `eq` function, tracing the input data result\n* ```js\n* // Init trace\n* const traceEq = isEqualTrace(isEqualValueDefault); \n* // Use it in some function that takes IsEqual<T>\n* compare(a, b, eq);\n* ```\n* @param eq \n* @returns \n*/\nconst isEqualTrace = (eq) => {\n\treturn (a, b) => {\n\t\tconst result = eq(a, b);\n\t\tconsole.log(`isEqualTrace eq: ${result} a: ${toStringAbbreviate(a)} b: ${toStringAbbreviate(b)}`);\n\t\treturn result;\n\t};\n};\n//#endregion\n//#region src/is-integer.ts\n/**\n* Returns _true_ if `value` is an integer. Parses string input, but\n* all other data types return _false_.\n* \n* ```js\n* isInteger(1); // true\n* isInteger(1.1); // false\n* isInteger(`1`); // true\n* isInteger(`1.1`); // false\n* isInteger(true); // false\n* isInteger(false); // false\n* ```\n* \n* Returns _false_ for _undefined_, NaN, booleans and infinite numbers.\n* @param value \n* @returns \n*/\nconst isInteger = (value) => {\n\tif (value === void 0) return false;\n\tif (typeof value === `string`) {\n\t\tconst v = Number.parseInt(value);\n\t\tif (Number.isNaN(v)) return false;\n\t\tif (v.toString() === value.toString()) return true;\n\t\treturn false;\n\t}\n\tif (typeof value === `number`) {\n\t\tif (Number.isNaN(value)) return false;\n\t\tif (!Number.isFinite(value)) return false;\n\t\tif (Math.round(value) === value) return true;\n\t\treturn false;\n\t}\n\treturn false;\n};\n//#endregion\n//#region src/iterable-compare-values-shallow.ts\n/**\n* Compares the values of two iterables, returning a list\n* of items they have in common and those unique in `a` or `b`.\n* Ignores ordering of values, and is NOT recursive.\n*\n* ```js\n* const a = ['apples', 'oranges', 'pears' ]\n* const b = ['pears', 'kiwis', 'bananas' ];\n*\n* const r = compareValuesShallow(a, b);\n* r.shared; // [ 'pears' ]\n* r.a; // [ 'apples', 'oranges' ]\n* r.b; // [ 'kiwis', 'bananas' ]\n* ```\n* \n* By default uses === semantics for comparison.\n* @param a\n* @param b\n* @param eq\n* @returns\n*/\nconst compareIterableValuesShallow = (a, b, eq = isEqualDefault) => {\n\tconst shared = [];\n\tconst aUnique = [];\n\tconst bUnique = [];\n\tfor (const elementOfA of a) {\n\t\tlet seenInB = false;\n\t\tfor (const elementOfB of b) if (eq(elementOfA, elementOfB)) {\n\t\t\tseenInB = true;\n\t\t\tbreak;\n\t\t}\n\t\tif (seenInB) shared.push(elementOfA);\n\t\telse aUnique.push(elementOfA);\n\t}\n\tfor (const elementOfB of b) {\n\t\tlet seenInA = false;\n\t\tfor (const elementOfA of a) if (eq(elementOfB, elementOfA)) seenInA = true;\n\t\tif (!seenInA) bUnique.push(elementOfB);\n\t}\n\treturn {\n\t\tshared,\n\t\tisSame: aUnique.length === 0 && bUnique.length === 0,\n\t\ta: aUnique,\n\t\tb: bUnique\n\t};\n};\n//#endregion\n//#region src/key-value.ts\nconst sorterByValueIndex = (index, reverse = false) => {\n\treturn (values) => {\n\t\tconst s = values.toSorted((a, b) => {\n\t\t\treturn defaultComparer(a[index], b[index]);\n\t\t});\n\t\tif (reverse) return s.reverse();\n\t\treturn s;\n\t};\n};\nconst keyValueSorter = (sortStyle) => {\n\tswitch (sortStyle) {\n\t\tcase `value`: return sorterByValueIndex(1, false);\n\t\tcase `value-reverse`: return sorterByValueIndex(1, true);\n\t\tcase `key`: return sorterByValueIndex(0, false);\n\t\tcase `key-reverse`: return sorterByValueIndex(0, true);\n\t\tdefault: throw new Error(`Unknown sorting value '${sortStyle}'. Expecting: value, value-reverse, key or key-reverse`);\n\t}\n};\n//#endregion\n//#region src/util/round.ts\n/**\n* Rounds a number.\n*\n* If one parameter is given, it's the decimal places,\n* and a rounding function is returned:\n* ```js\n* const r = round(2);\n* r(10.12355); // 10.12\n* ```\n*\n* If two parameters are given, the first is decimal places,\n* the second the value to round.\n* ```js\n* round(2, 10.12355); // 10.12\n* ```\n* @param decimalPlaces\n* @returns\n*/\nfunction round(a, b, roundUp) {\n\tresultThrow(integerTest(a, `positive`, `decimalPlaces`));\n\tconst up = typeof b === `boolean` ? b : roundUp ?? false;\n\tlet rounder;\n\tif (a === 0) rounder = Math.round;\n\telse {\n\t\tconst p = Math.pow(10, a);\n\t\tif (up) rounder = (v) => Math.ceil(v * p) / p;\n\t\telse rounder = (v) => Math.floor(v * p) / p;\n\t}\n\tif (typeof b === `number`) return rounder(b);\n\treturn rounder;\n}\n//#endregion\n//#region src/interval-type.ts\n/**\n* Returns _true_ if `date` is an instance of Date\n* @param date\n* @returns \n*/\nfunction isDateObject(date) {\n\tif (typeof date !== `object`) return false;\n\tif (date instanceof Date) return true;\n\treturn false;\n}\n/**\n* Return the millisecond value of an Interval.\n* \n* ```js\n* intervalToMs(100); // 100\n* intervalToMs({ millis: 100 }); // 100\n* ```\n*\n* Use `defaultNumber` to return a default in the case of\n* _undefined_ or invalid input.\n*\n* ```js\n* intervalToMs(undefined); // throws error\n* intervalToMs(undefined, 100); // 100\n* ```\n*\n* If no default is provided, an exception is thrown.\n* @param interval Interval\n* @param defaultNumber Default value if `interval` is _undefined_ or invalid\n* @returns Milliseconds\n*/\nfunction intervalToMs(interval, defaultNumber) {\n\tif (isInterval(interval)) {\n\t\tif (typeof interval === `number`) return interval;\n\t\tlet ms = interval.millis ?? 0;\n\t\tms += (interval.hours ?? 0) * 60 * 60 * 1e3;\n\t\tms += (interval.mins ?? 0) * 60 * 1e3;\n\t\tms += (interval.secs ?? 0) * 1e3;\n\t\treturn ms;\n\t} else {\n\t\tif (typeof defaultNumber !== `undefined`) return defaultNumber;\n\t\tthrow new Error(`Not a valid interval: ${JSON.stringify(interval)}`);\n\t}\n}\n/**\n* Returns _true_ if `interval` matches the {@link Interval} type.\n* @param interval \n* @returns _True_ if `interval` is an {@link Interval}.\n*/\nfunction isInterval(interval) {\n\tif (typeof interval === `undefined`) return false;\n\tif (interval === null) return false;\n\tif (typeof interval === `number`) {\n\t\tif (Number.isNaN(interval)) return false;\n\t\tif (!Number.isFinite(interval)) return false;\n\t\treturn true;\n\t}\n\tif (typeof interval !== `object`) return false;\n\tconst hasMillis = `millis` in interval;\n\tconst hasSecs = `secs` in interval;\n\tconst hasMins = `mins` in interval;\n\tconst hasHours = `hours` in interval;\n\tif (hasMillis && !numberTest(interval.millis).success) return false;\n\tif (hasSecs && !numberTest(interval.secs).success) return false;\n\tif (hasMins && !numberTest(interval.mins).success) return false;\n\tif (hasHours && !numberTest(interval.hours).success) return false;\n\tif (hasMillis || hasSecs || hasHours || hasMins) return true;\n\treturn false;\n}\n/**\n* Returns a human-readable representation\n* of some elapsed milliseconds\n* \n* @example\n* ```js\n* elapsedToHumanString(10); // `10ms`\n* elapsedToHumanString(2000); // `2s`\n* elapsedToHumanString(65*1000); // `1mins`\n* ```\n* @param millisOrFunction Milliseconds as a number, {@link Interval} or function that resolve to a number\n* @param rounding Rounding (default: 2)\n* @returns \n*/\nconst elapsedToHumanString = (millisOrFunction, rounding = 2) => {\n\tlet interval = 0;\n\tif (typeof millisOrFunction === `function`) return elapsedToHumanString(millisOrFunction());\n\telse if (typeof millisOrFunction === `number`) interval = millisOrFunction;\n\telse if (typeof millisOrFunction === `object`) interval = intervalToMs(millisOrFunction);\n\tlet ms = intervalToMs(interval);\n\tif (typeof ms === `undefined`) return `(undefined)`;\n\tif (ms < 1e3) return `${round(rounding, ms)}ms`;\n\tms /= 1e3;\n\tif (ms < 120) return `${ms.toFixed(1)}secs`;\n\tms /= 60;\n\tif (ms < 60) return `${ms.toFixed(2)}mins`;\n\tms /= 60;\n\treturn `${ms.toFixed(2)}hrs`;\n};\n//#endregion\n//#region src/platform.ts\n/**\n* Returns _true_ if it seems like the code is running on iOS (iPad/iPhone)\n* @returns \n*/\nconst runningiOS = () => [\n\t`iPad Simulator`,\n\t`iPhone Simulator`,\n\t`iPod Simulator`,\n\t`iPad`,\n\t`iPhone`,\n\t`iPod`\n].includes(navigator.platform) || navigator.userAgent.includes(`Mac`) && `ontouchend` in document;\n//#endregion\n//#region src/promise-from-event.ts\nconst promiseFromEvent = (target, name) => {\n\treturn new Promise((resolve) => {\n\t\tconst handler = (...args) => {\n\t\t\ttarget.removeEventListener(name, handler);\n\t\t\tif (Array.isArray(args) && args.length === 1) resolve(args[0]);\n\t\t\telse resolve(args);\n\t\t};\n\t\ttarget.addEventListener(name, handler);\n\t});\n};\n//#endregion\n//#region src/reactive-core.ts\n/**\n* Returns _true_ if `rx` is a Reactive\n* @param rx \n* @returns \n*/\nconst isReactive = (rx) => {\n\tif (typeof rx !== `object`) return false;\n\tif (rx === null) return false;\n\treturn `on` in rx && `onValue` in rx;\n};\n/**\n* Returns _true_ if `rx` has a last value\n* \n* Judged seeing if `.last()` exists on `rx`.\n* @param rx Reactive\n* @returns \n*/\nconst hasLast = (rx) => {\n\tif (!isReactive(rx)) return false;\n\tif (`last` in rx) {\n\t\tif (rx.last() !== void 0) return true;\n\t}\n\treturn false;\n};\n//#endregion\n//#region src/resolve-core.ts\n/**\n* Resolves the input to a concrete value. \n* \n* The input can be:\n* * primitive value (string, boolean, number, object)\n* * a/sync function\n* * a/sync generator/iterator\n* * ReactiveNonInitial\n* \n* Examples:\n* ```js\n* await resolve(10); // 10\n* await resolve(() => 10); // 10\n* await resole(async () => {\n* sleep(100);\n* return 10;\n* }); // 10\n* ```\n* \n* If the input is a function, any arguments given to `resolve` are passed to it as a spread.\n* \n* Resolve is not recursive. If the input is an object, it will be returned, even\n* though its properties may be resolvable. Use {@link resolveFields} if you want to handle this case.\n* @param resolvable Input to resolve\n* @param args Additional arguments to pass to function-resolvables.\n* @returns \n*/\nasync function resolve(resolvable, ...args) {\n\tif (typeof resolvable === `object`) if (`next` in resolvable) {\n\t\tconst tag = resolvable[Symbol.toStringTag];\n\t\tif (tag === `Generator` || tag == `Array Iterator`) {\n\t\t\tconst v = resolvable.next();\n\t\t\tif (`done` in v && `value` in v) return v.value;\n\t\t\treturn v;\n\t\t} else if (tag === `AsyncGenerator`) {\n\t\t\tconst v = await resolvable.next();\n\t\t\tif (`done` in v && `value` in v) return v.value;\n\t\t\treturn v;\n\t\t} else throw new Error(`Object has 'next' prop, but does not have 'AsyncGenerator', 'Generator' or 'Array Iterator' string tag symbol. Got: '${tag}'`);\n\t} else if (isReactive(resolvable)) {\n\t\tif (hasLast(resolvable)) return resolvable.last();\n\t\tthrow new Error(`Reactive does not have last value`);\n\t} else return resolvable;\n\telse if (typeof resolvable === `function`) return await resolvable(...args);\n\telse return resolvable;\n}\n/**\n* For the given input, attempts to 'resolve' it. See {@link resolve} for details and asynchronous version.\n* @param resolvable \n* @param args \n* @returns \n*/\nfunction resolveSync(resolvable, ...args) {\n\tif (typeof resolvable === `object`) if (`next` in resolvable) {\n\t\tconst tag = resolvable[Symbol.toStringTag];\n\t\tif (tag === `Generator` || tag == `Array Iterator`) {\n\t\t\tconst v = resolvable.next();\n\t\t\tif (`done` in v && `value` in v) return v.value;\n\t\t\treturn v;\n\t\t} else if (tag === `AsyncGenerator`) throw new Error(`resolveSync cannot work with an async generator`);\n\t\telse throw new Error(`Object has 'next' prop, but does not have 'Generator' or 'Array Iterator' string tag symbol. Got: '${tag}'`);\n\t} else if (isReactive(resolvable)) {\n\t\tif (hasLast(resolvable)) return resolvable.last();\n\t\tthrow new Error(`Reactive does not have last value`);\n\t} else return resolvable;\n\telse if (typeof resolvable === `function`) return resolvable(...args);\n\telse return resolvable;\n}\n/**\n* Resolves a value as per {@link resolve}, however f an error is thrown \n* or the resolution results in _undefined_ \n* or NaN, the fallback value is returned instead.\n* \n* `null` is an allowed return value.\n* \n* ```js\n* // Function returns undefined 50% of the time or 0\n* const fn = () => {\n* if (Math.random() >= 0.5) return; // undefined\n* return 0;\n* }\n* const r = resolveWithFallback(fn, 1);\n* const value = r(); // Always 0 or 1\n* ```\n* \n* See also {@link resolveWithFallbackSync}\n* @param p Thing to resolve\n* @param options Fallback value if an error happens, undefined or NaN\n* @param args \n* @returns \n*/\nasync function resolveWithFallback(p, options, ...args) {\n\tlet errored = false;\n\tlet fallbackValue = options.value;\n\tconst overrideWithLast = options.overrideWithLast ?? false;\n\tif (fallbackValue === void 0) throw new Error(`Param 'options.value' is undefined`);\n\ttry {\n\t\tconst r = await resolve(p, ...args);\n\t\tif (typeof r === `undefined`) return fallbackValue;\n\t\tif (typeof r === `number` && Number.isNaN(r)) return fallbackValue;\n\t\tif (overrideWithLast) fallbackValue = r;\n\t\treturn r;\n\t} catch (error) {\n\t\tif (!errored) {\n\t\t\terrored = true;\n\t\t\tconsole.warn(`resolveWithFallback swallowed an error. Additional errors not reported.`, getErrorMessage(error));\n\t\t}\n\t\treturn fallbackValue;\n\t}\n}\n/**\n* Resolves a 'resolvable', using a fallback value if it results to _undefined_ or _NaN_. _null_ is allowed.\n* \n* See also {@link resolveWithFallback} for the asynchronous version.\n* \n* Options:\n* * value: Fallback value\n* * overrideWithLast: If true, uses the previously-valid value as the replacement fallback (default: false)\n* @param p \n* @param options \n* @param args \n* @returns \n*/\nfunction resolveWithFallbackSync(p, options, ...args) {\n\tlet errored = false;\n\tlet fallbackValue = options.value;\n\tconst overrideWithLast = options.overrideWithLast ?? false;\n\tif (fallbackValue === void 0) throw new Error(`Param 'options.value' is undefined`);\n\ttry {\n\t\tconst r = resolveSync(p, ...args);\n\t\tif (typeof r === `undefined`) return fallbackValue;\n\t\tif (typeof r === `number` && Number.isNaN(r)) return fallbackValue;\n\t\tif (overrideWithLast) fallbackValue = r;\n\t\treturn r;\n\t} catch (error) {\n\t\tif (!errored) {\n\t\t\terrored = true;\n\t\t\tconsole.warn(`resolveWithFallbackSync swallowed an error. Additional errors not reported.`, getErrorMessage(error));\n\t\t}\n\t\treturn fallbackValue;\n\t}\n}\n//#endregion\n//#region src/util/zip.ts\nconst zip = (...arrays) => {\n\tif (arrays.some((a) => !Array.isArray(a))) throw new Error(`All parameters must be an array`);\n\tconst lengths = arrays.map((a) => a.length);\n\tconst returnValue = [];\n\tconst length = lengths[0];\n\tfor (let index = 0; index < length; index++) returnValue.push(arrays.map((a) => a[index]));\n\treturn returnValue;\n};\n//#endregion\n//#region src/resolve-fields.ts\n/**\n* Returns a copy of `object`, with the same properties. For each property\n* that has a basic value (string, number, boolean, object), the value is set\n* for the return object. If the property is a function or generator, its value\n* is used instead. Async functions and generators are also usable.\n* \n* Use {@link resolveFieldsSync} for a synchronous version.\n* \n* Not recursive.\n* \n* In the below example, the function for the property `random` is invoked.\n* ```js\n* const state = {\n* length: 10,\n* random: () => Math.random();\n* }\n* const x = resolveFields(state);\n* // { length: 10, random: 0.1235 }\n* ```\n* \n* It also works with generators. Probably best with those that are infinite.\n* \n* ```js\n* import { count } from './numbers.js';\n* \n* const state = {\n* length: 10,\n* index: count(2) // Generator that yields: 0, 1 and then ends\n* }\n* resolveFields(state); // { length: 10, index: 0 }\n* resolveFields(state); // { length: 10, index: 1 }\n* // Generator finishes after counting twice:\n* resolveFields(state); // { length: 10, index: undefined }\n* ```\n* @param object \n* @returns \n*/\nasync function resolveFields(object) {\n\tconst resolvers = [];\n\tconst keys = [];\n\tfor (const entry of Object.entries(object)) {\n\t\tconst resolvable = entry[1];\n\t\tresolvers.push(resolve(resolvable));\n\t\tkeys.push(entry[0]);\n\t}\n\tconst entries = zip(keys, await Promise.all(resolvers));\n\treturn Object.fromEntries(entries);\n}\n/**\n* 'Resolves' all the fields of `object` in a synchronous manner.\n* Uses {@link resolveSync} under-the-hood\n* @param object \n* @returns \n*/\nfunction resolveFieldsSync(object) {\n\tconst entries = [];\n\tfor (const entry of Object.entries(object)) {\n\t\tconst resolvable = entry[1];\n\t\tconst value = resolveSync(resolvable);\n\t\tentries.push([entry[0], value]);\n\t}\n\treturn Object.fromEntries(entries);\n}\n/**\n* Returns a function that resolves `object`.\n*\n* Use {@link resolveFields} to resolve an object directly.\n* @param object\n* @returns\n*/\n//#endregion\n//#region src/sleep.ts\nif (typeof window === `undefined` || !(`requestAnimationFrame` in window)) {\n\tif (typeof window === `undefined`) globalThis.requestAnimationFrame = (callback) => {\n\t\tsetTimeout(callback, 1);\n\t};\n}\n/**\n* Returns after timeout period.\n*\n* @example In an async function\n* ```js\n* console.log(`Hello`);\n* await sleep(1000);\n* console.log(`There`); // Prints one second after\n* ```\n*\n* @example As a promise\n* ```js\n* console.log(`Hello`);\n* sleep({ millis: 1000 })\n* .then(() => console.log(`There`)); // Prints one second after\n* ```\n*\n* If a timeout of 0 is given, `requestAnimationFrame` is used instead of `setTimeout`.\n*\n* `Flow.delay()` and {@link sleep} are similar. `Flow.delay()` takes a parameter of what code to execute after the timeout, while `sleep()` just resolves after the timeout.\n*\n* A value can be provided, which is returned on awaking:\n* ```js\n* const v = await sleep({ seconds: 1, value: `hello`);\n* // v = `hello`\n* ```\n*\n* Provide an AbortSignal to cancel the sleep and throwing an exception\n* so code after the sleep doesn't happen.\n*\n* ```js\n* const ac = new AbortController();\n* setTimeout(() => { ac.abort(); }, 1000); // Abort after 1s\n*\n* // Sleep for 1min\n* await sleep({ minutes: 1, signal: ac.signal });\n* console.log(`Awake`); // This line doesn't get called because an exception is thrown when aborting\n* ```\n* @param optsOrMillis Milliseconds to sleep, or options\n* @return\n*/\nconst sleep = (optsOrMillis) => {\n\tconst timeoutMs = intervalToMs(optsOrMillis, 1);\n\tconst signal = optsOrMillis.signal;\n\tconst value = optsOrMillis.value;\n\tresultThrow(numberTest(timeoutMs, `positive`, `timeoutMs`));\n\tif (timeoutMs === 0) return new Promise((resolve) => requestAnimationFrame((_) => {\n\t\tresolve(value);\n\t}));\n\telse return new Promise((resolve, reject) => {\n\t\tconst onAbortSignal = () => {\n\t\t\tclearTimeout(t);\n\t\t\tif (signal) {\n\t\t\t\tsignal.removeEventListener(`abort`, onAbortSignal);\n\t\t\t\treject(new Error(signal.reason));\n\t\t\t} else reject(/* @__PURE__ */ new Error(`Cancelled`));\n\t\t};\n\t\tif (signal) signal.addEventListener(`abort`, onAbortSignal);\n\t\tconst t = setTimeout(() => {\n\t\t\tsignal?.removeEventListener(`abort`, onAbortSignal);\n\t\t\tif (signal?.aborted) {\n\t\t\t\treject(new Error(signal.reason));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(value);\n\t\t}, timeoutMs);\n\t});\n};\n/**\n* Delays until `predicate` returns true.\n* Can be useful for synchronising with other async activities.\n* ```js\n* // Delay until 'count' reaches 5\n* await sleepWhile(() => count >= 5, 100);\n* ```\n* @param predicate \n* @param checkInterval \n*/\nconst sleepWhile = async (predicate, checkInterval = 100) => {\n\twhile (predicate()) await sleep(checkInterval);\n};\n//#endregion\n//#region src/url-parameters.ts\n/**\n* Allows for access to URL parameters.\n* \n* If `url` is not specified, `docment.location`'s .searchParams is used.\n* \n* ```js\n* const p = parseUrlParameters();\n* \n* // eg. gets an integer param called 'size`, using NaN as a default\n* p.int(`size`);\n* \n* // As above, but will return 10 if 'size' is not specified in URL.\n* p.int(`size`, 10);\n* \n* // Returns _true_ if 'engage' parameter is present and value is 'true'\n* p.bool(`engage`);\n* ```\n* @param url \n* @returns \n*/\nconst parseUrlParameters = (url) => {\n\tconst parameters = new URL(url ?? document.location.toString()).searchParams;\n\treturn {\n\t\tparams: parameters,\n\t\tint: (name, defaultValue = NaN) => intParamOrDefault(parameters, name, defaultValue),\n\t\tfloat: (name, defaultValue = NaN) => floatParamOrDefault(parameters, name, defaultValue),\n\t\tstring: (name, defaultValue = ``) => stringParamOrDefault(parameters, name, defaultValue),\n\t\tbool: (name) => boolParamOrDefault(parameters, name)\n\t};\n};\n/**\n* Return an integer value from URL parameter or use a default value.\n* Value is considered _false_ if it's not present, or it is explicitly 'false'\n* @returns \n*/\nfunction boolParamOrDefault(parameters, name) {\n\tconst p = parameters.get(name);\n\tif (p === null) return false;\n\tif (p === `true`) return true;\n\treturn false;\n}\n/**\n* Return an integer value from URL parameter or use a default value\n* @returns \n*/\nfunction intParamOrDefault(parameters, name, defaultValue) {\n\tconst p = parameters.get(name);\n\tif (p !== null) return Number.parseInt(p);\n\treturn defaultValue;\n}\n/**\n* Return a float value from URL parameter or use a default value\n* @returns \n*/\nfunction floatParamOrDefault(parameters, name, defaultValue) {\n\tconst p = parameters.get(name);\n\tif (p !== null) return Number.parseFloat(p);\n\treturn defaultValue;\n}\n/**\n* Return a string value from URL parameter or use a default value\n* @returns \n*/\nfunction stringParamOrDefault(parameters, name, defaultValue) {\n\tconst p = parameters.get(name);\n\tif (p !== null) return p;\n\treturn defaultValue;\n}\n//#endregion\nexport { cloneFromFields as $, pathed_exports as A, isPrimitive as B, defaultKeyer as C, trackers_exports as D, continuously as E, prettyPrintEntries as F, mapObjectByObject as G, prefixProperties as H, recordChildren as I, changedProperties as J, mapObjectShallow as K, recordEntriesDepthFirst as L, zip$1 as M, enumerateNumericalValues as N, unique as O, getRecordEntryByPath as P, mapObjectKeys as Q, recordEntryPrettyPrint as R, filterValue as S, alignById as T, merge as U, isPrimitiveOrObject as V, mergeSameShape as W, compareObjectData as X, compareArrays as Y, compareObjectKeys as Z, isInterval as _, resolveFieldsSync as a, isInteger as b, resolveWithFallback as c, isReactive as d, promiseFromEvent as f, isDateObject as g, intervalToMs as h, resolveFields as i, records_exports as j, uniqueInstances as k, resolveWithFallbackSync as l, elapsedToHumanString as m, sleep as n, resolve as o, runningiOS as p, keysToNumbers as q, sleepWhile as r, resolveSync as s, parseUrlParameters as t, hasLast as u, keyValueSorter as v, align as w, isEqualTrace as x, compareIterableValuesShallow as y, traceRecordEntryByPath as z };\n"],"x_google_ignoreList":[0,1,2,3],"mappings":"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"}