@compstats/core 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/LICENSE +21 -0
  3. package/README.md +310 -0
  4. package/dist/3d.d.ts +33 -0
  5. package/dist/3d.d.ts.map +1 -0
  6. package/dist/3d.js +1984 -0
  7. package/dist/3d.js.map +22 -0
  8. package/dist/core/arith.d.ts +133 -0
  9. package/dist/core/arith.d.ts.map +1 -0
  10. package/dist/core/frame.d.ts +98 -0
  11. package/dist/core/frame.d.ts.map +1 -0
  12. package/dist/core/histogram.d.ts +68 -0
  13. package/dist/core/histogram.d.ts.map +1 -0
  14. package/dist/core/kde.d.ts +106 -0
  15. package/dist/core/kde.d.ts.map +1 -0
  16. package/dist/core/logit.d.ts +109 -0
  17. package/dist/core/logit.d.ts.map +1 -0
  18. package/dist/core/matrix.d.ts +135 -0
  19. package/dist/core/matrix.d.ts.map +1 -0
  20. package/dist/core/moderation.d.ts +127 -0
  21. package/dist/core/moderation.d.ts.map +1 -0
  22. package/dist/core/ols.d.ts +76 -0
  23. package/dist/core/ols.d.ts.map +1 -0
  24. package/dist/core/pca.d.ts +99 -0
  25. package/dist/core/pca.d.ts.map +1 -0
  26. package/dist/core/precision.d.ts +10 -0
  27. package/dist/core/precision.d.ts.map +1 -0
  28. package/dist/core/pretty.d.ts +51 -0
  29. package/dist/core/pretty.d.ts.map +1 -0
  30. package/dist/core/regression.d.ts +68 -0
  31. package/dist/core/regression.d.ts.map +1 -0
  32. package/dist/core/rng.d.ts +206 -0
  33. package/dist/core/rng.d.ts.map +1 -0
  34. package/dist/core/sampling.d.ts +157 -0
  35. package/dist/core/sampling.d.ts.map +1 -0
  36. package/dist/core/special.d.ts +92 -0
  37. package/dist/core/special.d.ts.map +1 -0
  38. package/dist/core/tdist.d.ts +53 -0
  39. package/dist/core/tdist.d.ts.map +1 -0
  40. package/dist/core/ttest.d.ts +146 -0
  41. package/dist/core/ttest.d.ts.map +1 -0
  42. package/dist/data/moderationData.d.ts +40 -0
  43. package/dist/data/moderationData.d.ts.map +1 -0
  44. package/dist/data/pcaDegenerate.d.ts +18 -0
  45. package/dist/data/pcaDegenerate.d.ts.map +1 -0
  46. package/dist/index.d.ts +66 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +4195 -0
  49. package/dist/index.js.map +47 -0
  50. package/dist/interactive/controls.d.ts +97 -0
  51. package/dist/interactive/controls.d.ts.map +1 -0
  52. package/dist/interactive/logit.d.ts +57 -0
  53. package/dist/interactive/logit.d.ts.map +1 -0
  54. package/dist/interactive/matrixInverse.d.ts +86 -0
  55. package/dist/interactive/matrixInverse.d.ts.map +1 -0
  56. package/dist/interactive/moderation3d.d.ts +103 -0
  57. package/dist/interactive/moderation3d.d.ts.map +1 -0
  58. package/dist/interactive/pca.d.ts +90 -0
  59. package/dist/interactive/pca.d.ts.map +1 -0
  60. package/dist/interactive/regression.d.ts +57 -0
  61. package/dist/interactive/regression.d.ts.map +1 -0
  62. package/dist/interactive/sampling.d.ts +78 -0
  63. package/dist/interactive/sampling.d.ts.map +1 -0
  64. package/dist/interactive/scatter3d.d.ts +124 -0
  65. package/dist/interactive/scatter3d.d.ts.map +1 -0
  66. package/dist/interactive/tTest.d.ts +69 -0
  67. package/dist/interactive/tTest.d.ts.map +1 -0
  68. package/dist/interactive/target.d.ts +132 -0
  69. package/dist/interactive/target.d.ts.map +1 -0
  70. package/dist/plot/axes.d.ts +128 -0
  71. package/dist/plot/axes.d.ts.map +1 -0
  72. package/dist/plot/draw.d.ts +46 -0
  73. package/dist/plot/draw.d.ts.map +1 -0
  74. package/dist/plot/format.d.ts +33 -0
  75. package/dist/plot/format.d.ts.map +1 -0
  76. package/dist/plot/logit.d.ts +68 -0
  77. package/dist/plot/logit.d.ts.map +1 -0
  78. package/dist/plot/matrixInverse.d.ts +62 -0
  79. package/dist/plot/matrixInverse.d.ts.map +1 -0
  80. package/dist/plot/moderation3d.d.ts +135 -0
  81. package/dist/plot/moderation3d.d.ts.map +1 -0
  82. package/dist/plot/pca.d.ts +79 -0
  83. package/dist/plot/pca.d.ts.map +1 -0
  84. package/dist/plot/plotly.d.ts +209 -0
  85. package/dist/plot/plotly.d.ts.map +1 -0
  86. package/dist/plot/regression.d.ts +52 -0
  87. package/dist/plot/regression.d.ts.map +1 -0
  88. package/dist/plot/sampleCi.d.ts +82 -0
  89. package/dist/plot/sampleCi.d.ts.map +1 -0
  90. package/dist/plot/sampling.d.ts +159 -0
  91. package/dist/plot/sampling.d.ts.map +1 -0
  92. package/dist/plot/scatter3d.d.ts +164 -0
  93. package/dist/plot/scatter3d.d.ts.map +1 -0
  94. package/dist/plot/tTest.d.ts +49 -0
  95. package/dist/plot/tTest.d.ts.map +1 -0
  96. package/dist/plot/target.d.ts +55 -0
  97. package/dist/plot/target.d.ts.map +1 -0
  98. package/package.json +71 -0
package/dist/3d.js.map ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/plot/plotly.ts", "../src/core/frame.ts", "../src/plot/scatter3d.ts", "../src/interactive/controls.ts", "../src/plot/target.ts", "../src/interactive/target.ts", "../src/interactive/scatter3d.ts", "../src/core/arith.ts", "../src/core/ols.ts", "../src/core/moderation.ts", "../src/plot/moderation3d.ts", "../src/interactive/moderation3d.ts", "../src/data/moderationData.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * The seam between this library and Plotly.js.\n *\n * The two 3D plots of the R package are drawn by Plotly (`plot_scatter3d()`)\n * and by lattice (`plot_moderation_3d()`). In a browser there is one sensible\n * engine for both, and the R package already chose it for the scatterplot, so\n * both 3D plots of this port draw through Plotly.\n *\n * Plotly is four megabytes of code. Three rules keep that weight off everyone\n * who does not draw in three dimensions.\n *\n * 1. **The 2D entry never names it.** The 3D plots live behind their own entry\n * point, `src/3d.ts`, which the package exports as `compstatslib/3d`.\n * 2. **The 3D entry does not carry it either.** `loadPlotly()` reaches the\n * library through a dynamic `import`, which a bundler keeps in a chunk of\n * its own and a browser fetches only when a plot is drawn.\n * 3. **The engine is an argument.** Both plot functions take a `plotly`\n * option. The tests pass a recorder (`test/recording-plotly.ts`) and never\n * load Plotly at all: happy-dom has no WebGL, and the work this port does\n * is the trace and the layout it builds, not the picture Plotly makes.\n *\n * `PlotlyLike` lists the exact calls the port makes, in the manner of\n * `Context2D` in `./target.ts`. The real library satisfies it, and so does\n * any object with those two methods.\n *\n * The trace and layout types below are equally narrow. They describe the\n * fields this port sets, not the several hundred Plotly accepts.\n */\n\n/** A point in three dimensions, as Plotly writes one. */\nexport interface Vector3 {\n readonly x: number;\n readonly y: number;\n readonly z: number;\n}\n\n/**\n * Where the camera stands, where it looks, and which way is up. Plotly's\n * `scene.camera`. Every part is optional: Plotly supplies its own.\n */\nexport interface PlotlyCamera {\n readonly eye?: Vector3;\n readonly center?: Vector3;\n readonly up?: Vector3;\n}\n\n/**\n * A camera whose position is known. `cameraFromRotations` returns one, so a\n * caller can read the eye without asking whether it is there.\n */\nexport interface EyeCamera extends PlotlyCamera {\n readonly eye: Vector3;\n}\n\n/** How the markers of a 3D scatterplot are drawn. */\nexport interface Scatter3dMarker {\n /** R's `opacity`, in (0, 1]. */\n readonly opacity: number;\n /** R's `size`, in pixels. */\n readonly size: number;\n /** One value per point, when a numeric column drives the color. */\n readonly color?: readonly number[];\n /** The scale those values are read through. */\n readonly colorscale?: string;\n /** Whether the scale is drawn beside the plot as a color bar. */\n readonly showscale?: boolean;\n}\n\n/** A cloud of points. */\nexport interface Scatter3dTrace {\n readonly type: \"scatter3d\";\n readonly mode: \"markers\";\n readonly x: readonly number[];\n readonly y: readonly number[];\n readonly z: readonly number[];\n readonly marker: Scatter3dMarker;\n /** The level this trace holds, when a categorical column splits the data. */\n readonly name?: string;\n /** Whether the level is listed in the legend. */\n readonly showlegend?: boolean;\n}\n\n/**\n * A height field.\n *\n * `z[j][i]` is the height above `x[i]` and `y[j]` — the row index runs along\n * `y`, which is why the moderation plot writes the moderator into the rows.\n */\nexport interface SurfaceTrace {\n readonly type: \"surface\";\n readonly x: readonly number[];\n readonly y: readonly number[];\n readonly z: readonly (readonly number[])[];\n /** Whether the height scale is drawn beside the plot. */\n readonly showscale: boolean;\n}\n\n/** Anything this port draws. */\nexport type PlotlyTrace = Scatter3dTrace | SurfaceTrace;\n\n/** One axis of a 3D scene. */\nexport interface PlotlyAxis {\n /**\n * The axis label, in Plotly's object form. Plotly v2 silently drops a\n * bare-string title, so the type refuses the shorthand that would compile\n * and then show nothing.\n */\n readonly title: { readonly text: string };\n /**\n * The values the axis spans, as `[low, high]`. Plotly fits the data when\n * the range is absent.\n */\n readonly range?: readonly [number, number];\n}\n\n/** The 3D scene: three axes, the shape of the box, and the camera. */\nexport interface PlotlyScene {\n /** `\"manual\"` reads the ratio below. The others are Plotly's own rules. */\n readonly aspectmode?: \"auto\" | \"cube\" | \"data\" | \"manual\";\n readonly aspectratio?: Vector3;\n readonly xaxis: PlotlyAxis;\n readonly yaxis: PlotlyAxis;\n readonly zaxis: PlotlyAxis;\n /**\n * A name for the view. Plotly keeps the rotation and the zoom across a\n * redraw while this string does not change, which is how a slider can\n * rebuild the plot without throwing away the angle the user chose.\n */\n readonly uirevision?: string;\n readonly camera?: PlotlyCamera;\n}\n\n/** The layout of a 3D plot. */\nexport interface PlotlyLayout {\n readonly uirevision: string;\n readonly scene: PlotlyScene;\n}\n\n/** The behavior of the plot, as opposed to its content. */\nexport interface PlotlyConfig {\n /** Whether the plot follows the size of the element that holds it. */\n readonly responsive?: boolean;\n}\n\n/**\n * What Plotly reports after the user moves the plot.\n *\n * The camera arrives under the key `scene.camera`, which is a path, not a\n * nested object. The other keys depend on what moved.\n */\nexport interface PlotlyRelayoutEvent {\n readonly \"scene.camera\"?: PlotlyCamera;\n readonly [key: string]: unknown;\n}\n\n/**\n * A change pushed at a plot that is already drawn.\n *\n * Plotly's `relayout` takes the layout attribute by its path, so the camera\n * arrives under the same `scene.camera` key it is reported under.\n */\nexport interface PlotlyRelayoutUpdate {\n readonly \"scene.camera\"?: PlotlyCamera;\n}\n\n/**\n * The element Plotly hands back after it has drawn.\n *\n * Plotly adds an event emitter to that element, which is the only way to learn\n * that the user rotated the plot.\n */\nexport interface PlotlyHTMLElement extends HTMLElement {\n on(\n event: \"plotly_relayout\",\n handler: (event: PlotlyRelayoutEvent) => void,\n ): void;\n removeAllListeners(event: string): void;\n}\n\n/**\n * The part of Plotly this library calls.\n *\n * `react` both draws and updates: on an empty element it builds the plot, and\n * on one that already holds a plot it changes only what differs.\n *\n * `relayout` exists for one case that `react` cannot serve. The layouts of\n * this port carry a constant `uirevision`, which is what keeps a user's own\n * rotation across a redraw; Plotly honours that literally, so once the user\n * has dragged the plot, a `react` carrying a different `scene.camera` is\n * ignored. The rotation sliders of the moderation surface would then move\n * nothing. `relayout` is an instruction rather than a preference, so it moves\n * the camera whatever the user did before, and it is called only when a\n * slider asks for a view the plot is not already at.\n */\nexport interface PlotlyLike {\n react(\n element: HTMLElement,\n data: readonly PlotlyTrace[],\n layout: PlotlyLayout,\n config?: PlotlyConfig,\n ): Promise<PlotlyHTMLElement>;\n /** Change one part of the layout of a plot that is already drawn. */\n relayout(\n element: HTMLElement,\n update: PlotlyRelayoutUpdate,\n ): Promise<PlotlyHTMLElement>;\n /** Remove the plot, and everything it attached to the element. */\n purge(element: HTMLElement): void;\n}\n\n/**\n * Whether two cameras stand at the same view.\n *\n * The interactive components write a camera the user dragged to back into the\n * live layout, and the `relayout` that does so fires `plotly_relayout` again\n * with the same camera as a fresh object. Comparing by value is what lets the\n * capture handlers recognize that echo and stop, so this must never be\n * replaced with a reference comparison.\n *\n * @param a One camera, or nothing.\n * @param b The other, or nothing.\n * @returns True when both are absent, or both present with equal parts.\n */\nexport function sameCamera(\n a: PlotlyCamera | undefined,\n b: PlotlyCamera | undefined,\n): boolean {\n if (a === undefined || b === undefined) {\n return a === b;\n }\n return (\n sameVector(a.eye, b.eye) &&\n sameVector(a.center, b.center) &&\n sameVector(a.up, b.up)\n );\n}\n\n/** Whether two optional vectors carry the same coordinates. */\nfunction sameVector(a: Vector3 | undefined, b: Vector3 | undefined): boolean {\n if (a === undefined || b === undefined) {\n return a === b;\n }\n return a.x === b.x && a.y === b.y && a.z === b.z;\n}\n\n/** The one load, shared by every caller. */\nlet loading: Promise<PlotlyLike> | undefined;\n\n/**\n * Load Plotly.js.\n *\n * The library is fetched once. Every later call gets the same promise, so two\n * plots on one page load one copy.\n *\n * @returns The library, narrowed to the calls this port makes.\n */\nexport function loadPlotly(): Promise<PlotlyLike> {\n loading ??= import(\"plotly.js-dist-min\").then((module) => {\n const loaded = (module as { readonly default?: unknown }).default ?? module;\n return loaded as PlotlyLike;\n });\n return loading;\n}\n",
6
+ "/**\n * Column-keyed data frames, and the checks R gets for free.\n *\n * The 3D functions of the R package take an R data frame, which guarantees\n * two things a JavaScript object does not: every column holds one type, and\n * every column has the same length. `moderation.ts` and the scatter3d module\n * both need those guarantees, so the questions are asked in one place and\n * answered the same way for both.\n *\n * The port follows `../compstatslib/R/scatter3d_helpers.R`:\n *\n * ```r\n * scatter3d_numeric_cols <- function(data) {\n * names(data)[vapply(data, is.numeric, logical(1))]\n * }\n * ```\n *\n * with two departures, both forced by the language and both pinned by tests.\n * R reads a vector's declared type, so `is.numeric(numeric(0))` is TRUE and a\n * column of mixed types cannot exist. A JavaScript array declares nothing, so\n * this module reads the values: **a column is numeric when it holds at least\n * one value and every value is a number.** An empty column therefore is not\n * numeric — it offers no evidence either way, and an empty axis draws nothing\n * — and a column of numbers with one string in it is not numeric either,\n * because fitting it would give `NaN` for every coefficient.\n */\n\n/**\n * One column of a data frame.\n *\n * Numeric columns carry the statistics. The other two types are here because\n * `plot_scatter3d()` accepts a categorical column for `color`, which R allows\n * to be a factor, a character vector, or a logical vector.\n */\nexport type Column = readonly number[] | readonly string[] | readonly boolean[];\n\n/**\n * A data frame: named columns of equal length.\n *\n * The equal length is a rule, not a type. `frameRows` enforces it.\n */\nexport type DataFrame = { readonly [name: string]: Column };\n\n/**\n * Report whether a column holds numbers, and narrow it when it does.\n *\n * @param column The column to inspect.\n * @returns True when the column has at least one value and every value is a\n * number. `NaN` counts as a number, as R's missing values do.\n */\nexport function isNumericColumn(column: Column): column is readonly number[] {\n return column.length > 0 && column.every((value) => typeof value === \"number\");\n}\n\n/**\n * Name the numeric columns, in the order the frame declares them.\n *\n * This is R's `scatter3d_numeric_cols()`. The order matters: the scatter3d\n * default takes the first three names this returns.\n *\n * @param data The frame to inspect.\n * @returns The names of the numeric columns, in insertion order.\n */\nexport function numericColumns(data: DataFrame): string[] {\n return Object.keys(data).filter((name) =>\n isNumericColumn(data[name] as Column),\n );\n}\n\n/**\n * Refuse a frame that cannot fill three numeric axes.\n *\n * This is R's `scatter3d_require_3_numeric()`, which both the plot and the\n * gadget call with their own name, so that the message says which function\n * the caller reached.\n *\n * @param numeric The numeric column names, from `numericColumns`.\n * @param caller The name to print, such as `plotScatter3d`.\n * @throws RangeError If fewer than three names were given.\n */\nexport function requireThreeNumericColumns(\n numeric: readonly string[],\n caller: string,\n): void {\n if (numeric.length < 3) {\n throw new RangeError(\n `${caller}() needs at least 3 numeric columns; got ${numeric.length}. ` +\n \"Supply x/y/z explicitly or add numeric columns.\",\n );\n }\n}\n\n/**\n * Return the number of rows, and refuse a frame that has no single answer.\n *\n * @param data The frame to measure.\n * @returns The shared length of the columns. A frame with no columns has no\n * rows.\n * @throws RangeError If two columns have different lengths. An R data frame\n * cannot be built that way, so nothing downstream is written to survive it.\n */\nexport function frameRows(data: DataFrame): number {\n const names = Object.keys(data);\n const first = names[0];\n if (first === undefined) {\n return 0;\n }\n\n const rows = (data[first] as Column).length;\n const ragged = names.find((name) => (data[name] as Column).length !== rows);\n if (ragged !== undefined) {\n throw new RangeError(\n `every column needs the same number of rows: \"${first}\" has ${rows} ` +\n `but \"${ragged}\" has ${(data[ragged] as Column).length}`,\n );\n }\n\n return rows;\n}\n\n/**\n * Read one numeric column, or explain why it cannot be used.\n *\n * The wording follows R's own, which names both the column and the argument\n * it arrived through: `Column \"b\" (passed as \\`x\\`) is not in \\`data\\`.`\n *\n * @param data The frame to read.\n * @param name The column name the caller asked for.\n * @param role The option that carried the name, such as `iv` or `mod`. It\n * appears in the error, so the caller learns which argument is wrong.\n * @returns The column.\n * @throws RangeError If the frame has no such column, or the column is not\n * numeric.\n */\nexport function requireNumericColumn(\n data: DataFrame,\n name: string,\n role: string,\n): readonly number[] {\n const column = data[name];\n if (column === undefined) {\n throw new RangeError(\n `Column \"${name}\" (passed as \\`${role}\\`) is not in the data.`,\n );\n }\n if (!isNumericColumn(column)) {\n throw new RangeError(\n `Column \"${name}\" (passed as \\`${role}\\`) is not numeric; ` +\n \"only numeric columns can carry the statistics.\",\n );\n }\n\n return column;\n}\n",
7
+ "/**\n * The 3D scatterplot: three numeric columns as a cloud of points, with an\n * optional fourth column driving the color.\n *\n * This is `plot_scatter3d()` of `../compstatslib/R/scatter3d_plot.R`, drawn\n * through Plotly as the R original is. The trace and the layout follow the\n * object R actually builds, dumped in `.claude/plans/moderation-fixtures.md`\n * section 5.\n *\n * Four things are worth knowing before reading the code.\n *\n * **The work is the specification.** `scatter3dSpec` builds the traces and the\n * layout and touches nothing outside itself. `plotScatter3d` resolves the\n * engine and draws that specification. The split keeps every rule of the port\n * testable without a browser, and it gives the interactive layer a cheap way\n * to ask what a set of options would draw.\n *\n * **Nothing is drawn until everything is checked.** R validates the style,\n * then the axis arguments, then the columns, and only then calls Plotly. That\n * order was confirmed by tracing `plot_ly()`: every error fires with the\n * engine untouched. This module keeps the order and the wording, and the tests\n * count the calls to prove it.\n *\n * **The default axes are the first three numeric columns, in frame order.**\n * With the bundled `moderation_data` that is `y, x, z`, so the plot's own x\n * axis is titled \"y\". The collision is confusing, and it is R's, so the port\n * keeps it. A note names the chosen and the skipped columns, as R's\n * `message()` does; a library cannot write to a console, so the note is\n * returned and the caller decides whether to show it.\n *\n * **Color is the one place the port must invent.** R hands the color column\n * to plotly-R, which decides by itself what a numeric or a categorical column\n * means. Plotly.js decides nothing: the caller must build the traces. So a\n * numeric column becomes one trace carrying a value per point with a color\n * bar beside it, and a categorical column becomes one trace per level, named,\n * listed in the legend, and colored from Plotly's own sequence. The rule\n * follows what plotly-R does; the exact colors are Plotly's choice, in both\n * languages.\n */\n\nimport {\n frameRows,\n isNumericColumn,\n numericColumns,\n requireThreeNumericColumns,\n} from \"../core/frame\";\nimport type { Column, DataFrame } from \"../core/frame\";\nimport { loadPlotly } from \"./plotly\";\nimport type {\n PlotlyCamera,\n PlotlyHTMLElement,\n PlotlyLayout,\n PlotlyLike,\n Scatter3dMarker,\n Scatter3dTrace,\n} from \"./plotly\";\n\n/**\n * The name Plotly keeps the view under. R sets the same literal string, in\n * both the layout and the scene.\n */\nconst UIREVISION = \"scatter3d\";\n/**\n * The scale a numeric color column is read through. plotly-R colors a\n * numeric column with Viridis by default, so the port names it here.\n */\nconst NUMERIC_COLORSCALE = \"Viridis\";\n/** Plotly redraws the plot when the element that holds it changes size. */\nconst CONFIG = { responsive: true } as const;\n\n/** How the markers are drawn, apart from the data. */\nexport interface Scatter3dStyle {\n /** The x, y and z proportions of the box the points sit in. */\n readonly aspect: readonly number[];\n /** How solid each marker is, in (0, 1]. */\n readonly opacity: number;\n /** How large each marker is, in pixels. */\n readonly size: number;\n}\n\n/**\n * R's own defaults: `aspect = c(1, 1, 1), opacity = 0.8, size = 5`.\n *\n * `interactive_scatter3d()` repeats these three numbers in its own signature.\n * The port states them once, here, so the gadget's sliders and the plot they\n * drive cannot start from different places.\n */\nexport const DEFAULT_SCATTER3D_STYLE: Scatter3dStyle = {\n aspect: [1, 1, 1],\n opacity: 0.8,\n size: 5,\n};\n\n/** Titles to write on the axes instead of the column names. */\nexport interface Scatter3dTitles {\n readonly x?: string;\n readonly y?: string;\n readonly z?: string;\n}\n\n/** What to draw, and how. Every option is R's, with R's default. */\nexport interface Scatter3dSpecOptions {\n /** The column on the first horizontal axis. */\n readonly x?: string;\n /** The column on the second horizontal axis. */\n readonly y?: string;\n /** The column on the vertical axis. */\n readonly z?: string;\n /**\n * Any column to map to color. A numeric column gives a continuous scale\n * with a color bar; a text or true-or-false column gives one trace per\n * level, with a legend.\n */\n readonly color?: string;\n /**\n * The x, y and z proportions of the box the points sit in: three positive\n * numbers, `[1, 1, 1]` by default.\n */\n readonly aspect?: readonly number[];\n /** How solid each marker is, in (0, 1]. */\n readonly opacity?: number;\n /** How large each marker is, in pixels. */\n readonly size?: number;\n /**\n * Where the camera starts. Absent by default, which leaves Plotly's own\n * view. Pass a camera to reopen a plot at an angle captured earlier.\n */\n readonly camera?: PlotlyCamera;\n /** Axis titles. Each axis falls back to the name of its column. */\n readonly titles?: Scatter3dTitles;\n}\n\n/** The options of `plotScatter3d`: the specification, and the engine. */\nexport interface PlotScatter3dOptions extends Scatter3dSpecOptions {\n /**\n * The Plotly engine. `loadPlotly()` by default, which fetches the library on\n * first use. Pass your own to draw through a copy you already hold, or to\n * record what would be drawn.\n */\n readonly plotly?: PlotlyLike;\n}\n\n/** What a set of options draws. */\nexport interface Scatter3dSpec {\n /** One trace, or one for each level of a categorical color column. */\n readonly traces: readonly Scatter3dTrace[];\n readonly layout: PlotlyLayout;\n /**\n * What R says in its `message()`: which columns were chosen, and which were\n * skipped. Null when the caller named every axis, or when no numeric column\n * was left over.\n */\n readonly note: string | null;\n}\n\n/** A drawn scatterplot: its specification, its element, and its engine. */\nexport interface Scatter3dHandle extends Scatter3dSpec {\n /**\n * The element Plotly drew into. Plotly returns it with an event emitter\n * attached, which is how the interactive layer hears about rotation.\n */\n readonly element: PlotlyHTMLElement;\n /** The engine that drew, ready for the next redraw and for teardown. */\n readonly plotly: PlotlyLike;\n}\n\n/**\n * Build the traces and the layout of a 3D scatterplot.\n *\n * @param data The frame to read.\n * @param options Which columns to draw, and how.\n * @returns The traces, the layout, and the note about the column choice.\n * @throws RangeError If the style is out of range, if the frame is ragged, if\n * fewer than three numeric columns are available, or if a named column is\n * absent or, on an axis, not numeric.\n */\nexport function scatter3dSpec(\n data: DataFrame,\n options: Scatter3dSpecOptions = {},\n): Scatter3dSpec {\n const {\n aspect = DEFAULT_SCATTER3D_STYLE.aspect,\n opacity = DEFAULT_SCATTER3D_STYLE.opacity,\n size = DEFAULT_SCATTER3D_STYLE.size,\n camera,\n titles,\n color,\n } = options;\n\n // R's order: the style first, and nothing else read until it passes.\n validateScatter3dStyle(aspect, opacity, size);\n // R cannot hold a ragged data frame. A JavaScript object can, and the rest\n // of this function would read past the end of the shorter column.\n frameRows(data);\n\n const { axes, note } = chooseAxes(data, options);\n const points = {\n x: requireAxisColumn(data, axes.x, \"x\"),\n y: requireAxisColumn(data, axes.y, \"y\"),\n z: requireAxisColumn(data, axes.z, \"z\"),\n };\n\n const colorColumn = color === undefined ? undefined : data[color];\n if (color !== undefined && colorColumn === undefined) {\n throw new RangeError(\n `Column \"${color}\" (passed as \\`color\\`) is not in the data.`,\n );\n }\n\n const traces = buildTraces(points, { opacity, size }, colorColumn);\n const shown = { x: axes.x, y: axes.y, z: axes.z, ...titles };\n const layout: PlotlyLayout = {\n uirevision: UIREVISION,\n scene: {\n aspectmode: \"manual\",\n aspectratio: {\n x: aspect[0] as number,\n y: aspect[1] as number,\n z: aspect[2] as number,\n },\n xaxis: { title: { text: shown.x } },\n yaxis: { title: { text: shown.y } },\n zaxis: { title: { text: shown.z } },\n uirevision: UIREVISION,\n ...(camera === undefined ? {} : { camera }),\n },\n };\n\n return { traces, layout, note };\n}\n\n/**\n * Draw a 3D scatterplot.\n *\n * @param target The element to draw into. Plotly fills it.\n * @param data The frame to read.\n * @param options Which columns to draw, how, and through which engine.\n * @returns The drawn plot: its element, its specification, and its engine.\n * @throws RangeError Everything `scatter3dSpec` throws, as a rejected promise.\n * No option reaches the engine until every check has passed.\n */\nexport async function plotScatter3d(\n target: HTMLElement,\n data: DataFrame,\n options: PlotScatter3dOptions = {},\n): Promise<Scatter3dHandle> {\n const { plotly, ...specOptions } = options;\n const spec = scatter3dSpec(data, specOptions);\n const engine = plotly ?? (await loadPlotly());\n const element = await engine.react(target, spec.traces, spec.layout, CONFIG);\n\n return { ...spec, element, plotly: engine };\n}\n\n/**\n * R's `scatter3d_validate_style()`, less the checks the compiler makes.\n *\n * Exported because R shares this check between the plot and the gadget, and\n * the gadget runs it before it builds anything. Note what it does **not** do:\n * it refuses a style no plot could be drawn with, and says nothing about the\n * bounds of the gadget's sliders. An aspect of 12 passes here and is then\n * clamped by the slider, which is R's behavior exactly.\n *\n * @param aspect The three axis proportions.\n * @param opacity How solid a marker is.\n * @param size How large a marker is.\n * @throws RangeError With R's own wording, in R's own order.\n */\nexport function validateScatter3dStyle(\n aspect: readonly number[],\n opacity: number,\n size: number,\n): void {\n // R also refuses a camera that is not a list, and an axis name that is not a\n // string. Both are compiler errors here, so neither check is written.\n if (aspect.length !== 3 || !aspect.every((value) => Number.isFinite(value))) {\n throw new RangeError(\"`aspect` must be a numeric vector of length 3.\");\n }\n if (aspect.some((value) => value <= 0)) {\n throw new RangeError(\"`aspect` values must all be positive.\");\n }\n if (!Number.isFinite(opacity) || opacity <= 0 || opacity > 1) {\n throw new RangeError(\"`opacity` must be a single numeric in (0, 1].\");\n }\n if (!Number.isFinite(size) || size <= 0) {\n throw new RangeError(\"`size` must be a single positive numeric.\");\n }\n}\n\n/**\n * Settle which column goes on which axis.\n *\n * R fills every axis it was not given from the first three numeric columns,\n * and reports the choice whenever a numeric column was left over.\n */\nfunction chooseAxes(\n data: DataFrame,\n options: Scatter3dSpecOptions,\n): {\n readonly axes: { readonly x: string; readonly y: string; readonly z: string };\n readonly note: string | null;\n} {\n const { x, y, z } = options;\n if (x !== undefined && y !== undefined && z !== undefined) {\n return { axes: { x, y, z }, note: null };\n }\n\n const numeric = numericColumns(data);\n requireThreeNumericColumns(numeric, \"plotScatter3d\");\n\n const chosen = numeric.slice(0, 3) as [string, string, string];\n const skipped = numeric.slice(3);\n const note =\n skipped.length === 0\n ? null\n : `plotScatter3d(): using numeric columns ${chosen.join(\", \")}; ` +\n `skipped ${skipped.join(\", \")}. Pass x/y/z to choose explicitly.`;\n\n return {\n axes: { x: x ?? chosen[0], y: y ?? chosen[1], z: z ?? chosen[2] },\n note,\n };\n}\n\n/**\n * Read one axis column.\n *\n * The wording is R's, which names the column, the argument it arrived through,\n * what the column holds, and where a categorical column belongs instead.\n */\nfunction requireAxisColumn(\n data: DataFrame,\n name: string,\n axis: string,\n): readonly number[] {\n const column = data[name];\n if (column === undefined) {\n throw new RangeError(\n `Column \"${name}\" (passed as \\`${axis}\\`) is not in the data.`,\n );\n }\n if (!isNumericColumn(column)) {\n throw new RangeError(\n `Column \"${name}\" (passed as \\`${axis}\\`) is ${describe(column)}; ` +\n \"plotScatter3d() requires numeric columns on x/y/z. \" +\n \"Use `color` for categorical separation.\",\n );\n }\n return column;\n}\n\n/** Say what a column holds, where R names the column's class. */\nfunction describe(column: Column): string {\n const kinds = new Set<string>(column.map((value) => typeof value));\n if (kinds.size === 0) {\n return \"empty\";\n }\n if (kinds.size > 1) {\n return \"mixed\";\n }\n if (kinds.has(\"string\")) {\n return \"text\";\n }\n return kinds.has(\"boolean\") ? \"true or false\" : \"numbers\";\n}\n\n/** Build the trace, or the traces, that carry the points. */\nfunction buildTraces(\n points: {\n readonly x: readonly number[];\n readonly y: readonly number[];\n readonly z: readonly number[];\n },\n marker: Scatter3dMarker,\n color: Column | undefined,\n): readonly Scatter3dTrace[] {\n if (color === undefined) {\n return [{ type: \"scatter3d\", mode: \"markers\", ...points, marker }];\n }\n\n if (isNumericColumn(color)) {\n return [\n {\n type: \"scatter3d\",\n mode: \"markers\",\n ...points,\n marker: {\n ...marker,\n color,\n colorscale: NUMERIC_COLORSCALE,\n showscale: true,\n },\n },\n ];\n }\n\n // One trace for each level, in the order the levels first appear, which is\n // the order Plotly then lists them in the legend.\n const levels = [...new Set(color.map((value) => String(value)))];\n return levels.map((level) => {\n const rows = color.flatMap((value, row) =>\n String(value) === level ? [row] : [],\n );\n return {\n type: \"scatter3d\",\n mode: \"markers\",\n x: rows.map((row) => points.x[row] as number),\n y: rows.map((row) => points.y[row] as number),\n z: rows.map((row) => points.z[row] as number),\n marker,\n name: level,\n showlegend: true,\n };\n });\n}\n",
8
+ "/**\n * The controls the 3D components build, and the rule for where a slider may\n * stand.\n *\n * Both 3D gadgets of the R package are panels of shiny inputs above a plot,\n * and both need the same three things: a labeled slider that shows its own\n * value, a labeled picker, and a line of text for what R would have written\n * to the console. They are here so that the two components differ in what\n * they control, not in how a control is made.\n *\n * The 2D components came first and built their controls inline. The reuse\n * audit at the end of the port found the same builders written out again in\n * each of them, so they share this module too: `interactiveTTest` and\n * `interactiveMatrixInverse` for the slider and the standing rule,\n * `interactiveSampling` for the picker.\n */\n\n/** Where a slider may stand: R's `min`, `max` and `step`. */\nexport interface SliderRange {\n readonly min: number;\n readonly max: number;\n readonly step: number;\n}\n\n/** A control, its label, and the element the component listens to. */\nexport interface BuiltSlider {\n /** The label element that holds the caption, the value, and the input. */\n readonly wrapper: HTMLElement;\n readonly input: HTMLInputElement;\n /** The element that shows the current value beside the caption. */\n readonly readout: HTMLElement;\n}\n\n/** A picker, its label, and the element the component listens to. */\nexport interface BuiltSelect {\n readonly wrapper: HTMLElement;\n readonly input: HTMLSelectElement;\n}\n\n/** A line of text for what R writes to the console. */\nexport interface BuiltNote {\n readonly element: HTMLElement;\n /** Show a note, or take the line away when there is none. */\n show(text: string | null): void;\n}\n\n/**\n * Correct a starting value to something the slider can stand at.\n *\n * Three rules, in order, taken from the `validate()` of the\n * `ion.rangeSlider.js` that ships inside shiny. A value that is not a number\n * becomes the minimum; a value outside the range moves to the nearer bound; a\n * value that misses the step moves to the nearest step, counted from the\n * minimum.\n *\n * The third rule is not R's — R leaves the handle wherever it was asked to\n * stand — but an HTML range input rounds a step-mismatched value by itself,\n * so a component that kept the asked-for number would draw one picture and\n * show a slider standing at another.\n *\n * @param given The value the caller asked for, or nothing.\n * @param fallback The value R's own argument defaults to.\n * @param range Where the slider may stand.\n * @returns A value on the slider's own grid.\n */\nexport function startingSliderValue(\n given: number | undefined,\n fallback: number,\n range: SliderRange,\n): number {\n if (given === undefined) {\n return fallback;\n }\n if (!Number.isFinite(given)) {\n return range.min;\n }\n\n const clamped = Math.min(range.max, Math.max(range.min, given));\n // Scaling both sides by the step's own precision keeps a value that sits\n // exactly halfway from rounding the wrong way: 1.25 is 32.5 steps above a\n // minimum of −2, and 3.25 / 0.1 alone lands a hair below that.\n const decimals = decimalsOf(range.step);\n const factor = 10 ** decimals;\n const steps = Math.round(\n ((clamped - range.min) * factor) / (range.step * factor),\n );\n const snapped = Number((range.min + steps * range.step).toFixed(decimals));\n // Every range in this port has its maximum on the step grid, so this only\n // guards a range that does not.\n return Math.min(range.max, snapped);\n}\n\n/** Return how many decimals a step carries. */\nfunction decimalsOf(step: number): number {\n return String(step).split(\".\")[1]?.length ?? 0;\n}\n\n/**\n * Build one labeled slider that shows its own value.\n *\n * @param owner The document to build in.\n * @param name The name the component reads the event by.\n * @param label R's own caption.\n * @param range Where the slider may stand.\n * @param value Where it starts. Pass a value `startingSliderValue` returned.\n * @returns The wrapper to append, the input to listen to, and the readout.\n */\nexport function buildSlider(\n owner: Document,\n name: string,\n label: string,\n range: SliderRange,\n value: number,\n): BuiltSlider {\n const wrapper = owner.createElement(\"label\");\n wrapper.style.display = \"block\";\n\n const caption = owner.createElement(\"span\");\n caption.textContent = `${label} `;\n\n const readout = owner.createElement(\"output\");\n readout.textContent = String(value);\n\n const input = owner.createElement(\"input\");\n input.type = \"range\";\n input.name = name;\n input.min = String(range.min);\n input.max = String(range.max);\n input.step = String(range.step);\n input.value = String(value);\n input.style.width = \"100%\";\n\n wrapper.appendChild(caption);\n wrapper.appendChild(readout);\n wrapper.appendChild(input);\n return { wrapper, input, readout };\n}\n\n/**\n * Build one labeled picker.\n *\n * @param owner The document to build in.\n * @param name The name the component reads the event by.\n * @param label R's own caption.\n * @param choices The options, in the order R lists them. A numeric choice\n * reaches the DOM as its own text, which is how R's own numeric choices\n * arrive there.\n * @param selected The option to start on.\n * @returns The wrapper to append, and the input to listen to.\n */\nexport function buildSelect(\n owner: Document,\n name: string,\n label: string,\n choices: readonly (string | number)[],\n selected: string | number,\n): BuiltSelect {\n const wrapper = owner.createElement(\"label\");\n wrapper.style.display = \"block\";\n\n const caption = owner.createElement(\"span\");\n caption.textContent = `${label} `;\n\n const input = owner.createElement(\"select\");\n input.name = name;\n input.style.width = \"100%\";\n for (const choice of choices) {\n const option = owner.createElement(\"option\");\n option.value = String(choice);\n option.textContent = String(choice);\n input.appendChild(option);\n }\n input.value = String(selected);\n\n wrapper.appendChild(caption);\n wrapper.appendChild(input);\n return { wrapper, input };\n}\n\n/**\n * Build the line that carries what R writes to the console.\n *\n * A library cannot write to a console, and the plot layer therefore returns\n * its message instead of printing it. One element, whose text is replaced,\n * so that a hundred redraws leave one sentence rather than a hundred.\n *\n * @param owner The document to build in.\n * @returns The element to append, and the way to set its text.\n */\nexport function buildNote(owner: Document): BuiltNote {\n const element = owner.createElement(\"p\");\n element.style.margin = \"4px 0 0\";\n element.style.fontSize = \"12px\";\n element.textContent = \"\";\n element.hidden = true;\n\n return {\n element,\n show(text: string | null): void {\n element.textContent = text ?? \"\";\n element.hidden = text === null;\n },\n };\n}\n",
9
+ "/**\n * The drawing surface that every 2D plot writes to.\n *\n * R's base graphics draw to a current device. Nothing here does: a plot\n * function receives its target and draws only to that target.\n *\n * `Context2D` lists the exact members of `CanvasRenderingContext2D` that this\n * library uses. A real context satisfies the type, and a test can pass any\n * object that implements those members. This matters because happy-dom has no\n * 2D canvas context, so a DOM alone cannot exercise a plot function. See\n * `test/recording-context.ts` for the stub the plot tests use.\n */\n\n/** The part of a canvas 2D context that the plot functions draw through. */\nexport type Context2D = Pick<\n CanvasRenderingContext2D,\n | \"fillStyle\"\n | \"strokeStyle\"\n | \"lineWidth\"\n | \"font\"\n | \"textAlign\"\n | \"textBaseline\"\n | \"save\"\n | \"restore\"\n | \"beginPath\"\n | \"moveTo\"\n | \"lineTo\"\n | \"arc\"\n | \"rect\"\n | \"fillRect\"\n | \"clip\"\n | \"fill\"\n | \"stroke\"\n | \"fillText\"\n | \"setLineDash\"\n | \"translate\"\n | \"rotate\"\n>;\n\n/** A context together with the pixel size of its surface. */\nexport interface RenderTarget {\n readonly ctx: Context2D;\n readonly width: number;\n readonly height: number;\n}\n\n/**\n * What a plot function accepts.\n *\n * Pass a canvas in a browser. Pass a `RenderTarget` to draw through your own\n * context, which is how the tests run without a DOM.\n */\nexport type PlotTarget = HTMLCanvasElement | RenderTarget;\n\n/**\n * Reduce a plot target to a context and a size.\n *\n * A canvas reports the size of its pixel store, which is the size the plot\n * draws in. On a dense screen those two part company: the store has to hold\n * more pixels than the layout does, or the browser stretches the image and\n * softens every edge.\n *\n * This function never touches a canvas the caller passed in — the caller owns\n * it, and resizing it under them would throw away whatever else they drew. So\n * a caller who wants a crisp picture on such a screen does three things:\n *\n * 1. size the store at the layout size times `devicePixelRatio`, and set the\n * CSS width and height to the layout size;\n * 2. call `ctx.scale(ratio, ratio)` once, so drawing carries on in layout\n * pixels;\n * 3. pass `{ ctx, width, height }` with the **layout** size, rather than the\n * canvas.\n *\n * The third step matters. Handing over the canvas would report the store size\n * on top of a context that already scales, and the picture would come out at\n * the square of the ratio. Reporting layout pixels also keeps `eventPixel`\n * right, since it divides the surface size by the size of the client\n * rectangle. `resolveControlTarget` in `../interactive/target.ts` does all\n * three for the canvas it builds itself.\n */\nexport function resolveTarget(target: PlotTarget): RenderTarget {\n if (\"ctx\" in target) {\n return target;\n }\n const ctx = target.getContext(\"2d\");\n if (ctx === null) {\n throw new Error(\n \"plot target: the canvas gave no 2D context. In tests, pass \" +\n \"{ ctx, width, height } instead of a canvas element.\",\n );\n }\n return { ctx, width: target.width, height: target.height };\n}\n",
10
+ "/**\n * The target that every interactive component attaches to.\n *\n * An interactive component needs two things: a surface to draw on and an\n * element that reports the clicks. A canvas is both, so a browser caller\n * passes one canvas.\n *\n * A test cannot pass a canvas. happy-dom gives a canvas no 2D context, so\n * nothing can draw to it. A test therefore passes the two things apart: a\n * recording surface to draw to, and a real element to dispatch events at. This\n * split is the pattern for every module in `src/interactive/`.\n */\n\nimport { resolveTarget } from \"../plot/target\";\nimport type { RenderTarget } from \"../plot/target\";\n\n/** The part of an element that an interactive component listens to. */\nexport type ClickSource = Pick<\n HTMLElement,\n \"addEventListener\" | \"removeEventListener\" | \"getBoundingClientRect\"\n>;\n\n/** A surface and an element, held apart. */\nexport interface SplitTarget {\n /** Where the component draws. */\n readonly surface: RenderTarget;\n /** Where the component listens. */\n readonly element: ClickSource;\n}\n\n/** What an interactive component accepts. */\nexport type InteractiveTarget = HTMLCanvasElement | SplitTarget;\n\n/**\n * Reduce an interactive target to a surface and an element.\n *\n * @param target A canvas, or a surface and an element.\n * @returns The two parts.\n * @throws Error If a canvas gives no 2D context.\n */\nexport function resolveInteractiveTarget(\n target: InteractiveTarget,\n): SplitTarget {\n if (\"surface\" in target) {\n return target;\n }\n return { surface: resolveTarget(target), element: target };\n}\n\n/**\n * Convert the position of a mouse event to a pixel of the surface.\n *\n * CSS may show a canvas at a size other than its pixel size. The function\n * therefore scales the position by the ratio of the two. A rectangle of zero\n * width or height carries no ratio, so the function reads the client position\n * as a surface pixel. Only a hidden element and a stub report such a\n * rectangle.\n *\n * @param element The element that received the event.\n * @param surface The drawing surface and its pixel size.\n * @param event The mouse event.\n * @returns The pixel column and row of the event.\n */\nexport function eventPixel(\n element: ClickSource,\n surface: RenderTarget,\n event: MouseEvent,\n): { readonly x: number; readonly y: number } {\n const rect = element.getBoundingClientRect();\n const scaleX = rect.width === 0 ? 1 : surface.width / rect.width;\n const scaleY = rect.height === 0 ? 1 : surface.height / rect.height;\n return {\n x: (event.clientX - rect.left) * scaleX,\n y: (event.clientY - rect.top) * scaleY,\n };\n}\n\n/**\n * A drawing surface and an element to build controls in, held apart.\n *\n * This is the `SplitTarget` idea again, for a component driven by a panel of\n * controls rather than by clicks on the picture. A test passes the two parts,\n * so it can drive the inputs without a real layout and without a canvas that\n * happy-dom cannot give a context to.\n */\nexport interface PanelTarget {\n /** Where the component draws. */\n readonly surface: RenderTarget;\n /** Where the component builds its inputs. The caller keeps this element. */\n readonly controls: HTMLElement;\n}\n\n/**\n * What a control-driven component accepts.\n *\n * Pass a container element in a browser and the component fills it. Pass a\n * `PanelTarget` to hold the two parts apart, which is how the tests run.\n */\nexport type ControlTarget = HTMLElement | PanelTarget;\n\n/** A resolved panel, and a way to take back anything that was built for it. */\nexport interface ResolvedPanel {\n readonly surface: RenderTarget;\n readonly controls: HTMLElement;\n /** Remove what this resolver created. A no-op when the caller supplied it. */\n release(): void;\n}\n\n/** R lays the gadget out as a 140px column of controls beside the plot. */\nconst CONTROL_COLUMN_WIDTH = 140;\nconst FALLBACK_WIDTH = 640;\nconst FALLBACK_HEIGHT = 400;\n\n/**\n * Reduce a control target to a surface and a place to build controls.\n *\n * Given a container, this builds the canvas and the controls column inside it\n * in R's arrangement, and `release()` takes them out again. Given the parts,\n * it passes them through and `release()` does nothing, because the caller owns\n * what it supplied.\n *\n * @param target A container element, or a surface and a controls host.\n * @returns The two parts and a way to undo what was built.\n * @throws Error If a container is a canvas, or if a created canvas gives no 2D\n * context.\n */\nexport function resolveControlTarget(target: ControlTarget): ResolvedPanel {\n if (\"surface\" in target) {\n return {\n surface: target.surface,\n controls: target.controls,\n release: () => undefined,\n };\n }\n\n if (target.tagName === \"CANVAS\") {\n throw new Error(\n \"interactive target: pass a container element to build the panel in, \" +\n \"not a canvas. A canvas has no room for the controls.\",\n );\n }\n\n const owner = target.ownerDocument;\n const controls = owner.createElement(\"div\");\n controls.style.width = `${CONTROL_COLUMN_WIDTH}px`;\n controls.style.flexShrink = \"0\";\n controls.style.padding = \"4px 6px\";\n controls.style.overflowY = \"auto\";\n\n const width =\n target.clientWidth > CONTROL_COLUMN_WIDTH\n ? target.clientWidth - CONTROL_COLUMN_WIDTH\n : FALLBACK_WIDTH;\n const height =\n target.clientHeight > 0 ? target.clientHeight : FALLBACK_HEIGHT;\n const ratio = pixelRatio();\n\n // The store holds one pixel per device pixel; the style keeps the element\n // the size the layout asked for. Without this the browser stretches a\n // smaller image over a denser screen and every edge, letters worst of all,\n // comes out soft.\n const canvas = owner.createElement(\"canvas\");\n canvas.width = Math.round(width * ratio);\n canvas.height = Math.round(height * ratio);\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n canvas.style.minWidth = \"0\";\n\n target.style.display = \"flex\";\n target.appendChild(controls);\n target.appendChild(canvas);\n\n const remove = (): void => {\n controls.remove();\n canvas.remove();\n };\n\n const context = canvas.getContext(\"2d\");\n if (context === null) {\n // Leave the container as it was found rather than half filled.\n remove();\n throw new Error(\n \"interactive target: the canvas gave no 2D context. In tests, pass \" +\n \"{ surface: { ctx, width, height }, controls } instead of a container.\",\n );\n }\n\n // Scale once, here, so that everything drawn afterwards keeps working in\n // layout pixels and knows nothing about the density of the screen.\n if (ratio !== 1) {\n context.scale(ratio, ratio);\n }\n\n return { surface: { ctx: context, width, height }, controls, release: remove };\n}\n\n/**\n * An element for Plotly to fill, and an element to build controls in.\n *\n * The third target shape of the port, after `SplitTarget` and `PanelTarget`.\n * The 3D components need it because Plotly draws into an element of its own\n * rather than onto a canvas: there is no context to hand around, and the\n * element the plot lives in is the element the engine later purges.\n */\nexport interface Plot3dPanel {\n /** Where Plotly draws. The component gives this element to the plot. */\n readonly plot: HTMLElement;\n /** Where the component builds its inputs. */\n readonly controls: HTMLElement;\n}\n\n/**\n * What a 3D component accepts.\n *\n * Pass a container element in a browser and the component fills it. Pass the\n * two parts to hold them apart, which is how the tests run.\n */\nexport type Plot3dTarget = HTMLElement | Plot3dPanel;\n\n/** A resolved 3D panel, and a way to take back anything built for it. */\nexport interface ResolvedPlot3dPanel extends Plot3dPanel {\n /** Remove what this resolver created. A no-op when the caller supplied it. */\n release(): void;\n}\n\n/** The height a plot element falls back to when the container declares none. */\nconst FALLBACK_PLOT_HEIGHT = 480;\n\n/**\n * Reduce a 3D target to a plot element and a place to build controls.\n *\n * Given a container, this builds the two elements in R's own arrangement: a\n * strip of controls across the top, and the plot filling what is left. R's\n * gadget lays both 3D families out that way (`flex-direction: column`, the\n * control rows `flex-shrink: 0`, the plot `flex: 1`).\n *\n * @param target A container element, or the two parts.\n * @returns The two parts and a way to undo what was built.\n * @throws Error If a container is a canvas, which Plotly cannot draw into.\n */\nexport function resolvePlot3dTarget(target: Plot3dTarget): ResolvedPlot3dPanel {\n if (\"plot\" in target) {\n return {\n plot: target.plot,\n controls: target.controls,\n release: () => undefined,\n };\n }\n\n if (target.tagName === \"CANVAS\") {\n throw new Error(\n \"interactive target: pass a container element to build the panel in, \" +\n \"not a canvas. Plotly draws into an element of its own.\",\n );\n }\n\n const owner = target.ownerDocument;\n const controls = owner.createElement(\"div\");\n controls.style.display = \"flex\";\n controls.style.flexWrap = \"wrap\";\n controls.style.gap = \"12px\";\n controls.style.padding = \"8px\";\n controls.style.flexShrink = \"0\";\n\n const plot = owner.createElement(\"div\");\n plot.style.flex = \"1 1 auto\";\n plot.style.minHeight =\n target.clientHeight > 0 ? \"0\" : `${FALLBACK_PLOT_HEIGHT}px`;\n\n target.style.display = \"flex\";\n target.style.flexDirection = \"column\";\n target.appendChild(controls);\n target.appendChild(plot);\n\n return {\n plot,\n controls,\n release: () => {\n controls.remove();\n plot.remove();\n },\n };\n}\n\n/**\n * How many device pixels the screen puts in a layout pixel.\n *\n * Anything other than a positive number, which is what a test environment\n * without a screen reports, counts as one.\n */\nfunction pixelRatio(): number {\n const ratio = globalThis.devicePixelRatio;\n return typeof ratio === \"number\" && ratio > 0 ? ratio : 1;\n}\n",
11
+ "/**\n * The interactive 3D scatterplot: choose the columns, set the style, turn the\n * cloud, and take the resulting call away with you.\n *\n * This is the port of `interactive_scatter3d()` in\n * `../compstatslib/R/scatter3d_interactive.R`. R builds a shiny gadget with\n * four pickers and five sliders and re-runs `plot_scatter3d()` on every\n * change. This module does the same: it owns the controls, the state in them,\n * and the camera the user turned to, and hands every draw to `plotScatter3d`.\n * It builds no trace and no layout of its own.\n *\n * Four things are worth knowing before reading the code.\n *\n * **Everything is checked before anything is built.** R validates the style,\n * then the axis arguments, then the frame, and only then opens the gadget, so\n * a bad argument leaves no window and no plot. The order and the wording here\n * are R's, and the style check is R's own function, imported from the plot\n * layer rather than written again.\n *\n * **Out of range is not the same as invalid.** R's check refuses a style no\n * plot could be drawn with — an opacity of 0, a negative aspect — and says\n * nothing about the bounds of its own sliders. `aspect = 12` passes it, and\n * the widget then clamps the handle to 10. So this component throws exactly\n * where R throws, and clamps and snaps where R's widget clamps.\n *\n * **The camera is captured, not computed.** Plotly reports where the user\n * turned the plot to through `plotly_relayout`; the component stores that\n * camera and re-passes it into every later draw, so that changing a column\n * does not throw the angle away. Turning the plot draws nothing: Plotly has\n * already moved the picture. The captured camera is also written back into\n * Plotly's own stored layout, because the modebar's buttons relayout the\n * scene from that layout and would otherwise snap the view to the default —\n * a Plotly quirk the R gadget shares, and one deliberate deviation here.\n *\n * **Done hands back a state, not a printed call.** R prints a copy-pasteable\n * `plot_scatter3d(...)` line to the console and returns the same arguments\n * invisibly. A library has no console, and a string would have to be parsed\n * to be used again; so `getValues()` returns the options object that\n * reproduces the picture, and `onDone` receives it. Feeding it back to\n * `plotScatter3d` — or to this function — is R's `do.call` equivalent.\n *\n * One R behavior is absent for R's own reason: the gadget shows no message\n * about the column choice. `plot_scatter3d()` writes one when it picks the\n * columns itself, and neither gadget lets it: R passes `input$x`, `input$y`\n * and `input$z` on every render, as this component passes its own state. The\n * choice is visible in the pickers instead.\n */\n\nimport { numericColumns, requireThreeNumericColumns } from \"../core/frame\";\nimport type { DataFrame } from \"../core/frame\";\nimport {\n DEFAULT_SCATTER3D_STYLE,\n plotScatter3d,\n validateScatter3dStyle,\n} from \"../plot/scatter3d\";\nimport type {\n PlotScatter3dOptions,\n Scatter3dSpec,\n Scatter3dSpecOptions,\n} from \"../plot/scatter3d\";\nimport { sameCamera } from \"../plot/plotly\";\nimport type {\n PlotlyHTMLElement,\n PlotlyLike,\n PlotlyRelayoutEvent,\n} from \"../plot/plotly\";\nimport {\n buildNote,\n buildSelect,\n buildSlider,\n startingSliderValue,\n} from \"./controls\";\nimport type { SliderRange } from \"./controls\";\nimport { resolvePlot3dTarget } from \"./target\";\nimport type { Plot3dTarget } from \"./target\";\n\n/**\n * Everything the panel holds, and everything that reproduces the picture.\n *\n * This is `Scatter3dSpecOptions` with the parts the gadget always settles —\n * the three axes and the three style numbers — made certain. Hand it to\n * `plotScatter3d`, or back to `interactiveScatter3d`, to open at the same\n * view. It is the port's answer to the call R prints on Done.\n */\nexport interface Scatter3dValues extends Scatter3dSpecOptions {\n /** The column on the first horizontal axis. */\n readonly x: string;\n /** The column on the second horizontal axis. */\n readonly y: string;\n /** The column on the vertical axis. */\n readonly z: string;\n /** The three axis proportions. */\n readonly aspect: readonly number[];\n /** How solid each marker is. */\n readonly opacity: number;\n /** How large each marker is. */\n readonly size: number;\n}\n\n/**\n * What the component accepts.\n *\n * Every option of `plotScatter3d` is a starting value, exactly as in R, and\n * anything the plot grows later reaches it untouched.\n */\nexport interface InteractiveScatter3dOptions extends PlotScatter3dOptions {\n /** What to run on `done()`. */\n readonly onDone?: (values: Scatter3dValues) => void;\n}\n\n/** What the caller holds after the component starts. */\nexport interface InteractiveScatter3dHandle {\n /**\n * Return the state the panel stands at: the options that reproduce the\n * picture, including a camera the user turned to.\n */\n getValues(): Scatter3dValues;\n /**\n * Return what the last draw specified — its traces, its layout, and the\n * plot layer's note. Null until the first picture is drawn.\n */\n getSpec(): Scatter3dSpec | null;\n /**\n * Wait for the drawing now in flight. Drawing is asynchronous, so this is\n * how a caller — or a test — knows the picture is on the screen.\n */\n rendered(): Promise<void>;\n /** Hand the current state to the `onDone` callback. */\n done(): void;\n /** Stop listening, purge the plot, and take back what was built. */\n destroy(): void;\n}\n\n/** R's `choices = c(\"(none)\", names(data))` sentinel for no color. */\nconst NONE = \"(none)\";\n\n/** R: `sliderInput(\"aspect_x\", \"Aspect X\", min = 0.1, max = 10, step = .1)`. */\nconst ASPECT_RANGE: SliderRange = { min: 0.1, max: 10, step: 0.1 };\n/** R: `sliderInput(\"opacity\", \"Opacity\", min = 0.05, max = 1, step = 0.05)`. */\nconst OPACITY_RANGE: SliderRange = { min: 0.05, max: 1, step: 0.05 };\n/** R: `sliderInput(\"size\", \"Size\", min = 1, max = 20, step = 1)`. */\nconst SIZE_RANGE: SliderRange = { min: 1, max: 20, step: 1 };\n\n/** The three aspect sliders, in R's order, with the axis each one drives. */\nconst ASPECT_SLIDERS = [\n { name: \"aspectX\", label: \"Aspect X\" },\n { name: \"aspectY\", label: \"Aspect Y\" },\n { name: \"aspectZ\", label: \"Aspect Z\" },\n] as const;\n\n/**\n * Start an interactive 3D scatterplot on a target.\n *\n * The component builds its controls, draws once, and redraws on every change.\n *\n * @param target A container element, or a plot element and a controls host.\n * See `./target.ts`.\n * @param data The frame to read. It needs three numeric columns.\n * @param options Starting values, a done callback, and the options of\n * `plotScatter3d`.\n * @returns The handle to the running component. Await `rendered()` for the\n * first picture.\n * @throws RangeError If the style is one no plot could be drawn with, if the\n * frame has fewer than three numeric columns, or if an initial column is\n * not one the picker could stand on. Nothing is built and nothing is drawn\n * in any of those cases.\n * @throws Error If a canvas is passed as the container.\n */\nexport function interactiveScatter3d(\n target: Plot3dTarget,\n data: DataFrame,\n options: InteractiveScatter3dOptions = {},\n): InteractiveScatter3dHandle {\n // Everything `plotScatter3d` may grow later stays in `forwarded` and\n // reaches it untouched, so a new plot option needs no edit here.\n const {\n plotly: givenEngine,\n onDone,\n x,\n y,\n z,\n color,\n aspect,\n opacity,\n size,\n camera,\n titles,\n ...forwarded\n } = options;\n\n // R's order, and R's own check: the style first of all.\n const style = {\n aspect: aspect ?? DEFAULT_SCATTER3D_STYLE.aspect,\n opacity: opacity ?? DEFAULT_SCATTER3D_STYLE.opacity,\n size: size ?? DEFAULT_SCATTER3D_STYLE.size,\n };\n validateScatter3dStyle(style.aspect, style.opacity, style.size);\n\n const numeric = numericColumns(data);\n requireThreeNumericColumns(numeric, \"interactiveScatter3d\");\n for (const [axis, given] of [\n [\"x\", x],\n [\"y\", y],\n [\"z\", z],\n ] as const) {\n if (given !== undefined && !numeric.includes(given)) {\n throw new RangeError(\n `Initial \\`${axis}\\` (\"${given}\") is not a numeric column of ` +\n `\\`data\\`. Numeric columns: ${numeric.join(\", \")}.`,\n );\n }\n }\n if (color !== undefined && data[color] === undefined) {\n throw new RangeError(`Initial \\`color\\` (\"${color}\") is not in \\`data\\`.`);\n }\n\n const panel = resolvePlot3dTarget(target);\n const owner = panel.controls.ownerDocument;\n\n let values: Scatter3dValues = {\n x: x ?? numeric[0],\n y: y ?? numeric[1],\n z: z ?? numeric[2],\n color,\n aspect: style.aspect.map((value, axis) =>\n startingSliderValue(\n value,\n DEFAULT_SCATTER3D_STYLE.aspect[axis],\n ASPECT_RANGE,\n ),\n ),\n opacity: startingSliderValue(\n style.opacity,\n DEFAULT_SCATTER3D_STYLE.opacity,\n OPACITY_RANGE,\n ),\n size: startingSliderValue(\n style.size,\n DEFAULT_SCATTER3D_STYLE.size,\n SIZE_RANGE,\n ),\n camera,\n titles,\n };\n\n let spec: Scatter3dSpec | null = null;\n let engine: PlotlyLike | undefined = givenEngine;\n let element: PlotlyHTMLElement | null = null;\n let listening = false;\n let destroyed = false;\n let inFlight: Promise<void> | null = null;\n let queued = false;\n\n const note = buildNote(owner);\n\n /**\n * Draw once, at whatever the panel stands at now.\n *\n * The engine is resolved by the first draw and held afterwards, so a\n * component loads Plotly once however often it redraws.\n */\n async function renderOnce(): Promise<void> {\n const drawn = await plotScatter3d(panel.plot, data, {\n ...forwarded,\n ...values,\n plotly: engine,\n });\n if (destroyed) {\n return;\n }\n\n engine = drawn.plotly;\n element = drawn.element;\n spec = { traces: drawn.traces, layout: drawn.layout, note: drawn.note };\n note.show(drawn.note);\n\n // One listener for the life of the component: Plotly hands back the same\n // element every time, so attaching per draw would pile them up.\n if (!listening) {\n listening = true;\n element.on(\"plotly_relayout\", handleRelayout);\n }\n }\n\n /**\n * Draw, and never draw twice at once.\n *\n * A dragged slider fires an event for every step, and each draw is\n * asynchronous. Overlapping draws could reach the engine out of order and\n * leave the picture at a value the user has already left. So a request that\n * arrives while a draw is in flight is remembered, not started, and the\n * draw that follows reads the state as it stands then: the last value\n * always wins, and one draw is in flight at a time.\n */\n function requestRender(): void {\n if (destroyed) {\n return;\n }\n queued = true;\n inFlight ??= start();\n }\n\n function start(): Promise<void> {\n const run = pump();\n // A caller that never awaits must not be handed an unhandled rejection;\n // `rendered()` still reports the failure to anyone who asks.\n run.catch(() => undefined);\n return run;\n }\n\n async function pump(): Promise<void> {\n try {\n while (queued && !destroyed) {\n queued = false;\n await renderOnce();\n }\n } finally {\n inFlight = null;\n }\n }\n\n /**\n * R's observer: store the camera, and leave the picture alone — with one\n * addition R does not need. Plotly's own modebar buttons (orbit, turntable,\n * pan, zoom) relayout the scene from the stored layout, and a dragged\n * camera lives only in the WebGL scene until it is written back; without\n * the push below, every modebar click snapped the view to the default. The\n * push itself echoes through this handler with the same camera as a fresh\n * object, which is what the value comparison recognizes and drops.\n */\n function handleRelayout(event: PlotlyRelayoutEvent): void {\n const moved = event[\"scene.camera\"];\n if (moved === undefined || destroyed || sameCamera(moved, values.camera)) {\n return;\n }\n values = { ...values, camera: moved };\n if (element !== null && engine !== undefined) {\n // Fire and forget: the picture is already at this view, so a failure\n // here (a plot purged mid-flight) has nothing to repair.\n engine.relayout(element, { \"scene.camera\": moved }).catch(() => undefined);\n }\n }\n\n function handleChange(event: Event): void {\n const input = event.target as HTMLSelectElement;\n if (input.name === \"color\") {\n values = {\n ...values,\n color: input.value === NONE ? undefined : input.value,\n };\n } else {\n values = { ...values, [input.name]: input.value };\n }\n requestRender();\n }\n\n function handleInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n // A slider keeps its own value inside the range and on the step, so what\n // it reports needs no correcting.\n const moved = Number(input.value);\n const axis = ASPECT_SLIDERS.findIndex(\n (slider) => slider.name === input.name,\n );\n if (axis >= 0) {\n values = {\n ...values,\n aspect: values.aspect.map((was, index) =>\n index === axis ? moved : was,\n ),\n };\n } else {\n values = { ...values, [input.name]: moved };\n }\n\n const readout = readouts.get(input.name);\n if (readout !== undefined) {\n readout.textContent = input.value;\n }\n requestRender();\n }\n\n const built: HTMLElement[] = [];\n const selects: HTMLSelectElement[] = [];\n const sliders: HTMLInputElement[] = [];\n const readouts = new Map<string, HTMLElement>();\n\n for (const [axis, label] of [\n [\"x\", \"X\"],\n [\"y\", \"Y\"],\n [\"z\", \"Z\"],\n ] as const) {\n const picker = buildSelect(owner, axis, label, numeric, values[axis]);\n panel.controls.appendChild(picker.wrapper);\n built.push(picker.wrapper);\n selects.push(picker.input);\n }\n\n const colorPicker = buildSelect(\n owner,\n \"color\",\n \"Color\",\n [NONE, ...Object.keys(data)],\n values.color ?? NONE,\n );\n panel.controls.appendChild(colorPicker.wrapper);\n built.push(colorPicker.wrapper);\n selects.push(colorPicker.input);\n\n for (const [axis, wanted] of ASPECT_SLIDERS.entries()) {\n const control = buildSlider(\n owner,\n wanted.name,\n wanted.label,\n ASPECT_RANGE,\n values.aspect[axis],\n );\n panel.controls.appendChild(control.wrapper);\n built.push(control.wrapper);\n sliders.push(control.input);\n readouts.set(wanted.name, control.readout);\n }\n\n for (const [name, label, range, value] of [\n [\"opacity\", \"Opacity\", OPACITY_RANGE, values.opacity],\n [\"size\", \"Size\", SIZE_RANGE, values.size],\n ] as const) {\n const control = buildSlider(owner, name, label, range, value);\n panel.controls.appendChild(control.wrapper);\n built.push(control.wrapper);\n sliders.push(control.input);\n readouts.set(name, control.readout);\n }\n\n panel.controls.appendChild(note.element);\n built.push(note.element);\n\n for (const select of selects) {\n select.addEventListener(\"change\", handleChange);\n }\n for (const slider of sliders) {\n slider.addEventListener(\"input\", handleInput);\n }\n\n // R's renderPlot runs as the gadget opens, at the initial settings.\n requestRender();\n\n /** A copy deep enough that a caller cannot reach back into the state. */\n function currentValues(): Scatter3dValues {\n return { ...values, aspect: [...values.aspect] };\n }\n\n return {\n getValues: currentValues,\n getSpec: () => spec,\n rendered: () => inFlight ?? Promise.resolve(),\n done() {\n onDone?.(currentValues());\n },\n destroy() {\n if (destroyed) {\n return;\n }\n destroyed = true;\n for (const select of selects) {\n select.removeEventListener(\"change\", handleChange);\n }\n for (const slider of sliders) {\n slider.removeEventListener(\"input\", handleInput);\n }\n for (const node of built) {\n node.remove();\n }\n if (element !== null) {\n element.removeAllListeners(\"plotly_relayout\");\n engine?.purge(element);\n }\n panel.release();\n },\n };\n}\n",
12
+ "/**\n * Shared array arithmetic for the core modules.\n *\n * Use these helpers with `map` instead of index-based loops. See the\n * iteration convention in CLAUDE.md.\n */\n\n/** Add all values. Return 0 for an empty array. */\nexport function sum(values: readonly number[]): number {\n return values.reduce((total, value) => total + value, 0);\n}\n\n/** Return the arithmetic mean. Return NaN for an empty array. */\nexport function mean(values: readonly number[]): number {\n return sum(values) / values.length;\n}\n\n/**\n * Return the smallest and the largest value, as R's `range()` does.\n *\n * Written as a fold rather than `Math.min(...values)`, which overflows the\n * call stack on a long column.\n *\n * @param values The observations.\n * @returns The lowest and the highest value. An empty array returns\n * [Infinity, -Infinity], the shape of R's `range(numeric(0))`.\n *\n * A comparison keeps the accumulator when it is false, so a NaN entry is\n * skipped rather than carried through. No caller supports NaN input: the\n * modules that call this either drop the non-finite values first or state\n * that they do not handle R's NA.\n */\nexport function extent(values: readonly number[]): [number, number] {\n return values.reduce<[number, number]>(\n ([low, high], value) => [\n value < low ? value : low,\n value > high ? value : high,\n ],\n [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY],\n );\n}\n\n/**\n * Map a negative zero to a positive one.\n *\n * A computed zero can come out of an algorithm with a sign that R's own\n * zeros never carry: of 1498 zero entries of a matrix inverse over a sweep of\n * 20000 slider settings, R gives a positive zero every time.\n */\nexport function withoutNegativeZero(value: number): number {\n return value === 0 ? 0 : value;\n}\n\n/** Reject a count that is not a non-negative integer. */\nexport function requireCount(value: number, name: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new RangeError(`${name} must be a non-negative integer, got ${value}`);\n }\n}\n\n/**\n * Combine two arrays element by element.\n *\n * Stop at the end of the shorter array.\n */\nexport function zipWith<A, B, C>(\n as: readonly A[],\n bs: readonly B[],\n combine: (a: A, b: B) => C,\n): C[] {\n const length = Math.min(as.length, bs.length);\n // The slice bounds the index, so the access cannot be undefined.\n return as.slice(0, length).map((a, index) => combine(a, bs[index] as B));\n}\n\n/**\n * Return the standard deviation, with the n − 1 denominator of R's `sd()`.\n *\n * @param values The observations.\n * @returns The standard deviation, or NaN below two values. R returns NA\n * there, with a warning that a library cannot give.\n */\nexport function sd(values: readonly number[]): number {\n if (values.length < 2) {\n return Number.NaN;\n }\n\n const center = mean(values);\n const squares = values.map((value) => (value - center) * (value - center));\n return Math.sqrt(sum(squares) / (values.length - 1));\n}\n\n/**\n * Return the mean absolute deviation, `mean(|x - mean(x)|)`.\n *\n * R base has no function for this. R's `mad()` is the *median* absolute\n * deviation from the median, scaled by 1.4826, which is a different\n * statistic. A caller that shows either one to a reader must write the name\n * in full, because the abbreviation covers both.\n *\n * The sampling demonstration offers this as one of its choices of statistic.\n * It measures spread in the units of the data, as the standard deviation\n * does, but a value far from the mean moves it less, because the distance is\n * not squared.\n *\n * @param values The observations.\n * @returns The mean distance from the mean. One value gives 0, because it\n * sits at its own mean. No values gives NaN, as `mean` does.\n */\nexport function meanAbsoluteDeviation(values: readonly number[]): number {\n const center = mean(values);\n return mean(values.map((value) => Math.abs(value - center)));\n}\n\n/**\n * Return `a * b + c`, rounded once.\n *\n * Written as `a * b + c`, JavaScript rounds twice — once for the product,\n * once for the sum — and the two roundings show. R's `seq.int` rounds once\n * and lands one unit in the last place away often enough to change a tick.\n * The linear algebra in `matrix.ts` needs the same: the compiler of the R\n * install the fixtures come from contracts a multiply and an add into one\n * instruction, so a matrix near singular differs in every digit without it.\n *\n * The two helpers below split each operation into the value a double can\n * hold plus the part it drops, so the dropped parts can be added back before\n * the one rounding that remains. Both are the standard error-free\n * transformations (Dekker 1971, Knuth). Both need every intermediate to stay\n * in range, which fails only within a factor of 2^28 of the largest double.\n * There the plain form is used: the result is already dominated by its own\n * overflow.\n */\nexport function fusedMultiplyAdd(a: number, b: number, c: number): number {\n const [product, productError] = twoProduct(a, b);\n const [sum, sumError] = twoSum(c, product);\n const rounded = sum + (sumError + productError);\n return Number.isFinite(rounded) ? rounded : a * b + c;\n}\n\n/** Split a double into two halves whose product is exact. Dekker's method. */\nfunction split(value: number): [number, number] {\n const scaled = 134217729 * value;\n const high = scaled - (scaled - value);\n return [high, value - high];\n}\n\n/** Return the product and the part of it the product cannot hold. */\nfunction twoProduct(a: number, b: number): [number, number] {\n const product = a * b;\n const [aHigh, aLow] = split(a);\n const [bHigh, bLow] = split(b);\n const error =\n aLow * bLow - (product - aHigh * bHigh - aLow * bHigh - aHigh * bLow);\n return [product, error];\n}\n\n/** Return the sum and the part of it the sum cannot hold. */\nfunction twoSum(a: number, b: number): [number, number] {\n const sum = a + b;\n const carried = sum - a;\n return [sum, a - (sum - carried) + (b - carried)];\n}\n\n/**\n * Return a sample quantile, by the rule of R's `quantile(type = 7)`.\n *\n * Type 7 is the default of R's `quantile()`, and so the rule behind the\n * `IQR()` that `bw.nrd0()` uses to pick a bandwidth. It reads the sorted\n * values at position `1 + (n - 1) * p` and interpolates between the two\n * neighbors of a fractional position.\n *\n * @param values The observations. The function does not modify them.\n * @param p The probability. It must be in [0, 1].\n * @returns The quantile, or NaN for no values. R returns NA there.\n * @throws RangeError If p is outside [0, 1], as R does.\n */\nexport function quantile(values: readonly number[], p: number): number {\n return quantiles(values, [p])[0] as number;\n}\n\n/**\n * Return several sample quantiles, by the rule of R's `quantile(type = 7)`.\n *\n * R's `quantile()` also takes a vector of probabilities, and for one reason:\n * it sorts once and reads every position off the one sorted copy. Asking for\n * the two quartiles together instead of one at a time halves the work, which\n * is what the bandwidth rule does over a pooled sample.\n *\n * @param values The observations. The function does not modify them.\n * @param probs The probabilities. Each must be in [0, 1].\n * @returns One quantile per probability, in the order given. Each is NaN for\n * no values, where R returns NA.\n * @throws RangeError If a probability is outside [0, 1], as R does.\n */\nexport function quantiles(\n values: readonly number[],\n probs: readonly number[],\n): number[] {\n if (probs.some((p) => !(p >= 0 && p <= 1))) {\n throw new RangeError(`every probability must be in [0, 1], got ${probs}`);\n }\n if (values.length === 0) {\n return probs.map(() => Number.NaN);\n }\n\n // A Float64Array sorts by value with no comparator to call, which is about\n // three times faster than sorting a copy of the array over a pooled sample.\n const sorted = Float64Array.from(values).sort();\n\n return probs.map((p) => type7(sorted, p));\n}\n\n/**\n * Return the median, the value with half the observations on each side.\n *\n * R's `median()` sorts the values and, on an even count, averages the two in\n * the middle. That is the type-7 quantile at 0.5, which weights those same two\n * values by a half each, so this delegates rather than repeat the rule. The\n * two forms land on the same double, the halves included.\n *\n * The sampling demonstration offers this as one of its choices of statistic.\n * It marks the center in the units of the data, as the mean does, but a value\n * far from the center moves it very little, because only the ordering counts.\n *\n * @param values The observations. The function does not modify them.\n * @returns The median, or NaN for no values. R returns NA there.\n */\nexport function median(values: readonly number[]): number {\n return quantile(values, 0.5);\n}\n\n/** Read one type-7 quantile off already sorted values. */\nfunction type7(sorted: Float64Array, p: number): number {\n const position = 1 + (sorted.length - 1) * p;\n const below = Math.floor(position);\n const above = Math.ceil(position);\n // Both indices are inside the array: p in [0, 1] bounds the position by\n // 1 and by the length.\n const low = sorted[below - 1] as number;\n const high = sorted[above - 1] as number;\n\n if (position > below && high !== low) {\n // R's own form. The algebraically equal low + h * (high - low) rounds\n // differently, and this keeps the last bits with R.\n const h = position - below;\n return (1 - h) * low + h * high;\n }\n return low;\n}\n",
13
+ "/**\n * Dense (weighted) least squares for small designs.\n *\n * This is the equivalent of R's `lm.wfit()`, and of the solver R runs inside\n * every step of `glm.fit()`'s IRLS loop. R factors the design with `dqrdc2`,\n * a Householder QR with a limited column-pivoting rule: a column whose norm\n * has collapsed against the columns to its left is moved to the right edge\n * and its coefficient is reported as `NA`. The port reproduces that rule,\n * because it is what makes `lm()` and `glm()` report an aliased coefficient\n * instead of dividing by a near-zero pivot. Verified against R in\n * `ols.test.ts`.\n *\n * Designs here are tiny — two columns for logit, four for a moderation\n * surface — so the code follows the LINPACK routine plainly rather than\n * blocking or vectorizing it.\n */\n\nimport { sum, zipWith } from \"./arith\";\n\n/**\n * The result of a fit.\n *\n * A `null` coefficient is the equivalent of R's `NA`: the column carried no\n * information beyond the columns to its left, so R aliases it. `linearRegression`\n * uses the same convention.\n */\nexport interface LeastSquaresFit {\n /**\n * One coefficient per design column, in column order. An aliased column\n * reports null.\n */\n readonly coefficients: readonly (number | null)[];\n /** The fitted response of each row, in input order. */\n readonly fitted: readonly number[];\n /** Response minus fit, of each row, in input order. */\n readonly residuals: readonly number[];\n /** The number of columns the fit could identify. */\n readonly rank: number;\n}\n\nexport interface LeastSquaresOptions {\n /**\n * One weight per row, on R's `lm.wfit()` scale: the solver applies the\n * square root itself.\n *\n * IRLS is the trap here. `glm.fit` carries square-root weights `w` and\n * hands `x * w` to its QR routine, so a caller porting that loop passes\n * `w * w` here, not `w`.\n *\n * A weight of zero drops the row from the fit. The row still gets a fitted\n * value, predicted from the other rows, as it does in R.\n */\n readonly weights?: readonly number[];\n /**\n * How far a column's norm may collapse before the fit aliases it.\n *\n * A column is aliased when its norm, after the columns to its left are\n * projected out, falls below this fraction of its original norm. The\n * default is the value `lm.fit()` uses. `glm.fit()` passes\n * `min(1e-7, epsilon / 1000)`, which is `1e-11` at R's default epsilon.\n */\n readonly tolerance?: number;\n}\n\n/** The rank tolerance of R's `lm.fit()`. */\nexport const DEFAULT_LEAST_SQUARES_TOLERANCE = 1e-7;\n\n/**\n * Fit `y` on the columns of `design` by least squares.\n *\n * @param design One row per observation, each row one value per column. A\n * model with an intercept carries a leading column of ones. The function\n * does not modify it.\n * @param y The response, one value per row.\n * @param options Weights and the rank tolerance.\n * @returns The coefficients, the fit, and the rank.\n * @throws RangeError if there are no rows, if the shapes disagree, or if a\n * weight is negative. R refuses the same inputs: \"0 (non-NA) cases\" and\n * \"missing or negative weights not allowed\".\n */\nexport function leastSquares(\n design: readonly (readonly number[])[],\n y: readonly number[],\n options: LeastSquaresOptions = {},\n): LeastSquaresFit {\n const { weights, tolerance = DEFAULT_LEAST_SQUARES_TOLERANCE } = options;\n const rows = design.length;\n\n if (rows === 0) {\n throw new RangeError(\"least squares needs at least one row\");\n }\n const width = design[0].length;\n if (design.some((row) => row.length !== width)) {\n throw new RangeError(\"every design row needs the same number of columns\");\n }\n if (y.length !== rows) {\n throw new RangeError(\n `the response has ${y.length} values but the design has ${rows} rows`,\n );\n }\n if (weights !== undefined) {\n if (weights.length !== rows) {\n throw new RangeError(\n `there are ${weights.length} weights but ${rows} rows`,\n );\n }\n if (weights.some((weight) => !(weight >= 0))) {\n throw new RangeError(\"weights cannot be negative or missing\");\n }\n }\n\n // Scale each row by the square root of its weight, which turns the weighted\n // problem into an ordinary one. This is what lm.wfit and glm.fit both do.\n const scale = weights?.map((weight) => Math.sqrt(weight));\n const scaled = (value: number, row: number): number =>\n scale === undefined ? value : value * scale[row];\n\n const columns = Array.from({ length: width }, (_, column) =>\n design.map((row, index) => scaled(row[column], index)),\n );\n const projected = y.map(scaled);\n\n const { householders, pivot, rank } = decompose(columns, tolerance, rows);\n applyHouseholders(columns, householders, projected, Math.min(rank, rows - 1));\n const solved = backSubstitute(columns, projected, rank);\n\n // The solve returns the coefficients in pivot order. An aliased column\n // never reaches the solve and keeps its null, the way R reports NA.\n const coefficients = new Array<number | null>(width).fill(null);\n pivot.slice(0, rank).forEach((column, position) => {\n coefficients[column] = solved[position];\n });\n\n const fitted = design.map((row) =>\n sum(\n zipWith(row, coefficients, (value, coefficient) =>\n coefficient === null ? 0 : value * coefficient,\n ),\n ),\n );\n const residuals = zipWith(y, fitted, (value, fit) => value - fit);\n\n return { coefficients, fitted, residuals, rank };\n}\n\n/**\n * Factor the columns in place, R's way.\n *\n * `dqrdc2` walks the columns left to right. A column whose remaining norm has\n * fallen below `tolerance` times its original norm moves to the right edge and\n * the columns behind it shift left, so the columns that survive keep their\n * original order — which is why R can report the coefficients of a rank-\n * deficient fit in their own slots, with `NA` in the slot of the column it\n * dropped.\n *\n * On return each column holds its part of R above the diagonal and the\n * Householder vector below it, as LINPACK stores them.\n *\n * @returns The Householder scalars, the column order, and the rank.\n */\nfunction decompose(\n columns: number[][],\n tolerance: number,\n rows: number,\n): { householders: number[]; pivot: number[]; rank: number } {\n const width = columns.length;\n const pivot = columns.map((_, column) => column);\n // R substitutes 1 for a zero norm, so that an all-zero column compares as\n // negligible rather than dividing by zero.\n const originalNorms = columns.map((column) => norm(column, 0) || 1);\n const householders = new Array<number>(width).fill(0);\n // The count of columns still in play. R keeps this as `k` and rank is\n // min(k, rows) once the walk is over.\n let live = width;\n\n // Index loops throughout: a QR factorization addresses single matrix\n // entries by position, and this one follows LINPACK's dqrdc2 step for step.\n for (let step = 0; step < Math.min(rows, width); step++) {\n while (\n step < live &&\n norm(columns[step], step) < originalNorms[step] * tolerance\n ) {\n cycleToEnd(columns, pivot, originalNorms, step);\n live -= 1;\n }\n\n // The last row leaves nothing to reflect. R skips it and keeps the entry\n // as it stands, which is how a design with more columns than rows still\n // resolves the coefficients it can.\n if (step === rows - 1) {\n continue;\n }\n householders[step] = reflect(columns, step, rows);\n }\n\n return { householders, pivot, rank: Math.min(live, rows) };\n}\n\n/**\n * Build the Householder reflector of one column and apply it to the columns\n * to its right.\n *\n * @returns The leading entry of the reflector, which R keeps in `qraux`.\n */\nfunction reflect(columns: number[][], step: number, rows: number): number {\n const column = columns[step];\n const length = norm(column, step);\n if (length === 0) {\n return 0;\n }\n // Reflect away from the leading entry, so that nothing cancels.\n const pivotNorm = column[step] < 0 ? -length : length;\n\n for (let row = step; row < rows; row++) {\n column[row] = column[row] / pivotNorm;\n }\n const leading = 1 + column[step];\n column[step] = leading;\n\n for (let index = step + 1; index < columns.length; index++) {\n const other = columns[index];\n let inner = 0;\n for (let row = step; row < rows; row++) {\n inner += column[row] * other[row];\n }\n const factor = -inner / leading;\n for (let row = step; row < rows; row++) {\n other[row] = other[row] + factor * column[row];\n }\n }\n\n column[step] = -pivotNorm;\n return leading;\n}\n\n/** Apply the stored reflectors to the response, giving Qᵀy. */\nfunction applyHouseholders(\n columns: readonly number[][],\n householders: readonly number[],\n response: number[],\n count: number,\n): void {\n const rows = response.length;\n\n for (let step = 0; step < count; step++) {\n const leading = householders[step];\n if (leading === 0) {\n continue;\n }\n const column = columns[step];\n // The reflector's leading entry lives outside the column, so the two\n // passes below read it separately from the entries under the diagonal.\n let inner = leading * response[step];\n for (let row = step + 1; row < rows; row++) {\n inner += column[row] * response[row];\n }\n const factor = -inner / leading;\n response[step] = response[step] + factor * leading;\n for (let row = step + 1; row < rows; row++) {\n response[row] = response[row] + factor * column[row];\n }\n }\n}\n\n/** Solve the leading `rank` columns of the triangular system. */\nfunction backSubstitute(\n columns: readonly number[][],\n response: readonly number[],\n rank: number,\n): number[] {\n const solved = new Array<number>(rank).fill(0);\n\n for (let row = rank - 1; row >= 0; row--) {\n let value = response[row];\n for (let column = row + 1; column < rank; column++) {\n value -= columns[column][row] * solved[column];\n }\n solved[row] = value / columns[row][row];\n }\n\n return solved;\n}\n\n/** Move one column to the right edge, sliding the rest left. */\nfunction cycleToEnd(\n columns: number[][],\n pivot: number[],\n originalNorms: number[],\n step: number,\n): void {\n moveToEnd(columns, step);\n moveToEnd(pivot, step);\n moveToEnd(originalNorms, step);\n}\n\n/** Move one entry of an array to its end, sliding the rest left. */\nfunction moveToEnd<T>(track: T[], from: number): void {\n const [moved] = track.splice(from, 1) as [T];\n track.push(moved);\n}\n\n/** The Euclidean length of a column from `from` down. */\nfunction norm(column: readonly number[], from: number): number {\n return Math.hypot(...column.slice(from));\n}\n",
14
+ "/**\n * The fitted surface of a moderated regression.\n *\n * This is the statistics half of `plot_moderation_3d()` in the R package,\n * which fits `lm(formula, data)`, predicts over a 15 by 15 grid of the IV and\n * the moderator, and hands the grid to `lattice::wireframe()`. Verified\n * against R in `moderation.test.ts`.\n *\n * Four things are worth knowing before reading the code.\n *\n * **Columns, not a formula.** R names the model with `y ~ x * z`. TypeScript\n * has no such notation, so the model arrives as column names, per CLAUDE.md:\n * an outcome, an IV, a moderator, an optional list of controls, and a flag\n * for the interaction. The three models the fixtures pin are\n * `{outcome: \"y\", iv: \"x\", mod: \"z\"}` (R's `y ~ x * z`), the same with\n * `interaction: false` (`y ~ x + z`), and the same with `controls: [\"w\"]`\n * (`y ~ x + z + w + x:z`).\n *\n * **The design follows R's model matrix, not the option order.** R's\n * `model.matrix` puts every main effect before any interaction, whatever\n * order the formula was typed in, so `y ~ x + z + w + x:z` gives the columns\n * `(Intercept), x, z, w, x:z`. This module builds them in that order, which\n * is what lets a caller read the coefficients next to R's.\n *\n * **Controls are held at their mean, and only numbers are accepted.** R's\n * `hold_value()` also handles factors (first level), characters (first in\n * sort order) and logicals (always FALSE). The bundled data has no such\n * column and no doc example uses one, so this port supports the numeric\n * branch alone and refuses the rest, rather than shipping three rules nothing\n * exercises. The other rules are recorded in\n * `.claude/plans/moderation-fixtures.md` section 4 if they are ever wanted.\n *\n * **Missing values leave the fit, as R's do.** `lm()` drops incomplete rows\n * through `na.omit` and `hold_value()` averages with `na.rm = TRUE`; this\n * port does the same, with NaN standing in for `NA` and any non-finite value\n * counting as missing. The details — the `na.exclude`-style NaN padding of\n * `fitted` and `residuals`, the one departure on `zlim` — are on\n * `moderationSurface` itself.\n */\n\nimport { extent, mean, sum, zipWith } from \"./arith\";\nimport { frameRows, requireNumericColumn, type DataFrame } from \"./frame\";\nimport { leastSquares } from \"./ols\";\n\n/**\n * The number of steps along each axis of the grid. R's\n * `plot_moderation_3d()` hardcodes `length.out = 15` for both.\n */\nconst GRID_STEPS = 15;\n\n/** Which columns make the model. */\nexport interface ModerationOptions {\n /** The column to predict — the vertical axis of the surface. */\n readonly outcome: string;\n /** The predictor on the first horizontal axis. */\n readonly iv: string;\n /** The predictor on the second horizontal axis. */\n readonly mod: string;\n /**\n * Whether the model carries the IV by moderator product. True by default,\n * which is R's `y ~ x * z`. False gives R's additive `y ~ x + z`, whose\n * surface is a plane with no twist.\n */\n readonly interaction?: boolean;\n /**\n * Further predictors to fit but not to plot. Each is held at its own mean\n * over the grid, R's `hold_value()` for a numeric column. Empty by default.\n */\n readonly controls?: readonly string[];\n}\n\n/** One fitted term, named as R names it. */\nexport interface ModerationTerm {\n /**\n * R's coefficient name: `(Intercept)`, a column name, or `iv:mod` for the\n * product term.\n */\n readonly name: string;\n /**\n * The coefficient, or null where R reports `NA` — a column the fit could\n * not tell apart from the columns before it.\n */\n readonly value: number | null;\n}\n\n/** A fitted model and the surface it predicts. */\nexport interface ModerationSurface {\n /** The fitted terms, in R's model-matrix order. */\n readonly coefficients: readonly ModerationTerm[];\n /**\n * The fitted outcome of each data row, in input order. NaN where the row\n * was dropped for a missing value, as R's `na.exclude` pads.\n */\n readonly fitted: readonly number[];\n /**\n * The outcome minus the fit, of each data row, in input order. NaN where\n * the row was dropped for a missing value.\n */\n readonly residuals: readonly number[];\n /** The 15 IV values of the grid, from the column's minimum to its maximum. */\n readonly ivValues: readonly number[];\n /** The 15 moderator values of the grid, over the same span. */\n readonly modValues: readonly number[];\n /**\n * The 225 predicted outcomes, **with the IV varying fastest**: index\n * `j * 15 + i` holds the prediction at `ivValues[i]` and `modValues[j]`.\n * This is the row order of R's `expand.grid(seq_iv, seq_mod)`.\n */\n readonly predictions: readonly number[];\n /**\n * The vertical range to draw, as `[low, high]`: the range of the observed\n * outcome together with the range of the surface. Which of the two reaches\n * further depends on the model — an interaction usually swings the surface\n * past the data at the corners of the grid, while a plane stays inside it.\n */\n readonly zlim: readonly [number, number];\n /** The value each control is held at over the grid: its mean. */\n readonly holds: Readonly<Record<string, number>>;\n}\n\n/**\n * Fit the model and predict its surface.\n *\n * Rows with a missing (non-finite) value in any model column are dropped\n * before fitting, R's `na.action = na.omit`; their fitted values and\n * residuals report NaN, keeping input order. The grid and zlim span the\n * finite values of their columns, and a control is held at its finite mean —\n * R's `hold_value()` with `na.rm = TRUE`. (R itself computes zlim with no\n * `na.rm` and fails on a missing outcome; the port draws what it can fit, a\n * stated departure.)\n *\n * @param data The frame holding every column the options name.\n * @param options Which column plays which part in the model.\n * @returns The fit, the grid, the surface, and the vertical range.\n * @throws RangeError If a named column is absent, empty, or not numeric, if\n * the IV and the moderator are the same column, if a control repeats\n * another named column, if the frame is ragged, or if no row is complete.\n */\nexport function moderationSurface(\n data: DataFrame,\n options: ModerationOptions,\n): ModerationSurface {\n const { outcome, iv, mod, interaction = true, controls = [] } = options;\n\n if (iv === mod) {\n throw new RangeError(\n `\\`iv\\` and \\`mod\\` must name different columns, both name \"${iv}\"`,\n );\n }\n // A repeated column would enter the design twice and alias itself, and the\n // caller would read a null coefficient with no clue why.\n const named = new Set([outcome, iv, mod]);\n controls.forEach((control) => {\n if (named.has(control)) {\n throw new RangeError(\n `control \"${control}\" already names the outcome, the iv, the mod, ` +\n \"or another control\",\n );\n }\n named.add(control);\n });\n\n const rows = frameRows(data);\n const y = requireNumericColumn(data, outcome, \"outcome\");\n const ivColumn = requireNumericColumn(data, iv, \"iv\");\n const modColumn = requireNumericColumn(data, mod, \"mod\");\n const controlColumns = controls.map((control) =>\n requireNumericColumn(data, control, \"controls\"),\n );\n\n // R's na.omit: a row with a missing value in any model column leaves the\n // fit. NaN is this library's missing value, and an infinity would poison\n // the fit the same way, so \"complete\" means finite everywhere.\n const modelColumns = [y, ivColumn, modColumn, ...controlColumns];\n const completeRows = y\n .map((_, row) => row)\n .filter((row) =>\n modelColumns.every((column) => Number.isFinite(column[row])),\n );\n if (completeRows.length === 0) {\n throw new RangeError(\n \"the model has no complete rows: every row is missing a value in \" +\n \"the outcome, the IV, the moderator, or a control\",\n );\n }\n\n // R's model.matrix order: the intercept, the main effects in the order the\n // model names them, then the interaction.\n const designColumns: readonly {\n readonly name: string;\n readonly values: readonly number[];\n }[] = [\n { name: \"(Intercept)\", values: new Array<number>(rows).fill(1) },\n { name: iv, values: ivColumn },\n { name: mod, values: modColumn },\n ...controls.map((control, index) => ({\n name: control,\n values: controlColumns[index] as readonly number[],\n })),\n ...(interaction\n ? [\n {\n name: `${iv}:${mod}`,\n values: zipWith(ivColumn, modColumn, (a, b) => a * b),\n },\n ]\n : []),\n ];\n\n const design = completeRows.map((row) =>\n designColumns.map((column) => column.values[row] as number),\n );\n const fit = leastSquares(\n design,\n completeRows.map((row) => y[row] as number),\n );\n const coefficients = designColumns.map((column, index) => ({\n name: column.name,\n value: fit.coefficients[index] ?? null,\n }));\n\n // R's na.exclude padding: report the fit in input order, NaN where a row\n // was dropped.\n const fitted = new Array<number>(rows).fill(Number.NaN);\n const residuals = new Array<number>(rows).fill(Number.NaN);\n completeRows.forEach((row, survivor) => {\n fitted[row] = fit.fitted[survivor] as number;\n residuals[row] = fit.residuals[survivor] as number;\n });\n\n // extent() ignores non-finite values, so each axis spans its column's\n // finite range — R's seq over min and max, which R only reaches when the\n // column has no NA. The hold is R's hold_value(): mean with na.rm = TRUE.\n const ivValues = rSeq(...extent(ivColumn), GRID_STEPS);\n const modValues = rSeq(...extent(modColumn), GRID_STEPS);\n const holds = Object.fromEntries(\n controls.map((control, index) => [\n control,\n mean(\n (controlColumns[index] as readonly number[]).filter(Number.isFinite),\n ),\n ]),\n );\n\n // R's predict() drops an aliased term rather than giving up on the row, so\n // a null coefficient contributes nothing here either.\n const weights = coefficients.map((term) => term.value ?? 0);\n const predictions = modValues.flatMap((modValue) =>\n ivValues.map((ivValue) => {\n const gridRow = [\n 1,\n ivValue,\n modValue,\n ...controls.map((control) => holds[control] as number),\n ...(interaction ? [ivValue * modValue] : []),\n ];\n return sum(zipWith(gridRow, weights, (value, weight) => value * weight));\n }),\n );\n\n const [dataLow, dataHigh] = extent(y);\n const [surfaceLow, surfaceHigh] = extent(predictions);\n\n return {\n coefficients,\n fitted,\n residuals,\n ivValues,\n modValues,\n predictions,\n zlim: [Math.min(dataLow, surfaceLow), Math.max(dataHigh, surfaceHigh)],\n holds,\n };\n}\n\n/**\n * Step from one end of a span to the other, the way R's\n * `seq(from, to, length.out = n)` does.\n *\n * R computes `from + i * by` in plain double arithmetic and writes both\n * endpoints in exactly. That last part matters — it is why the grid always\n * reaches the data's own minimum and maximum — and so does the plain\n * arithmetic: rounding the product and the sum together, as `pretty.ts` must\n * for R's other sequence path, moves 14 of the 30 grid coordinates of the\n * bundled dataset off R's values.\n *\n * @param from The first value.\n * @param to The last value.\n * @param length How many values to return.\n * @returns The sequence. A span of no width repeats its one value, as R's\n * `seq(3, 3, length.out = 15)` does.\n */\nfunction rSeq(from: number, to: number, length: number): number[] {\n if (from === to) {\n return new Array<number>(length).fill(from);\n }\n\n const by = (to - from) / (length - 1);\n return Array.from({ length }, (_, index) =>\n index === 0 ? from : index === length - 1 ? to : from + index * by,\n );\n}\n",
15
+ "/**\n * The moderation surface: a fitted regression drawn as a height field over\n * the IV and the moderator.\n *\n * This is the drawing half of `plot_moderation_3d()` of\n * `../compstatslib/R/moderation_3d_plot.R`. Every number comes from\n * `moderationSurface` in `src/core/moderation.ts`; this module computes no\n * statistics of its own. The grid values are pinned in\n * `.claude/plans/moderation-fixtures.md` section 3.\n *\n * Three decisions are worth stating.\n *\n * **The engine is Plotly, not lattice.** R draws this surface with\n * `lattice::wireframe(drape = TRUE, colorkey = FALSE)`, which colors the mesh\n * by height and hides the key. A Plotly surface is colored by height already,\n * so the port sets `showscale: false` and keeps the rest. The colors\n * themselves are Plotly's, not lattice's: a browser has no lattice palette,\n * and the teaching point of the picture is the twist of the surface, not its\n * hue.\n *\n * **The rotation arguments become a camera, approximately.** Lattice takes\n * `screen = list(z = z_rot, x = x_rot)`, two rotations of the data. Plotly\n * takes a camera position. `cameraFromRotations` maps one onto the other, and\n * says how.\n *\n * **The vertical axis carries the outcome.** With the bundled data the\n * moderator is named `z` and it is drawn on a horizontal axis, while the\n * outcome `y` stands up. R's help makes the same point, twice.\n */\n\nimport { moderationSurface } from \"../core/moderation\";\nimport type { ModerationOptions, ModerationSurface } from \"../core/moderation\";\nimport type { DataFrame } from \"../core/frame\";\nimport { loadPlotly } from \"./plotly\";\nimport type {\n EyeCamera,\n PlotlyHTMLElement,\n PlotlyLayout,\n PlotlyLike,\n SurfaceTrace,\n Vector3,\n} from \"./plotly\";\n\n/** R's `z_rot = 40`: the turn about the vertical axis, in degrees. */\nconst DEFAULT_Z_ROT = 40;\n/** R's `x_rot = -70`: the tilt, in degrees. */\nconst DEFAULT_X_ROT = -70;\n/**\n * How far the camera stands from the middle of the scene. This is the length\n * of Plotly's own default eye, `(1.25, 1.25, 1.25)`, so a plot that sets a\n * camera opens at the same distance as one that does not.\n */\nconst EYE_DISTANCE = 1.25 * Math.sqrt(3);\n/** The name Plotly keeps the view under, across every redraw. */\nconst UIREVISION = \"moderation3d\";\n/** Plotly redraws the plot when the element that holds it changes size. */\nconst CONFIG = { responsive: true } as const;\n\n/** How to look at the surface. */\nexport interface Moderation3dViewOptions {\n /**\n * The turn about the vertical axis, in degrees. R's `z_rot`, 40 by default.\n * 0 lays the IV across the screen; 270 lays the moderator across it.\n */\n readonly zRot?: number;\n /**\n * The tilt, in degrees. R's `x_rot`, −70 by default. −90 looks along the\n * floor of the plot, and the view rises towards 0.\n */\n readonly xRot?: number;\n /**\n * The values the vertical axis spans, as `[low, high]`. The range of the\n * data together with the range of the surface by default, which is R's own\n * rule and what `moderationSurface` reports as `zlim`.\n */\n readonly zlim?: readonly [number, number];\n}\n\n/** The options of `plotModeration3d`: the model, the view, and the engine. */\nexport interface PlotModeration3dOptions\n extends ModerationOptions,\n Moderation3dViewOptions {\n /**\n * The Plotly engine. `loadPlotly()` by default, which fetches the library on\n * first use.\n */\n readonly plotly?: PlotlyLike;\n}\n\n/** What a surface and a set of view options draw. */\nexport interface Moderation3dSpec {\n /** The one height field. */\n readonly traces: readonly SurfaceTrace[];\n readonly layout: PlotlyLayout;\n /**\n * What R says in its `message()` when predictors are held off the axes.\n * Null when every predictor of the model is drawn.\n */\n readonly note: string | null;\n}\n\n/** A drawn surface: its specification, its fit, its element, and its engine. */\nexport interface Moderation3dHandle extends Moderation3dSpec {\n /** The element Plotly drew into, with its event emitter attached. */\n readonly element: PlotlyHTMLElement;\n /** The engine that drew, ready for the next redraw and for teardown. */\n readonly plotly: PlotlyLike;\n /** The fit and the grid behind the picture. */\n readonly surface: ModerationSurface;\n}\n\n/**\n * Place the camera for a pair of lattice rotations.\n *\n * This is a visual approximation, not an equivalence: lattice rotates the data\n * and Plotly moves the camera, and the two pictures agree in direction, not\n * pixel for pixel. The mapping is\n *\n * ```text\n * azimuth = -90 - zRot degrees\n * elevation = 90 + xRot degrees\n * eye = distance * (cos elevation * cos azimuth,\n * cos elevation * sin azimuth,\n * sin elevation)\n * ```\n *\n * Both anchors of R's own help hold under it. At `zRot = 0` the camera stands\n * on the moderator axis, so the IV runs across the screen and the IV slope\n * plane faces the viewer; at `zRot = 270` the camera stands on the IV axis and\n * the moderator plane faces it. The tilt reads the same way as lattice's: at\n * `xRot = -90` the camera is level with the floor of the plot, and R's default\n * −70 lifts it 20 degrees above it.\n *\n * @param zRot The turn about the vertical axis, in degrees.\n * @param xRot The tilt, in degrees.\n * @returns The camera, as Plotly's `scene.camera`.\n * @throws RangeError If either angle is not a finite number, which would\n * place the camera nowhere.\n */\nexport function cameraFromRotations(zRot: number, xRot: number): EyeCamera {\n if (!Number.isFinite(zRot) || !Number.isFinite(xRot)) {\n throw new RangeError(\"`zRot` and `xRot` must be finite numbers.\");\n }\n\n const azimuth = ((-90 - zRot) * Math.PI) / 180;\n const elevation = ((90 + xRot) * Math.PI) / 180;\n const eye: Vector3 = {\n x: EYE_DISTANCE * Math.cos(elevation) * Math.cos(azimuth),\n y: EYE_DISTANCE * Math.cos(elevation) * Math.sin(azimuth),\n z: EYE_DISTANCE * Math.sin(elevation),\n };\n\n return { eye };\n}\n\n/**\n * Build the trace and the layout of a moderation surface.\n *\n * @param surface The fit and the grid, from `moderationSurface`.\n * @param model The columns the surface was fitted over. Their names title the\n * axes, and the controls decide whether there is a note.\n * @param view How to look at the surface.\n * @returns The trace, the layout, and the note about held predictors.\n * @throws RangeError If a rotation is not finite, if a given vertical range is\n * not two finite numbers, or if any height of the surface is not finite —\n * a non-finite height would crash the WebGL engine for the whole page.\n */\nexport function moderation3dSpec(\n surface: ModerationSurface,\n model: ModerationOptions,\n view: Moderation3dViewOptions = {},\n): Moderation3dSpec {\n const { zRot = DEFAULT_Z_ROT, xRot = DEFAULT_X_ROT, zlim } = view;\n const camera = cameraFromRotations(zRot, xRot);\n\n if (zlim !== undefined) {\n if (zlim.length !== 2 || !zlim.every((value) => Number.isFinite(value))) {\n throw new RangeError(\"`zlim` must be two finite numbers.\");\n }\n }\n const range: readonly [number, number] = zlim ?? [\n surface.zlim[0],\n surface.zlim[1],\n ];\n\n // Plotly reads a height field row by row along y, so each row of z holds one\n // moderator value and runs across the IV. That is R's own grid order, the IV\n // varying fastest: index j * 15 + i.\n const steps = surface.ivValues.length;\n const heights = surface.modValues.map((_, j) =>\n surface.ivValues.map((__, i) => surface.predictions[j * steps + i] as number),\n );\n\n // A NaN in the height field does not fail politely: it crashes WebGL inside\n // plotly.js, and every surface drawn on the page afterwards fails too.\n // Refuse here so that no caller can poison the engine.\n if (!surface.predictions.every(Number.isFinite)) {\n throw new RangeError(\n \"the surface must have finite heights everywhere; \" +\n \"a prediction is NaN or infinite\",\n );\n }\n\n const trace: SurfaceTrace = {\n type: \"surface\",\n x: surface.ivValues,\n y: surface.modValues,\n z: heights,\n // R's `colorkey = FALSE`.\n showscale: false,\n };\n\n const layout: PlotlyLayout = {\n uirevision: UIREVISION,\n scene: {\n xaxis: { title: { text: model.iv } },\n yaxis: { title: { text: model.mod } },\n zaxis: { title: { text: model.outcome }, range },\n uirevision: UIREVISION,\n camera,\n },\n };\n\n return { traces: [trace], layout, note: describeHolds(model) };\n}\n\n/**\n * Fit the model and draw its surface.\n *\n * @param target The element to draw into. Plotly fills it.\n * @param data The frame holding every column the model names.\n * @param options The model, the view, and the engine.\n * @returns The drawn plot: its element, its specification, its engine, and the\n * surface behind it.\n * @throws RangeError Everything `moderationSurface` and `moderation3dSpec`\n * throw, as a rejected promise. Nothing reaches the engine until the model\n * is fitted and the view is settled.\n */\nexport async function plotModeration3d(\n target: HTMLElement,\n data: DataFrame,\n options: PlotModeration3dOptions,\n): Promise<Moderation3dHandle> {\n const { plotly, zRot, xRot, zlim, ...model } = options;\n const surface = moderationSurface(data, model);\n const spec = moderation3dSpec(surface, model, { zRot, xRot, zlim });\n const engine = plotly ?? (await loadPlotly());\n const element = await engine.react(target, spec.traces, spec.layout, CONFIG);\n\n return { ...spec, element, plotly: engine, surface };\n}\n\n/** R's `describe_holds()`: one sentence, and only when a predictor is held. */\nfunction describeHolds(model: ModerationOptions): string | null {\n if ((model.controls ?? []).length === 0) {\n return null;\n }\n return (\n `Surface shows predicted ${model.outcome} over ${model.iv} and ` +\n `${model.mod}. Other predictors are held at their typical values.`\n );\n}\n",
16
+ "/**\n * The interactive moderation surface: turn the wireframe and watch the twist\n * of the interaction appear and disappear.\n *\n * This is the port of `interactive_moderation_3d()` in\n * `../compstatslib/R/moderation_3d_interactive.R`. R builds a shiny gadget\n * with two rotation sliders and re-runs `plot_moderation_3d()` whenever one\n * moves. This module does the same: it owns the two sliders and hands every\n * draw to `plotModeration3d`. It fits nothing and draws nothing itself.\n *\n * Three things are worth knowing before reading the code.\n *\n * **The sliders are kept, although a browser can drag the camera.** They are\n * what R's help teaches with: \"Try 0 to align the IV slope plane with the\n * screen, or 270 to align the moderator slope plane.\" A free drag cannot name\n * an angle, and those two angles are the lesson. Dragging still works, and\n * the two live together: a drag is preserved until a slider asks for\n * something else.\n *\n * **A slider must push the camera at the plot.** The plot layer sets a\n * constant `uirevision`, which is what keeps a drag across a redraw. Plotly\n * honours it literally: once the user has turned the plot, a later `react`\n * carrying a different `scene.camera` is ignored, because the user's own edit\n * wins. The sliders would then move nothing. So a rotation change is sent\n * after the redraw as a `relayout`, which is an instruction rather than a\n * preference. The alternative — changing the `uirevision` whenever a slider\n * moves — would have to reach into the layout the plot layer owns, and would\n * throw away the drag on every redraw whether or not the view changed.\n * Nothing new is pushed when the rotations have not moved, so a redraw for\n * any other reason leaves the user's own view alone. The one other push this\n * component makes runs the opposite way: a camera the user drags to is\n * written back into Plotly's stored layout (see `handleRelayout`), because\n * the modebar's own buttons relayout the scene from that layout and would\n * otherwise snap the view to the sliders' angles.\n *\n * **Done hands back the current view.** R returns `data`, which the caller\n * already holds and which says nothing about the picture. The rotations do,\n * and together with the model they reopen the same plot — the same choice the\n * t-test component made for the same reason.\n *\n * There is no Reset: R has Done and Cancel only. There is no validation of\n * the model here either. R's gadget opens and lets `plot_moderation_3d()`\n * report a bad column in the plot pane; the port's equivalent is a rejected\n * `rendered()`, so a caller that wants to hear about it must await.\n */\n\nimport type { DataFrame } from \"../core/frame\";\nimport type { ModerationOptions, ModerationSurface } from \"../core/moderation\";\nimport { plotModeration3d } from \"../plot/moderation3d\";\nimport type {\n Moderation3dSpec,\n Moderation3dViewOptions,\n PlotModeration3dOptions,\n} from \"../plot/moderation3d\";\nimport { sameCamera } from \"../plot/plotly\";\nimport type {\n PlotlyCamera,\n PlotlyHTMLElement,\n PlotlyLike,\n PlotlyRelayoutEvent,\n} from \"../plot/plotly\";\nimport { buildNote, buildSlider, startingSliderValue } from \"./controls\";\nimport type { SliderRange } from \"./controls\";\nimport { resolvePlot3dTarget } from \"./target\";\nimport type { Plot3dTarget } from \"./target\";\n\n/**\n * Everything the panel holds: the two rotations, and the model behind the\n * surface. Hand it back to `interactiveModeration3d` or to\n * `plotModeration3d` to reopen the same picture.\n */\nexport interface Moderation3dValues\n extends ModerationOptions,\n Moderation3dViewOptions {\n /** The turn about the vertical axis, in degrees. */\n readonly zRot: number;\n /** The tilt, in degrees. */\n readonly xRot: number;\n}\n\n/**\n * What the component accepts.\n *\n * Every option of `plotModeration3d` is a starting value, and anything the\n * plot grows later reaches it untouched. The model itself — which column is\n * the outcome, the IV and the moderator — is required, as it is by the plot.\n */\nexport interface InteractiveModeration3dOptions\n extends PlotModeration3dOptions {\n /** What to run on `done()`. */\n readonly onDone?: (values: Moderation3dValues) => void;\n}\n\n/** What the caller holds after the component starts. */\nexport interface InteractiveModeration3dHandle {\n /** Return the rotations the sliders stand at, and the model being drawn. */\n getValues(): Moderation3dValues;\n /** Return the fit and the grid behind the last picture. */\n getSurface(): ModerationSurface | null;\n /** Return the traces, the layout, and the note of the last draw. */\n getSpec(): Moderation3dSpec | null;\n /** Wait for the drawing now in flight. Drawing is asynchronous. */\n rendered(): Promise<void>;\n /** Hand the current values to the `onDone` callback. */\n done(): void;\n /** Stop listening, purge the plot, and take back what was built. */\n destroy(): void;\n}\n\n/** R: `sliderInput(\"z_rot\", \"Z rotation\", min = 0, max = 360, value = 40)`. */\nconst Z_ROT_RANGE: SliderRange = { min: 0, max: 360, step: 1 };\n/**\n * R: `sliderInput(\"x_rot\", \"X rotation\", min = -90, max = -70, value = -70)`.\n */\nconst X_ROT_RANGE: SliderRange = { min: -90, max: -70, step: 1 };\n/** R's own starting angles, from the same two `sliderInput` calls. */\nconst DEFAULT_Z_ROT = 40;\nconst DEFAULT_X_ROT = -70;\n\n/** The two sliders, in R's order. */\nconst SLIDERS = [\n {\n name: \"zRot\",\n label: \"Z rotation\",\n range: Z_ROT_RANGE,\n fallback: DEFAULT_Z_ROT,\n },\n {\n name: \"xRot\",\n label: \"X rotation\",\n range: X_ROT_RANGE,\n fallback: DEFAULT_X_ROT,\n },\n] as const;\n\n/**\n * Start an interactive moderation surface on a target.\n *\n * The component builds its two sliders, draws once, and redraws on every\n * change.\n *\n * @param target A container element, or a plot element and a controls host.\n * See `./target.ts`.\n * @param data The frame holding every column the model names.\n * @param options The model, the starting rotations, a done callback, and the\n * options of `plotModeration3d`.\n * @returns The handle to the running component. Await `rendered()` for the\n * first picture, and to hear about a model the data cannot carry.\n * @throws Error If a canvas is passed as the container.\n */\nexport function interactiveModeration3d(\n target: Plot3dTarget,\n data: DataFrame,\n options: InteractiveModeration3dOptions,\n): InteractiveModeration3dHandle {\n // Everything `plotModeration3d` may grow later stays in `model` and reaches\n // it untouched, so a new plot option needs no edit here.\n const { plotly: givenEngine, onDone, zRot, xRot, ...model } = options;\n\n const panel = resolvePlot3dTarget(target);\n const owner = panel.controls.ownerDocument;\n\n let values: Moderation3dValues = {\n ...model,\n zRot: startingSliderValue(zRot, DEFAULT_Z_ROT, Z_ROT_RANGE),\n xRot: startingSliderValue(xRot, DEFAULT_X_ROT, X_ROT_RANGE),\n };\n\n let spec: Moderation3dSpec | null = null;\n let surface: ModerationSurface | null = null;\n let engine: PlotlyLike | undefined = givenEngine;\n let element: PlotlyHTMLElement | null = null;\n /** The rotations the plot was last told to stand at, or null before then. */\n let painted: { readonly zRot: number; readonly xRot: number } | null = null;\n /**\n * The camera this component last put into Plotly's stored layout — by a\n * slider's push or by persisting a drag — or undefined before either. What\n * the capture handler compares against to recognize its own echo.\n */\n let seenCamera: PlotlyCamera | undefined;\n let listening = false;\n let destroyed = false;\n let inFlight: Promise<void> | null = null;\n let queued = false;\n\n const note = buildNote(owner);\n\n /**\n * Draw once, at whatever the sliders stand at now, and move the camera if\n * they ask for a view the plot is not already at.\n *\n * The camera pushed is the one the plot layer computed, read back out of\n * the layout it built. Nothing here works out where a camera goes.\n */\n async function renderOnce(): Promise<void> {\n const wanted = { zRot: values.zRot, xRot: values.xRot };\n const drawn = await plotModeration3d(panel.plot, data, {\n ...values,\n plotly: engine,\n });\n if (destroyed) {\n return;\n }\n\n engine = drawn.plotly;\n element = drawn.element;\n surface = drawn.surface;\n spec = { traces: drawn.traces, layout: drawn.layout, note: drawn.note };\n note.show(drawn.note);\n\n // One listener for the life of the component: Plotly hands back the same\n // element every time, so attaching per draw would pile them up.\n if (!listening) {\n listening = true;\n element.on(\"plotly_relayout\", handleRelayout);\n }\n\n const moved =\n painted !== null &&\n (painted.zRot !== wanted.zRot || painted.xRot !== wanted.xRot);\n painted = wanted;\n\n const camera = drawn.layout.scene.camera;\n if (moved && camera !== undefined) {\n seenCamera = camera;\n await drawn.plotly.relayout(element, { \"scene.camera\": camera });\n } else if (seenCamera !== undefined && !sameCamera(seenCamera, camera)) {\n // A redraw that asked for no new view: the react above rewrote the\n // stored layout with the sliders' camera while the screen keeps the\n // user's drag (uirevision). Re-persist the drag, or Plotly's own\n // relayouts would rebuild at the sliders' angles after all.\n await drawn.plotly.relayout(element, { \"scene.camera\": seenCamera });\n }\n }\n\n /**\n * Persist a camera the user dragged to into Plotly's stored layout.\n *\n * Plotly's own modebar buttons (orbit, turntable, pan, zoom) relayout the\n * scene from that layout, and a drag lives only in the WebGL scene until it\n * is written back; without this, every modebar click snapped the view to\n * the sliders' angles. The push itself echoes through this handler with the\n * same camera as a fresh object, which is what the value comparison\n * recognizes and drops. The sliders stay in charge: their own pushes set\n * `seenCamera` first, so a slider still overrides any drag before it.\n */\n function handleRelayout(event: PlotlyRelayoutEvent): void {\n const moved = event[\"scene.camera\"];\n if (moved === undefined || destroyed || sameCamera(moved, seenCamera)) {\n return;\n }\n seenCamera = moved;\n if (element !== null && engine !== undefined) {\n // Fire and forget: the picture is already at this view, so a failure\n // here (a plot purged mid-flight) has nothing to repair.\n engine.relayout(element, { \"scene.camera\": moved }).catch(() => undefined);\n }\n }\n\n /**\n * Draw, and never draw twice at once.\n *\n * A dragged slider fires an event for every step, and each draw is\n * asynchronous. A request that arrives while a draw is in flight is\n * remembered, not started, and the draw that follows reads the sliders as\n * they stand then: the last value wins, and the pictures cannot arrive out\n * of order.\n */\n function requestRender(): void {\n if (destroyed) {\n return;\n }\n queued = true;\n inFlight ??= start();\n }\n\n function start(): Promise<void> {\n const run = pump();\n // A caller that never awaits must not be handed an unhandled rejection;\n // `rendered()` still reports the failure to anyone who asks.\n run.catch(() => undefined);\n return run;\n }\n\n async function pump(): Promise<void> {\n try {\n while (queued && !destroyed) {\n queued = false;\n await renderOnce();\n }\n } finally {\n inFlight = null;\n }\n }\n\n function handleInput(event: Event): void {\n const input = event.target as HTMLInputElement;\n // A slider keeps its own value inside the range and on the step, so what\n // it reports needs no correcting.\n values = { ...values, [input.name]: Number(input.value) };\n\n const readout = readouts.get(input.name);\n if (readout !== undefined) {\n readout.textContent = input.value;\n }\n requestRender();\n }\n\n const built: HTMLElement[] = [];\n const inputs: HTMLInputElement[] = [];\n const readouts = new Map<string, HTMLElement>();\n\n for (const slider of SLIDERS) {\n const control = buildSlider(\n owner,\n slider.name,\n slider.label,\n slider.range,\n values[slider.name],\n );\n panel.controls.appendChild(control.wrapper);\n built.push(control.wrapper);\n inputs.push(control.input);\n readouts.set(slider.name, control.readout);\n control.input.addEventListener(\"input\", handleInput);\n }\n\n panel.controls.appendChild(note.element);\n built.push(note.element);\n\n // R's renderPlot runs as the gadget opens, at the initial settings.\n requestRender();\n\n return {\n getValues: () => ({ ...values }),\n getSurface: () => surface,\n getSpec: () => spec,\n rendered: () => inFlight ?? Promise.resolve(),\n done() {\n onDone?.({ ...values });\n },\n destroy() {\n if (destroyed) {\n return;\n }\n destroyed = true;\n for (const input of inputs) {\n input.removeEventListener(\"input\", handleInput);\n }\n for (const node of built) {\n node.remove();\n }\n if (element !== null) {\n element.removeAllListeners(\"plotly_relayout\");\n engine?.purge(element);\n }\n panel.release();\n },\n };\n}\n",
17
+ "/**\n * The `moderation_data` dataset of the R package.\n *\n * Two hundred rows of a moderated relationship, used as the default data of\n * `plot_moderation_3d()` and `plot_scatter3d()` so that both work with no\n * arguments. R's `data.R` records the recipe: `x`, `z` and `w` are drawn\n * independently from a normal distribution with standard deviation 2, and\n *\n * ```text\n * y = 0.5 x + 0.3 z + 0.8 x z + N(0, 1)\n * ```\n *\n * so the effect of `x` on `y` grows with `z` — the interaction the surface\n * shows as a twist. Column `w` enters no equation: it is noise, and it is\n * there so an example can carry a control variable that means nothing.\n *\n * The values below are the exact doubles of the R data file\n * (`../compstatslib/data/moderation_data.rda`), printed at 17 significant\n * digits, which round-trips an IEEE-754 double. **Exported from R, never\n * regenerated** — the draw used `set.seed(42)` under R's own generator, so a\n * JavaScript regeneration would produce different numbers and silently change\n * every default demo. Source of the printed values:\n * `.claude/plans/moderation-data.tsv`, checked against the column checksums of\n * `.claude/plans/moderation-fixtures.md` in `moderationData.test.ts`.\n *\n * The columns are in the order of the R data frame — `y, x, z, w`, not\n * alphabetical and not `x, y, z`. That order is load-bearing: `plot_scatter3d()`\n * with no axis arguments takes the first three numeric columns, which is why\n * its default plot puts `y` on the horizontal axis.\n */\n\n/** The four columns of the R `moderation_data` data frame. */\nexport type ModerationData = {\n readonly y: readonly number[];\n readonly x: readonly number[];\n readonly z: readonly number[];\n readonly w: readonly number[];\n};\n\n/** The 200 rows of the R `moderation_data` data frame, in file order. */\nexport const moderationData: ModerationData = {\n y: [\n -7.2728972000711964, -1.8368504105536234,\n 2.4825030269210964, 6.0885502472158235,\n -2.7813932586215913, -1.4045477434849749,\n -2.3283702256411951, 0.24770227680217238,\n -1.0630104614416778, -2.0458910688111343,\n -5.1341052959159876, 18.102464141094789,\n -3.4663420296290077, -1.0047522093312424,\n -0.82474666408975483, 0.011971257899126564,\n -2.4321918294924254, -14.110628278307653,\n -1.5077118301445713, -3.3519580636316557,\n 0.34228397854096548, -1.4420566151665186,\n -0.09954101599791107, -4.1717572290618348,\n 5.638370200339164, -0.24209932633994577,\n -0.92942202986679767, -0.14306775813444911,\n -0.75191873199673909, -2.6149345603765624,\n 1.9162030995224288, 2.882308922335612,\n -4.1366719661768885, -1.5262757249783787,\n -0.13241561132928859, 1.0868995782488633,\n -5.4322398208224598, -1.0526454319438507,\n -5.3360807036936473, 0.80370589439224283,\n 0.64566701092436662, -0.58086531051744095,\n 5.9958208137315907, -3.748881331929856,\n 4.7991068639205681, 3.9170147432586608,\n -2.5205797162580499, 1.0052100508228277,\n -1.2592451123609627, -1.4191054380364576,\n -2.7688068774363885, -1.1283556266006958,\n -5.0155719117359876, 0.74436508929657408,\n 1.3457889732609731, -1.5775936354323048,\n 0.24940175331052905, 0.84534536563058338,\n 9.1086395504851989, -1.0895764398669741,\n -0.054834750835499602, 3.4396743692990768,\n 1.82777129315956, -9.0876817903961307,\n -1.6403441299936004, 6.3441120121592336,\n 3.0068415808329494, 1.0402916701960967,\n -10.792485667257104, 0.19774249672127087,\n -2.6230964327485333, -1.5340564759379902,\n 1.7265739813235901, -4.4727441322331023,\n 0.051358701883551766, 3.4112581498484817,\n 1.7155585583877218, -2.4096746494084527,\n -3.6580899543881662, -4.2196299413161089,\n 5.7706115536478979, -4.0368554837030199,\n -1.8534915424952012, -1.4551065653571458,\n -0.57333130613680428, 1.2587331393918402,\n -0.18074955316901531, -1.7541060455623132,\n -7.1816739672594787, 2.2681715762809351,\n -2.2618552849857134, -1.0033432551835315,\n -1.5998101004488254, 13.776336779706227,\n -1.3601934670356379, 0.84377053596043516,\n 0.26923062515768637, -6.1587204803542566,\n 0.28455942391067712, -3.7313390977173673,\n 2.209575611277963, 4.9573155152467479,\n -1.1074416328100625, 6.773590899689121,\n -1.1622855609602678, -0.1468882418607233,\n -1.8138297100034615, -0.88229772478568436,\n -2.5310587963205209, 0.92250684930151283,\n 1.0529999297345707, -1.0226841183124429,\n -0.62826191336833026, 0.047095104558446066,\n -2.1862971987559754, 1.9185432668727294,\n -1.4157898788687031, 3.8559400012867275,\n 4.8196910254616006, 1.1859049624611124,\n 2.1292032810255828, -2.5804694939165822,\n 0.7806460650847441, -0.77177474486716457,\n 4.3023231287427057, 1.1280497997890846,\n -3.3823450205179935, -2.8141768087650334,\n 1.9176969652481777, -1.8022438527307034,\n 0.56769922608595746, -1.1988798479187797,\n -0.81127142895301252, 3.0023694027723717,\n 6.3138141892914694, -0.72091317245731745,\n -0.49342129711845351, -5.3116450695380282,\n 1.5864321371634191, -1.3767448543412033,\n -0.32149297043332475, -2.7378068772633672,\n 0.44512957644982276, 1.0144155909083761,\n -0.33982995595512711, 3.6424411700938926,\n -0.80484964968788497, 0.26491344714041165,\n 1.0255159271802998, -3.4431481857611512,\n -1.2617728430815081, 2.4072718264535986,\n 4.1858481441966102, 0.84449896500128463,\n 0.68906644248057036, -4.9301730292087731,\n 1.3181686730513686, -3.9504745741065488,\n 0.69966539975680719, -7.7331713344467277,\n 0.37966613312994063, 2.0980485157760418,\n 0.58696762292169558, -0.095335203753901337,\n -1.3602473690753563, -1.8363341184552933,\n -5.3271971097587407, -2.4667878836756927,\n -0.84771180433706672, 1.794347325600735,\n -1.1215052328640052, 0.96938089278474238,\n -8.8525095689727635, -10.171192748327044,\n 5.5154793606449468, 0.81334743443491231,\n 1.5442257490953633, -2.3028072866769134,\n 0.68983698216899647, 1.9915198521027817,\n 2.8322478461703762, 0.34764862749885805,\n -0.50342712629907482, 1.1733004427545144,\n 0.18449984894824215, -1.9938893833160367,\n 0.8829064829548916, 0.62667972173052222,\n -3.9311936779928676, -4.6930573223273164,\n 0.5942425542793619, -0.040913228103484439,\n 1.5529759191506414, 0.52558975177612277,\n -0.51812524140199456, 5.7138238288601553,\n 0.80645695222572478, 2.7208395005315182,\n -1.9931388422548042, 2.0982441518090775,\n ],\n x: [\n 2.741916894293337, -1.1293963427921776,\n 0.72625682267467828, 1.265725209922081,\n 0.80853664628199817, -0.21224903218296798,\n 3.0230439948778778, -0.18931807682619511,\n 4.0368474277540827, -0.12542819810484199,\n 2.6097393084469704, 4.5732907854022136,\n -2.7777214022246786, -0.55757753363474283,\n -0.26664267278731602, 1.2719007961401489,\n -0.56850584283214478, -5.3129108418095523,\n -4.8809338571510379, 2.6402266914603838,\n -0.6132771881569492, -3.562616867960001,\n -0.34383471151924272, 2.4293493983451979,\n 3.7903869225299305, -0.86093826321239919,\n -0.51453876553785927, -3.5263261703895603,\n 0.9201947096625428, -1.2799897519202386,\n 0.91090024648243872, 1.4096746744576383,\n 2.0702070439398446, -1.2178527508144228,\n 1.0099102465959404, -3.434017358146686,\n -1.5689180167589927, -1.7018151883530368,\n -4.8284152998932646, 0.07224521378451125,\n 0.41199720040050775, -0.72211459709733239,\n 1.5163264713990341, -1.4534096541531503,\n -2.7365620888385891, 0.86563605177743408,\n -1.6227863523733432, 2.8882025234425055,\n -0.86289240522669086, 1.3112957668044132,\n 0.64385053040789308, -1.5676778817607508,\n 3.1514550395839547, 1.2857986114346329,\n 0.17952129319921128, 0.5531014945829259,\n 1.3585776321105416, 0.17966577315816343,\n -5.9861801663058696, 0.5697659070613188,\n -0.73446928548195067, 0.3704611297312187,\n 1.1636474547310138, 2.799473654585356,\n -1.4545841189489299, 2.6050852640882871,\n 0.67169623950414881, 2.0770121973952422,\n 1.8414571365812926, 1.4417563257337251,\n -2.08623787713571, -0.18037277322141337,\n 1.2470363239990871, -1.907046715544688,\n -1.0856576291477136, 1.1619929953633648,\n 1.536357475669182, 0.92753517708033439,\n -1.7715525948193589, -2.1995617972957109,\n 3.025414019609856, 0.51584287506406168,\n 0.17688045831917268, -0.24179307507817885,\n -2.3886577903210564, 1.2239937960807739,\n -0.43427969149304169, -0.36551341266384341,\n 1.8666926571423201, 1.6435462210164979,\n 2.7842327518685419, -0.95234784610934875,\n 1.3006971214526097, 2.7822209127800015,\n -2.2215777588957977, -1.7215851737556847,\n -2.2634773617075399, -2.9184279990047917,\n 0.15996510648232234, 1.30640867929838,\n 2.4019307511969883, 2.0895021743354505,\n -2.006417293679696, 3.696963803345493,\n -1.3335468175156342, 0.21102762491213886,\n -0.84451176373771208, -0.24470034390994258,\n 0.37638606900299576, 0.23832191599401276,\n -0.050185101734805754, 0.2161454558840652,\n -0.9708704716933354, -1.0084342613758068,\n -3.322198159829624, -0.76466745374763623,\n -1.025300515755601, 5.4037820006895947,\n -2.7242324623794376, 0.27451243711721379,\n -2.987250134632581, -2.9408714828735931,\n 0.2494047723940136, -1.9932782697680742,\n -0.0036452286094163897, -0.85651776285163062,\n -1.2273432128989903, -4.0493556908382153,\n -2.4494959007199721, 0.35903288223587582,\n 1.1352411888470701, -0.98575470710694957,\n 0.00012576813070224816, 2.2457792867599329,\n 2.87971148595238, -2.1942275368116433,\n -0.23463912050035363, 2.4029968018394023,\n -0.93945916113260175, -0.10493896987799263,\n -0.17221459647417905, -1.7753580358128629,\n -0.88936800976947616, -0.058889758176476292,\n -0.82773769811584708, 2.2267720467364067,\n -0.96198568330796386, -0.86633806520145806,\n 1.3937251531042052, -2.1127368263418163,\n -0.081396950302429855, -3.1030896446951792,\n 2.3343390984713639, -0.54729140274816135,\n -0.93569064934450719, -2.4765046559724295,\n -0.015524067554653256, -1.6005643559033189,\n -1.066984659900873, 2.5753504911691776,\n -0.35105174048425475, -2.1435647683013519,\n 0.32641376493476459, -0.72547683125589957,\n 1.1800270959746773, 2.8648438554619791,\n -1.9853850222189862, 0.90930059516056516,\n 0.16979611735697459, 1.7911311645290895,\n -0.45955627789253306, 1.6732381369212268,\n -3.4901117226733867, 3.378917842626747,\n 1.7295559570371559, -0.30155197777149562,\n -2.8980142602783352, 1.2860174000839635,\n 0.96638772762953518, -0.012711252842777425,\n 0.30291178572484884, -1.1682179406996087,\n 0.73761346526048421, 0.5893086794390312,\n -0.55851874668515011, -2.6724733097863078,\n 1.4014976368800685, 1.1083932445480671,\n -1.6726131856028299, -3.189176324012486,\n 0.40991716117526766, -0.69017595594577974,\n 0.50522340672890931, -2.5880049309691064,\n -1.9183408887607261, 2.1715497073598016,\n 0.80754980943142785, 1.1729750734385955,\n 3.6304568923079059, 0.25764285720476621,\n ],\n z: [\n -4.0018584754630222, 0.66755439486714041,\n 2.3426502547175891, 4.1190784845986084,\n -2.7537231964810425, -2.3017111312542111,\n -1.4116427895202421, -2.1081115641543828,\n -1.2914874462849828, -0.37075593535300683,\n -2.4024441014799702, 4.0739443339663,\n 0.21554948977109339, -0.16821620101116128,\n 0.99123928320918786, 0.074830372235930684,\n -0.2641760739118198, 2.9535748471041936,\n -0.43406042018420693, -2.5672044081844505,\n 0.77133578088680466, -0.70302574705818488,\n -1.0435921867125384, -2.1362624013743408,\n 0.85673180653338499, -0.34803646885398981,\n 1.0313354572960587, -0.46873055461184299,\n -1.3170068516435418, 2.500473208157433,\n -0.54352743022279359, 1.8959039917503921,\n -2.4031648602178755, -0.93223219275100444,\n -0.53870279030635992, -0.78193081626172145,\n 2.697414023983427, -0.04552940259682519,\n 0.48845170220690071, -1.8847434157278455,\n -1.4584345530191491, 1.9961378171096964,\n 2.5169633291911206, 2.4977273776201918,\n -2.7612740990506603, 4.0999213872727882,\n 2.0337456595990835, -0.053434928276515886,\n 1.4072155575965211, -1.9427704583037273,\n -2.1923124831177145, 0.098100901875194116,\n -2.3969917131155598, 0.38003799711949598,\n 2.5954117992093324, -2.067747445929502,\n -1.4768815084261278, 0.093127878901726704,\n -2.0351922396522117, -0.76656791977255634,\n 1.7455108233427969, 1.9390900279402341,\n 0.76769333005418883, -3.7031113261349291,\n -0.10799347365233136, 2.1295464286765675,\n 1.6263900748232101, -0.38163294820856347,\n -5.3998596171274054, 0.1219332776022331,\n 1.1475033949671558, 0.091607159450197734,\n 0.31482508035175089, 0.86313074573754156,\n -0.79309947210042442, 2.6199564515030986,\n 0.94078679974788604, -2.4853405411492027,\n 2.7631509127710658, 2.4089178740196484,\n 1.648147927363762, -3.3252588043711886,\n -1.1386126872109616, 1.2710276345790525,\n 0.087444015155715843, 0.69602460732261417,\n 4.9191870977408296, -1.6367606487993389,\n -4.2264002298582737, 0.54739054486082928,\n -1.3751936824868236, 0.89208210592373138,\n -1.6247694475811947, 4.424110960670272,\n -0.24741194315485965, -0.95467101206010463,\n -0.33252298297321642, 1.7251267672528618,\n 0.19468097040563787, -3.2512334784225763,\n -0.00924153565291559, 1.5204843353241098,\n 0.077981825745125244, 1.4701442832288814,\n -0.29294525399773952, -0.11577467076256517,\n 0.96473893220906526, 1.9858872735514685,\n -2.4927909960640844, -0.066975049691219368,\n -0.1419243624999926, -1.517841307461901,\n -2.0687187218783056, -1.2614639079416392,\n 1.1736154400259904, -0.83264531236730377,\n -1.5697756190106404, 0.32683263897219417,\n -2.4734284702186993, 2.0917475524733429,\n -0.96919083243741866, 0.37825762336133084,\n 0.10201266314994641, -0.00048133777288395359,\n 3.6187640848857319, -1.6506559142198896,\n 2.2909409044559705, 0.063146375106486144,\n -1.6704116106134392, -0.13752729803302502,\n 1.4935433740249338, -0.85103746878920816,\n -1.5441644703869135, 0.30552821349578935,\n 1.977193690357598, -0.14691666934434808,\n -2.7740531071194838, -2.6133518087507257,\n -1.5367906501558772, -1.0542162507489161,\n -0.042854130083249252, 1.3409961419925638,\n -0.86923407714481304, -2.2277595666256937,\n 1.2142119897569996, 0.5509139374791826,\n 2.3146941388294735, -3.3649617189565113,\n 0.17463817778974872, 2.7067237878853372,\n 1.4483476013667382, -1.665105651528423,\n 1.4650569735368288, -1.7438537399944254,\n -0.90679502245958543, 2.3750685572581554,\n -0.58029062358015848, 1.6570922899308729,\n -0.58245541755833752, -3.1527248094958122,\n -1.6976313938978438, -2.1770397239143895,\n -0.96858114223434699, -0.67262241801914557,\n -0.30671578132328758, -0.48649445714969192,\n 3.784404083200223, -2.7719966745708398,\n -0.82964860141556074, 0.69816305621366226,\n 3.256884531630813, 0.17704379142723264,\n 2.4783014168011261, -3.2891110715074134,\n 2.8927130507569592, -1.3811203433303656,\n -0.55286217090770406, -2.2188375197988743,\n 0.26773863285890354, 3.5706781034631039,\n 4.8443267105031795, -2.1536578042368233,\n 0.97188222080619802, 2.7770434774885837,\n -0.3913136345690878, -0.43634959541242196,\n -0.60955590909289048, 1.1956654482228859,\n 2.7948588216315193, 1.3752395224799268,\n 0.64037602859393727, -0.60373985155452159,\n 0.99669737111589907, -1.0990738358335126,\n -0.55851300727448538, 2.1930268862234645,\n 0.88402617635762248, 0.48203258805222476,\n -0.51121531071103665, 1.8620658029697648,\n ],\n w: [\n -0.49696586637986573, 0.84464077166478657,\n 1.9753065872793472, 1.6711363440700464,\n -1.321043718091411, 3.1281389865836706,\n -3.2459518705830939, 1.7277927469579759,\n -1.0232055468724002, -3.8347300508908027,\n -3.731627697239897, 0.4903581268793773,\n 4.447068603816132, 0.54675212828893049,\n 2.261569589056565, 1.6773387481201982,\n -1.3092305557564106, 1.9079219569587911,\n 0.70590293097864509, 0.41319858529922687,\n 2.0022264686204969, 1.4949039832805529,\n -1.2531496734462773, 0.79044737187342806,\n -1.7843359080911552, 1.2616368201835455,\n -0.86541036656913495, 0.90427728843703359,\n 0.73599809039269093, -0.54077497932381824,\n 0.9310252354259575, 1.1487124512539382,\n -0.46139998031482182, 2.3444850166049025,\n 2.7854054134662434, -1.3239825114191694,\n -1.5547384134500284, 1.0270771578175601,\n -1.8266244760825443, -0.89884761050060125,\n 1.6058653982072366, -1.1469537019622078,\n -3.8562503356966524, 1.3287816676442965,\n -3.205080447588506, -2.7092005149076992,\n -6.0358653588357924, 1.6624756444601259,\n 0.50219417769468799, 0.92458693188265906,\n 1.6895844464464735, -0.083943048643124199,\n -2.2111518114000552, 1.1275513046617478,\n 2.6067295116393412, -3.0004418755893147,\n -1.2139784702380723, -0.58449013131315453,\n -2.579366686647206, 1.3882116975493977,\n -1.1983638057942381, 2.5138132879432744,\n 0.10701602725472605, 1.4561850353437049,\n 3.1221961364212145, 0.53124950719437969,\n 2.1534525184145346, 0.42139586335849089,\n -3.0233470516447363, 0.044804519827250026,\n 1.4362724120842063, 0.97891403568453961,\n -0.34777669175653925, -2.435398977336801,\n 1.292796737418924, -1.8329120566957797,\n -2.5036468848511326, 1.1898554368110026,\n -2.465621330379653, 0.48872882981227517,\n 0.005544370687190118, -2.65641937205113,\n 2.3593928236655501, -1.1856099982978574,\n 2.3999566326733439, -0.95006735922426966,\n -1.1501141923016327, -0.062452049216998061,\n -0.71611399195691117, -0.7132021552954626,\n -1.7553287668674522, -2.4257942503559256,\n 1.2265732373740676, -1.6124066829249548,\n -2.7529138598177902, -1.0156957983270942,\n -1.6018709734746754, -4.3855713713401352,\n -0.58187429853534967, 0.33434824232103538,\n 0.5893847129713754, 0.7854825308414517,\n -2.0016874260016304, -0.65145423964686777,\n -2.0166976108576851, -1.2708629640675322,\n -2.4196813759746849, -2.2329276013053807,\n 1.2597623251518704, -0.54504314035725121,\n -0.5176823367573421, 3.4591163597829868,\n -0.11678433081474329, -1.0741275692178371,\n 1.4945733923314797, -0.97451567077946588,\n 2.7458155629590104, -0.75534472129244146,\n -1.2323052282367883, -2.3362501021493713,\n 0.65728071718217163, 2.9330212548803298,\n -0.71201909017782516, 0.5229352837548622,\n 0.66665771035146226, 2.8443864806190855,\n 1.3277532013323454, -2.1473103113906209,\n -1.3938035493334802, -1.4922609138691223,\n 0.28314574426443873, -0.0078944414613061446,\n 0.73587500218353108, -1.3146858293944941,\n -0.75269334032210411, 1.4827201208501692,\n -0.19921351289694036, -1.3085797572141897,\n 1.942328748122542, 0.02699262313677293,\n -1.8330693340430899, 3.4193771225232736,\n -2.3362019798933114, -3.5620725203050472,\n -4.5062648971364343, 1.3022519390933986,\n -1.0656652512055347, -0.55111871394456635,\n 0.57925394525809126, -0.93296812358152814,\n -3.2161203498893749, -3.8995675920839759,\n -0.68139983646196156, 0.3494510546626397,\n -4.5555551215544581, 0.58104896189416777,\n 0.84461271494722856, 2.5894747264134295,\n 0.32942803714790875, 0.40990768160047042,\n 1.2092072534516118, -0.038281538337862839,\n -0.15942869475761728, 0.2319689288056091,\n 1.4883467280967757, -0.86258120705538532,\n -0.99905790382246884, -1.7303241535114227,\n -1.915514566543747, 0.65359994267727539,\n 3.0947444513703499, -1.9377191377288612,\n -0.37688085251892567, -2.0600023229118372,\n 1.8161728837209921, -0.63476372941625703,\n 0.35800793308084394, 0.6960563754583543,\n -2.1085580425488804, -0.20948857622140291,\n -0.45668523418905876, 1.3507111248550778,\n -2.4664893870126186, -2.3999230888455583,\n 1.5317331532322156, -1.1761957225659538,\n -1.3205916599511518, 0.22602704439468746,\n -0.64079759937207748, 3.7327629938775755,\n 0.51906291153559747, 0.32312014183613985,\n 1.8621498186707084, -0.11989349851924225,\n 0.097479400154900323, -2.1457508014679263,\n -4.5859428609613451, -2.4144137001286841,\n 0.22821885959438232, -2.0665941582107541,\n ],\n};\n"
18
+ ],
19
+ "mappings": ";;;;;;;;;AA+NO,SAAS,UAAU,CACxB,GACA,GACS;AAAA,EACT,IAAI,MAAM,aAAa,MAAM,WAAW;AAAA,IACtC,OAAO,MAAM;AAAA,EACf;AAAA,EACA,OACE,WAAW,EAAE,KAAK,EAAE,GAAG,KACvB,WAAW,EAAE,QAAQ,EAAE,MAAM,KAC7B,WAAW,EAAE,IAAI,EAAE,EAAE;AAAA;AAKzB,SAAS,UAAU,CAAC,GAAwB,GAAiC;AAAA,EAC3E,IAAI,MAAM,aAAa,MAAM,WAAW;AAAA,IACtC,OAAO,MAAM;AAAA,EACf;AAAA,EACA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;AAAA;AAIjD,IAAI;AAUG,SAAS,UAAU,GAAwB;AAAA,EAChD,YAAmB,6BAAsB,KAAK,CAAC,WAAW;AAAA,IACxD,MAAM,SAAU,OAA0C,WAAW;AAAA,IACrE,OAAO;AAAA,GACR;AAAA,EACD,OAAO;AAAA;;ACnNF,SAAS,eAAe,CAAC,QAA6C;AAAA,EAC3E,OAAO,OAAO,SAAS,KAAK,OAAO,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ;AAAA;AAYxE,SAAS,cAAc,CAAC,MAA2B;AAAA,EACxD,OAAO,OAAO,KAAK,IAAI,EAAE,OAAO,CAAC,SAC/B,gBAAgB,KAAK,KAAe,CACtC;AAAA;AAcK,SAAS,0BAA0B,CACxC,SACA,QACM;AAAA,EACN,IAAI,QAAQ,SAAS,GAAG;AAAA,IACtB,MAAM,IAAI,WACR,GAAG,kDAAkD,QAAQ,aAC3D,iDACJ;AAAA,EACF;AAAA;AAYK,SAAS,SAAS,CAAC,MAAyB;AAAA,EACjD,MAAM,QAAQ,OAAO,KAAK,IAAI;AAAA,EAC9B,MAAM,QAAQ,MAAM;AAAA,EACpB,IAAI,UAAU,WAAW;AAAA,IACvB,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAQ,KAAK,OAAkB;AAAA,EACrC,MAAM,SAAS,MAAM,KAAK,CAAC,SAAU,KAAK,MAAiB,WAAW,IAAI;AAAA,EAC1E,IAAI,WAAW,WAAW;AAAA,IACxB,MAAM,IAAI,WACR,gDAAgD,cAAc,UAC5D,QAAQ,eAAgB,KAAK,QAAmB,QACpD;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAiBF,SAAS,oBAAoB,CAClC,MACA,MACA,MACmB;AAAA,EACnB,MAAM,SAAS,KAAK;AAAA,EACpB,IAAI,WAAW,WAAW;AAAA,IACxB,MAAM,IAAI,WACR,WAAW,sBAAsB,6BACnC;AAAA,EACF;AAAA,EACA,IAAI,CAAC,gBAAgB,MAAM,GAAG;AAAA,IAC5B,MAAM,IAAI,WACR,WAAW,sBAAsB,6BAC/B,gDACJ;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;;;AC3FT,IAAM,aAAa;AAKnB,IAAM,qBAAqB;AAE3B,IAAM,SAAS,EAAE,YAAY,KAAK;AAmB3B,IAAM,0BAA0C;AAAA,EACrD,QAAQ,CAAC,GAAG,GAAG,CAAC;AAAA,EAChB,SAAS;AAAA,EACT,MAAM;AACR;AAqFO,SAAS,aAAa,CAC3B,MACA,UAAgC,CAAC,GAClB;AAAA,EACf;AAAA,IACE,SAAS,wBAAwB;AAAA,IACjC,UAAU,wBAAwB;AAAA,IAClC,OAAO,wBAAwB;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,MACE;AAAA,EAGJ,uBAAuB,QAAQ,SAAS,IAAI;AAAA,EAG5C,UAAU,IAAI;AAAA,EAEd,QAAQ,MAAM,SAAS,WAAW,MAAM,OAAO;AAAA,EAC/C,MAAM,SAAS;AAAA,IACb,GAAG,kBAAkB,MAAM,KAAK,GAAG,GAAG;AAAA,IACtC,GAAG,kBAAkB,MAAM,KAAK,GAAG,GAAG;AAAA,IACtC,GAAG,kBAAkB,MAAM,KAAK,GAAG,GAAG;AAAA,EACxC;AAAA,EAEA,MAAM,cAAc,UAAU,YAAY,YAAY,KAAK;AAAA,EAC3D,IAAI,UAAU,aAAa,gBAAgB,WAAW;AAAA,IACpD,MAAM,IAAI,WACR,WAAW,kDACb;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,YAAY,QAAQ,EAAE,SAAS,KAAK,GAAG,WAAW;AAAA,EACjE,MAAM,QAAQ,EAAE,GAAG,KAAK,GAAG,GAAG,KAAK,GAAG,GAAG,KAAK,MAAM,OAAO;AAAA,EAC3D,MAAM,SAAuB;AAAA,IAC3B,YAAY;AAAA,IACZ,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,aAAa;AAAA,QACX,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,QACV,GAAG,OAAO;AAAA,MACZ;AAAA,MACA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,EAAE,EAAE;AAAA,MAClC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,EAAE,EAAE;AAAA,MAClC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,EAAE,EAAE;AAAA,MAClC,YAAY;AAAA,SACR,WAAW,YAAY,CAAC,IAAI,EAAE,OAAO;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,QAAQ,QAAQ,KAAK;AAAA;AAahC,eAAsB,aAAa,CACjC,QACA,MACA,UAAgC,CAAC,GACP;AAAA,EAC1B,QAAQ,WAAW,gBAAgB;AAAA,EACnC,MAAM,OAAO,cAAc,MAAM,WAAW;AAAA,EAC5C,MAAM,SAAS,UAAW,MAAM,WAAW;AAAA,EAC3C,MAAM,UAAU,MAAM,OAAO,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,MAAM;AAAA,EAE3E,OAAO,KAAK,MAAM,SAAS,QAAQ,OAAO;AAAA;AAiBrC,SAAS,sBAAsB,CACpC,QACA,SACA,MACM;AAAA,EAGN,IAAI,OAAO,WAAW,KAAK,CAAC,OAAO,MAAM,CAAC,UAAU,OAAO,SAAS,KAAK,CAAC,GAAG;AAAA,IAC3E,MAAM,IAAI,WAAW,gDAAgD;AAAA,EACvE;AAAA,EACA,IAAI,OAAO,KAAK,CAAC,UAAU,SAAS,CAAC,GAAG;AAAA,IACtC,MAAM,IAAI,WAAW,uCAAuC;AAAA,EAC9D;AAAA,EACA,IAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,KAAK,UAAU,GAAG;AAAA,IAC5D,MAAM,IAAI,WAAW,+CAA+C;AAAA,EACtE;AAAA,EACA,IAAI,CAAC,OAAO,SAAS,IAAI,KAAK,QAAQ,GAAG;AAAA,IACvC,MAAM,IAAI,WAAW,2CAA2C;AAAA,EAClE;AAAA;AASF,SAAS,UAAU,CACjB,MACA,SAIA;AAAA,EACA,QAAQ,GAAG,GAAG,MAAM;AAAA,EACpB,IAAI,MAAM,aAAa,MAAM,aAAa,MAAM,WAAW;AAAA,IACzD,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,EAAE,GAAG,MAAM,KAAK;AAAA,EACzC;AAAA,EAEA,MAAM,UAAU,eAAe,IAAI;AAAA,EACnC,2BAA2B,SAAS,eAAe;AAAA,EAEnD,MAAM,SAAS,QAAQ,MAAM,GAAG,CAAC;AAAA,EACjC,MAAM,UAAU,QAAQ,MAAM,CAAC;AAAA,EAC/B,MAAM,OACJ,QAAQ,WAAW,IACf,OACA,0CAA0C,OAAO,KAAK,IAAI,QAC1D,WAAW,QAAQ,KAAK,IAAI;AAAA,EAElC,OAAO;AAAA,IACL,MAAM,EAAE,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,OAAO,GAAG;AAAA,IAChE;AAAA,EACF;AAAA;AASF,SAAS,iBAAiB,CACxB,MACA,MACA,MACmB;AAAA,EACnB,MAAM,SAAS,KAAK;AAAA,EACpB,IAAI,WAAW,WAAW;AAAA,IACxB,MAAM,IAAI,WACR,WAAW,sBAAsB,6BACnC;AAAA,EACF;AAAA,EACA,IAAI,CAAC,gBAAgB,MAAM,GAAG;AAAA,IAC5B,MAAM,IAAI,WACR,WAAW,sBAAsB,cAAc,SAAS,MAAM,QAC5D,wDACA,yCACJ;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAIT,SAAS,QAAQ,CAAC,QAAwB;AAAA,EACxC,MAAM,QAAQ,IAAI,IAAY,OAAO,IAAI,CAAC,UAAU,OAAO,KAAK,CAAC;AAAA,EACjE,IAAI,MAAM,SAAS,GAAG;AAAA,IACpB,OAAO;AAAA,EACT;AAAA,EACA,IAAI,MAAM,OAAO,GAAG;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA,IAAI,MAAM,IAAI,QAAQ,GAAG;AAAA,IACvB,OAAO;AAAA,EACT;AAAA,EACA,OAAO,MAAM,IAAI,SAAS,IAAI,kBAAkB;AAAA;AAIlD,SAAS,WAAW,CAClB,QAKA,QACA,OAC2B;AAAA,EAC3B,IAAI,UAAU,WAAW;AAAA,IACvB,OAAO,CAAC,EAAE,MAAM,aAAa,MAAM,cAAc,QAAQ,OAAO,CAAC;AAAA,EACnE;AAAA,EAEA,IAAI,gBAAgB,KAAK,GAAG;AAAA,IAC1B,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,WACH;AAAA,QACH,QAAQ;AAAA,aACH;AAAA,UACH;AAAA,UACA,YAAY;AAAA,UACZ,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAIA,MAAM,SAAS,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC;AAAA,EAC/D,OAAO,OAAO,IAAI,CAAC,UAAU;AAAA,IAC3B,MAAM,OAAO,MAAM,QAAQ,CAAC,OAAO,QACjC,OAAO,KAAK,MAAM,QAAQ,CAAC,GAAG,IAAI,CAAC,CACrC;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,GAAG,KAAK,IAAI,CAAC,QAAQ,OAAO,EAAE,IAAc;AAAA,MAC5C,GAAG,KAAK,IAAI,CAAC,QAAQ,OAAO,EAAE,IAAc;AAAA,MAC5C,GAAG,KAAK,IAAI,CAAC,QAAQ,OAAO,EAAE,IAAc;AAAA,MAC5C;AAAA,MACA,MAAM;AAAA,MACN,YAAY;AAAA,IACd;AAAA,GACD;AAAA;;AC5VI,SAAS,mBAAmB,CACjC,OACA,UACA,OACQ;AAAA,EACR,IAAI,UAAU,WAAW;AAAA,IACvB,OAAO;AAAA,EACT;AAAA,EACA,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAAA,IAC3B,OAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,UAAU,KAAK,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,CAAC;AAAA,EAI9D,MAAM,WAAW,WAAW,MAAM,IAAI;AAAA,EACtC,MAAM,SAAS,MAAM;AAAA,EACrB,MAAM,QAAQ,KAAK,OACf,UAAU,MAAM,OAAO,UAAW,MAAM,OAAO,OACnD;AAAA,EACA,MAAM,UAAU,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,QAAQ,QAAQ,CAAC;AAAA,EAGzE,OAAO,KAAK,IAAI,MAAM,KAAK,OAAO;AAAA;AAIpC,SAAS,UAAU,CAAC,MAAsB;AAAA,EACxC,OAAO,OAAO,IAAI,EAAE,MAAM,GAAG,EAAE,IAAI,UAAU;AAAA;AAaxC,SAAS,WAAW,CACzB,OACA,MACA,OACA,OACA,OACa;AAAA,EACb,MAAM,UAAU,MAAM,cAAc,OAAO;AAAA,EAC3C,QAAQ,MAAM,UAAU;AAAA,EAExB,MAAM,UAAU,MAAM,cAAc,MAAM;AAAA,EAC1C,QAAQ,cAAc,GAAG;AAAA,EAEzB,MAAM,UAAU,MAAM,cAAc,QAAQ;AAAA,EAC5C,QAAQ,cAAc,OAAO,KAAK;AAAA,EAElC,MAAM,QAAQ,MAAM,cAAc,OAAO;AAAA,EACzC,MAAM,OAAO;AAAA,EACb,MAAM,OAAO;AAAA,EACb,MAAM,MAAM,OAAO,MAAM,GAAG;AAAA,EAC5B,MAAM,MAAM,OAAO,MAAM,GAAG;AAAA,EAC5B,MAAM,OAAO,OAAO,MAAM,IAAI;AAAA,EAC9B,MAAM,QAAQ,OAAO,KAAK;AAAA,EAC1B,MAAM,MAAM,QAAQ;AAAA,EAEpB,QAAQ,YAAY,OAAO;AAAA,EAC3B,QAAQ,YAAY,OAAO;AAAA,EAC3B,QAAQ,YAAY,KAAK;AAAA,EACzB,OAAO,EAAE,SAAS,OAAO,QAAQ;AAAA;AAe5B,SAAS,WAAW,CACzB,OACA,MACA,OACA,SACA,UACa;AAAA,EACb,MAAM,UAAU,MAAM,cAAc,OAAO;AAAA,EAC3C,QAAQ,MAAM,UAAU;AAAA,EAExB,MAAM,UAAU,MAAM,cAAc,MAAM;AAAA,EAC1C,QAAQ,cAAc,GAAG;AAAA,EAEzB,MAAM,QAAQ,MAAM,cAAc,QAAQ;AAAA,EAC1C,MAAM,OAAO;AAAA,EACb,MAAM,MAAM,QAAQ;AAAA,EACpB,WAAW,UAAU,SAAS;AAAA,IAC5B,MAAM,SAAS,MAAM,cAAc,QAAQ;AAAA,IAC3C,OAAO,QAAQ,OAAO,MAAM;AAAA,IAC5B,OAAO,cAAc,OAAO,MAAM;AAAA,IAClC,MAAM,YAAY,MAAM;AAAA,EAC1B;AAAA,EACA,MAAM,QAAQ,OAAO,QAAQ;AAAA,EAE7B,QAAQ,YAAY,OAAO;AAAA,EAC3B,QAAQ,YAAY,KAAK;AAAA,EACzB,OAAO,EAAE,SAAS,MAAM;AAAA;AAanB,SAAS,SAAS,CAAC,OAA4B;AAAA,EACpD,MAAM,UAAU,MAAM,cAAc,GAAG;AAAA,EACvC,QAAQ,MAAM,SAAS;AAAA,EACvB,QAAQ,MAAM,WAAW;AAAA,EACzB,QAAQ,cAAc;AAAA,EACtB,QAAQ,SAAS;AAAA,EAEjB,OAAO;AAAA,IACL;AAAA,IACA,IAAI,CAAC,MAA2B;AAAA,MAC9B,QAAQ,cAAc,QAAQ;AAAA,MAC9B,QAAQ,SAAS,SAAS;AAAA;AAAA,EAE9B;AAAA;;;AC1HK,SAAS,aAAa,CAAC,QAAkC;AAAA,EAC9D,IAAI,SAAS,QAAQ;AAAA,IACnB,OAAO;AAAA,EACT;AAAA,EACA,MAAM,MAAM,OAAO,WAAW,IAAI;AAAA,EAClC,IAAI,QAAQ,MAAM;AAAA,IAChB,MAAM,IAAI,MACR,gEACE,qDACJ;AAAA,EACF;AAAA,EACA,OAAO,EAAE,KAAK,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO;AAAA;;;ACnDpD,SAAS,wBAAwB,CACtC,QACa;AAAA,EACb,IAAI,aAAa,QAAQ;AAAA,IACvB,OAAO;AAAA,EACT;AAAA,EACA,OAAO,EAAE,SAAS,cAAc,MAAM,GAAG,SAAS,OAAO;AAAA;AAiBpD,SAAS,UAAU,CACxB,SACA,SACA,OAC4C;AAAA,EAC5C,MAAM,OAAO,QAAQ,sBAAsB;AAAA,EAC3C,MAAM,SAAS,KAAK,UAAU,IAAI,IAAI,QAAQ,QAAQ,KAAK;AAAA,EAC3D,MAAM,SAAS,KAAK,WAAW,IAAI,IAAI,QAAQ,SAAS,KAAK;AAAA,EAC7D,OAAO;AAAA,IACL,IAAI,MAAM,UAAU,KAAK,QAAQ;AAAA,IACjC,IAAI,MAAM,UAAU,KAAK,OAAO;AAAA,EAClC;AAAA;AAmCF,IAAM,uBAAuB;AAC7B,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AAejB,SAAS,oBAAoB,CAAC,QAAsC;AAAA,EACzE,IAAI,aAAa,QAAQ;AAAA,IACvB,OAAO;AAAA,MACL,SAAS,OAAO;AAAA,MAChB,UAAU,OAAO;AAAA,MACjB,SAAS,MAAG;AAAA,QAAG;AAAA;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,IAAI,OAAO,YAAY,UAAU;AAAA,IAC/B,MAAM,IAAI,MACR,yEACE,sDACJ;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,OAAO;AAAA,EACrB,MAAM,WAAW,MAAM,cAAc,KAAK;AAAA,EAC1C,SAAS,MAAM,QAAQ,GAAG;AAAA,EAC1B,SAAS,MAAM,aAAa;AAAA,EAC5B,SAAS,MAAM,UAAU;AAAA,EACzB,SAAS,MAAM,YAAY;AAAA,EAE3B,MAAM,QACJ,OAAO,cAAc,uBACjB,OAAO,cAAc,uBACrB;AAAA,EACN,MAAM,SACJ,OAAO,eAAe,IAAI,OAAO,eAAe;AAAA,EAClD,MAAM,QAAQ,WAAW;AAAA,EAMzB,MAAM,SAAS,MAAM,cAAc,QAAQ;AAAA,EAC3C,OAAO,QAAQ,KAAK,MAAM,QAAQ,KAAK;AAAA,EACvC,OAAO,SAAS,KAAK,MAAM,SAAS,KAAK;AAAA,EACzC,OAAO,MAAM,QAAQ,GAAG;AAAA,EACxB,OAAO,MAAM,SAAS,GAAG;AAAA,EACzB,OAAO,MAAM,WAAW;AAAA,EAExB,OAAO,MAAM,UAAU;AAAA,EACvB,OAAO,YAAY,QAAQ;AAAA,EAC3B,OAAO,YAAY,MAAM;AAAA,EAEzB,MAAM,SAAS,MAAY;AAAA,IACzB,SAAS,OAAO;AAAA,IAChB,OAAO,OAAO;AAAA;AAAA,EAGhB,MAAM,UAAU,OAAO,WAAW,IAAI;AAAA,EACtC,IAAI,YAAY,MAAM;AAAA,IAEpB,OAAO;AAAA,IACP,MAAM,IAAI,MACR,uEACE,uEACJ;AAAA,EACF;AAAA,EAIA,IAAI,UAAU,GAAG;AAAA,IACf,QAAQ,MAAM,OAAO,KAAK;AAAA,EAC5B;AAAA,EAEA,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,OAAO,OAAO,GAAG,UAAU,SAAS,OAAO;AAAA;AAiC/E,IAAM,uBAAuB;AActB,SAAS,mBAAmB,CAAC,QAA2C;AAAA,EAC7E,IAAI,UAAU,QAAQ;AAAA,IACpB,OAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,UAAU,OAAO;AAAA,MACjB,SAAS,MAAG;AAAA,QAAG;AAAA;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,IAAI,OAAO,YAAY,UAAU;AAAA,IAC/B,MAAM,IAAI,MACR,yEACE,wDACJ;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,OAAO;AAAA,EACrB,MAAM,WAAW,MAAM,cAAc,KAAK;AAAA,EAC1C,SAAS,MAAM,UAAU;AAAA,EACzB,SAAS,MAAM,WAAW;AAAA,EAC1B,SAAS,MAAM,MAAM;AAAA,EACrB,SAAS,MAAM,UAAU;AAAA,EACzB,SAAS,MAAM,aAAa;AAAA,EAE5B,MAAM,OAAO,MAAM,cAAc,KAAK;AAAA,EACtC,KAAK,MAAM,OAAO;AAAA,EAClB,KAAK,MAAM,YACT,OAAO,eAAe,IAAI,MAAM,GAAG;AAAA,EAErC,OAAO,MAAM,UAAU;AAAA,EACvB,OAAO,MAAM,gBAAgB;AAAA,EAC7B,OAAO,YAAY,QAAQ;AAAA,EAC3B,OAAO,YAAY,IAAI;AAAA,EAEvB,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,SAAS,MAAM;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,KAAK,OAAO;AAAA;AAAA,EAEhB;AAAA;AASF,SAAS,UAAU,GAAW;AAAA,EAC5B,MAAM,QAAQ,WAAW;AAAA,EACzB,OAAO,OAAO,UAAU,YAAY,QAAQ,IAAI,QAAQ;AAAA;;;AC9J1D,IAAM,OAAO;AAGb,IAAM,eAA4B,EAAE,KAAK,KAAK,KAAK,IAAI,MAAM,IAAI;AAEjE,IAAM,gBAA6B,EAAE,KAAK,MAAM,KAAK,GAAG,MAAM,KAAK;AAEnE,IAAM,aAA0B,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,EAAE;AAG3D,IAAM,iBAAiB;AAAA,EACrB,EAAE,MAAM,WAAW,OAAO,WAAW;AAAA,EACrC,EAAE,MAAM,WAAW,OAAO,WAAW;AAAA,EACrC,EAAE,MAAM,WAAW,OAAO,WAAW;AACvC;AAoBO,SAAS,oBAAoB,CAClC,QACA,MACA,UAAuC,CAAC,GACZ;AAAA,EAG5B;AAAA,IACE,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,OACG;AAAA,MACD;AAAA,EAGJ,MAAM,QAAQ;AAAA,IACZ,QAAQ,UAAU,wBAAwB;AAAA,IAC1C,SAAS,WAAW,wBAAwB;AAAA,IAC5C,MAAM,QAAQ,wBAAwB;AAAA,EACxC;AAAA,EACA,uBAAuB,MAAM,QAAQ,MAAM,SAAS,MAAM,IAAI;AAAA,EAE9D,MAAM,UAAU,eAAe,IAAI;AAAA,EACnC,2BAA2B,SAAS,sBAAsB;AAAA,EAC1D,YAAY,MAAM,UAAU;AAAA,IAC1B,CAAC,KAAK,CAAC;AAAA,IACP,CAAC,KAAK,CAAC;AAAA,IACP,CAAC,KAAK,CAAC;AAAA,EACT,GAAY;AAAA,IACV,IAAI,UAAU,aAAa,CAAC,QAAQ,SAAS,KAAK,GAAG;AAAA,MACnD,MAAM,IAAI,WACR,aAAa,YAAY,wCACvB,8BAA8B,QAAQ,KAAK,IAAI,IACnD;AAAA,IACF;AAAA,EACF;AAAA,EACA,IAAI,UAAU,aAAa,KAAK,WAAW,WAAW;AAAA,IACpD,MAAM,IAAI,WAAW,uBAAuB,6BAA6B;AAAA,EAC3E;AAAA,EAEA,MAAM,QAAQ,oBAAoB,MAAM;AAAA,EACxC,MAAM,QAAQ,MAAM,SAAS;AAAA,EAE7B,IAAI,SAA0B;AAAA,IAC5B,GAAG,KAAK,QAAQ;AAAA,IAChB,GAAG,KAAK,QAAQ;AAAA,IAChB,GAAG,KAAK,QAAQ;AAAA,IAChB;AAAA,IACA,QAAQ,MAAM,OAAO,IAAI,CAAC,OAAO,SAC/B,oBACE,OACA,wBAAwB,OAAO,OAC/B,YACF,CACF;AAAA,IACA,SAAS,oBACP,MAAM,SACN,wBAAwB,SACxB,aACF;AAAA,IACA,MAAM,oBACJ,MAAM,MACN,wBAAwB,MACxB,UACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EAEA,IAAI,OAA6B;AAAA,EACjC,IAAI,SAAiC;AAAA,EACrC,IAAI,UAAoC;AAAA,EACxC,IAAI,YAAY;AAAA,EAChB,IAAI,YAAY;AAAA,EAChB,IAAI,WAAiC;AAAA,EACrC,IAAI,SAAS;AAAA,EAEb,MAAM,OAAO,UAAU,KAAK;AAAA,EAQ5B,eAAe,UAAU,GAAkB;AAAA,IACzC,MAAM,QAAQ,MAAM,cAAc,MAAM,MAAM,MAAM;AAAA,SAC/C;AAAA,SACA;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAAA,IACD,IAAI,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IAEA,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,OAAO,EAAE,QAAQ,MAAM,QAAQ,QAAQ,MAAM,QAAQ,MAAM,MAAM,KAAK;AAAA,IACtE,KAAK,KAAK,MAAM,IAAI;AAAA,IAIpB,IAAI,CAAC,WAAW;AAAA,MACd,YAAY;AAAA,MACZ,QAAQ,GAAG,mBAAmB,cAAc;AAAA,IAC9C;AAAA;AAAA,EAaF,SAAS,aAAa,GAAS;AAAA,IAC7B,IAAI,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,aAAa,MAAM;AAAA;AAAA,EAGrB,SAAS,KAAK,GAAkB;AAAA,IAC9B,MAAM,MAAM,KAAK;AAAA,IAGjB,IAAI,MAAM,MAAG;AAAA,MAAG;AAAA,KAAS;AAAA,IACzB,OAAO;AAAA;AAAA,EAGT,eAAe,IAAI,GAAkB;AAAA,IACnC,IAAI;AAAA,MACF,OAAO,UAAU,CAAC,WAAW;AAAA,QAC3B,SAAS;AAAA,QACT,MAAM,WAAW;AAAA,MACnB;AAAA,cACA;AAAA,MACA,WAAW;AAAA;AAAA;AAAA,EAaf,SAAS,cAAc,CAAC,OAAkC;AAAA,IACxD,MAAM,QAAQ,MAAM;AAAA,IACpB,IAAI,UAAU,aAAa,aAAa,WAAW,OAAO,OAAO,MAAM,GAAG;AAAA,MACxE;AAAA,IACF;AAAA,IACA,SAAS,KAAK,QAAQ,QAAQ,MAAM;AAAA,IACpC,IAAI,YAAY,QAAQ,WAAW,WAAW;AAAA,MAG5C,OAAO,SAAS,SAAS,EAAE,gBAAgB,MAAM,CAAC,EAAE,MAAM,MAAG;AAAA,QAAG;AAAA,OAAS;AAAA,IAC3E;AAAA;AAAA,EAGF,SAAS,YAAY,CAAC,OAAoB;AAAA,IACxC,MAAM,QAAQ,MAAM;AAAA,IACpB,IAAI,MAAM,SAAS,SAAS;AAAA,MAC1B,SAAS;AAAA,WACJ;AAAA,QACH,OAAO,MAAM,UAAU,OAAO,YAAY,MAAM;AAAA,MAClD;AAAA,IACF,EAAO;AAAA,MACL,SAAS,KAAK,SAAS,MAAM,OAAO,MAAM,MAAM;AAAA;AAAA,IAElD,cAAc;AAAA;AAAA,EAGhB,SAAS,WAAW,CAAC,OAAoB;AAAA,IACvC,MAAM,QAAQ,MAAM;AAAA,IAGpB,MAAM,QAAQ,OAAO,MAAM,KAAK;AAAA,IAChC,MAAM,OAAO,eAAe,UAC1B,CAAC,WAAW,OAAO,SAAS,MAAM,IACpC;AAAA,IACA,IAAI,QAAQ,GAAG;AAAA,MACb,SAAS;AAAA,WACJ;AAAA,QACH,QAAQ,OAAO,OAAO,IAAI,CAAC,KAAK,UAC9B,UAAU,OAAO,QAAQ,GAC3B;AAAA,MACF;AAAA,IACF,EAAO;AAAA,MACL,SAAS,KAAK,SAAS,MAAM,OAAO,MAAM;AAAA;AAAA,IAG5C,MAAM,UAAU,SAAS,IAAI,MAAM,IAAI;AAAA,IACvC,IAAI,YAAY,WAAW;AAAA,MACzB,QAAQ,cAAc,MAAM;AAAA,IAC9B;AAAA,IACA,cAAc;AAAA;AAAA,EAGhB,MAAM,QAAuB,CAAC;AAAA,EAC9B,MAAM,UAA+B,CAAC;AAAA,EACtC,MAAM,UAA8B,CAAC;AAAA,EACrC,MAAM,WAAW,IAAI;AAAA,EAErB,YAAY,MAAM,UAAU;AAAA,IAC1B,CAAC,KAAK,GAAG;AAAA,IACT,CAAC,KAAK,GAAG;AAAA,IACT,CAAC,KAAK,GAAG;AAAA,EACX,GAAY;AAAA,IACV,MAAM,SAAS,YAAY,OAAO,MAAM,OAAO,SAAS,OAAO,KAAK;AAAA,IACpE,MAAM,SAAS,YAAY,OAAO,OAAO;AAAA,IACzC,MAAM,KAAK,OAAO,OAAO;AAAA,IACzB,QAAQ,KAAK,OAAO,KAAK;AAAA,EAC3B;AAAA,EAEA,MAAM,cAAc,YAClB,OACA,SACA,SACA,CAAC,MAAM,GAAG,OAAO,KAAK,IAAI,CAAC,GAC3B,OAAO,SAAS,IAClB;AAAA,EACA,MAAM,SAAS,YAAY,YAAY,OAAO;AAAA,EAC9C,MAAM,KAAK,YAAY,OAAO;AAAA,EAC9B,QAAQ,KAAK,YAAY,KAAK;AAAA,EAE9B,YAAY,MAAM,WAAW,eAAe,QAAQ,GAAG;AAAA,IACrD,MAAM,UAAU,YACd,OACA,OAAO,MACP,OAAO,OACP,cACA,OAAO,OAAO,KAChB;AAAA,IACA,MAAM,SAAS,YAAY,QAAQ,OAAO;AAAA,IAC1C,MAAM,KAAK,QAAQ,OAAO;AAAA,IAC1B,QAAQ,KAAK,QAAQ,KAAK;AAAA,IAC1B,SAAS,IAAI,OAAO,MAAM,QAAQ,OAAO;AAAA,EAC3C;AAAA,EAEA,YAAY,MAAM,OAAO,OAAO,UAAU;AAAA,IACxC,CAAC,WAAW,WAAW,eAAe,OAAO,OAAO;AAAA,IACpD,CAAC,QAAQ,QAAQ,YAAY,OAAO,IAAI;AAAA,EAC1C,GAAY;AAAA,IACV,MAAM,UAAU,YAAY,OAAO,MAAM,OAAO,OAAO,KAAK;AAAA,IAC5D,MAAM,SAAS,YAAY,QAAQ,OAAO;AAAA,IAC1C,MAAM,KAAK,QAAQ,OAAO;AAAA,IAC1B,QAAQ,KAAK,QAAQ,KAAK;AAAA,IAC1B,SAAS,IAAI,MAAM,QAAQ,OAAO;AAAA,EACpC;AAAA,EAEA,MAAM,SAAS,YAAY,KAAK,OAAO;AAAA,EACvC,MAAM,KAAK,KAAK,OAAO;AAAA,EAEvB,WAAW,UAAU,SAAS;AAAA,IAC5B,OAAO,iBAAiB,UAAU,YAAY;AAAA,EAChD;AAAA,EACA,WAAW,UAAU,SAAS;AAAA,IAC5B,OAAO,iBAAiB,SAAS,WAAW;AAAA,EAC9C;AAAA,EAGA,cAAc;AAAA,EAGd,SAAS,aAAa,GAAoB;AAAA,IACxC,OAAO,KAAK,QAAQ,QAAQ,CAAC,GAAG,OAAO,MAAM,EAAE;AAAA;AAAA,EAGjD,OAAO;AAAA,IACL,WAAW;AAAA,IACX,SAAS,MAAM;AAAA,IACf,UAAU,MAAM,YAAY,QAAQ,QAAQ;AAAA,IAC5C,IAAI,GAAG;AAAA,MACL,SAAS,cAAc,CAAC;AAAA;AAAA,IAE1B,OAAO,GAAG;AAAA,MACR,IAAI,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MACA,YAAY;AAAA,MACZ,WAAW,UAAU,SAAS;AAAA,QAC5B,OAAO,oBAAoB,UAAU,YAAY;AAAA,MACnD;AAAA,MACA,WAAW,UAAU,SAAS;AAAA,QAC5B,OAAO,oBAAoB,SAAS,WAAW;AAAA,MACjD;AAAA,MACA,WAAW,QAAQ,OAAO;AAAA,QACxB,KAAK,OAAO;AAAA,MACd;AAAA,MACA,IAAI,YAAY,MAAM;AAAA,QACpB,QAAQ,mBAAmB,iBAAiB;AAAA,QAC5C,QAAQ,MAAM,OAAO;AAAA,MACvB;AAAA,MACA,MAAM,QAAQ;AAAA;AAAA,EAElB;AAAA;;ACvdK,SAAS,GAAG,CAAC,QAAmC;AAAA,EACrD,OAAO,OAAO,OAAO,CAAC,OAAO,UAAU,QAAQ,OAAO,CAAC;AAAA;AAIlD,SAAS,IAAI,CAAC,QAAmC;AAAA,EACtD,OAAO,IAAI,MAAM,IAAI,OAAO;AAAA;AAkBvB,SAAS,MAAM,CAAC,QAA6C;AAAA,EAClE,OAAO,OAAO,OACZ,EAAE,KAAK,OAAO,UAAU;AAAA,IACtB,QAAQ,MAAM,QAAQ;AAAA,IACtB,QAAQ,OAAO,QAAQ;AAAA,EACzB,GACA,CAAC,OAAO,mBAAmB,OAAO,iBAAiB,CACrD;AAAA;AAUK,SAAS,mBAAmB,CAAC,OAAuB;AAAA,EACzD,OAAO,UAAU,IAAI,IAAI;AAAA;AAIpB,SAAS,YAAY,CAAC,OAAe,MAAoB;AAAA,EAC9D,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GAAG;AAAA,IACzC,MAAM,IAAI,WAAW,GAAG,4CAA4C,OAAO;AAAA,EAC7E;AAAA;AAQK,SAAS,OAAgB,CAC9B,IACA,IACA,SACK;AAAA,EACL,MAAM,SAAS,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM;AAAA,EAE5C,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,IAAI,CAAC,GAAG,UAAU,QAAQ,GAAG,GAAG,MAAW,CAAC;AAAA;AAUlE,SAAS,EAAE,CAAC,QAAmC;AAAA,EACpD,IAAI,OAAO,SAAS,GAAG;AAAA,IACrB,OAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,SAAS,KAAK,MAAM;AAAA,EAC1B,MAAM,UAAU,OAAO,IAAI,CAAC,WAAW,QAAQ,WAAW,QAAQ,OAAO;AAAA,EACzE,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK,OAAO,SAAS,EAAE;AAAA;AAoB9C,SAAS,qBAAqB,CAAC,QAAmC;AAAA,EACvE,MAAM,SAAS,KAAK,MAAM;AAAA,EAC1B,OAAO,KAAK,OAAO,IAAI,CAAC,UAAU,KAAK,IAAI,QAAQ,MAAM,CAAC,CAAC;AAAA;AAqBtD,SAAS,gBAAgB,CAAC,GAAW,GAAW,GAAmB;AAAA,EACxE,OAAO,SAAS,gBAAgB,WAAW,GAAG,CAAC;AAAA,EAC/C,OAAO,MAAK,YAAY,OAAO,GAAG,OAAO;AAAA,EACzC,MAAM,UAAU,QAAO,WAAW;AAAA,EAClC,OAAO,OAAO,SAAS,OAAO,IAAI,UAAU,IAAI,IAAI;AAAA;AAItD,SAAS,KAAK,CAAC,OAAiC;AAAA,EAC9C,MAAM,SAAS,YAAY;AAAA,EAC3B,MAAM,OAAO,UAAU,SAAS;AAAA,EAChC,OAAO,CAAC,MAAM,QAAQ,IAAI;AAAA;AAI5B,SAAS,UAAU,CAAC,GAAW,GAA6B;AAAA,EAC1D,MAAM,UAAU,IAAI;AAAA,EACpB,OAAO,OAAO,QAAQ,MAAM,CAAC;AAAA,EAC7B,OAAO,OAAO,QAAQ,MAAM,CAAC;AAAA,EAC7B,MAAM,QACJ,OAAO,QAAQ,UAAU,QAAQ,QAAQ,OAAO,QAAQ,QAAQ;AAAA,EAClE,OAAO,CAAC,SAAS,KAAK;AAAA;AAIxB,SAAS,MAAM,CAAC,GAAW,GAA6B;AAAA,EACtD,MAAM,OAAM,IAAI;AAAA,EAChB,MAAM,UAAU,OAAM;AAAA,EACtB,OAAO,CAAC,MAAK,KAAK,OAAM,YAAY,IAAI,QAAQ;AAAA;AAgB3C,SAAS,QAAQ,CAAC,QAA2B,GAAmB;AAAA,EACrE,OAAO,UAAU,QAAQ,CAAC,CAAC,CAAC,EAAE;AAAA;AAiBzB,SAAS,SAAS,CACvB,QACA,OACU;AAAA,EACV,IAAI,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK,KAAK,KAAK,EAAE,GAAG;AAAA,IAC1C,MAAM,IAAI,WAAW,4CAA4C,OAAO;AAAA,EAC1E;AAAA,EACA,IAAI,OAAO,WAAW,GAAG;AAAA,IACvB,OAAO,MAAM,IAAI,MAAM,OAAO,GAAG;AAAA,EACnC;AAAA,EAIA,MAAM,SAAS,aAAa,KAAK,MAAM,EAAE,KAAK;AAAA,EAE9C,OAAO,MAAM,IAAI,CAAC,MAAM,MAAM,QAAQ,CAAC,CAAC;AAAA;AAkBnC,SAAS,MAAM,CAAC,QAAmC;AAAA,EACxD,OAAO,SAAS,QAAQ,GAAG;AAAA;AAI7B,SAAS,KAAK,CAAC,QAAsB,GAAmB;AAAA,EACtD,MAAM,WAAW,KAAK,OAAO,SAAS,KAAK;AAAA,EAC3C,MAAM,QAAQ,KAAK,MAAM,QAAQ;AAAA,EACjC,MAAM,QAAQ,KAAK,KAAK,QAAQ;AAAA,EAGhC,MAAM,MAAM,OAAO,QAAQ;AAAA,EAC3B,MAAM,OAAO,OAAO,QAAQ;AAAA,EAE5B,IAAI,WAAW,SAAS,SAAS,KAAK;AAAA,IAGpC,MAAM,IAAI,WAAW;AAAA,IACrB,QAAQ,IAAI,KAAK,MAAM,IAAI;AAAA,EAC7B;AAAA,EACA,OAAO;AAAA;;;ACtLF,IAAM,kCAAkC;AAexC,SAAS,YAAY,CAC1B,QACA,GACA,UAA+B,CAAC,GACf;AAAA,EACjB,QAAQ,SAAS,YAAY,oCAAoC;AAAA,EACjE,MAAM,OAAO,OAAO;AAAA,EAEpB,IAAI,SAAS,GAAG;AAAA,IACd,MAAM,IAAI,WAAW,sCAAsC;AAAA,EAC7D;AAAA,EACA,MAAM,QAAQ,OAAO,GAAG;AAAA,EACxB,IAAI,OAAO,KAAK,CAAC,QAAQ,IAAI,WAAW,KAAK,GAAG;AAAA,IAC9C,MAAM,IAAI,WAAW,mDAAmD;AAAA,EAC1E;AAAA,EACA,IAAI,EAAE,WAAW,MAAM;AAAA,IACrB,MAAM,IAAI,WACR,oBAAoB,EAAE,oCAAoC,WAC5D;AAAA,EACF;AAAA,EACA,IAAI,YAAY,WAAW;AAAA,IACzB,IAAI,QAAQ,WAAW,MAAM;AAAA,MAC3B,MAAM,IAAI,WACR,aAAa,QAAQ,sBAAsB,WAC7C;AAAA,IACF;AAAA,IACA,IAAI,QAAQ,KAAK,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG;AAAA,MAC5C,MAAM,IAAI,WAAW,uCAAuC;AAAA,IAC9D;AAAA,EACF;AAAA,EAIA,MAAM,QAAQ,SAAS,IAAI,CAAC,WAAW,KAAK,KAAK,MAAM,CAAC;AAAA,EACxD,MAAM,SAAS,CAAC,OAAe,QAC7B,UAAU,YAAY,QAAQ,QAAQ,MAAM;AAAA,EAE9C,MAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,WAChD,OAAO,IAAI,CAAC,KAAK,UAAU,OAAO,IAAI,SAAS,KAAK,CAAC,CACvD;AAAA,EACA,MAAM,YAAY,EAAE,IAAI,MAAM;AAAA,EAE9B,QAAQ,cAAc,OAAO,SAAS,UAAU,SAAS,WAAW,IAAI;AAAA,EACxE,kBAAkB,SAAS,cAAc,WAAW,KAAK,IAAI,MAAM,OAAO,CAAC,CAAC;AAAA,EAC5E,MAAM,SAAS,eAAe,SAAS,WAAW,IAAI;AAAA,EAItD,MAAM,eAAe,IAAI,MAAqB,KAAK,EAAE,KAAK,IAAI;AAAA,EAC9D,MAAM,MAAM,GAAG,IAAI,EAAE,QAAQ,CAAC,QAAQ,aAAa;AAAA,IACjD,aAAa,UAAU,OAAO;AAAA,GAC/B;AAAA,EAED,MAAM,SAAS,OAAO,IAAI,CAAC,QACzB,IACE,QAAQ,KAAK,cAAc,CAAC,OAAO,gBACjC,gBAAgB,OAAO,IAAI,QAAQ,WACrC,CACF,CACF;AAAA,EACA,MAAM,YAAY,QAAQ,GAAG,QAAQ,CAAC,OAAO,QAAQ,QAAQ,GAAG;AAAA,EAEhE,OAAO,EAAE,cAAc,QAAQ,WAAW,KAAK;AAAA;AAkBjD,SAAS,SAAS,CAChB,SACA,WACA,MAC2D;AAAA,EAC3D,MAAM,QAAQ,QAAQ;AAAA,EACtB,MAAM,QAAQ,QAAQ,IAAI,CAAC,GAAG,WAAW,MAAM;AAAA,EAG/C,MAAM,gBAAgB,QAAQ,IAAI,CAAC,WAAW,KAAK,QAAQ,CAAC,KAAK,CAAC;AAAA,EAClE,MAAM,eAAe,IAAI,MAAc,KAAK,EAAE,KAAK,CAAC;AAAA,EAGpD,IAAI,OAAO;AAAA,EAIX,SAAS,OAAO,EAAG,OAAO,KAAK,IAAI,MAAM,KAAK,GAAG,QAAQ;AAAA,IACvD,OACE,OAAO,QACP,KAAK,QAAQ,OAAO,IAAI,IAAI,cAAc,QAAQ,WAClD;AAAA,MACA,WAAW,SAAS,OAAO,eAAe,IAAI;AAAA,MAC9C,QAAQ;AAAA,IACV;AAAA,IAKA,IAAI,SAAS,OAAO,GAAG;AAAA,MACrB;AAAA,IACF;AAAA,IACA,aAAa,QAAQ,QAAQ,SAAS,MAAM,IAAI;AAAA,EAClD;AAAA,EAEA,OAAO,EAAE,cAAc,OAAO,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE;AAAA;AAS3D,SAAS,OAAO,CAAC,SAAqB,MAAc,MAAsB;AAAA,EACxE,MAAM,SAAS,QAAQ;AAAA,EACvB,MAAM,SAAS,KAAK,QAAQ,IAAI;AAAA,EAChC,IAAI,WAAW,GAAG;AAAA,IAChB,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,OAAO,QAAQ,IAAI,CAAC,SAAS;AAAA,EAE/C,SAAS,MAAM,KAAM,MAAM,MAAM,OAAO;AAAA,IACtC,OAAO,OAAO,OAAO,OAAO;AAAA,EAC9B;AAAA,EACA,MAAM,UAAU,IAAI,OAAO;AAAA,EAC3B,OAAO,QAAQ;AAAA,EAEf,SAAS,QAAQ,OAAO,EAAG,QAAQ,QAAQ,QAAQ,SAAS;AAAA,IAC1D,MAAM,QAAQ,QAAQ;AAAA,IACtB,IAAI,QAAQ;AAAA,IACZ,SAAS,MAAM,KAAM,MAAM,MAAM,OAAO;AAAA,MACtC,SAAS,OAAO,OAAO,MAAM;AAAA,IAC/B;AAAA,IACA,MAAM,SAAS,CAAC,QAAQ;AAAA,IACxB,SAAS,MAAM,KAAM,MAAM,MAAM,OAAO;AAAA,MACtC,MAAM,OAAO,MAAM,OAAO,SAAS,OAAO;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,OAAO,QAAQ,CAAC;AAAA,EAChB,OAAO;AAAA;AAIT,SAAS,iBAAiB,CACxB,SACA,cACA,UACA,OACM;AAAA,EACN,MAAM,OAAO,SAAS;AAAA,EAEtB,SAAS,OAAO,EAAG,OAAO,OAAO,QAAQ;AAAA,IACvC,MAAM,UAAU,aAAa;AAAA,IAC7B,IAAI,YAAY,GAAG;AAAA,MACjB;AAAA,IACF;AAAA,IACA,MAAM,SAAS,QAAQ;AAAA,IAGvB,IAAI,QAAQ,UAAU,SAAS;AAAA,IAC/B,SAAS,MAAM,OAAO,EAAG,MAAM,MAAM,OAAO;AAAA,MAC1C,SAAS,OAAO,OAAO,SAAS;AAAA,IAClC;AAAA,IACA,MAAM,SAAS,CAAC,QAAQ;AAAA,IACxB,SAAS,QAAQ,SAAS,QAAQ,SAAS;AAAA,IAC3C,SAAS,MAAM,OAAO,EAAG,MAAM,MAAM,OAAO;AAAA,MAC1C,SAAS,OAAO,SAAS,OAAO,SAAS,OAAO;AAAA,IAClD;AAAA,EACF;AAAA;AAIF,SAAS,cAAc,CACrB,SACA,UACA,MACU;AAAA,EACV,MAAM,SAAS,IAAI,MAAc,IAAI,EAAE,KAAK,CAAC;AAAA,EAE7C,SAAS,MAAM,OAAO,EAAG,OAAO,GAAG,OAAO;AAAA,IACxC,IAAI,QAAQ,SAAS;AAAA,IACrB,SAAS,SAAS,MAAM,EAAG,SAAS,MAAM,UAAU;AAAA,MAClD,SAAS,QAAQ,QAAQ,OAAO,OAAO;AAAA,IACzC;AAAA,IACA,OAAO,OAAO,QAAQ,QAAQ,KAAK;AAAA,EACrC;AAAA,EAEA,OAAO;AAAA;AAIT,SAAS,UAAU,CACjB,SACA,OACA,eACA,MACM;AAAA,EACN,UAAU,SAAS,IAAI;AAAA,EACvB,UAAU,OAAO,IAAI;AAAA,EACrB,UAAU,eAAe,IAAI;AAAA;AAI/B,SAAS,SAAY,CAAC,OAAY,MAAoB;AAAA,EACpD,OAAO,SAAS,MAAM,OAAO,MAAM,CAAC;AAAA,EACpC,MAAM,KAAK,KAAK;AAAA;AAIlB,SAAS,IAAI,CAAC,QAA2B,MAAsB;AAAA,EAC7D,OAAO,KAAK,MAAM,GAAG,OAAO,MAAM,IAAI,CAAC;AAAA;;;AC/PzC,IAAM,aAAa;AA0FZ,SAAS,iBAAiB,CAC/B,MACA,SACmB;AAAA,EACnB,QAAQ,SAAS,IAAI,KAAK,cAAc,MAAM,WAAW,CAAC,MAAM;AAAA,EAEhE,IAAI,OAAO,KAAK;AAAA,IACd,MAAM,IAAI,WACR,8DAA8D,KAChE;AAAA,EACF;AAAA,EAGA,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC;AAAA,EACxC,SAAS,QAAQ,CAAC,YAAY;AAAA,IAC5B,IAAI,MAAM,IAAI,OAAO,GAAG;AAAA,MACtB,MAAM,IAAI,WACR,YAAY,0DACV,oBACJ;AAAA,IACF;AAAA,IACA,MAAM,IAAI,OAAO;AAAA,GAClB;AAAA,EAED,MAAM,OAAO,UAAU,IAAI;AAAA,EAC3B,MAAM,IAAI,qBAAqB,MAAM,SAAS,SAAS;AAAA,EACvD,MAAM,WAAW,qBAAqB,MAAM,IAAI,IAAI;AAAA,EACpD,MAAM,YAAY,qBAAqB,MAAM,KAAK,KAAK;AAAA,EACvD,MAAM,iBAAiB,SAAS,IAAI,CAAC,YACnC,qBAAqB,MAAM,SAAS,UAAU,CAChD;AAAA,EAKA,MAAM,eAAe,CAAC,GAAG,UAAU,WAAW,GAAG,cAAc;AAAA,EAC/D,MAAM,eAAe,EAClB,IAAI,CAAC,GAAG,QAAQ,GAAG,EACnB,OAAO,CAAC,QACP,aAAa,MAAM,CAAC,WAAW,OAAO,SAAS,OAAO,IAAI,CAAC,CAC7D;AAAA,EACF,IAAI,aAAa,WAAW,GAAG;AAAA,IAC7B,MAAM,IAAI,WACR,qEACE,kDACJ;AAAA,EACF;AAAA,EAIA,MAAM,gBAGA;AAAA,IACJ,EAAE,MAAM,eAAe,QAAQ,IAAI,MAAc,IAAI,EAAE,KAAK,CAAC,EAAE;AAAA,IAC/D,EAAE,MAAM,IAAI,QAAQ,SAAS;AAAA,IAC7B,EAAE,MAAM,KAAK,QAAQ,UAAU;AAAA,IAC/B,GAAG,SAAS,IAAI,CAAC,SAAS,WAAW;AAAA,MACnC,MAAM;AAAA,MACN,QAAQ,eAAe;AAAA,IACzB,EAAE;AAAA,IACF,GAAI,cACA;AAAA,MACE;AAAA,QACE,MAAM,GAAG,MAAM;AAAA,QACf,QAAQ,QAAQ,UAAU,WAAW,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,MACtD;AAAA,IACF,IACA,CAAC;AAAA,EACP;AAAA,EAEA,MAAM,SAAS,aAAa,IAAI,CAAC,QAC/B,cAAc,IAAI,CAAC,WAAW,OAAO,OAAO,IAAc,CAC5D;AAAA,EACA,MAAM,MAAM,aACV,QACA,aAAa,IAAI,CAAC,QAAQ,EAAE,IAAc,CAC5C;AAAA,EACA,MAAM,eAAe,cAAc,IAAI,CAAC,QAAQ,WAAW;AAAA,IACzD,MAAM,OAAO;AAAA,IACb,OAAO,IAAI,aAAa,UAAU;AAAA,EACpC,EAAE;AAAA,EAIF,MAAM,SAAS,IAAI,MAAc,IAAI,EAAE,KAAK,OAAO,GAAG;AAAA,EACtD,MAAM,YAAY,IAAI,MAAc,IAAI,EAAE,KAAK,OAAO,GAAG;AAAA,EACzD,aAAa,QAAQ,CAAC,KAAK,aAAa;AAAA,IACtC,OAAO,OAAO,IAAI,OAAO;AAAA,IACzB,UAAU,OAAO,IAAI,UAAU;AAAA,GAChC;AAAA,EAKD,MAAM,WAAW,KAAK,GAAG,OAAO,QAAQ,GAAG,UAAU;AAAA,EACrD,MAAM,YAAY,KAAK,GAAG,OAAO,SAAS,GAAG,UAAU;AAAA,EACvD,MAAM,QAAQ,OAAO,YACnB,SAAS,IAAI,CAAC,SAAS,UAAU;AAAA,IAC/B;AAAA,IACA,KACG,eAAe,OAA6B,OAAO,OAAO,QAAQ,CACrE;AAAA,EACF,CAAC,CACH;AAAA,EAIA,MAAM,UAAU,aAAa,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC;AAAA,EAC1D,MAAM,cAAc,UAAU,QAAQ,CAAC,aACrC,SAAS,IAAI,CAAC,YAAY;AAAA,IACxB,MAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,SAAS,IAAI,CAAC,YAAY,MAAM,QAAkB;AAAA,MACrD,GAAI,cAAc,CAAC,UAAU,QAAQ,IAAI,CAAC;AAAA,IAC5C;AAAA,IACA,OAAO,IAAI,QAAQ,SAAS,SAAS,CAAC,OAAO,WAAW,QAAQ,MAAM,CAAC;AAAA,GACxE,CACH;AAAA,EAEA,OAAO,SAAS,YAAY,OAAO,CAAC;AAAA,EACpC,OAAO,YAAY,eAAe,OAAO,WAAW;AAAA,EAEpD,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,CAAC,KAAK,IAAI,SAAS,UAAU,GAAG,KAAK,IAAI,UAAU,WAAW,CAAC;AAAA,IACrE;AAAA,EACF;AAAA;AAoBF,SAAS,IAAI,CAAC,MAAc,IAAY,QAA0B;AAAA,EAChE,IAAI,SAAS,IAAI;AAAA,IACf,OAAO,IAAI,MAAc,MAAM,EAAE,KAAK,IAAI;AAAA,EAC5C;AAAA,EAEA,MAAM,MAAM,KAAK,SAAS,SAAS;AAAA,EACnC,OAAO,MAAM,KAAK,EAAE,OAAO,GAAG,CAAC,GAAG,UAChC,UAAU,IAAI,OAAO,UAAU,SAAS,IAAI,KAAK,OAAO,QAAQ,EAClE;AAAA;;;AChQF,IAAM,gBAAgB;AAEtB,IAAM,gBAAgB;AAMtB,IAAM,eAAe,OAAO,KAAK,KAAK,CAAC;AAEvC,IAAM,cAAa;AAEnB,IAAM,UAAS,EAAE,YAAY,KAAK;AAmF3B,SAAS,mBAAmB,CAAC,MAAc,MAAyB;AAAA,EACzE,IAAI,CAAC,OAAO,SAAS,IAAI,KAAK,CAAC,OAAO,SAAS,IAAI,GAAG;AAAA,IACpD,MAAM,IAAI,WAAW,2CAA2C;AAAA,EAClE;AAAA,EAEA,MAAM,WAAY,MAAM,QAAQ,KAAK,KAAM;AAAA,EAC3C,MAAM,aAAc,KAAK,QAAQ,KAAK,KAAM;AAAA,EAC5C,MAAM,MAAe;AAAA,IACnB,GAAG,eAAe,KAAK,IAAI,SAAS,IAAI,KAAK,IAAI,OAAO;AAAA,IACxD,GAAG,eAAe,KAAK,IAAI,SAAS,IAAI,KAAK,IAAI,OAAO;AAAA,IACxD,GAAG,eAAe,KAAK,IAAI,SAAS;AAAA,EACtC;AAAA,EAEA,OAAO,EAAE,IAAI;AAAA;AAeR,SAAS,gBAAgB,CAC9B,SACA,OACA,OAAgC,CAAC,GACf;AAAA,EAClB,QAAQ,OAAO,eAAe,OAAO,eAAe,SAAS;AAAA,EAC7D,MAAM,SAAS,oBAAoB,MAAM,IAAI;AAAA,EAE7C,IAAI,SAAS,WAAW;AAAA,IACtB,IAAI,KAAK,WAAW,KAAK,CAAC,KAAK,MAAM,CAAC,UAAU,OAAO,SAAS,KAAK,CAAC,GAAG;AAAA,MACvE,MAAM,IAAI,WAAW,oCAAoC;AAAA,IAC3D;AAAA,EACF;AAAA,EACA,MAAM,QAAmC,QAAQ;AAAA,IAC/C,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK;AAAA,EACf;AAAA,EAKA,MAAM,QAAQ,QAAQ,SAAS;AAAA,EAC/B,MAAM,UAAU,QAAQ,UAAU,IAAI,CAAC,GAAG,MACxC,QAAQ,SAAS,IAAI,CAAC,IAAI,MAAM,QAAQ,YAAY,IAAI,QAAQ,EAAY,CAC9E;AAAA,EAKA,IAAI,CAAC,QAAQ,YAAY,MAAM,OAAO,QAAQ,GAAG;AAAA,IAC/C,MAAM,IAAI,WACR,sDACE,iCACJ;AAAA,EACF;AAAA,EAEA,MAAM,QAAsB;AAAA,IAC1B,MAAM;AAAA,IACN,GAAG,QAAQ;AAAA,IACX,GAAG,QAAQ;AAAA,IACX,GAAG;AAAA,IAEH,WAAW;AAAA,EACb;AAAA,EAEA,MAAM,SAAuB;AAAA,IAC3B,YAAY;AAAA,IACZ,OAAO;AAAA,MACL,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,GAAG,EAAE;AAAA,MACnC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,IAAI,EAAE;AAAA,MACpC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,QAAQ,GAAG,MAAM;AAAA,MAC/C,YAAY;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,QAAQ,CAAC,KAAK,GAAG,QAAQ,MAAM,cAAc,KAAK,EAAE;AAAA;AAe/D,eAAsB,gBAAgB,CACpC,QACA,MACA,SAC6B;AAAA,EAC7B,QAAQ,QAAQ,MAAM,MAAM,SAAS,UAAU;AAAA,EAC/C,MAAM,UAAU,kBAAkB,MAAM,KAAK;AAAA,EAC7C,MAAM,OAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,MAAM,KAAK,CAAC;AAAA,EAClE,MAAM,SAAS,UAAW,MAAM,WAAW;AAAA,EAC3C,MAAM,UAAU,MAAM,OAAO,MAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,OAAM;AAAA,EAE3E,OAAO,KAAK,MAAM,SAAS,QAAQ,QAAQ,QAAQ;AAAA;AAIrD,SAAS,aAAa,CAAC,OAAyC;AAAA,EAC9D,KAAK,MAAM,YAAY,CAAC,GAAG,WAAW,GAAG;AAAA,IACvC,OAAO;AAAA,EACT;AAAA,EACA,OACE,2BAA2B,MAAM,gBAAgB,MAAM,YACvD,GAAG,MAAM;AAAA;;;ACrJb,IAAM,cAA2B,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,EAAE;AAI7D,IAAM,cAA2B,EAAE,KAAK,KAAK,KAAK,KAAK,MAAM,EAAE;AAE/D,IAAM,iBAAgB;AACtB,IAAM,iBAAgB;AAGtB,IAAM,UAAU;AAAA,EACd;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;AACF;AAiBO,SAAS,uBAAuB,CACrC,QACA,MACA,SAC+B;AAAA,EAG/B,QAAQ,QAAQ,aAAa,QAAQ,MAAM,SAAS,UAAU;AAAA,EAE9D,MAAM,QAAQ,oBAAoB,MAAM;AAAA,EACxC,MAAM,QAAQ,MAAM,SAAS;AAAA,EAE7B,IAAI,SAA6B;AAAA,OAC5B;AAAA,IACH,MAAM,oBAAoB,MAAM,gBAAe,WAAW;AAAA,IAC1D,MAAM,oBAAoB,MAAM,gBAAe,WAAW;AAAA,EAC5D;AAAA,EAEA,IAAI,OAAgC;AAAA,EACpC,IAAI,UAAoC;AAAA,EACxC,IAAI,SAAiC;AAAA,EACrC,IAAI,UAAoC;AAAA,EAExC,IAAI,UAAmE;AAAA,EAMvE,IAAI;AAAA,EACJ,IAAI,YAAY;AAAA,EAChB,IAAI,YAAY;AAAA,EAChB,IAAI,WAAiC;AAAA,EACrC,IAAI,SAAS;AAAA,EAEb,MAAM,OAAO,UAAU,KAAK;AAAA,EAS5B,eAAe,UAAU,GAAkB;AAAA,IACzC,MAAM,SAAS,EAAE,MAAM,OAAO,MAAM,MAAM,OAAO,KAAK;AAAA,IACtD,MAAM,QAAQ,MAAM,iBAAiB,MAAM,MAAM,MAAM;AAAA,SAClD;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAAA,IACD,IAAI,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IAEA,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,UAAU,MAAM;AAAA,IAChB,OAAO,EAAE,QAAQ,MAAM,QAAQ,QAAQ,MAAM,QAAQ,MAAM,MAAM,KAAK;AAAA,IACtE,KAAK,KAAK,MAAM,IAAI;AAAA,IAIpB,IAAI,CAAC,WAAW;AAAA,MACd,YAAY;AAAA,MACZ,QAAQ,GAAG,mBAAmB,cAAc;AAAA,IAC9C;AAAA,IAEA,MAAM,QACJ,YAAY,SACX,QAAQ,SAAS,OAAO,QAAQ,QAAQ,SAAS,OAAO;AAAA,IAC3D,UAAU;AAAA,IAEV,MAAM,SAAS,MAAM,OAAO,MAAM;AAAA,IAClC,IAAI,SAAS,WAAW,WAAW;AAAA,MACjC,aAAa;AAAA,MACb,MAAM,MAAM,OAAO,SAAS,SAAS,EAAE,gBAAgB,OAAO,CAAC;AAAA,IACjE,EAAO,SAAI,eAAe,aAAa,CAAC,WAAW,YAAY,MAAM,GAAG;AAAA,MAKtE,MAAM,MAAM,OAAO,SAAS,SAAS,EAAE,gBAAgB,WAAW,CAAC;AAAA,IACrE;AAAA;AAAA,EAcF,SAAS,cAAc,CAAC,OAAkC;AAAA,IACxD,MAAM,QAAQ,MAAM;AAAA,IACpB,IAAI,UAAU,aAAa,aAAa,WAAW,OAAO,UAAU,GAAG;AAAA,MACrE;AAAA,IACF;AAAA,IACA,aAAa;AAAA,IACb,IAAI,YAAY,QAAQ,WAAW,WAAW;AAAA,MAG5C,OAAO,SAAS,SAAS,EAAE,gBAAgB,MAAM,CAAC,EAAE,MAAM,MAAG;AAAA,QAAG;AAAA,OAAS;AAAA,IAC3E;AAAA;AAAA,EAYF,SAAS,aAAa,GAAS;AAAA,IAC7B,IAAI,WAAW;AAAA,MACb;AAAA,IACF;AAAA,IACA,SAAS;AAAA,IACT,aAAa,MAAM;AAAA;AAAA,EAGrB,SAAS,KAAK,GAAkB;AAAA,IAC9B,MAAM,MAAM,KAAK;AAAA,IAGjB,IAAI,MAAM,MAAG;AAAA,MAAG;AAAA,KAAS;AAAA,IACzB,OAAO;AAAA;AAAA,EAGT,eAAe,IAAI,GAAkB;AAAA,IACnC,IAAI;AAAA,MACF,OAAO,UAAU,CAAC,WAAW;AAAA,QAC3B,SAAS;AAAA,QACT,MAAM,WAAW;AAAA,MACnB;AAAA,cACA;AAAA,MACA,WAAW;AAAA;AAAA;AAAA,EAIf,SAAS,WAAW,CAAC,OAAoB;AAAA,IACvC,MAAM,QAAQ,MAAM;AAAA,IAGpB,SAAS,KAAK,SAAS,MAAM,OAAO,OAAO,MAAM,KAAK,EAAE;AAAA,IAExD,MAAM,UAAU,SAAS,IAAI,MAAM,IAAI;AAAA,IACvC,IAAI,YAAY,WAAW;AAAA,MACzB,QAAQ,cAAc,MAAM;AAAA,IAC9B;AAAA,IACA,cAAc;AAAA;AAAA,EAGhB,MAAM,QAAuB,CAAC;AAAA,EAC9B,MAAM,SAA6B,CAAC;AAAA,EACpC,MAAM,WAAW,IAAI;AAAA,EAErB,WAAW,UAAU,SAAS;AAAA,IAC5B,MAAM,UAAU,YACd,OACA,OAAO,MACP,OAAO,OACP,OAAO,OACP,OAAO,OAAO,KAChB;AAAA,IACA,MAAM,SAAS,YAAY,QAAQ,OAAO;AAAA,IAC1C,MAAM,KAAK,QAAQ,OAAO;AAAA,IAC1B,OAAO,KAAK,QAAQ,KAAK;AAAA,IACzB,SAAS,IAAI,OAAO,MAAM,QAAQ,OAAO;AAAA,IACzC,QAAQ,MAAM,iBAAiB,SAAS,WAAW;AAAA,EACrD;AAAA,EAEA,MAAM,SAAS,YAAY,KAAK,OAAO;AAAA,EACvC,MAAM,KAAK,KAAK,OAAO;AAAA,EAGvB,cAAc;AAAA,EAEd,OAAO;AAAA,IACL,WAAW,OAAO,KAAK,OAAO;AAAA,IAC9B,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM;AAAA,IACf,UAAU,MAAM,YAAY,QAAQ,QAAQ;AAAA,IAC5C,IAAI,GAAG;AAAA,MACL,SAAS,KAAK,OAAO,CAAC;AAAA;AAAA,IAExB,OAAO,GAAG;AAAA,MACR,IAAI,WAAW;AAAA,QACb;AAAA,MACF;AAAA,MACA,YAAY;AAAA,MACZ,WAAW,SAAS,QAAQ;AAAA,QAC1B,MAAM,oBAAoB,SAAS,WAAW;AAAA,MAChD;AAAA,MACA,WAAW,QAAQ,OAAO;AAAA,QACxB,KAAK,OAAO;AAAA,MACd;AAAA,MACA,IAAI,YAAY,MAAM;AAAA,QACpB,QAAQ,mBAAmB,iBAAiB;AAAA,QAC5C,QAAQ,MAAM,OAAO;AAAA,MACvB;AAAA,MACA,MAAM,QAAQ;AAAA;AAAA,EAElB;AAAA;;AC9TK,IAAM,iBAAiC;AAAA,EAC5C,GAAG;AAAA,IACD;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAuB;AAAA,IACvB;AAAA,IAAkB;AAAA,IAClB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,EACvB;AAAA,EACA,GAAG;AAAA,IACD;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAuB;AAAA,IACvB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAwB;AAAA,IACxB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAwB;AAAA,IACxB;AAAA,IAAkB;AAAA,IAClB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAuB;AAAA,IACvB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAuB;AAAA,IACvB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,EACtB;AAAA,EACA,GAAG;AAAA,IACD;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAuB;AAAA,IACvB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,EACxB;AAAA,EACA,GAAG;AAAA,IACD;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAmB;AAAA,IACnB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAqB;AAAA,EACvB;AACF;",
20
+ "debugId": "167ACAEEE5BCC45664756E2164756E21",
21
+ "names": []
22
+ }
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Shared array arithmetic for the core modules.
3
+ *
4
+ * Use these helpers with `map` instead of index-based loops. See the
5
+ * iteration convention in CLAUDE.md.
6
+ */
7
+ /** Add all values. Return 0 for an empty array. */
8
+ export declare function sum(values: readonly number[]): number;
9
+ /** Return the arithmetic mean. Return NaN for an empty array. */
10
+ export declare function mean(values: readonly number[]): number;
11
+ /**
12
+ * Return the smallest and the largest value, as R's `range()` does.
13
+ *
14
+ * Written as a fold rather than `Math.min(...values)`, which overflows the
15
+ * call stack on a long column.
16
+ *
17
+ * @param values The observations.
18
+ * @returns The lowest and the highest value. An empty array returns
19
+ * [Infinity, -Infinity], the shape of R's `range(numeric(0))`.
20
+ *
21
+ * A comparison keeps the accumulator when it is false, so a NaN entry is
22
+ * skipped rather than carried through. No caller supports NaN input: the
23
+ * modules that call this either drop the non-finite values first or state
24
+ * that they do not handle R's NA.
25
+ */
26
+ export declare function extent(values: readonly number[]): [number, number];
27
+ /**
28
+ * Map a negative zero to a positive one.
29
+ *
30
+ * A computed zero can come out of an algorithm with a sign that R's own
31
+ * zeros never carry: of 1498 zero entries of a matrix inverse over a sweep of
32
+ * 20000 slider settings, R gives a positive zero every time.
33
+ */
34
+ export declare function withoutNegativeZero(value: number): number;
35
+ /** Reject a count that is not a non-negative integer. */
36
+ export declare function requireCount(value: number, name: string): void;
37
+ /**
38
+ * Combine two arrays element by element.
39
+ *
40
+ * Stop at the end of the shorter array.
41
+ */
42
+ export declare function zipWith<A, B, C>(as: readonly A[], bs: readonly B[], combine: (a: A, b: B) => C): C[];
43
+ /**
44
+ * Return the standard deviation, with the n − 1 denominator of R's `sd()`.
45
+ *
46
+ * @param values The observations.
47
+ * @returns The standard deviation, or NaN below two values. R returns NA
48
+ * there, with a warning that a library cannot give.
49
+ */
50
+ export declare function sd(values: readonly number[]): number;
51
+ /**
52
+ * Return the mean absolute deviation, `mean(|x - mean(x)|)`.
53
+ *
54
+ * R base has no function for this. R's `mad()` is the *median* absolute
55
+ * deviation from the median, scaled by 1.4826, which is a different
56
+ * statistic. A caller that shows either one to a reader must write the name
57
+ * in full, because the abbreviation covers both.
58
+ *
59
+ * The sampling demonstration offers this as one of its choices of statistic.
60
+ * It measures spread in the units of the data, as the standard deviation
61
+ * does, but a value far from the mean moves it less, because the distance is
62
+ * not squared.
63
+ *
64
+ * @param values The observations.
65
+ * @returns The mean distance from the mean. One value gives 0, because it
66
+ * sits at its own mean. No values gives NaN, as `mean` does.
67
+ */
68
+ export declare function meanAbsoluteDeviation(values: readonly number[]): number;
69
+ /**
70
+ * Return `a * b + c`, rounded once.
71
+ *
72
+ * Written as `a * b + c`, JavaScript rounds twice — once for the product,
73
+ * once for the sum — and the two roundings show. R's `seq.int` rounds once
74
+ * and lands one unit in the last place away often enough to change a tick.
75
+ * The linear algebra in `matrix.ts` needs the same: the compiler of the R
76
+ * install the fixtures come from contracts a multiply and an add into one
77
+ * instruction, so a matrix near singular differs in every digit without it.
78
+ *
79
+ * The two helpers below split each operation into the value a double can
80
+ * hold plus the part it drops, so the dropped parts can be added back before
81
+ * the one rounding that remains. Both are the standard error-free
82
+ * transformations (Dekker 1971, Knuth). Both need every intermediate to stay
83
+ * in range, which fails only within a factor of 2^28 of the largest double.
84
+ * There the plain form is used: the result is already dominated by its own
85
+ * overflow.
86
+ */
87
+ export declare function fusedMultiplyAdd(a: number, b: number, c: number): number;
88
+ /**
89
+ * Return a sample quantile, by the rule of R's `quantile(type = 7)`.
90
+ *
91
+ * Type 7 is the default of R's `quantile()`, and so the rule behind the
92
+ * `IQR()` that `bw.nrd0()` uses to pick a bandwidth. It reads the sorted
93
+ * values at position `1 + (n - 1) * p` and interpolates between the two
94
+ * neighbors of a fractional position.
95
+ *
96
+ * @param values The observations. The function does not modify them.
97
+ * @param p The probability. It must be in [0, 1].
98
+ * @returns The quantile, or NaN for no values. R returns NA there.
99
+ * @throws RangeError If p is outside [0, 1], as R does.
100
+ */
101
+ export declare function quantile(values: readonly number[], p: number): number;
102
+ /**
103
+ * Return several sample quantiles, by the rule of R's `quantile(type = 7)`.
104
+ *
105
+ * R's `quantile()` also takes a vector of probabilities, and for one reason:
106
+ * it sorts once and reads every position off the one sorted copy. Asking for
107
+ * the two quartiles together instead of one at a time halves the work, which
108
+ * is what the bandwidth rule does over a pooled sample.
109
+ *
110
+ * @param values The observations. The function does not modify them.
111
+ * @param probs The probabilities. Each must be in [0, 1].
112
+ * @returns One quantile per probability, in the order given. Each is NaN for
113
+ * no values, where R returns NA.
114
+ * @throws RangeError If a probability is outside [0, 1], as R does.
115
+ */
116
+ export declare function quantiles(values: readonly number[], probs: readonly number[]): number[];
117
+ /**
118
+ * Return the median, the value with half the observations on each side.
119
+ *
120
+ * R's `median()` sorts the values and, on an even count, averages the two in
121
+ * the middle. That is the type-7 quantile at 0.5, which weights those same two
122
+ * values by a half each, so this delegates rather than repeat the rule. The
123
+ * two forms land on the same double, the halves included.
124
+ *
125
+ * The sampling demonstration offers this as one of its choices of statistic.
126
+ * It marks the center in the units of the data, as the mean does, but a value
127
+ * far from the center moves it very little, because only the ordering counts.
128
+ *
129
+ * @param values The observations. The function does not modify them.
130
+ * @returns The median, or NaN for no values. R returns NA there.
131
+ */
132
+ export declare function median(values: readonly number[]): number;
133
+ //# sourceMappingURL=arith.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arith.d.ts","sourceRoot":"","sources":["../../src/core/arith.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,mDAAmD;AACnD,wBAAgB,GAAG,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAErD;AAED,iEAAiE;AACjE,wBAAgB,IAAI,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQlE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAI9D;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC7B,EAAE,EAAE,SAAS,CAAC,EAAE,EAChB,EAAE,EAAE,SAAS,CAAC,EAAE,EAChB,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GACzB,CAAC,EAAE,CAIL;AAED;;;;;;GAMG;AACH,wBAAgB,EAAE,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAQpD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAGvE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAKxE;AA0BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,MAAM,EAAE,CAaV;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAExD"}