bamtigraph 1.0.0 → 1.1.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["/*\n * SPDX-License-Identifier: BSD-3-Clause\n * Copyright (c) 2026, GoSuda\n * BamtiGraph TypeScript implementation. See the root LICENSE.\n */\n/** Unix seconds, an explicit Date, or an ISO datetime with a timezone offset. */\nexport type Timestamp = number | Date | string;\n/** RGB or RGBA channels, hexadecimal notation, or a supported named color. */\nexport type Color =\n | string\n | readonly [number, number, number]\n | readonly [number, number, number, number];\nexport type Values = ArrayLike<number | null | undefined>;\n/** Normalized red, green, blue, and alpha bytes. */\nexport type RGBA = [number, number, number, number];\nexport type Interpolation = \"linear\" | \"step-post\";\n/** Mutable preprocessing output, with NaN marking missing samples. */\nexport interface Samples {\n timestamps: number[];\n values: number[];\n}\nexport interface LegendValues {\n current: number | null;\n average: number | null;\n maximum: number | null;\n}\nexport interface SeriesOptions {\n kind?: \"line\" | \"area\";\n color?: Color;\n outline?: Color | null;\n lineWidth?: number;\n baseline?: number;\n interpolation?: Interpolation;\n gapAfter?: number;\n legendValues?: Partial<LegendValues> | null;\n}\nexport interface SeriesInput extends SeriesOptions {\n name: string;\n timestamps: ArrayLike<Timestamp>;\n values: Values;\n}\nexport interface Series extends Readonly<\n Required<Omit<SeriesOptions, \"legendValues\" | \"color\" | \"outline\">>\n> {\n readonly color: Readonly<RGBA>;\n readonly outline: Readonly<RGBA> | null;\n readonly name: string;\n readonly timestamps: readonly number[];\n readonly values: readonly number[];\n readonly legendValues: Readonly<LegendValues> | null;\n}\nexport interface Tick {\n time: Timestamp;\n label: string;\n}\nexport interface TimeAxis {\n start?: Timestamp | null;\n end?: Timestamp | null;\n mode?: \"auto\" | \"daily\" | \"weekly\" | \"monthly\" | \"yearly\" | \"custom\";\n timezone?: string;\n minorSeconds?: number | null;\n majorSeconds?: number | null;\n labelSeconds?: number | null;\n labelFormat?: string | null;\n labelOffsetSeconds?: number;\n ticks?: readonly Tick[] | null;\n minorTicks?: readonly Timestamp[] | null;\n majorTicks?: readonly Timestamp[] | null;\n}\nexport interface YAxis {\n minimum?: number | null;\n maximum?: number | null;\n majorStep?: number | null;\n minorDivisions?: number;\n base?: 1000 | 1024;\n scaleFactor?: number | null;\n suffix?: string | null;\n decimals?: number | null;\n legendDecimals?: number;\n showZeroSuffix?: boolean;\n}\nexport type ColumnAnchors = readonly [\n readonly [number, number],\n readonly [number, number],\n readonly [number, number],\n];\nexport interface LegendLayout {\n nameX?: number;\n swatchX?: number;\n swatchWidth?: number;\n swatchHeight?: number;\n referenceWidth?: number;\n autoScaleColumns?: boolean;\n compact?: ColumnAnchors;\n expanded?: ColumnAnchors;\n aligned?: ColumnAnchors;\n}\nexport interface Layout {\n width?: number;\n plotHeight?: number;\n left?: number;\n right?: number;\n top?: number;\n titleY?: number;\n titleOffsetX?: number;\n unitX?: number;\n xLabelGap?: number;\n yLabelGap?: number;\n legendGap?: number;\n legendRowHeight?: number;\n legendBottom?: number;\n legend?: \"reference\" | \"aligned\" | \"none\";\n legendLayout?: LegendLayout;\n antialias?: number;\n pixelScale?: number;\n}\nexport interface Theme {\n background?: Color;\n canvas?: Color;\n shadeLight?: Color;\n shadeDark?: Color;\n text?: Color;\n minorGrid?: Color;\n majorGrid?: Color;\n axis?: Color;\n arrow?: Color;\n watermark?: Color;\n frame?: Color;\n gridFront?: boolean;\n gridDash?: readonly [number, number];\n titleSize?: number;\n axisSize?: number;\n unitSize?: number;\n legendSize?: number;\n watermarkSize?: number;\n captionSize?: number;\n titleAdvance?: number;\n axisAdvance?: number;\n legendAdvance?: number;\n}\nexport interface FontOptions {\n mode?: \"system\" | \"bitmap\";\n family?: string;\n titleFamily?: string | null;\n unitFamily?: string | null;\n captionFamily?: string | null;\n strictGlyphs?: boolean;\n}\nexport interface RuleStyle {\n color?: Color;\n width?: number;\n dash?: readonly [number, number] | null;\n}\nexport interface HRule extends RuleStyle {\n value: number;\n}\nexport interface VRule extends RuleStyle {\n time: Timestamp;\n}\n/** Immutable chart input. Nested objects merge; arrays replace their defaults. */\nexport interface ChartOptions {\n series?: readonly SeriesInput[];\n title?: string;\n verticalLabel?: string;\n watermark?: string;\n timeAxis?: TimeAxis;\n yAxis?: YAxis;\n layout?: Layout;\n theme?: Theme;\n fonts?: FontOptions;\n legendLabels?: readonly [string, string, string];\n missingLabel?: string;\n hRules?: readonly HRule[];\n vRules?: readonly VRule[];\n}\nexport interface TrafficOptions extends ChartOptions {\n gapAfter?: number;\n}\nexport interface Unit {\n factor: number;\n suffix: string;\n}\nexport interface Statistics {\n name: string;\n current: number | null;\n average: number | null;\n maximum: number | null;\n minimum: number | null;\n count: number;\n missing: number;\n displayOverride: LegendValues | null;\n}\n/** Serializable chart manifest. Missing statistics are null, not NaN. */\nexport interface GraphMetadata {\n version: string;\n imageSize: [number, number];\n logicalSize: [number, number];\n plotBox: [number, number, number, number];\n pixelScale: number;\n title: string;\n verticalLabel: string;\n watermark: string;\n timeRange: [number, number];\n timezone: string;\n timeMode: string;\n yRange: [number, number];\n yStep: number;\n yUnit: Unit;\n xLabels: { time: number; label: string; x: number }[];\n statistics: Statistics[];\n statisticsPolicy: string;\n font: {\n mode: \"system\" | \"bitmap\";\n family: string | null;\n pixelAlphabet: string | null;\n };\n layout: Layout;\n theme: Theme;\n warnings: string[];\n}\n/** Row-major straight-alpha bytes. Pixel storage intentionally remains mutable. */\nexport interface RGBAImage {\n width: number;\n height: number;\n data: Uint8ClampedArray | Uint8Array;\n}\nexport interface PNGOptions {\n metadata?: boolean;\n}\nexport interface NearestSample {\n name: string;\n index: number | null;\n time: number | null;\n value: number | null;\n}\nexport interface MountOptions {\n interactive?: boolean;\n ariaLabel?: string;\n onHover?: (event: { time: number; samples: NearestSample[] }) => void;\n}\n/** Mounted browser lifecycle. Destroy restores the canvas DOM position and attributes. */\nexport interface Controller {\n readonly canvas: HTMLCanvasElement;\n readonly chart: Chart;\n readonly result: RenderResult;\n readonly destroyed: boolean;\n update(patch: ChartOptions | Chart): RenderResult;\n destroy(): void;\n}\nexport interface DashboardOptions {\n gap?: number;\n padding?: readonly [number, number, number, number];\n background?: Color;\n cropHeight?: number | null;\n}\nexport interface DashboardPanel {\n chart: Chart;\n caption?: string;\n}\nexport interface DashboardMetadata {\n version: string;\n imageSize: [number, number];\n pixelScale: number;\n panels: {\n position: [number, number];\n caption: string;\n chart: GraphMetadata;\n }[];\n}\nexport interface CounterOptions {\n factor?: number;\n onDecrease?: \"gap\" | \"wrap\";\n counterBits?: number | null;\n maxRate?: number | null;\n}\nexport interface AggregateOptions {\n interval?: number;\n method?: \"mean\" | \"min\" | \"max\" | \"last\" | \"sum\";\n origin?: number;\n minCoverage?: number;\n expectedStep?: number | null;\n maxBuckets?: number;\n}\nexport interface CSVColumn extends SeriesOptions {\n column: string;\n name?: string;\n}\nexport interface CSVOptions {\n timestampColumn?: string;\n columns?: readonly CSVColumn[];\n maxRows?: number;\n maxBytes?: number;\n}\nexport interface PixelDifference {\n pixels: number;\n exactPixels: number;\n exactRatio: number;\n toleranceRatio: number;\n meanAbsoluteError: number;\n rootMeanSquareError: number;\n maxError: number;\n differenceBox: [number, number, number, number] | null;\n}\nexport interface CompareOptions {\n tolerance?: number;\n box?: readonly [number, number, number, number] | null;\n}\n\n/** All chart fields after default merging and normalization. */\nexport interface ResolvedChartOptions extends Omit<\n Required<ChartOptions>,\n | \"series\"\n | \"timeAxis\"\n | \"yAxis\"\n | \"layout\"\n | \"theme\"\n | \"fonts\"\n | \"hRules\"\n | \"vRules\"\n> {\n series: readonly Series[];\n timeAxis: ResolvedTimeAxis;\n yAxis: Required<YAxis>;\n layout: ResolvedLayout;\n theme: ResolvedTheme;\n fonts: Required<FontOptions>;\n hRules: readonly ResolvedHRule[];\n vRules: readonly ResolvedVRule[];\n}\n/** A calendar axis whose timestamp inputs have been converted to Unix seconds. */\nexport interface ResolvedTimeAxis extends Omit<\n Required<TimeAxis>,\n \"start\" | \"end\" | \"ticks\" | \"minorTicks\" | \"majorTicks\"\n> {\n start: number | null;\n end: number | null;\n ticks: readonly ResolvedTick[] | null;\n minorTicks: readonly number[] | null;\n majorTicks: readonly number[] | null;\n}\n/** A label positioned at a numerical Unix timestamp. */\nexport interface ResolvedTick {\n time: number;\n label: string;\n}\n/** Complete logical-pixel layout including the legend geometry. */\nexport interface ResolvedLayout extends Required<Omit<Layout, \"legendLayout\">> {\n legendLayout: Required<LegendLayout>;\n}\ntype ThemeColorKey =\n | \"background\"\n | \"canvas\"\n | \"shadeLight\"\n | \"shadeDark\"\n | \"text\"\n | \"minorGrid\"\n | \"majorGrid\"\n | \"axis\"\n | \"arrow\"\n | \"watermark\"\n | \"frame\";\n/** Fully specified theme with parsed RGBA colors. */\nexport type ResolvedTheme = Required<Omit<Theme, ThemeColorKey>> & {\n [K in ThemeColorKey]: Readonly<RGBA>;\n};\n/** Normalized horizontal rule in original data units. */\nexport interface ResolvedHRule {\n value: number;\n color: Readonly<RGBA>;\n width: number;\n dash: readonly [number, number] | null;\n}\n/** Normalized vertical rule in Unix seconds. */\nexport interface ResolvedVRule {\n time: number;\n color: Readonly<RGBA>;\n width: number;\n dash: readonly [number, number] | null;\n}\n/** Recursive readonly view of plain chart configuration and metadata. */\nexport type DeepReadonly<T> = T extends object\n ? { readonly [K in keyof T]: DeepReadonly<T[K]> }\n : T;\ntype CompleteChartInput = Omit<\n Required<ChartOptions>,\n \"timeAxis\" | \"yAxis\" | \"layout\" | \"theme\" | \"fonts\"\n> & {\n timeAxis: Required<TimeAxis>;\n yAxis: Required<YAxis>;\n layout: ResolvedLayout;\n theme: Required<Theme>;\n fonts: Required<FontOptions>;\n};\ntype CompleteSeriesInput = Required<Omit<SeriesInput, \"legendValues\">> & {\n legendValues: Partial<LegendValues> | null;\n};\ntype ChartConfig = DeepReadonly<ResolvedChartOptions>;\ntype Point = [number, number];\ntype Canvas = HTMLCanvasElement | OffscreenCanvas;\ntype Context2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\ntype FontRole = \"title\" | \"axis\" | \"unit\" | \"legend\" | \"watermark\" | \"caption\";\ninterface WallParts {\n year: number;\n month: number;\n day: number;\n hour: number;\n minute: number;\n second: number;\n}\ninterface YResolution extends Unit {\n minimum: number;\n maximum: number;\n step: number;\n major: number[];\n minor: number[];\n decimals: number;\n}\ninterface XResolution {\n minor: number[];\n major: number[];\n labels: ResolvedTick[];\n mode: NonNullable<TimeAxis[\"mode\"]>;\n}\ntype MountedCanvas = HTMLCanvasElement & {\n __bamtiGraphController?: BrowserController;\n};\n\n/** BamtiGraph library version. */\nexport const VERSION: string = \"1.0.0\";\n/** Per-operation allocation and enumeration guards. */\nexport const LIMITS: Readonly<{\n pixels: number;\n layerPixels: number;\n ticks: number;\n series: number;\n samples: number;\n text: number;\n}> = Object.freeze({\n pixels: 16000000,\n layerPixels: 40000000,\n ticks: 5000,\n series: 128,\n samples: 2000000,\n text: 4096,\n});\nconst finite = (v: unknown): v is number => Number.isFinite(v);\nconst round = (v: number): number => Math.floor(v + 0.5);\nconst clamp = (v: number, a: number, b: number): number =>\n Math.max(a, Math.min(b, v));\nconst own = (o: object, k: PropertyKey): boolean =>\n Object.prototype.hasOwnProperty.call(o, k);\nconst missing = (v: unknown): boolean =>\n v === null || v === undefined || (typeof v === \"number\" && Number.isNaN(v));\nfunction check(ok: unknown, message: string): asserts ok {\n if (!ok) throw new RangeError(message);\n}\nfunction text(s: unknown, name: string): string {\n check(\n typeof s === \"string\" && s.length <= LIMITS.text && !/[\\r\\n\\u0000]/.test(s),\n name + \" must be a single-line string.\",\n );\n return s;\n}\nfunction number(\n v: unknown,\n name: string,\n lo: number = -Infinity,\n hi: number = Infinity,\n): number {\n check(\n finite(v) && v >= lo && v <= hi,\n name + \" is outside its finite range.\",\n );\n return v;\n}\nfunction integer(v: unknown, name: string, lo: number, hi: number): number {\n check(Number.isInteger(v), name + \" must be an integer.\");\n return number(v, name, lo, hi);\n}\nfunction record(o: unknown): o is Record<string, unknown> {\n return (\n o !== null &&\n typeof o === \"object\" &&\n (Object.getPrototypeOf(o) === Object.prototype ||\n Object.getPrototypeOf(o) === null)\n );\n}\n// Configuration inputs are plain data. Typed views are restored only at this\n// recursive ownership boundary; property values remain unknown while copied.\nfunction clone<T>(v: T): T {\n if (Array.isArray(v) || ArrayBuffer.isView(v))\n return Array.from(v as ArrayLike<unknown>, (value) => clone(value)) as T;\n if (v instanceof Date) return new Date(v.getTime()) as T;\n if (record(v)) {\n const r: Record<string, unknown> = {};\n for (const k of Object.keys(v)) {\n check(\n ![\"__proto__\", \"prototype\", \"constructor\"].includes(k),\n \"Unsafe property name.\",\n );\n r[k] = clone(v[k]);\n }\n return r as T;\n }\n return v;\n}\nfunction merge<T extends object>(a: T, b: object): T {\n check(record(b), \"Options must be a plain object.\");\n const r = clone(a) as Record<string, unknown>;\n for (const k of Object.keys(b)) {\n check(\n ![\"__proto__\", \"prototype\", \"constructor\"].includes(k),\n \"Unsafe property name.\",\n );\n const previous = r[k],\n next = b[k];\n r[k] =\n record(previous) && record(next) ? merge(previous, next) : clone(next);\n }\n return r as T;\n}\nfunction freeze<T>(o: T): T {\n if (o && typeof o === \"object\") {\n for (const v of Object.values(o)) freeze(v);\n Object.freeze(o);\n }\n return o;\n}\n/** Parse a supported color into integer RGBA bytes. */\nexport function color(value: Color): RGBA {\n if (Array.isArray(value) || ArrayBuffer.isView(value)) {\n check(\n value.length === 3 || value.length === 4,\n \"Color needs 3 or 4 channels.\",\n );\n const c = Array.from(value);\n c.forEach((v) => integer(v, \"Color channel\", 0, 255));\n if (c.length === 3) c.push(255);\n return c as RGBA;\n }\n const named: Record<string, string> = {\n black: \"#000000\",\n white: \"#ffffff\",\n red: \"#ff0000\",\n green: \"#008000\",\n blue: \"#0000ff\",\n transparent: \"#00000000\",\n };\n check(\n typeof value === \"string\",\n \"Color must be hexadecimal or an RGB(A) array.\",\n );\n let h = named[value.toLowerCase()] || value;\n check(\n /^#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(h),\n \"Invalid color: \" + value,\n );\n h = h.slice(1);\n if (h.length <= 4) h = [...h].map((c) => c + c).join(\"\");\n if (h.length === 6) h += \"ff\";\n return [0, 2, 4, 6].map((i) => parseInt(h.slice(i, i + 2), 16)) as RGBA;\n}\n/** Normalize a timestamp to Unix seconds; naive dates and invalid calendars fail. */\nexport function epoch(value: Timestamp): number {\n if (value instanceof Date) value = value.getTime() / 1000;\n if (typeof value === \"string\") {\n const v = value.trim();\n if (/^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?$/i.test(v)) value = Number(v);\n else {\n const m =\n /^(\\d{4})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d)(?::(\\d\\d)(\\.\\d{1,3})?)?(Z|[+-]\\d\\d:\\d\\d)$/i.exec(\n v,\n );\n check(\n m,\n \"Datetime strings require ISO 8601 with an explicit offset; numeric timestamps are seconds.\",\n );\n const [y, mo, d, h, mi, s] = [\n m[1],\n m[2],\n m[3],\n m[4],\n m[5],\n m[6] || \"0\",\n ].map(Number);\n check(\n y >= 1 && mo >= 1 && mo <= 12 && d >= 1 && h < 24 && mi < 60 && s < 60,\n \"Invalid calendar date.\",\n );\n const test = new Date(0);\n test.setUTCFullYear(y, mo - 1, d);\n test.setUTCHours(h, mi, s, 0);\n check(\n test.getUTCMonth() === mo - 1 && test.getUTCDate() === d,\n \"Invalid calendar date.\",\n );\n if (m[8].toUpperCase() !== \"Z\")\n check(\n Number(m[8].slice(1, 3)) <= 23 && Number(m[8].slice(4)) <= 59,\n \"Invalid timezone offset.\",\n );\n value = Date.parse(v) / 1000;\n }\n }\n return number(value, \"Timestamp\", -62135596800, 253402300799.999);\n}\nfunction samples(timestamps: ArrayLike<Timestamp>, values: Values): Samples {\n check(\n (Array.isArray(timestamps) || ArrayBuffer.isView(timestamps)) &&\n (Array.isArray(values) || ArrayBuffer.isView(values)),\n \"Timestamps and values must be arrays.\",\n );\n check(\n timestamps.length === values.length && timestamps.length <= LIMITS.samples,\n \"Sample lengths must match and stay within the sample limit.\",\n );\n const ts = Array.from(timestamps, epoch),\n vs = Array.from(values, (v, i) =>\n missing(v) ? NaN : number(v, \"Value at \" + i),\n );\n for (let i = 1; i < ts.length; i++)\n check(\n ts[i] > ts[i - 1],\n \"Timestamps must be strictly increasing (index \" + i + \").\",\n );\n return { timestamps: ts, values: vs };\n}\nconst DEFAULTS: CompleteChartInput = freeze<CompleteChartInput>({\n title: \"\",\n verticalLabel: \"\",\n watermark: \"\",\n series: [],\n timeAxis: {\n start: null,\n end: null,\n mode: \"auto\",\n timezone: \"UTC\",\n minorSeconds: null,\n majorSeconds: null,\n labelSeconds: null,\n labelFormat: null,\n ticks: null,\n majorTicks: null,\n minorTicks: null,\n labelOffsetSeconds: 0,\n },\n yAxis: {\n minimum: 0,\n maximum: null,\n majorStep: null,\n minorDivisions: 5,\n base: 1000,\n scaleFactor: null,\n suffix: null,\n decimals: null,\n legendDecimals: 2,\n showZeroSuffix: false,\n },\n layout: {\n width: 595,\n plotHeight: 122,\n left: 64,\n right: 31,\n top: 34,\n titleY: 8,\n titleOffsetX: 27,\n unitX: 5,\n xLabelGap: 5,\n yLabelGap: 6,\n legendGap: 20,\n legendRowHeight: 14,\n legendBottom: 7,\n legend: \"reference\",\n antialias: 4,\n pixelScale: 1,\n legendLayout: {\n nameX: 30,\n swatchX: 15,\n swatchWidth: 9,\n swatchHeight: 10,\n referenceWidth: 595,\n autoScaleColumns: true,\n compact: [\n [102, 228],\n [244, 370],\n [386, 512],\n ],\n expanded: [\n [124, 250],\n [289, 415],\n [454, 580],\n ],\n aligned: [\n [102, 250],\n [267, 415],\n [432, 580],\n ],\n },\n },\n theme: {\n background: \"#f3f3f3\",\n canvas: \"#ffffff\",\n shadeLight: \"#cfcfcf\",\n shadeDark: \"#9e9e9e\",\n text: \"#000000\",\n minorGrid: \"#8f8f8f3c\",\n majorGrid: \"#df4f4f3c\",\n axis: \"#777777\",\n arrow: \"#7f1f1f\",\n watermark: \"#aaaaaa\",\n frame: \"#000000\",\n gridFront: true,\n gridDash: [1, 1],\n titleSize: 14,\n axisSize: 11,\n unitSize: 10,\n legendSize: 11,\n watermarkSize: 8,\n captionSize: 11,\n titleAdvance: 8,\n axisAdvance: 6,\n legendAdvance: 7,\n },\n fonts: {\n mode: \"system\",\n family: '\"DejaVu Sans Mono\", \"Liberation Mono\", Consolas, monospace',\n titleFamily: null,\n unitFamily: null,\n captionFamily: \"Arial, sans-serif\",\n strictGlyphs: true,\n },\n legendLabels: [\"Current:\", \"Average:\", \"Maximum:\"],\n missingLabel: \"NaN\",\n hRules: [],\n vRules: [],\n});\n/** Copy, validate, and deeply freeze an independently timestamped series. */\nexport function series(\n name: string,\n timestamps: ArrayLike<Timestamp>,\n values: Values,\n options: SeriesOptions = {},\n): Series {\n const s = merge<CompleteSeriesInput>(\n {\n name,\n timestamps,\n values,\n kind: \"line\",\n color: \"#0000cc\",\n lineWidth: 0.7,\n outline: null,\n baseline: 0,\n interpolation: \"linear\",\n gapAfter: 0,\n legendValues: null,\n },\n options,\n );\n text(s.name, \"Series name\");\n const data = samples(s.timestamps, s.values);\n s.timestamps = data.timestamps;\n s.values = data.values;\n check([\"line\", \"area\"].includes(s.kind), \"Series kind must be line or area.\");\n check(\n [\"linear\", \"step-post\"].includes(s.interpolation),\n \"Interpolation must be linear or step-post.\",\n );\n number(s.lineWidth, \"Line width\", 0.01, 128);\n number(s.baseline, \"Baseline\");\n number(s.gapAfter, \"Gap threshold\", 0);\n s.color = color(s.color);\n if (s.outline !== null) s.outline = color(s.outline);\n if (s.legendValues !== null) {\n check(record(s.legendValues), \"Legend overrides must be an object.\");\n for (const k of [\"current\", \"average\", \"maximum\"] as const)\n s.legendValues[k] = missing(s.legendValues[k])\n ? null\n : number(s.legendValues[k], \"Legend override\");\n }\n return freeze(s as Series);\n}\n/** Create a series with fixed elapsed-second spacing and copied observations. */\nexport function regularSeries(\n name: string,\n values: Values,\n start: Timestamp,\n step: number = 300,\n options: SeriesOptions = {},\n): Series {\n start = epoch(start);\n number(step, \"Step\", Number.MIN_VALUE);\n const first = start;\n return series(\n name,\n Array.from(values, (_, i) => first + i * step),\n values,\n options,\n );\n}\nfunction modeAxis(\n mode: NonNullable<TimeAxis[\"mode\"]>,\n options: TimeAxis | string = {},\n): TimeAxis {\n return merge(\n DEFAULTS.timeAxis,\n merge(\n { mode },\n typeof options === \"string\" ? { timezone: options } : options,\n ),\n );\n}\n/** Daily tick presentation, without resampling observations. */\nexport function daily(options: TimeAxis | string = {}): TimeAxis {\n return modeAxis(\"daily\", options);\n}\n/** Weekly calendar-noon labels, without resampling observations. */\nexport function weekly(options: TimeAxis | string = {}): TimeAxis {\n return modeAxis(\"weekly\", options);\n}\n/** Monthly tick presentation, without resampling observations. */\nexport function monthly(options: TimeAxis | string = {}): TimeAxis {\n return modeAxis(\"monthly\", options);\n}\n/** Real calendar-month ticks, without resampling observations. */\nexport function yearly(options: TimeAxis | string = {}): TimeAxis {\n return modeAxis(\"yearly\", options);\n}\nfunction dimensions(c: {\n layout: DeepReadonly<ResolvedLayout>;\n series: readonly unknown[];\n}): [number, number] {\n const l = c.layout;\n return [\n l.width,\n l.top +\n l.plotHeight +\n (l.legend === \"none\"\n ? 18\n : l.legendGap +\n Math.max(1, c.series.length) * l.legendRowHeight +\n l.legendBottom),\n ];\n}\nfunction dash(d: readonly [number, number] | null): void {\n if (d === null) return;\n check(Array.isArray(d) && d.length === 2, \"Dash must be null or [on, off].\");\n d.forEach((v) => integer(v, \"Dash interval\", 1, 16384));\n}\nfunction normalize(options: ChartOptions): ChartConfig {\n const c = merge(DEFAULTS, options);\n check(\n Array.isArray(c.series) && c.series.length <= LIMITS.series,\n \"Invalid series count.\",\n );\n c.series = c.series.map((s) => series(s.name, s.timestamps, s.values, s));\n for (const k of [\n \"title\",\n \"verticalLabel\",\n \"watermark\",\n \"missingLabel\",\n ] as const)\n text(c[k], k);\n check(\n Array.isArray(c.legendLabels) && c.legendLabels.length === 3,\n \"Three statistic labels are required.\",\n );\n c.legendLabels.forEach((v) => text(v, \"Statistic label\"));\n const a = c.timeAxis,\n l = c.layout,\n y = c.yAxis,\n t = c.theme,\n f = c.fonts;\n check(\n [\"auto\", \"daily\", \"weekly\", \"monthly\", \"yearly\", \"custom\"].includes(a.mode),\n \"Unknown time axis mode.\",\n );\n text(a.timezone, \"Timezone\");\n zoneFormatter(a.timezone);\n for (const k of [\"start\", \"end\"] as const)\n if (a[k] !== null) a[k] = epoch(a[k]);\n if (a.start !== null && a.end !== null)\n check(\n (a.end as number) > (a.start as number),\n \"Time end must exceed start.\",\n );\n for (const k of [\"minorSeconds\", \"majorSeconds\", \"labelSeconds\"] as const)\n if (a[k] !== null) number(a[k], k, 0.001);\n number(a.labelOffsetSeconds, \"Label offset\", -31622400, 31622400);\n if (a.labelFormat !== null) {\n text(a.labelFormat, \"Label format\");\n formatTime(0, \"UTC\", a.labelFormat);\n }\n if (a.ticks !== null) {\n check(\n Array.isArray(a.ticks) && a.ticks.length <= LIMITS.ticks,\n \"Too many or invalid ticks.\",\n );\n const ticks = a.ticks.map((v) => ({\n time: epoch(v.time),\n label: text(v.label, \"Tick label\"),\n }));\n for (let i = 1; i < ticks.length; i++)\n check(\n ticks[i].time > ticks[i - 1].time,\n \"Explicit ticks must be strictly increasing.\",\n );\n a.ticks = ticks;\n }\n for (const k of [\"minorTicks\", \"majorTicks\"] as const)\n if (a[k] !== null) {\n const input = a[k];\n check(\n Array.isArray(input) && input.length <= LIMITS.ticks,\n \"Too many or invalid ticks.\",\n );\n const ticks = input.map(epoch);\n for (let i = 1; i < ticks.length; i++)\n check(\n ticks[i] > ticks[i - 1],\n \"Explicit ticks must be strictly increasing.\",\n );\n a[k] = ticks;\n }\n for (const k of [\"minimum\", \"maximum\", \"majorStep\", \"scaleFactor\"] as const)\n if (y[k] !== null) number(y[k], k);\n for (const k of [\"majorStep\", \"scaleFactor\"] as const)\n if (y[k] !== null) check(y[k] > 0, k + \" must be positive.\");\n if (y.minimum !== null && y.maximum !== null)\n check(y.maximum > y.minimum, \"Y maximum must exceed minimum.\");\n check(y.base === 1000 || y.base === 1024, \"Unit base must be 1000 or 1024.\");\n integer(y.minorDivisions, \"Minor divisions\", 1, 100);\n integer(y.legendDecimals, \"Legend decimals\", 0, 12);\n if (y.decimals !== null) integer(y.decimals, \"Decimals\", 0, 12);\n if (y.suffix !== null) text(y.suffix, \"Suffix\");\n integer(l.width, \"Width\", 400, 8192);\n integer(l.plotHeight, \"Plot height\", 30, 4096);\n for (const k of [\n \"left\",\n \"right\",\n \"top\",\n \"titleY\",\n \"unitX\",\n \"xLabelGap\",\n \"yLabelGap\",\n \"legendGap\",\n \"legendRowHeight\",\n \"legendBottom\",\n ] as const)\n integer(l[k], k, 0, 16384);\n check(\n l.left >= 20 &&\n l.right >= 12 &&\n l.top >= 12 &&\n l.width - l.left - l.right >= 100,\n \"Insufficient plot margins.\",\n );\n number(l.titleOffsetX, \"Title offset\", -8192, 8192);\n check(\n [\"reference\", \"aligned\", \"none\"].includes(l.legend),\n \"Invalid legend mode.\",\n );\n if (l.legend !== \"none\")\n check(\n l.legendGap >= 14 && l.legendRowHeight >= 10,\n \"Legend spacing is insufficient.\",\n );\n integer(l.antialias, \"Antialias\", 1, 8);\n integer(l.pixelScale, \"Pixel scale\", 1, 8);\n const ll = l.legendLayout;\n for (const k of [\n \"nameX\",\n \"swatchX\",\n \"swatchWidth\",\n \"swatchHeight\",\n \"referenceWidth\",\n ] as const)\n integer(ll[k], k, 0, 16384);\n check(\n ll.swatchWidth >= 3 && ll.swatchHeight >= 3 && ll.referenceWidth > ll.nameX,\n \"Invalid legend geometry.\",\n );\n for (const key of [\"compact\", \"expanded\", \"aligned\"] as const) {\n const cols = ll[key];\n check(Array.isArray(cols) && cols.length === 3, \"Invalid legend columns.\");\n let last = ll.nameX;\n for (const p of cols) {\n check(\n Array.isArray(p) &&\n p.length === 2 &&\n finite(p[0]) &&\n finite(p[1]) &&\n last < p[0] &&\n p[0] < p[1] &&\n p[1] < ll.referenceWidth,\n \"Legend columns must not overlap.\",\n );\n last = p[1];\n }\n }\n for (const k of [\n \"background\",\n \"canvas\",\n \"shadeLight\",\n \"shadeDark\",\n \"text\",\n \"minorGrid\",\n \"majorGrid\",\n \"axis\",\n \"arrow\",\n \"watermark\",\n \"frame\",\n ] as const)\n t[k] = color(t[k]);\n check(\n t.background[3] === 255 && t.canvas[3] === 255,\n \"Background and canvas must be opaque.\",\n );\n dash(t.gridDash);\n check(t.gridDash !== null, \"Grid dash is required.\");\n for (const k of [\n \"titleSize\",\n \"axisSize\",\n \"unitSize\",\n \"legendSize\",\n \"watermarkSize\",\n \"captionSize\",\n \"titleAdvance\",\n \"axisAdvance\",\n \"legendAdvance\",\n ] as const)\n number(t[k], k, 1, 128);\n check(\n [\"system\", \"bitmap\"].includes(f.mode),\n \"Font mode must be system or bitmap.\",\n );\n text(f.family, \"Font family\");\n for (const k of [\"titleFamily\", \"unitFamily\", \"captionFamily\"] as const)\n if (f[k] !== null) text(f[k], k);\n function rule<R extends HRule | VRule>(\n input: R,\n field: \"time\" | \"value\",\n ): R & Required<RuleStyle> {\n const r = merge(\n { color: \"#990000\", width: 1, dash: [3, 2] },\n input,\n ) as unknown as R & Required<RuleStyle>;\n if (field === \"time\") (r as VRule).time = epoch((r as VRule).time);\n else (r as HRule).value = number((r as HRule).value, \"Rule value\");\n number(r.width, \"Rule width\", 0.1, 128);\n dash(r.dash);\n r.color = color(r.color);\n return r;\n }\n check(\n Array.isArray(c.hRules) && c.hRules.length <= 1000,\n \"Invalid rule count.\",\n );\n c.hRules = c.hRules.map((r) => rule(r, \"value\"));\n check(\n Array.isArray(c.vRules) && c.vRules.length <= 1000,\n \"Invalid rule count.\",\n );\n c.vRules = c.vRules.map((r) => rule(r, \"time\"));\n const [w, h] = dimensions(c);\n check(\n w * h * l.pixelScale ** 2 <= LIMITS.pixels,\n \"Output allocation exceeds the pixel limit.\",\n );\n check(\n (l.width - l.left - l.right + 1) * (l.plotHeight + 1) * l.antialias ** 2 <=\n LIMITS.layerPixels,\n \"Supersampled layer exceeds the pixel limit.\",\n );\n // All timestamp, color, series and rule fields have now been normalized.\n return freeze(c as ResolvedChartOptions);\n}\n// A straight-alpha pixel surface: data geometry never depends on a browser path rasterizer.\nclass Surface implements RGBAImage {\n readonly width: number;\n readonly height: number;\n readonly data: Uint8ClampedArray;\n constructor(\n width: number,\n height: number,\n fill: Readonly<RGBA> | null = null,\n ) {\n integer(width, \"Image width\", 1, 65536);\n integer(height, \"Image height\", 1, 65536);\n check(width * height <= LIMITS.layerPixels, \"Image is too large.\");\n this.width = width;\n this.height = height;\n this.data = new Uint8ClampedArray(width * height * 4);\n if (fill) this.rect(0, 0, width, height, fill);\n }\n pixel(x: number, y: number, c: Readonly<RGBA>, blend: boolean = false): void {\n if (x < 0 || y < 0 || x >= this.width || y >= this.height) return;\n const i = (y * this.width + x) * 4,\n d = this.data;\n if (!blend || c[3] === 255) {\n d[i] = c[0];\n d[i + 1] = c[1];\n d[i + 2] = c[2];\n d[i + 3] = c[3];\n return;\n }\n if (c[3] === 0) return;\n const sa = c[3],\n da = d[i + 3],\n alpha = sa * 255 + da * (255 - sa);\n for (let k = 0; k < 3; k++)\n d[i + k] = Math.floor(\n (c[k] * sa * 255 + d[i + k] * da * (255 - sa) + alpha / 2) / alpha,\n );\n d[i + 3] = Math.floor((alpha + 127) / 255);\n }\n rect(\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n c: Readonly<RGBA>,\n ): void {\n x0 = Math.max(0, Math.ceil(x0));\n y0 = Math.max(0, Math.ceil(y0));\n x1 = Math.min(this.width, Math.ceil(x1));\n y1 = Math.min(this.height, Math.ceil(y1));\n for (let y = y0; y < y1; y++)\n for (let x = x0, i = (y * this.width + x0) * 4; x < x1; x++, i += 4) {\n this.data[i] = c[0];\n this.data[i + 1] = c[1];\n this.data[i + 2] = c[2];\n this.data[i + 3] = c[3];\n }\n }\n over(src: RGBAImage, dx: number = 0, dy: number = 0): void {\n const p: RGBA = [0, 0, 0, 0];\n for (\n let y = Math.max(0, -dy);\n y < Math.min(src.height, this.height - dy);\n y++\n )\n for (\n let x = Math.max(0, -dx);\n x < Math.min(src.width, this.width - dx);\n x++\n ) {\n const i = (y * src.width + x) * 4;\n if (src.data[i + 3]) {\n p[0] = src.data[i];\n p[1] = src.data[i + 1];\n p[2] = src.data[i + 2];\n p[3] = src.data[i + 3];\n this.pixel(x + dx, y + dy, p, true);\n }\n }\n }\n polygon(points: readonly Point[], c: Readonly<RGBA>): void {\n if (points.length < 3) return;\n let lo = Infinity,\n hi = -Infinity;\n for (const p of points) {\n lo = Math.min(lo, p[1]);\n hi = Math.max(hi, p[1]);\n }\n for (\n let y = Math.max(0, Math.ceil(lo));\n y <= Math.min(this.height - 1, Math.floor(hi));\n y++\n ) {\n const xs = [];\n let a = points[points.length - 1];\n for (const b of points) {\n if (a[1] === b[1]) {\n if (y === a[1])\n this.rect(\n Math.ceil(Math.min(a[0], b[0])),\n y,\n Math.floor(Math.max(a[0], b[0])) + 1,\n y + 1,\n c,\n );\n } else if ((a[1] <= y && y < b[1]) || (b[1] <= y && y < a[1]))\n xs.push(a[0] + ((y - a[1]) / (b[1] - a[1])) * (b[0] - a[0]));\n a = b;\n }\n xs.sort((a, b) => a - b);\n for (let i = 0; i + 1 < xs.length; i += 2)\n this.rect(\n Math.ceil(xs[i] - 1e-9),\n y,\n Math.floor(xs[i + 1] + 1e-9) + 1,\n y + 1,\n c,\n );\n }\n }\n line(a: Point, b: Point, c: Readonly<RGBA>, width: number = 1): void {\n let x = round(a[0]),\n y = round(a[1]),\n x1 = round(b[0]),\n y1 = round(b[1]);\n width = Math.max(1, round(width));\n if (width > 1) {\n const r = (width - 1) / 2;\n if (x === x1) {\n this.rect(\n x - Math.floor(width / 2),\n Math.min(y, y1),\n x + Math.floor((width - 1) / 2) + 1,\n Math.max(y, y1) + 1,\n c,\n );\n return;\n }\n if (y === y1) {\n this.rect(\n Math.min(x, x1),\n y - Math.floor(width / 2),\n Math.max(x, x1) + 1,\n y + Math.floor((width - 1) / 2) + 1,\n c,\n );\n return;\n }\n const len = Math.hypot(x1 - x, y1 - y),\n ox = (-(y1 - y) / len) * r,\n oy = ((x1 - x) / len) * r;\n this.polygon(\n [\n [x + ox, y + oy],\n [x1 + ox, y1 + oy],\n [x1 - ox, y1 - oy],\n [x - ox, y - oy],\n ].map((p): Point => [round(p[0]), round(p[1])]),\n c,\n );\n return;\n }\n const dx = Math.abs(x1 - x),\n dy = -Math.abs(y1 - y),\n sx = x < x1 ? 1 : -1,\n sy = y < y1 ? 1 : -1;\n let err = dx + dy;\n for (;;) {\n this.pixel(x, y, c);\n if (x === x1 && y === y1) break;\n const e = 2 * err;\n if (e >= dy) {\n err += dy;\n x += sx;\n }\n if (e <= dx) {\n err += dx;\n y += sy;\n }\n }\n }\n dashed(\n a: Point,\n b: Point,\n c: Readonly<RGBA>,\n pattern: readonly [number, number] | null = [1, 1],\n width: number = 1,\n ): void {\n if (pattern === null) {\n this.line(a, b, c, width);\n return;\n }\n const len = Math.hypot(b[0] - a[0], b[1] - a[1]);\n if (!len) {\n this.pixel(round(a[0]), round(a[1]), c);\n return;\n }\n const dx = (b[0] - a[0]) / len,\n dy = (b[1] - a[1]) / len;\n for (let s = 0; s <= Math.ceil(len); s += pattern[0] + pattern[1]) {\n const e = Math.min(len, s + pattern[0] - 1);\n this.line(\n [a[0] + dx * s, a[1] + dy * s],\n [a[0] + dx * e, a[1] + dy * e],\n c,\n width,\n );\n }\n }\n circle(x: number, y: number, r: number, c: Readonly<RGBA>): void {\n for (\n let yy = Math.max(0, Math.floor(y - r));\n yy <= Math.min(this.height - 1, Math.ceil(y + r));\n yy++\n )\n for (\n let xx = Math.max(0, Math.floor(x - r));\n xx <= Math.min(this.width - 1, Math.ceil(x + r));\n xx++\n )\n if ((xx - x) ** 2 + (yy - y) ** 2 <= r * r) this.pixel(xx, yy, c);\n }\n down(scale: number): Surface {\n if (scale === 1) return this;\n const out = new Surface(this.width / scale, this.height / scale),\n p: RGBA = [0, 0, 0, 0],\n n = scale * scale;\n for (let y = 0; y < out.height; y++)\n for (let x = 0; x < out.width; x++) {\n let a = 0,\n r = 0,\n g = 0,\n b = 0;\n for (let sy = 0; sy < scale; sy++)\n for (let sx = 0; sx < scale; sx++) {\n const i = ((y * scale + sy) * this.width + x * scale + sx) * 4,\n ca = this.data[i + 3];\n a += ca;\n r += this.data[i] * ca;\n g += this.data[i + 1] * ca;\n b += this.data[i + 2] * ca;\n }\n if (a) {\n p[0] = Math.floor(r / a + 0.5);\n p[1] = Math.floor(g / a + 0.5);\n p[2] = Math.floor(b / a + 0.5);\n p[3] = Math.floor(a / n + 0.5);\n out.pixel(x, y, p);\n }\n }\n return out;\n }\n scale(n: number): Surface {\n if (n === 1) return this;\n const out = new Surface(this.width * n, this.height * n);\n for (let y = 0; y < out.height; y++)\n for (let x = 0; x < out.width; x++) {\n const s = (Math.floor(y / n) * this.width + Math.floor(x / n)) * 4,\n i = (y * out.width + x) * 4;\n out.data[i] = this.data[s];\n out.data[i + 1] = this.data[s + 1];\n out.data[i + 2] = this.data[s + 2];\n out.data[i + 3] = this.data[s + 3];\n }\n return out;\n }\n}\nfunction clipLine(\n a: Point,\n b: Point,\n w: number,\n h: number,\n): [Point, Point] | null {\n let lo = 0,\n hi = 1;\n const dx = b[0] - a[0],\n dy = b[1] - a[1];\n for (const [p, q] of [\n [-dx, a[0]],\n [dx, w - a[0]],\n [-dy, a[1]],\n [dy, h - a[1]],\n ]) {\n if (p === 0) {\n if (q < 0) return null;\n } else {\n const u = q / p;\n if (p < 0) lo = Math.max(lo, u);\n else hi = Math.min(hi, u);\n if (lo > hi) return null;\n }\n }\n return [\n [a[0] + lo * dx, a[1] + lo * dy],\n [a[0] + hi * dx, a[1] + hi * dy],\n ];\n}\nfunction clipPolygon(points: Point[], w: number, h: number): Point[] {\n let ps = points;\n for (const [axis, bound, greater] of [\n [0, 0, true],\n [0, w, false],\n [1, 0, true],\n [1, h, false],\n ] as const) {\n if (!ps.length) break;\n const out: Point[] = [],\n inside = (p: Point): boolean =>\n greater ? p[axis] >= bound : p[axis] <= bound;\n let a = ps[ps.length - 1],\n ai = inside(a);\n for (const b of ps) {\n const bi = inside(b);\n if (ai !== bi) {\n const q = (bound - a[axis]) / (b[axis] - a[axis]);\n const p: Point = [a[0] + q * (b[0] - a[0]), a[1] + q * (b[1] - a[1])];\n p[axis] = bound;\n out.push(p);\n }\n if (bi) out.push(b);\n a = b;\n ai = bi;\n }\n ps = out;\n }\n return ps;\n}\nfunction lowerBound(a: readonly number[], x: number): number {\n let l = 0,\n r = a.length;\n while (l < r) {\n const m = (l + r) >>> 1;\n if (a[m] < x) l = m + 1;\n else r = m;\n }\n return l;\n}\nfunction upperBound(a: readonly number[], x: number): number {\n let l = 0,\n r = a.length;\n while (l < r) {\n const m = (l + r) >>> 1;\n if (a[m] <= x) l = m + 1;\n else r = m;\n }\n return l;\n}\nfunction visibleRuns(s: Series, start: number, end: number): Point[][] {\n const ts = s.timestamps,\n vs = s.values,\n result: Point[][] = [];\n let run: Point[] = [];\n const push = () => {\n if (run.length) {\n result.push(run);\n run = [];\n }\n };\n const left = Math.max(0, lowerBound(ts, start) - 1),\n right = Math.min(ts.length, upperBound(ts, end) + 1);\n for (let i = left; i < right; i++) {\n if (!finite(vs[i])) {\n push();\n continue;\n }\n if (i > left && s.gapAfter > 0 && ts[i] - ts[i - 1] > s.gapAfter) push();\n if (run.length && s.interpolation === \"step-post\")\n run.push([ts[i], run[run.length - 1][1]]);\n run.push([ts[i], vs[i]]);\n }\n push();\n const clipped: Point[][] = [];\n for (const r of result) {\n const out: Point[] = [];\n if (r.length === 1) {\n if (r[0][0] >= start && r[0][0] <= end) out.push(r[0]);\n }\n for (let i = 1; i < r.length; i++) {\n const a = r[i - 1],\n b = r[i];\n if (b[0] < start || a[0] > end) continue;\n const interp = (x: number): number =>\n a[1] * (1 - (x - a[0]) / (b[0] - a[0])) +\n b[1] * ((x - a[0]) / (b[0] - a[0]));\n const p: Point = a[0] < start ? [start, interp(start)] : a,\n q: Point = b[0] > end ? [end, interp(end)] : b;\n if (\n !out.length ||\n out[out.length - 1][0] !== p[0] ||\n out[out.length - 1][1] !== p[1]\n )\n out.push(p);\n out.push(q);\n }\n if (out.length) clipped.push(out);\n }\n return clipped;\n}\nfunction decimate(\n ps: Point[],\n start: number,\n end: number,\n width: number,\n): Point[] {\n if (ps.length <= width * 4) return ps;\n const out = [];\n let pos = 0;\n while (pos < ps.length) {\n const col = Math.floor(((ps[pos][0] - start) / (end - start)) * width),\n first = pos;\n let mn = pos,\n mx = pos;\n while (\n pos + 1 < ps.length &&\n Math.floor(((ps[pos + 1][0] - start) / (end - start)) * width) === col\n ) {\n pos++;\n if (ps[pos][1] < ps[mn][1]) mn = pos;\n if (ps[pos][1] > ps[mx][1]) mx = pos;\n }\n for (const i of [...new Set([first, mn, mx, pos])].sort((a, b) => a - b))\n out.push(ps[i]);\n pos++;\n }\n return out;\n}\nfunction stableMean(values: readonly number[]): number | null {\n if (!values.length) return null;\n let max = 0;\n for (const v of values) max = Math.max(max, Math.abs(v));\n if (max === 0) return 0;\n let sum = 0,\n c = 0;\n for (const v of values) {\n const a = v / max - c,\n t = sum + a;\n c = t - sum - a;\n sum = t;\n }\n return clamp(sum / values.length, -1, 1) * max;\n}\nfunction statistics(s: Series, start: number, end: number): Statistics {\n const a = lowerBound(s.timestamps, start),\n b = upperBound(s.timestamps, end),\n values = [];\n let mn = Infinity,\n mx = -Infinity,\n miss = 0;\n for (let i = a; i < b; i++) {\n const v = s.values[i];\n if (!finite(v)) miss++;\n else {\n values.push(v);\n mn = Math.min(mn, v);\n mx = Math.max(mx, v);\n }\n }\n return {\n name: s.name,\n current: b > a && finite(s.values[b - 1]) ? s.values[b - 1] : null,\n average: stableMean(values),\n maximum: values.length ? mx : null,\n minimum: values.length ? mn : null,\n count: values.length,\n missing: miss,\n displayOverride: s.legendValues,\n };\n}\n// Numeric units and ticks. All limits and data use original (unscaled) units.\nfunction multiples(lo: number, hi: number, step: number): number[] {\n check(\n finite(step) &&\n step > 0 &&\n finite((hi - lo) / step) &&\n (hi - lo) / step <= LIMITS.ticks,\n \"Too many ticks or invalid step.\",\n );\n const a = Math.ceil(lo / step - 1e-10),\n b = Math.floor(hi / step + 1e-10);\n check(\n Math.abs(a) < 9e15 && Math.abs(b) < 9e15 && b - a <= LIMITS.ticks,\n \"Tick precision limit exceeded.\",\n );\n return Array.from(\n { length: Math.max(0, b - a + 1) },\n (_, i) => (a + i) * step || 0,\n );\n}\nfunction nice(v: number): number {\n check(finite(v) && v >= 1e-300, \"Unsupported numeric axis span.\");\n const p = 10 ** Math.floor(Math.log10(v));\n for (const m of [1, 2, 5, 10]) if (v <= m * p * (1 + 1e-12)) return m * p;\n return 10 * p;\n}\nfunction unitFor(v: number, base: 1000 | 1024): Unit {\n if (!v) return { factor: 1, suffix: \"\" };\n let i = Math.floor(Math.log(Math.abs(v)) / Math.log(base) + 1e-12);\n i = clamp(i, base === 1024 ? 0 : -8, 8);\n return {\n factor: base ** i,\n suffix: (base === 1024\n ? [\"\", \"Ki\", \"Mi\", \"Gi\", \"Ti\", \"Pi\", \"Ei\", \"Zi\", \"Yi\"]\n : [\n \"y\",\n \"z\",\n \"a\",\n \"f\",\n \"p\",\n \"n\",\n \"u\",\n \"m\",\n \"\",\n \"k\",\n \"M\",\n \"G\",\n \"T\",\n \"P\",\n \"E\",\n \"Z\",\n \"Y\",\n ])[base === 1024 ? i : i + 8],\n };\n}\nfunction resolveY(\n a: Readonly<Required<YAxis>>,\n loData: number,\n hiData: number,\n): YResolution {\n let lo = a.minimum === null ? Math.min(0, loData) : a.minimum,\n hi = a.maximum === null ? Math.max(0, hiData) : a.maximum;\n if (a.maximum === null && hi <= lo)\n hi = lo + Math.max(Math.abs(lo) * 0.05, 1);\n if (a.minimum === null && lo >= hi)\n lo = hi - Math.max(Math.abs(hi) * 0.05, 1);\n const span = hi - lo;\n check(finite(span) && span > 0, \"Invalid Y span.\");\n const af =\n a.scaleFactor === null\n ? unitFor(Math.max(Math.abs(lo), Math.abs(hi)), a.base).factor\n : a.scaleFactor;\n const step = a.majorStep === null ? nice(span / af / 5) * af : a.majorStep,\n q = step / a.minorDivisions;\n check(finite(q) && q > 0, \"Invalid Y quantum.\");\n if (a.minimum === null && lo < 0) lo = Math.floor((lo - span * 0.02) / q) * q;\n if (a.maximum === null) hi = Math.ceil((hi + span * 0.02) / q) * q;\n check(finite(hi - lo) && hi > lo, \"Degenerate Y range.\");\n const major = multiples(lo, hi, step),\n minor = multiples(lo, hi, q).filter(\n (v) => Math.abs(v / step - round(v / step)) > 1e-8,\n );\n const unit = unitFor(Math.max(Math.abs(lo), Math.abs(hi)), a.base);\n if (a.scaleFactor !== null) {\n unit.factor = a.scaleFactor;\n if (a.suffix === null) unit.suffix = \"\";\n }\n if (a.suffix !== null) unit.suffix = a.suffix;\n let decimals = a.decimals;\n if (decimals === null) {\n const s = step / unit.factor;\n decimals = 9;\n for (let d = 0; d < 10; d++)\n if (\n Math.abs(s - round(s * 10 ** d) / 10 ** d) <=\n Math.max(1e-10, Math.abs(s) * 1e-9)\n ) {\n decimals = d;\n break;\n }\n }\n return { minimum: lo, maximum: hi, step, major, minor, ...unit, decimals };\n}\n/** Format a value using an already validated common unit and decimal precision. */\nexport function formatValue(\n value: number | null,\n unit: Unit,\n decimals: number = 2,\n missingText: string = \"NaN\",\n): string {\n if (!finite(value)) return missingText;\n let v = value / unit.factor;\n if (Math.abs(v) < 0.5 * 10 ** -decimals) v = 0;\n return v.toFixed(decimals) + (unit.suffix ? \" \" + unit.suffix : \"\");\n}\nconst formatterCache = new Map<string, Intl.DateTimeFormat>();\nfunction zoneFormatter(zone: string): Intl.DateTimeFormat {\n if (formatterCache.has(zone)) return formatterCache.get(zone)!;\n let f;\n try {\n f = new Intl.DateTimeFormat(\"en-GB-u-ca-gregory-nu-latn\", {\n timeZone: zone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hourCycle: \"h23\",\n });\n } catch (e) {\n throw new RangeError(\"Unsupported time zone: \" + zone);\n }\n if (formatterCache.size >= 32)\n formatterCache.delete(formatterCache.keys().next().value!);\n formatterCache.set(zone, f);\n return f;\n}\nfunction utcFromParts(\n y: number,\n m: number,\n d: number,\n h: number = 0,\n mi: number = 0,\n s: number = 0,\n): number {\n const t = new Date(0);\n t.setUTCFullYear(y, m - 1, d);\n t.setUTCHours(h, mi, s, 0);\n return t.getTime() / 1000;\n}\nfunction wallParts(t: number, zone: string): WallParts {\n if (zone === \"UTC\") {\n const d = new Date(t * 1000);\n return {\n year: d.getUTCFullYear(),\n month: d.getUTCMonth() + 1,\n day: d.getUTCDate(),\n hour: d.getUTCHours(),\n minute: d.getUTCMinutes(),\n second: d.getUTCSeconds(),\n };\n }\n const r = {} as WallParts;\n for (const p of zoneFormatter(zone).formatToParts(new Date(t * 1000)))\n if (p.type !== \"literal\") r[p.type as keyof WallParts] = Number(p.value);\n if (r.hour === 24) r.hour = 0;\n return r;\n}\nfunction wallEpoch(t: number, zone: string): number {\n const p = wallParts(t, zone);\n return (\n utcFromParts(p.year, p.month, p.day, p.hour, p.minute, p.second) +\n (t - Math.floor(t))\n );\n}\nfunction offsetAt(t: number, zone: string): number {\n return Math.round(wallEpoch(t, zone) - t);\n}\nfunction localCandidates(w: number, zone: string): number[] {\n if (zone === \"UTC\") return [w];\n const offsets = new Set(\n [-172800, -86400, 0, 86400, 172800].map((d) => offsetAt(w + d, zone)),\n ),\n out = [];\n for (const off of offsets) {\n const t = w - off;\n if (Math.abs(wallEpoch(t, zone) - w) < 0.001) out.push(t);\n }\n return out.sort((a, b) => a - b);\n}\nfunction wallTicks(\n start: number,\n end: number,\n step: number,\n zone: string,\n): number[] {\n if (zone === \"UTC\") return multiples(start, end, step);\n const sa = wallEpoch(start, zone),\n sb = wallEpoch(end, zone),\n a = Math.floor(Math.min(sa, sb) / step) - 2,\n b = Math.ceil(Math.max(sa, sb) / step) + 2;\n check(\n finite(b - a) &&\n b - a <= LIMITS.ticks &&\n Math.abs(a) < 9e15 &&\n Math.abs(b) < 9e15,\n \"Too many time ticks; increase the interval.\",\n );\n // One offset set for a tick range; 12-hour probes plus endpoint probes preserve ordinary IANA folds.\n const offsets = new Set<number>();\n const probe = Math.max(43200, (end - start) / 4096);\n for (let t = start - 172800; t <= end + 172800; t += probe)\n offsets.add(offsetAt(t, zone));\n offsets.add(offsetAt(end, zone));\n const out = new Set<number>();\n for (let i = 0; i <= b - a; i++) {\n const w = (a + i) * step;\n for (const off of offsets) {\n const t = w - off;\n if (t >= start && t <= end && Math.abs(wallEpoch(t, zone) - w) < 0.001)\n out.add(t);\n }\n }\n return [...out].sort((a, b) => a - b);\n}\nfunction monthTicks(\n start: number,\n end: number,\n zone: string,\n stride: number = 1,\n): number[] {\n const a = wallParts(start, zone),\n b = wallParts(end, zone),\n first = Math.floor((a.year * 12 + a.month - 1) / stride) * stride,\n last = b.year * 12 + b.month - 1 + stride;\n check((last - first) / stride <= LIMITS.ticks, \"Too many calendar ticks.\");\n const out = [];\n for (let i = first; i <= last; i += stride) {\n const y = Math.floor(i / 12),\n m = (i % 12) + 1;\n if (y < 1 || y > 9999) continue;\n for (const t of localCandidates(utcFromParts(y, m, 1), zone))\n if (t >= start && t <= end) out.push(t);\n }\n return out.sort((a, b) => a - b);\n}\nconst MONTHS = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n];\nconst DAYS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst pad = (v: number, n: number = 2): string => String(v).padStart(n, \"0\");\n/** Format a timestamp with fixed English calendar names and IANA timezone rules. */\nexport function formatTime(\n t: Timestamp,\n zone: string = \"UTC\",\n format: string = \"%H:%M\",\n): string {\n t = epoch(t);\n const p = wallParts(t, zone),\n d = new Date(utcFromParts(p.year, p.month, p.day) * 1000),\n off = offsetAt(t, zone),\n day = d.getUTCDay();\n const fields: Record<string, string> = {\n H: pad(p.hour),\n I: pad(p.hour % 12 || 12),\n M: pad(p.minute),\n S: pad(p.second),\n d: pad(p.day),\n e: String(p.day).padStart(2, \" \"),\n m: pad(p.month),\n Y: pad(p.year, 4),\n y: pad(p.year % 100),\n a: DAYS[day],\n A: [\n \"Sunday\",\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n ][day],\n b: MONTHS[p.month - 1],\n h: MONTHS[p.month - 1],\n B: [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ][p.month - 1],\n p: p.hour < 12 ? \"AM\" : \"PM\",\n w: String(day),\n u: String(day || 7),\n j: pad(\n Math.floor((d.getTime() / 1000 - utcFromParts(p.year, 1, 1)) / 86400) + 1,\n 3,\n ),\n z:\n (off < 0 ? \"-\" : \"+\") +\n pad(Math.floor(Math.abs(off) / 3600)) +\n pad(Math.floor((Math.abs(off) % 3600) / 60)),\n Z: zone,\n \"%\": \"%\",\n };\n fields.F = fields.Y + \"-\" + fields.m + \"-\" + fields.d;\n fields.T = fields.H + \":\" + fields.M + \":\" + fields.S;\n fields.R = fields.H + \":\" + fields.M;\n let out = \"\";\n for (let i = 0; i < format.length; i++) {\n if (format[i] !== \"%\") {\n out += format[i];\n continue;\n }\n const k = format[++i];\n check(own(fields, k), \"Unsupported date directive: %\" + (k || \"\"));\n out += fields[k];\n }\n return out;\n}\nfunction resolveX(\n a: DeepReadonly<ResolvedTimeAxis>,\n start: number,\n end: number,\n width: number,\n): XResolution {\n const span = end - start,\n zone = a.timezone,\n mode =\n a.mode === \"auto\"\n ? span <= 172800\n ? \"daily\"\n : span <= 864000\n ? \"weekly\"\n : span <= 5356800\n ? \"monthly\"\n : \"yearly\"\n : a.mode;\n let minor: number[] = [],\n major: number[] = [],\n labelTimes: number[] = [],\n format = \"%H:%M\";\n if (mode === \"yearly\") {\n const stride =\n span > 550 * 86400 ? Math.max(1, Math.ceil(span / (365.25 * 86400))) : 1;\n format = stride > 1 ? \"%b %Y\" : \"%b\";\n if (a.majorTicks === null || a.ticks === null) {\n major = monthTicks(start, end, zone, stride);\n labelTimes = major;\n }\n if (a.minorTicks === null) minor = monthTicks(start, end, zone, 1);\n if (a.majorTicks === null && a.majorSeconds !== null)\n major = wallTicks(start, end, a.majorSeconds, zone);\n if (a.minorTicks === null && a.minorSeconds !== null)\n minor = wallTicks(start, end, a.minorSeconds, zone);\n if (a.ticks === null && a.labelSeconds !== null)\n labelTimes = wallTicks(start, end, a.labelSeconds, zone);\n } else {\n let mi = 1800,\n ma = 7200,\n ls = 7200;\n if (mode === \"weekly\") {\n mi = 21600;\n ma = ls = 86400;\n format = \"%d\";\n }\n if (mode === \"monthly\") {\n mi = 86400;\n ma = ls = 604800;\n format = \"%d %b\";\n }\n if (a.mode === \"auto\" && span < 43200) {\n const target = span / Math.max(2, Math.floor(width / 48));\n ls =\n [1, 5, 10, 15, 30, 60, 120, 300, 600, 900, 1800, 3600, 7200].find(\n (v) => v >= target,\n ) || 7200;\n mi = Math.max(1, ls / 4);\n ma = ls;\n if (ls < 60) format = \"%H:%M:%S\";\n }\n mi = Math.max(mi, span / 2000);\n if (a.minorSeconds !== null) mi = a.minorSeconds;\n if (a.majorSeconds !== null) ma = a.majorSeconds;\n if (a.labelSeconds !== null) ls = a.labelSeconds;\n if (a.minorTicks === null) minor = wallTicks(start, end, mi, zone);\n if (a.majorTicks === null) major = wallTicks(start, end, ma, zone);\n if (a.ticks === null) labelTimes = wallTicks(start, end, ls, zone);\n }\n if (a.minorTicks !== null)\n minor = a.minorTicks.filter((v) => v >= start && v <= end);\n if (a.majorTicks !== null)\n major = a.majorTicks.filter((v) => v >= start && v <= end);\n if (a.labelFormat !== null) format = a.labelFormat;\n let labels: ResolvedTick[] = [];\n if (a.ticks !== null)\n labels = a.ticks.filter((v) => v.time >= start && v.time <= end);\n else if (\n mode === \"weekly\" &&\n a.labelSeconds === null &&\n a.labelOffsetSeconds === 0\n ) {\n for (const t of wallTicks(start - 172800, end, 86400, zone)) {\n const w = wallEpoch(t, zone),\n next = localCandidates(w + 86400, zone);\n if (t < start || !next.length || next[next.length - 1] > end) continue;\n for (const noon of localCandidates(w + 43200, zone))\n if (noon >= start && noon <= end)\n labels.push({ time: noon, label: formatTime(t, zone, format) });\n }\n } else\n for (const t of labelTimes) {\n const pos = t + a.labelOffsetSeconds;\n if (pos >= start && pos <= end)\n labels.push({ time: pos, label: formatTime(t, zone, format) });\n }\n labels.sort((a, b) => a.time - b.time);\n if (a.ticks === null && mode === \"daily\" && span <= 95040) {\n const seen = new Map<string, Set<number>>();\n for (const t of labels) {\n if (!seen.has(t.label)) seen.set(t.label, new Set());\n seen.get(t.label)!.add(offsetAt(t.time, zone));\n }\n labels = labels.map((t) =>\n seen.get(t.label)!.size > 1\n ? {\n time: t.time,\n label: t.label + \" \" + formatTime(t.time, zone, \"%z\"),\n }\n : t,\n );\n }\n const majorSet = new Set(major);\n minor = minor.filter((v) => !majorSet.has(v));\n return { minor, major, labels, mode };\n}\nfunction timeRange(c: ChartConfig): [number, number] {\n let start = Infinity,\n end = -Infinity;\n for (const s of c.series)\n if (s.timestamps.length) {\n start = Math.min(start, s.timestamps[0]);\n end = Math.max(end, s.timestamps[s.timestamps.length - 1]);\n }\n if (c.timeAxis.start !== null) start = c.timeAxis.start;\n if (c.timeAxis.end !== null) end = c.timeAxis.end;\n if (start === end && c.timeAxis.start === null && c.timeAxis.end === null) {\n start -= 150;\n end += 150;\n }\n epoch(start);\n epoch(end);\n check(\n end > start,\n \"Empty data needs explicit start and end; range must be nonzero.\",\n );\n return [start, end];\n}\n// Original 5\u00D77 pixel-letter descriptions. Not extracted from a font, no font asset shipped.\n// This optional ASCII renderer trades typographic likeness for host-independent pixels.\nconst PIXEL_GLYPHS: Readonly<Record<string, readonly string[]>> = {\n \" \": [\"00000\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\"],\n \"0\": [\"01110\", \"10001\", \"10011\", \"10101\", \"11001\", \"10001\", \"01110\"],\n \"1\": [\"00100\", \"01100\", \"00100\", \"00100\", \"00100\", \"00100\", \"01110\"],\n \"2\": [\"01110\", \"10001\", \"00001\", \"00010\", \"00100\", \"01000\", \"11111\"],\n \"3\": [\"11110\", \"00001\", \"00001\", \"01110\", \"00001\", \"00001\", \"11110\"],\n \"4\": [\"00010\", \"00110\", \"01010\", \"10010\", \"11111\", \"00010\", \"00010\"],\n \"5\": [\"11111\", \"10000\", \"10000\", \"11110\", \"00001\", \"00001\", \"11110\"],\n \"6\": [\"01110\", \"10000\", \"10000\", \"11110\", \"10001\", \"10001\", \"01110\"],\n \"7\": [\"11111\", \"00001\", \"00010\", \"00100\", \"01000\", \"01000\", \"01000\"],\n \"8\": [\"01110\", \"10001\", \"10001\", \"01110\", \"10001\", \"10001\", \"01110\"],\n \"9\": [\"01110\", \"10001\", \"10001\", \"01111\", \"00001\", \"00001\", \"01110\"],\n A: [\"01110\", \"10001\", \"10001\", \"11111\", \"10001\", \"10001\", \"10001\"],\n B: [\"11110\", \"10001\", \"10001\", \"11110\", \"10001\", \"10001\", \"11110\"],\n C: [\"01111\", \"10000\", \"10000\", \"10000\", \"10000\", \"10000\", \"01111\"],\n D: [\"11110\", \"10001\", \"10001\", \"10001\", \"10001\", \"10001\", \"11110\"],\n E: [\"11111\", \"10000\", \"10000\", \"11110\", \"10000\", \"10000\", \"11111\"],\n F: [\"11111\", \"10000\", \"10000\", \"11110\", \"10000\", \"10000\", \"10000\"],\n G: [\"01110\", \"10001\", \"10000\", \"10111\", \"10001\", \"10001\", \"01111\"],\n H: [\"10001\", \"10001\", \"10001\", \"11111\", \"10001\", \"10001\", \"10001\"],\n I: [\"01110\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"01110\"],\n J: [\"00111\", \"00010\", \"00010\", \"00010\", \"00010\", \"10010\", \"01100\"],\n K: [\"10001\", \"10010\", \"10100\", \"11000\", \"10100\", \"10010\", \"10001\"],\n L: [\"10000\", \"10000\", \"10000\", \"10000\", \"10000\", \"10000\", \"11111\"],\n M: [\"10001\", \"11011\", \"10101\", \"10101\", \"10001\", \"10001\", \"10001\"],\n N: [\"10001\", \"11001\", \"10101\", \"10011\", \"10001\", \"10001\", \"10001\"],\n O: [\"01110\", \"10001\", \"10001\", \"10001\", \"10001\", \"10001\", \"01110\"],\n P: [\"11110\", \"10001\", \"10001\", \"11110\", \"10000\", \"10000\", \"10000\"],\n Q: [\"01110\", \"10001\", \"10001\", \"10001\", \"10101\", \"10010\", \"01101\"],\n R: [\"11110\", \"10001\", \"10001\", \"11110\", \"10100\", \"10010\", \"10001\"],\n S: [\"01111\", \"10000\", \"10000\", \"01110\", \"00001\", \"00001\", \"11110\"],\n T: [\"11111\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\"],\n U: [\"10001\", \"10001\", \"10001\", \"10001\", \"10001\", \"10001\", \"01110\"],\n V: [\"10001\", \"10001\", \"10001\", \"10001\", \"10001\", \"01010\", \"00100\"],\n W: [\"10001\", \"10001\", \"10001\", \"10101\", \"10101\", \"11011\", \"10001\"],\n X: [\"10001\", \"10001\", \"01010\", \"00100\", \"01010\", \"10001\", \"10001\"],\n Y: [\"10001\", \"10001\", \"01010\", \"00100\", \"00100\", \"00100\", \"00100\"],\n Z: [\"11111\", \"00001\", \"00010\", \"00100\", \"01000\", \"10000\", \"11111\"],\n a: [\"00000\", \"00000\", \"01110\", \"00001\", \"01111\", \"10001\", \"01111\"],\n b: [\"10000\", \"10000\", \"10110\", \"11001\", \"10001\", \"10001\", \"11110\"],\n c: [\"00000\", \"00000\", \"01111\", \"10000\", \"10000\", \"10000\", \"01111\"],\n d: [\"00001\", \"00001\", \"01101\", \"10011\", \"10001\", \"10001\", \"01111\"],\n e: [\"00000\", \"00000\", \"01110\", \"10001\", \"11111\", \"10000\", \"01110\"],\n f: [\"00110\", \"01001\", \"01000\", \"11100\", \"01000\", \"01000\", \"01000\"],\n g: [\"00000\", \"01111\", \"10001\", \"10001\", \"01111\", \"00001\", \"01110\"],\n h: [\"10000\", \"10000\", \"10110\", \"11001\", \"10001\", \"10001\", \"10001\"],\n i: [\"00100\", \"00000\", \"01100\", \"00100\", \"00100\", \"00100\", \"01110\"],\n j: [\"00010\", \"00000\", \"00110\", \"00010\", \"00010\", \"10010\", \"01100\"],\n k: [\"10000\", \"10000\", \"10010\", \"10100\", \"11000\", \"10100\", \"10010\"],\n l: [\"01100\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"01110\"],\n m: [\"00000\", \"00000\", \"11010\", \"10101\", \"10101\", \"10101\", \"10101\"],\n n: [\"00000\", \"00000\", \"10110\", \"11001\", \"10001\", \"10001\", \"10001\"],\n o: [\"00000\", \"00000\", \"01110\", \"10001\", \"10001\", \"10001\", \"01110\"],\n p: [\"00000\", \"00000\", \"11110\", \"10001\", \"11110\", \"10000\", \"10000\"],\n q: [\"00000\", \"00000\", \"01111\", \"10001\", \"01111\", \"00001\", \"00001\"],\n r: [\"00000\", \"00000\", \"10111\", \"11000\", \"10000\", \"10000\", \"10000\"],\n s: [\"00000\", \"00000\", \"01111\", \"10000\", \"01110\", \"00001\", \"11110\"],\n t: [\"01000\", \"01000\", \"11100\", \"01000\", \"01000\", \"01001\", \"00110\"],\n u: [\"00000\", \"00000\", \"10001\", \"10001\", \"10001\", \"10011\", \"01101\"],\n v: [\"00000\", \"00000\", \"10001\", \"10001\", \"10001\", \"01010\", \"00100\"],\n w: [\"00000\", \"00000\", \"10001\", \"10001\", \"10101\", \"10101\", \"01010\"],\n x: [\"00000\", \"00000\", \"10001\", \"01010\", \"00100\", \"01010\", \"10001\"],\n y: [\"00000\", \"00000\", \"10001\", \"10001\", \"01111\", \"00001\", \"01110\"],\n z: [\"00000\", \"00000\", \"11111\", \"00010\", \"00100\", \"01000\", \"11111\"],\n \"-\": [\"00000\", \"00000\", \"00000\", \"11111\", \"00000\", \"00000\", \"00000\"],\n _: [\"00000\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\", \"11111\"],\n \":\": [\"00000\", \"00100\", \"00100\", \"00000\", \"00100\", \"00100\", \"00000\"],\n \".\": [\"00000\", \"00000\", \"00000\", \"00000\", \"00000\", \"00100\", \"00100\"],\n \",\": [\"00000\", \"00000\", \"00000\", \"00000\", \"00100\", \"00100\", \"01000\"],\n \"/\": [\"00001\", \"00010\", \"00010\", \"00100\", \"01000\", \"01000\", \"10000\"],\n \"\\\\\": [\"10000\", \"01000\", \"01000\", \"00100\", \"00010\", \"00010\", \"00001\"],\n \"(\": [\"00010\", \"00100\", \"01000\", \"01000\", \"01000\", \"00100\", \"00010\"],\n \")\": [\"01000\", \"00100\", \"00010\", \"00010\", \"00010\", \"00100\", \"01000\"],\n \"[\": [\"01110\", \"01000\", \"01000\", \"01000\", \"01000\", \"01000\", \"01110\"],\n \"]\": [\"01110\", \"00010\", \"00010\", \"00010\", \"00010\", \"00010\", \"01110\"],\n \"+\": [\"00000\", \"00100\", \"00100\", \"11111\", \"00100\", \"00100\", \"00000\"],\n \"=\": [\"00000\", \"00000\", \"11111\", \"00000\", \"11111\", \"00000\", \"00000\"],\n \"%\": [\"11001\", \"11010\", \"00010\", \"00100\", \"01000\", \"01011\", \"10011\"],\n \"?\": [\"01110\", \"10001\", \"00001\", \"00010\", \"00100\", \"00000\", \"00100\"],\n \"!\": [\"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"00000\", \"00100\"],\n \"#\": [\"01010\", \"01010\", \"11111\", \"01010\", \"11111\", \"01010\", \"01010\"],\n \"*\": [\"00000\", \"10101\", \"01110\", \"11111\", \"01110\", \"10101\", \"00000\"],\n \"<\": [\"00010\", \"00100\", \"01000\", \"10000\", \"01000\", \"00100\", \"00010\"],\n \">\": [\"01000\", \"00100\", \"00010\", \"00001\", \"00010\", \"00100\", \"01000\"],\n \"|\": [\"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\"],\n '\"': [\"01010\", \"01010\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\"],\n \"'\": [\"00100\", \"00100\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\"],\n \";\": [\"00000\", \"00100\", \"00100\", \"00000\", \"00100\", \"00100\", \"01000\"],\n \"@\": [\"01110\", \"10001\", \"10111\", \"10101\", \"10111\", \"10000\", \"01111\"],\n $: [\"00100\", \"01111\", \"10100\", \"01110\", \"00101\", \"11110\", \"00100\"],\n \"&\": [\"01100\", \"10010\", \"10100\", \"01000\", \"10101\", \"10010\", \"01101\"],\n \"^\": [\"00100\", \"01010\", \"10001\", \"00000\", \"00000\", \"00000\", \"00000\"],\n \"`\": [\"01000\", \"00100\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\"],\n \"~\": [\"00000\", \"00000\", \"01001\", \"10110\", \"00000\", \"00000\", \"00000\"],\n \"{\": [\"00011\", \"00100\", \"00100\", \"01000\", \"00100\", \"00100\", \"00011\"],\n \"}\": [\"11000\", \"00100\", \"00100\", \"00010\", \"00100\", \"00100\", \"11000\"],\n};\nfunction createCanvas(w: number, h: number): Canvas {\n let canvas;\n if (typeof document !== \"undefined\" && document.createElement)\n canvas = document.createElement(\"canvas\");\n else if (typeof OffscreenCanvas !== \"undefined\")\n canvas = new OffscreenCanvas(w, h);\n else\n throw new Error(\n 'System fonts need Canvas 2D. Use fonts: { mode: \"bitmap\" } in a DOM-free runtime.',\n );\n canvas.width = w;\n canvas.height = h;\n return canvas;\n}\nfunction wide(ch: string): boolean {\n const n = ch.codePointAt(0)!;\n return (\n n >= 0x1100 &&\n (n <= 0x115f ||\n (n >= 0x2e80 && n <= 0xa4cf) ||\n (n >= 0xac00 && n <= 0xd7a3) ||\n (n >= 0xf900 && n <= 0xfaff) ||\n (n >= 0xff00 && n <= 0xff60) ||\n n >= 0x1f300)\n );\n}\nclass Fonts {\n readonly config: Readonly<Required<FontOptions>>;\n readonly theme: DeepReadonly<ResolvedTheme>;\n private readonly cache: Map<string, Surface>;\n private canvas!: Canvas;\n private ctx!: Context2D;\n constructor(\n config: Readonly<Required<FontOptions>>,\n theme: DeepReadonly<ResolvedTheme>,\n ) {\n this.config = config;\n this.theme = theme;\n this.cache = new Map();\n if (config.mode === \"system\") {\n this.canvas = createCanvas(8, 8);\n const ctx = this.canvas.getContext(\"2d\", {\n willReadFrequently: true,\n }) as Context2D | null;\n check(ctx, \"Canvas 2D is unavailable.\");\n this.ctx = ctx;\n }\n }\n size(role: FontRole, scale: number = 1): number {\n return this.theme[`${role}Size`] * scale;\n }\n family(role: FontRole): string {\n return (\n (role === \"title\" || role === \"unit\" || role === \"caption\"\n ? this.config[`${role}Family`]\n : null) || this.config.family\n );\n }\n setup(role: FontRole, size: number): void {\n this.ctx.font =\n (role === \"caption\" ? \"bold \" : \"\") + size + \"px \" + this.family(role);\n this.ctx.textBaseline = \"alphabetic\";\n this.ctx.fillStyle = \"#000000\";\n if (\"fontKerning\" in this.ctx) this.ctx.fontKerning = \"none\";\n }\n width(\n value: string,\n role: FontRole,\n advance: number = 0,\n scale: number = 1,\n ): number {\n if (advance > 0)\n return [...value].reduce((n, ch) => n + advance * (wide(ch) ? 2 : 1), 0);\n if (this.config.mode === \"bitmap\")\n return [...value].length * this.size(role, scale) * 0.6;\n this.setup(role, this.size(role, scale));\n return this.ctx.measureText(value).width;\n }\n fit(\n value: string,\n maxWidth: number,\n role: FontRole,\n advance: number,\n scale: number = 1,\n ): string {\n if (this.width(value, role, advance, scale) <= maxWidth) return value;\n const end = \"...\";\n if (this.width(end, role, advance, scale) > maxWidth) return \"\";\n const a = [...value];\n while (\n a.length &&\n this.width(a.join(\"\") + end, role, advance, scale) > maxWidth\n )\n a.pop();\n return a.join(\"\") + end;\n }\n raster(\n value: string,\n role: FontRole,\n advance: number = 0,\n scale: number = 1,\n ): Surface {\n const key = JSON.stringify([value, role, advance, scale]);\n if (this.cache.has(key)) return this.cache.get(key)!;\n const size = this.size(role, scale),\n w = Math.max(1, Math.ceil(this.width(value, role, advance, scale)) + 4);\n let out;\n check(\n w <= 32768 && w * size < LIMITS.pixels,\n \"Text allocation limit exceeded.\",\n );\n if (this.config.mode === \"bitmap\") {\n const h = Math.max(1, round(size * 0.72));\n out = new Surface(w, h + 2);\n let x = 1;\n for (const ch of value) {\n let rows = PIXEL_GLYPHS[ch];\n if (!rows) {\n check(\n !this.config.strictGlyphs,\n \"Bitmap text supports printable ASCII only: \" + ch,\n );\n rows = PIXEL_GLYPHS[\"?\"];\n }\n const cell = advance > 0 ? advance : size * 0.6,\n gw = Math.max(1, Math.min(round(size * 0.5), Math.floor(cell) - 1));\n for (let yy = 0; yy < h; yy++)\n for (let xx = 0; xx < gw; xx++)\n if (\n rows[Math.min(6, Math.floor((yy / h) * 7))][\n Math.min(4, Math.floor((xx / gw) * 5))\n ] === \"1\"\n )\n out.pixel(round(x) + xx, yy + 1, [0, 0, 0, 255]);\n x += cell * (wide(ch) ? 2 : 1);\n }\n } else {\n this.setup(role, size);\n const metric = this.ctx.measureText(value || \"0\");\n const ascent = Math.ceil(metric.actualBoundingBoxAscent || size * 0.8),\n descent = Math.ceil(metric.actualBoundingBoxDescent || 0),\n h = Math.max(1, ascent + descent) + 2;\n this.canvas.width = w;\n this.canvas.height = h;\n this.setup(role, size);\n let x = 1;\n for (const ch of value) {\n this.ctx.fillText(ch, round(x), 1 + ascent);\n x +=\n advance > 0\n ? advance * (wide(ch) ? 2 : 1)\n : this.ctx.measureText(ch).width;\n }\n const d = this.ctx.getImageData(0, 0, w, h);\n out = new Surface(w, h);\n out.data.set(d.data);\n }\n if (this.cache.size >= 512)\n this.cache.delete(this.cache.keys().next().value!);\n this.cache.set(key, out);\n return out;\n }\n draw(\n im: Surface,\n x: number,\n y: number,\n value: string,\n role: FontRole,\n fill: Readonly<RGBA>,\n advance: number = 0,\n align: \"left\" | \"center\" | \"right\" = \"left\",\n centerY: boolean = false,\n scale: number = 1,\n ): void {\n if (!value) return;\n const r = this.raster(value, role, advance, scale),\n width = this.width(value, role, advance, scale);\n if (align === \"center\") x -= width / 2;\n else if (align === \"right\") x -= width;\n if (centerY) y -= (r.height - 2) / 2;\n const xx = round(x) - 1,\n yy = round(y) - 1,\n p: RGBA = [fill[0], fill[1], fill[2], 0];\n for (let sy = 0; sy < r.height; sy++)\n for (let sx = 0; sx < r.width; sx++) {\n const a = r.data[(sy * r.width + sx) * 4 + 3];\n if (a) {\n p[3] = round((a * fill[3]) / 255);\n im.pixel(xx + sx, yy + sy, p, true);\n }\n }\n }\n rotated(\n value: string,\n role: FontRole,\n fill: Readonly<RGBA>,\n clockwise: boolean = false,\n ): Surface {\n const r = this.raster(value, role),\n out = new Surface(r.height, r.width),\n p: RGBA = [fill[0], fill[1], fill[2], 0];\n for (let y = 0; y < r.height; y++)\n for (let x = 0; x < r.width; x++) {\n p[3] = round((r.data[(y * r.width + x) * 4 + 3] * fill[3]) / 255);\n if (p[3])\n out.pixel(\n clockwise ? r.height - 1 - y : y,\n clockwise ? x : r.width - 1 - x,\n p,\n );\n }\n return out;\n }\n}\nfunction renderChart(c: ChartConfig): RenderResult {\n const l = c.layout,\n t = c.theme,\n [width, height] = dimensions(c),\n left = l.left,\n top = l.top,\n right = l.width - l.right,\n bottom = l.top + l.plotHeight,\n pw = right - left,\n ph = bottom - top;\n const [start, end] = timeRange(c);\n const runs = c.series.map((s) => visibleRuns(s, start, end));\n let loData = Infinity,\n hiData = -Infinity;\n for (let i = 0; i < runs.length; i++) {\n for (const run of runs[i])\n for (const p of run) {\n check(finite(p[1]), \"Interpolated value overflow.\");\n loData = Math.min(loData, p[1]);\n hiData = Math.max(hiData, p[1]);\n }\n if (c.series[i].kind === \"area\") {\n loData = Math.min(loData, c.series[i].baseline);\n hiData = Math.max(hiData, c.series[i].baseline);\n }\n }\n if (loData === Infinity) loData = hiData = 0;\n const ys = resolveY(c.yAxis, loData, hiData),\n xs = resolveX(c.timeAxis, start, end, pw),\n fonts = new Fonts(c.fonts, t),\n im = new Surface(width, height, t.background);\n im.rect(left, top, right + 1, bottom + 1, t.canvas);\n const xx = (v: number): number => ((v - start) / (end - start)) * pw,\n yy = (v: number): number =>\n ph *\n (1 -\n (v / (ys.maximum - ys.minimum) -\n ys.minimum / (ys.maximum - ys.minimum)));\n const projected = runs.map((rr) =>\n rr.map((r) =>\n decimate(r, start, end, pw).map((p): Point => {\n const x = xx(p[0]),\n y = yy(p[1]);\n check(\n finite(x) && finite(y) && Math.abs(y) < 1e15,\n \"Data magnitude is too large relative to the Y axis.\",\n );\n return [x, y];\n }),\n ),\n );\n function grid(): void {\n const lay = new Surface(pw + 1, ph + 1);\n for (const [values, col] of [\n [ys.minor, t.minorGrid],\n [ys.major, t.majorGrid],\n ] as const)\n for (const v of values) {\n const y = round(yy(v));\n if (y >= 0 && y <= ph) lay.dashed([0, y], [pw, y], col, t.gridDash);\n }\n for (const [values, col] of [\n [xs.minor, t.minorGrid],\n [xs.major, t.majorGrid],\n ] as const)\n for (const v of values) {\n const x = round(xx(v));\n lay.dashed([x, 0], [x, ph], col, t.gridDash);\n }\n im.over(lay, left, top);\n }\n const aa = l.antialias,\n layerWidth = (pw + 1) * aa,\n layerHeight = (ph + 1) * aa;\n if (!t.gridFront) grid();\n for (let i = 0; i < c.series.length; i++) {\n const s = c.series[i];\n if (s.kind !== \"area\") continue;\n const base = yy(s.baseline);\n check(\n finite(base) && Math.abs(base) < 1e15,\n \"Baseline magnitude is too large.\",\n );\n const layer = new Surface(layerWidth, layerHeight);\n for (const ps of projected[i])\n if (ps.length > 1) {\n const poly = clipPolygon(\n [[ps[0][0], base], ...ps, [ps[ps.length - 1][0], base]],\n pw,\n ph,\n ).map((p): Point => [round(p[0] * aa), round(p[1] * aa)]);\n layer.polygon(poly, s.color);\n }\n im.over(layer.down(aa), left, top);\n }\n if (t.gridFront) grid();\n for (let i = 0; i < c.series.length; i++) {\n const s = c.series[i],\n col = s.kind === \"line\" ? s.color : s.outline;\n if (col === null) continue;\n const layer = new Surface(layerWidth, layerHeight),\n lw = Math.max(1, round(s.lineWidth * aa));\n for (const ps of projected[i]) {\n if (ps.length === 1) {\n const p = ps[0];\n if (p[0] >= 0 && p[0] <= pw && p[1] >= 0 && p[1] <= ph)\n layer.circle(p[0] * aa, p[1] * aa, Math.max(aa / 2, lw / 2), col);\n }\n for (let k = 1; k < ps.length; k++) {\n const seg = clipLine(ps[k - 1], ps[k], pw, ph);\n if (seg)\n layer.line(\n [round(seg[0][0] * aa), round(seg[0][1] * aa)],\n [round(seg[1][0] * aa), round(seg[1][1] * aa)],\n col,\n lw,\n );\n }\n }\n im.over(layer.down(aa), left, top);\n }\n const rules = new Surface(pw + 1, ph + 1);\n for (const r of c.hRules)\n if (r.value >= ys.minimum && r.value <= ys.maximum)\n rules.dashed(\n [0, round(yy(r.value))],\n [pw, round(yy(r.value))],\n r.color,\n r.dash,\n Math.max(1, round(r.width)),\n );\n for (const r of c.vRules)\n if (r.time >= start && r.time <= end)\n rules.dashed(\n [round(xx(r.time)), 0],\n [round(xx(r.time)), ph],\n r.color,\n r.dash,\n Math.max(1, round(r.width)),\n );\n im.over(rules, left, top);\n im.line([left, top - 3], [left, bottom + 4], t.axis);\n im.line([left - 4, bottom], [right + 4, bottom], t.axis);\n im.polygon(\n [\n [left, top - 5],\n [left - 3, top],\n [left + 3, top],\n ],\n t.arrow,\n );\n im.polygon(\n [\n [right + 7, bottom],\n [right + 2, bottom - 3],\n [right + 2, bottom + 3],\n ],\n t.arrow,\n );\n for (const v of ys.major) {\n const y = top + yy(v),\n unit =\n v === 0 && !c.yAxis.showZeroSuffix\n ? { factor: ys.factor, suffix: \"\" }\n : ys,\n label = formatValue(v, unit, ys.decimals);\n check(\n fonts.width(label, \"axis\", t.axisAdvance) <= left - l.yLabelGap - 20,\n \"Y labels overlap the vertical label. Increase layout.left or adjust units.\",\n );\n im.line([left - 3, round(y)], [left, round(y)], t.axis);\n fonts.draw(\n im,\n left - l.yLabelGap,\n y,\n label,\n \"axis\",\n t.text,\n t.axisAdvance,\n \"right\",\n true,\n );\n }\n const xLabels = [];\n let lastRight = -Infinity;\n for (const tick of xs.labels) {\n const x = left + xx(tick.time),\n tw = fonts.width(tick.label, \"axis\", t.axisAdvance),\n a = x - tw / 2,\n b = x + tw / 2;\n if (c.timeAxis.ticks === null && a < lastRight + 3) continue;\n if (a < 2 || b > width - 3) continue;\n im.line(\n [round(x), bottom],\n [round(x), bottom + 3],\n [t.majorGrid[0], t.majorGrid[1], t.majorGrid[2], 255],\n );\n fonts.draw(\n im,\n x,\n bottom + l.xLabelGap,\n tick.label,\n \"axis\",\n t.text,\n t.axisAdvance,\n \"center\",\n );\n lastRight = b;\n xLabels.push({ ...tick, x });\n }\n const titleX = (left + right) / 2 + l.titleOffsetX,\n title = fonts.fit(\n c.title,\n 2 * Math.min(titleX - 5, width - 14 - titleX),\n \"title\",\n t.titleAdvance,\n );\n fonts.draw(\n im,\n titleX,\n l.titleY,\n title,\n \"title\",\n t.text,\n t.titleAdvance,\n \"center\",\n );\n if (c.verticalLabel) {\n const unit = fonts.rotated(c.verticalLabel, \"unit\", t.text);\n check(\n unit.height <= ph + 18 && l.unitX + unit.width <= left - l.yLabelGap,\n \"Vertical label does not fit.\",\n );\n im.over(unit, l.unitX, round((top + bottom - unit.height) / 2));\n }\n if (c.watermark) {\n const mark = fonts.rotated(c.watermark, \"watermark\", t.watermark, true);\n check(\n mark.height <= height - 8 && mark.width <= l.right - 9,\n \"Watermark does not fit.\",\n );\n im.over(mark, width - mark.width - 4, 4);\n }\n const stats = c.series.map((s) => statistics(s, start, end));\n if (l.legend !== \"none\") {\n const scale = Math.min(1, (width - 40) / 555),\n advance = t.legendAdvance * scale,\n ll = l.legendLayout,\n factor = ll.autoScaleColumns\n ? (width - ll.nameX) / (ll.referenceWidth - ll.nameX)\n : 1,\n anchor = (x: number): number => ll.nameX + (x - ll.nameX) * factor;\n c.series.forEach((s, i) => {\n const pairs =\n l.legend === \"aligned\"\n ? ll.aligned\n : l.legend === \"reference\" && i === c.series.length - 1 && i > 0\n ? ll.expanded\n : ll.compact,\n y = bottom + l.legendGap + i * l.legendRowHeight;\n check(\n ll.swatchHeight <= l.legendRowHeight &&\n ll.swatchX + ll.swatchWidth < width &&\n y + ll.swatchHeight <= height - 2,\n \"Legend swatch does not fit.\",\n );\n im.rect(\n ll.swatchX,\n y,\n ll.swatchX + ll.swatchWidth,\n y + ll.swatchHeight,\n t.frame,\n );\n const swatch = new Surface(\n ll.swatchWidth - 2,\n ll.swatchHeight - 2,\n s.color,\n );\n im.over(swatch, ll.swatchX + 1, y + 1);\n const name = fonts.fit(\n s.name,\n anchor(pairs[0][0]) - ll.nameX - 12,\n \"legend\",\n advance,\n scale,\n );\n fonts.draw(\n im,\n ll.nameX,\n y,\n name,\n \"legend\",\n t.text,\n advance,\n \"left\",\n false,\n scale,\n );\n const display = s.legendValues || stats[i];\n ([\"current\", \"average\", \"maximum\"] as const).forEach((key, j) => {\n const label = c.legendLabels[j],\n value = formatValue(\n display[key],\n ys,\n c.yAxis.legendDecimals,\n c.missingLabel,\n ),\n a = anchor(pairs[j][0]),\n b = anchor(pairs[j][1]);\n check(b < width - 3, \"Legend column is outside the panel.\");\n check(\n fonts.width(label, \"legend\", advance, scale) +\n fonts.width(value, \"legend\", advance, scale) +\n 7 * scale <=\n b - a + 1,\n \"Legend statistic does not fit. Increase width, adjust anchors or reduce legendDecimals.\",\n );\n fonts.draw(\n im,\n a,\n y,\n label,\n \"legend\",\n t.text,\n advance,\n \"left\",\n false,\n scale,\n );\n fonts.draw(\n im,\n b,\n y,\n value,\n \"legend\",\n t.text,\n advance,\n \"right\",\n false,\n scale,\n );\n });\n });\n }\n for (const [a, b] of [\n [\n [0, 0],\n [width - 1, 0],\n ],\n [\n [1, 1],\n [width - 2, 1],\n ],\n [\n [0, 0],\n [0, height - 1],\n ],\n [\n [1, 1],\n [1, height - 2],\n ],\n ] as [Point, Point][])\n im.line(a, b, t.shadeLight);\n for (const [a, b] of [\n [\n [width - 2, 1],\n [width - 2, height - 1],\n ],\n [\n [width - 1, 0],\n [width - 1, height - 1],\n ],\n [\n [1, height - 2],\n [width - 1, height - 2],\n ],\n [\n [0, height - 1],\n [width - 1, height - 1],\n ],\n ] as [Point, Point][])\n im.line(a, b, t.shadeDark);\n for (let i = 3; i < im.data.length; i += 4) im.data[i] = 255;\n const out = im.scale(l.pixelScale);\n const metadata: GraphMetadata = {\n version: VERSION,\n imageSize: [out.width, out.height],\n logicalSize: [width, height],\n plotBox: [left, top, right, bottom],\n pixelScale: l.pixelScale,\n title: c.title,\n verticalLabel: c.verticalLabel,\n watermark: c.watermark,\n timeRange: [start, end],\n timezone: c.timeAxis.timezone,\n timeMode: xs.mode,\n yRange: [ys.minimum, ys.maximum],\n yStep: ys.step,\n yUnit: { factor: ys.factor, suffix: ys.suffix },\n xLabels,\n statistics: stats,\n statisticsPolicy:\n \"inclusive viewport; original sample arithmetic mean; current includes final missing sample\",\n font: {\n mode: c.fonts.mode,\n family: c.fonts.mode === \"system\" ? c.fonts.family : null,\n pixelAlphabet: c.fonts.mode === \"bitmap\" ? \"ascii-5x7-v1\" : null,\n },\n layout: clone(l),\n theme: clone(t),\n warnings:\n c.fonts.mode === \"system\"\n ? [\"System font selection and glyph rasterization depend on the host.\"]\n : [],\n };\n return new RenderResult(out, metadata);\n}\n// Dependency-free PNG encoder: adaptive row filters + deterministic fixed-Huffman DEFLATE.\n// No Canvas encoder or compression library is involved in exported PNG bytes.\nconst CRC_TABLE = (() => {\n const t = new Uint32Array(256);\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let j = 0; j < 8; j++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n t[i] = c >>> 0;\n }\n return t;\n})();\nfunction crc32(bytes: Uint8Array): number {\n let c = 0xffffffff;\n for (const b of bytes) c = CRC_TABLE[(c ^ b) & 255] ^ (c >>> 8);\n return (c ^ 0xffffffff) >>> 0;\n}\nfunction adler32(bytes: Uint8Array): number {\n let a = 1,\n b = 0;\n for (let i = 0; i < bytes.length;) {\n const end = Math.min(i + 5552, bytes.length);\n for (; i < end; i++) {\n a += bytes[i];\n b += a;\n }\n a %= 65521;\n b %= 65521;\n }\n return ((b << 16) | a) >>> 0;\n}\nfunction concat(parts: readonly Uint8Array[]): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));\n let at = 0;\n for (const p of parts) {\n out.set(p, at);\n at += p.length;\n }\n return out;\n}\nfunction u32(n: number): Uint8Array<ArrayBuffer> {\n return new Uint8Array([\n (n >>> 24) & 255,\n (n >>> 16) & 255,\n (n >>> 8) & 255,\n n & 255,\n ]);\n}\nfunction chunk(type: string, data: Uint8Array): Uint8Array<ArrayBuffer> {\n const code = Uint8Array.from(type, (c) => c.charCodeAt(0)),\n body = concat([code, data]);\n return concat([u32(data.length), body, u32(crc32(body))]);\n}\nfunction reverseBits(n: number, bits: number): number {\n let out = 0;\n for (let i = 0; i < bits; i++) {\n out = (out << 1) | (n & 1);\n n >>>= 1;\n }\n return out;\n}\nconst FIXED = (() => {\n const out = [];\n for (let i = 0; i < 288; i++) {\n let code, bits;\n if (i <= 143) {\n bits = 8;\n code = 0x30 + i;\n } else if (i <= 255) {\n bits = 9;\n code = 0x190 + i - 144;\n } else if (i <= 279) {\n bits = 7;\n code = i - 256;\n } else {\n bits = 8;\n code = 0xc0 + i - 280;\n }\n out.push([reverseBits(code, bits), bits]);\n }\n return out;\n})();\nconst LEN_BASE = [\n 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67,\n 83, 99, 115, 131, 163, 195, 227, 258,\n];\nconst LEN_EXTRA = [\n 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,\n 5, 5, 0,\n];\nconst DIST_BASE = [\n 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769,\n 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577,\n];\nconst DIST_EXTRA = [\n 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11,\n 11, 12, 12, 13, 13,\n];\nfunction deflate(data: Uint8Array): Uint8Array<ArrayBuffer> {\n let bytes = new Uint8Array(Math.max(128, data.length + 64)),\n len = 0,\n buffer = 0,\n count = 0;\n function byte(b: number): void {\n if (len === bytes.length) {\n const next = new Uint8Array(bytes.length * 2);\n next.set(bytes);\n bytes = next;\n }\n bytes[len++] = b;\n }\n function bits(value: number, n: number): void {\n buffer |= value << count;\n count += n;\n while (count >= 8) {\n byte(buffer & 255);\n buffer >>>= 8;\n count -= 8;\n }\n }\n const sym = (v: number): void => bits(FIXED[v][0], FIXED[v][1]);\n byte(0x78);\n byte(0x01);\n bits(3, 3); // final block, fixed Huffman\n const head = new Int32Array(65536).fill(-1),\n prev = new Int32Array(32768).fill(-1);\n const hash = (i: number): number =>\n ((data[i] * 251 + data[i + 1]) * 251 + data[i + 2]) & 65535;\n function insert(i: number): void {\n if (i + 2 >= data.length) return;\n const h = hash(i);\n prev[i & 32767] = head[h];\n head[h] = i;\n }\n for (let i = 0; i < data.length;) {\n let best = 0,\n dist = 0;\n if (i + 2 < data.length) {\n let candidate = head[hash(i)],\n tries = 64;\n const max = Math.min(258, data.length - i);\n while (\n candidate >= 0 &&\n i - candidate <= 32768 &&\n candidate < i &&\n tries--\n ) {\n if (\n data[candidate] === data[i] &&\n data[candidate + best] === data[i + best]\n ) {\n let n = 0;\n while (n < max && data[candidate + n] === data[i + n]) n++;\n if (n > best && n >= 3) {\n best = n;\n dist = i - candidate;\n if (n === max) break;\n }\n }\n const next = prev[candidate & 32767];\n if (next >= candidate) break;\n candidate = next;\n }\n }\n if (best >= 3) {\n let lc = 0;\n while (lc < 28 && LEN_BASE[lc + 1] <= best) lc++;\n sym(257 + lc);\n bits(best - LEN_BASE[lc], LEN_EXTRA[lc]);\n let dc = 0;\n while (dc < 29 && DIST_BASE[dc + 1] <= dist) dc++;\n bits(reverseBits(dc, 5), 5);\n bits(dist - DIST_BASE[dc], DIST_EXTRA[dc]);\n for (let j = 0; j < best; j++) insert(i + j);\n i += best;\n } else {\n sym(data[i]);\n insert(i);\n i++;\n }\n }\n sym(256);\n if (count) byte(buffer & 255);\n const sum = adler32(data);\n for (const b of u32(sum)) byte(b);\n return bytes.slice(0, len);\n}\nfunction paeth(a: number, b: number, c: number): number {\n const p = a + b - c,\n pa = Math.abs(p - a),\n pb = Math.abs(p - b),\n pc = Math.abs(p - c);\n return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;\n}\n/** Encode RGBA pixels as PNG with optional uncompressed UTF-8 chart metadata. */\nexport function encodePNG(\n image: RGBAImage,\n metadata: object | null = null,\n): Uint8Array<ArrayBuffer> {\n validateImage(image);\n check(\n image.width * image.height <= LIMITS.pixels,\n \"PNG image exceeds output limit.\",\n );\n const w = image.width,\n h = image.height,\n stride = w * 4,\n raw = new Uint8Array((stride + 1) * h),\n candidates = Array.from({ length: 5 }, () => new Uint8Array(stride));\n for (let y = 0; y < h; y++) {\n const scores = [0, 0, 0, 0, 0],\n off = y * stride;\n for (let x = 0; x < stride; x++) {\n const v = image.data[off + x],\n a = x >= 4 ? image.data[off + x - 4] : 0,\n b = y ? image.data[off + x - stride] : 0,\n c = y && x >= 4 ? image.data[off + x - stride - 4] : 0,\n predict = [0, a, b, Math.floor((a + b) / 2), paeth(a, b, c)];\n for (let f = 0; f < 5; f++) {\n const n = (v - predict[f]) & 255;\n candidates[f][x] = n;\n scores[f] += Math.min(n, 256 - n);\n }\n }\n let best = 0;\n for (let f = 1; f < 5; f++) if (scores[f] < scores[best]) best = f;\n raw[y * (stride + 1)] = best;\n raw.set(candidates[best], y * (stride + 1) + 1);\n }\n const ihdr = concat([u32(w), u32(h), new Uint8Array([8, 6, 0, 0, 0])]),\n parts = [\n new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]),\n chunk(\"IHDR\", ihdr),\n chunk(\"sRGB\", new Uint8Array([0])),\n ];\n if (metadata !== null) {\n const json = JSON.stringify(metadata);\n check(json.length <= 1048576, \"PNG metadata is too large.\");\n parts.push(\n chunk(\n \"iTXt\",\n concat([\n new TextEncoder().encode(\"chart\"),\n new Uint8Array([0, 0, 0, 0, 0]),\n new TextEncoder().encode(json),\n ]),\n ),\n );\n }\n parts.push(chunk(\"IDAT\", deflate(raw)), chunk(\"IEND\", new Uint8Array(0)));\n return concat(parts);\n}\nfunction validateImage(im: RGBAImage): void {\n check(\n im &&\n Number.isInteger(im.width) &&\n Number.isInteger(im.height) &&\n im.width > 0 &&\n im.height > 0 &&\n im.width * im.height <= LIMITS.layerPixels &&\n im.data &&\n im.data.length === im.width * im.height * 4,\n \"Expected an RGBA image with matching dimensions.\",\n );\n}\n/** Draw image bytes without browser resampling and return the target canvas. */\nexport function drawImageToCanvas(image: RGBAImage, canvas: Canvas): Canvas {\n validateImage(image);\n check(\n canvas && typeof canvas.getContext === \"function\",\n \"Expected a canvas element.\",\n );\n const ctx = canvas.getContext(\"2d\") as Context2D | null;\n check(ctx, \"Canvas 2D context is unavailable.\");\n canvas.width = image.width;\n canvas.height = image.height;\n const data = ctx.createImageData(image.width, image.height);\n data.data.set(image.data);\n ctx.putImageData(data, 0, 0);\n return canvas;\n}\n/** Download bytes in a browser; filenames may not contain path separators. */\nexport function downloadBytes(\n bytes: Uint8Array,\n name: string,\n type: string = \"application/octet-stream\",\n): void {\n check(\n typeof document !== \"undefined\",\n \"Downloads require a browser document.\",\n );\n text(name, \"Filename\");\n check(\n !/[\\\\/\\x00-\\x1f]/.test(name),\n \"Filename must not contain path separators or controls.\",\n );\n const data =\n bytes.buffer instanceof ArrayBuffer\n ? (bytes as Uint8Array<ArrayBuffer>)\n : new Uint8Array(bytes);\n const blob = new Blob([data], { type }),\n url = URL.createObjectURL(blob),\n a = document.createElement(\"a\");\n a.href = url;\n a.download = name;\n a.hidden = true;\n document.body.appendChild(a);\n a.click();\n a.remove();\n setTimeout(() => URL.revokeObjectURL(url), 30000);\n}\n/** Rendered pixels and a frozen manifest; PNG encoding never requires Canvas. */\nexport class RenderResult<M extends object = GraphMetadata> {\n /** Pixels intentionally remain mutable; exports observe subsequent edits. */\n readonly image: RGBAImage;\n /** Immutable metadata captured at rendering time. */\n readonly metadata: Readonly<M>;\n constructor(image: RGBAImage, metadata: M) {\n this.image = image;\n this.metadata = freeze(metadata);\n }\n get width(): number {\n return this.image.width;\n }\n get height(): number {\n return this.image.height;\n }\n get data(): RGBAImage[\"data\"] {\n return this.image.data;\n }\n draw(canvas: Canvas): Canvas {\n return drawImageToCanvas(this.image, canvas);\n }\n toPNG(options: PNGOptions = {}): Uint8Array<ArrayBuffer> {\n return encodePNG(\n this.image,\n options.metadata === false ? null : this.metadata,\n );\n }\n toBlob(options: PNGOptions = {}): Blob {\n return new Blob([this.toPNG(options)], { type: \"image/png\" });\n }\n download(filename: string = \"chart.png\", options: PNGOptions = {}): void {\n downloadBytes(this.toPNG(options), filename, \"image/png\");\n }\n}\n/** An immutable validated chart. Use with() to derive a changed chart. */\nexport class Chart {\n /** Fully normalized, deeply frozen options used by every render. */\n readonly config: DeepReadonly<ResolvedChartOptions>;\n constructor(options: ChartOptions = {}) {\n this.config = normalize(options);\n Object.freeze(this);\n }\n with(patch: ChartOptions): Chart {\n return new Chart(merge(this.config, patch));\n }\n render(): RenderResult {\n return renderChart(this.config);\n }\n draw(canvas: Canvas): RenderResult {\n const r = this.render();\n r.draw(canvas);\n return r;\n }\n toPNG(options: PNGOptions = {}): Uint8Array<ArrayBuffer> {\n return this.render().toPNG(options);\n }\n mount(canvas: HTMLCanvasElement, options: MountOptions = {}): Controller {\n return new BrowserController(this, canvas, options);\n }\n nearest(input: Timestamp): NearestSample[] {\n const time = epoch(input);\n const [start, end] = timeRange(this.config);\n return this.config.series.map((s) => {\n const lo = lowerBound(s.timestamps, start),\n hi = upperBound(s.timestamps, end);\n if (lo === hi)\n return { name: s.name, index: null, time: null, value: null };\n let i = clamp(lowerBound(s.timestamps, time), lo, hi - 1);\n if (\n i > lo &&\n Math.abs(s.timestamps[i - 1] - time) <= Math.abs(s.timestamps[i] - time)\n )\n i--;\n return {\n name: s.name,\n index: i,\n time: s.timestamps[i],\n value: finite(s.values[i]) ? s.values[i] : null,\n };\n });\n }\n}\n/** Build the conventional inbound area and outbound line without unit conversion. */\nexport function traffic(\n timestamps: ArrayLike<Timestamp>,\n inbound: Values,\n outbound: Values,\n options: TrafficOptions = {},\n): Chart {\n const gap = options.gapAfter === undefined ? 0 : options.gapAfter,\n opts = { ...options };\n delete opts.gapAfter;\n return new Chart(\n merge(\n {\n title: \"Traffic - ether1\",\n verticalLabel: \"bits per second\",\n series: [\n series(\"Inbound\", timestamps, inbound, {\n kind: \"area\",\n color: \"#00cc00\",\n outline: \"#003000\",\n gapAfter: gap,\n }),\n series(\"Outbound\", timestamps, outbound, {\n kind: \"line\",\n color: \"#0000cc\",\n gapAfter: gap,\n }),\n ],\n },\n opts,\n ),\n );\n}\n/** Compose native chart renders and optional captions at a shared pixel scale. */\nexport function dashboard(\n panels: readonly (DashboardPanel | Chart)[],\n options: DashboardOptions = {},\n): RenderResult<DashboardMetadata> {\n check(\n Array.isArray(panels) && panels.length > 0 && panels.length <= 128,\n \"Dashboard requires 1..128 panels.\",\n );\n const o = merge<Required<DashboardOptions>>(\n { gap: 24, padding: [4, 3, 6, 6], background: \"#f3f3f3\", cropHeight: null },\n options,\n );\n integer(o.gap, \"Panel gap\", 0, 4096);\n check(\n Array.isArray(o.padding) && o.padding.length === 4,\n \"Padding is [left, top, right, bottom].\",\n );\n o.padding.forEach((v) => integer(v, \"Padding\", 0, 4096));\n if (o.cropHeight !== null) integer(o.cropHeight, \"Crop height\", 1, 65536);\n const pp = panels.map((p) =>\n p instanceof Chart ? { chart: p, caption: \"\" } : p,\n );\n for (const p of pp) {\n check(p.chart instanceof Chart, \"Panel needs a Chart.\");\n text(p.caption || \"\", \"Caption\");\n }\n const scale = pp[0].chart.config.layout.pixelScale;\n check(\n pp.every((p) => p.chart.config.layout.pixelScale === scale),\n \"Dashboard panels must have equal pixelScale.\",\n );\n const rendered = pp.map((p) => p.chart.render()),\n left = o.padding[0] * scale,\n top = o.padding[1] * scale,\n gap = o.gap * scale;\n const width =\n Math.max(...rendered.map((r) => r.width)) +\n (o.padding[0] + o.padding[2]) * scale;\n let height =\n rendered.reduce((n, r) => n + r.height, 0) +\n (o.padding[1] + o.padding[3]) * scale +\n gap * (pp.length - 1 + (pp[pp.length - 1].caption ? 1 : 0));\n if (o.cropHeight !== null) height = Math.min(height, o.cropHeight * scale);\n check(width * height <= LIMITS.pixels, \"Dashboard is too large.\");\n const out = new Surface(width, height, color(o.background));\n let y = top;\n const meta: DashboardMetadata[\"panels\"] = [];\n for (let i = 0; i < pp.length; i++) {\n const r = rendered[i],\n p = pp[i];\n out.over(r.image, left, y);\n meta.push({\n position: [left, y],\n caption: p.caption || \"\",\n chart: r.metadata,\n });\n y += r.height;\n if (p.caption) {\n const f = new Fonts(p.chart.config.fonts, p.chart.config.theme),\n w = f.width(p.caption, \"caption\"),\n h = p.chart.config.theme.captionSize;\n check(\n w <= width / scale - 8 && h + 4 <= o.gap,\n \"Caption does not fit the dashboard gap.\",\n );\n const line = new Surface(width / scale, o.gap);\n f.draw(\n line,\n width / scale / 2,\n 4,\n p.caption,\n \"caption\",\n p.chart.config.theme.text,\n 0,\n \"center\",\n );\n out.over(line.scale(scale), 0, y);\n }\n y += gap;\n }\n return new RenderResult<DashboardMetadata>(out, {\n version: VERSION,\n imageSize: [width, height],\n pixelScale: scale,\n panels: meta,\n });\n}\n/** Compute right-endpoint rates with exact BigInt counter subtraction. */\nexport function counterRate(\n timestamps: ArrayLike<Timestamp>,\n counters: ArrayLike<number | bigint | null | undefined>,\n options: CounterOptions = {},\n): Samples {\n const o = merge<Required<CounterOptions>>(\n { factor: 1, onDecrease: \"gap\", counterBits: null, maxRate: null },\n options,\n );\n number(o.factor, \"Rate factor\", Number.MIN_VALUE);\n check(\n [\"gap\", \"wrap\"].includes(o.onDecrease),\n \"Decrease policy must be gap or wrap.\",\n );\n if (o.counterBits !== null) integer(o.counterBits, \"Counter bits\", 1, 128);\n if (o.maxRate !== null) number(o.maxRate, \"Maximum rate\", 0);\n check(\n o.onDecrease !== \"wrap\" || o.counterBits !== null,\n \"Wrapping requires an explicit counterBits.\",\n );\n check(\n (Array.isArray(counters) || ArrayBuffer.isView(counters)) &&\n counters.length === timestamps.length,\n \"Counter and timestamp lengths must match.\",\n );\n const s = samples(\n timestamps,\n Array.from(counters, () => 0),\n ),\n max = (1n << BigInt(o.counterBits || 128)) - 1n;\n const cs = Array.from(counters, (v, i) => {\n if (missing(v)) return null;\n if (typeof v === \"number\") {\n check(\n Number.isSafeInteger(v) && v >= 0,\n \"Counter \" +\n i +\n \" must be a safe nonnegative integer; use BigInt for large counters.\",\n );\n v = BigInt(v);\n }\n check(\n typeof v === \"bigint\" && v >= 0n && v <= max,\n \"Counter must fit the configured unsigned bit width.\",\n );\n return v;\n });\n s.values.fill(NaN);\n for (let i = 1; i < cs.length; i++) {\n const current = cs[i],\n previous = cs[i - 1];\n if (current === null || previous === null) continue;\n let d = current - previous;\n if (d < 0n) {\n if (o.onDecrease === \"gap\") continue;\n d += max + 1n;\n }\n const v = (Number(d) * o.factor) / (s.timestamps[i] - s.timestamps[i - 1]);\n check(finite(v), \"Counter rate overflow.\");\n if (o.maxRate === null || v <= o.maxRate) s.values[i] = v;\n }\n return s;\n}\n/** Aggregate elapsed-time buckets, preserving gaps and explicit coverage policy. */\nexport function aggregate(\n timestamps: ArrayLike<Timestamp>,\n values: Values,\n options: AggregateOptions = {},\n): Samples {\n const o = merge<Required<AggregateOptions>>(\n {\n interval: 300,\n method: \"mean\",\n origin: 0,\n minCoverage: 0,\n expectedStep: null,\n maxBuckets: 1000000,\n },\n options,\n );\n number(o.interval, \"Aggregation interval\", 0.001);\n number(o.origin, \"Aggregation origin\");\n number(o.minCoverage, \"Minimum coverage\", 0, 1);\n if (o.expectedStep !== null)\n number(o.expectedStep, \"Expected step\", Number.MIN_VALUE);\n integer(o.maxBuckets, \"Maximum buckets\", 1, 1000000);\n check(\n [\"mean\", \"min\", \"max\", \"last\", \"sum\"].includes(o.method),\n \"Unknown aggregation method.\",\n );\n const s = samples(timestamps, values);\n if (!s.timestamps.length) return s;\n const bucket = (t: number): number => Math.floor((t - o.origin) / o.interval),\n a = bucket(s.timestamps[0]),\n b = bucket(s.timestamps[s.timestamps.length - 1]);\n check(\n Number.isSafeInteger(a) &&\n Number.isSafeInteger(b) &&\n b - a + 1 <= o.maxBuckets,\n \"Aggregation bucket limit or precision exceeded.\",\n );\n const out: Samples = { timestamps: [], values: [] };\n let i = 0;\n for (let k = a; k <= b; k++) {\n const ts = o.origin + k * o.interval;\n epoch(ts);\n out.timestamps.push(ts);\n let total = 0,\n last = NaN,\n mn = Infinity,\n mx = -Infinity;\n const finiteValues = [];\n while (i < s.timestamps.length && bucket(s.timestamps[i]) === k) {\n const v = s.values[i++];\n total++;\n last = v;\n if (finite(v)) {\n finiteValues.push(v);\n mn = Math.min(mn, v);\n mx = Math.max(mx, v);\n }\n }\n const denominator = Math.max(\n total,\n o.expectedStep === null ? 0 : o.interval / o.expectedStep,\n );\n if (\n !finiteValues.length ||\n finiteValues.length / denominator < o.minCoverage\n ) {\n out.values.push(NaN);\n continue;\n }\n let value;\n if (o.method === \"mean\") value = stableMean(finiteValues)!;\n else if (o.method === \"min\") value = mn;\n else if (o.method === \"max\") value = mx;\n else if (o.method === \"last\") value = last;\n else {\n value = stableMean(finiteValues)! * finiteValues.length;\n check(finite(value), \"Aggregation sum overflow.\");\n }\n out.values.push(value);\n }\n return out;\n}\n/** Parse quoted CSV into validated series; timestamps must strictly increase. */\nexport function parseCSV(input: string, options: CSVOptions = {}): Series[] {\n const o = merge<Required<CSVOptions>>(\n {\n timestampColumn: \"timestamp\",\n columns: [\n {\n column: \"inbound\",\n name: \"Inbound\",\n kind: \"area\",\n color: \"#00cc00\",\n outline: \"#003000\",\n },\n {\n column: \"outbound\",\n name: \"Outbound\",\n kind: \"line\",\n color: \"#0000cc\",\n },\n ],\n maxRows: 1000000,\n maxBytes: 16777216,\n },\n options,\n );\n check(typeof input === \"string\", \"CSV must be a string.\");\n integer(o.maxRows, \"Maximum CSV rows\", 1, 2000000);\n integer(o.maxBytes, \"Maximum CSV bytes\", 1, 67108864);\n check(\n input.length <= o.maxBytes &&\n new TextEncoder().encode(input).length <= o.maxBytes,\n \"CSV exceeds the configured byte limit.\",\n );\n check(\n Array.isArray(o.columns) && o.columns.length > 0 && o.columns.length <= 128,\n \"CSV needs at least one column mapping.\",\n );\n if (input.charCodeAt(0) === 0xfeff) input = input.slice(1);\n const rows: string[][] = [];\n let row: string[] = [],\n cell = \"\",\n quoted = false,\n closed = false;\n function endCell(): void {\n row.push(cell);\n cell = \"\";\n closed = false;\n }\n function endRow(): void {\n endCell();\n if (row.some((v) => v !== \"\")) rows.push(row);\n row = [];\n check(rows.length <= o.maxRows + 1, \"CSV row limit exceeded.\");\n }\n for (let i = 0; i < input.length; i++) {\n const ch = input[i];\n if (quoted) {\n if (ch === '\"') {\n if (input[i + 1] === '\"') {\n cell += '\"';\n i++;\n } else {\n quoted = false;\n closed = true;\n }\n } else cell += ch;\n continue;\n }\n if (closed) {\n check(\n ch === \",\" || ch === \"\\r\" || ch === \"\\n\",\n \"Unexpected text after a closing CSV quote.\",\n );\n }\n if (ch === '\"') {\n check(\n cell === \"\" && !closed,\n \"Unexpected quote in an unquoted CSV field.\",\n );\n quoted = true;\n } else if (ch === \",\") endCell();\n else if (ch === \"\\n\" || ch === \"\\r\") {\n if (ch === \"\\r\" && input[i + 1] === \"\\n\") i++;\n endRow();\n } else cell += ch;\n }\n check(!quoted, \"Unterminated quoted CSV field.\");\n if (cell !== \"\" || row.length || closed) endRow();\n check(rows.length >= 1, \"CSV header is missing.\");\n const header = rows.shift()!.map((v) => v.trim());\n check(\n header.every(Boolean) && new Set(header).size === header.length,\n \"CSV headers must be nonempty and unique.\",\n );\n const ti = header.indexOf(o.timestampColumn);\n check(ti >= 0, \"Timestamp column not found: \" + o.timestampColumn);\n const ids = o.columns.map((v) => {\n const i = header.indexOf(v.column);\n check(i >= 0, \"Column not found: \" + v.column);\n return i;\n });\n const ts: number[] = [],\n vv: number[][] = o.columns.map(() => []);\n for (let i = 0; i < rows.length; i++) {\n const r = rows[i];\n check(\n r.length === header.length,\n \"CSV row \" + (i + 2) + \" has the wrong number of columns.\",\n );\n try {\n ts.push(epoch(r[ti]));\n } catch (e) {\n throw new RangeError(\n \"CSV row \" +\n (i + 2) +\n \": \" +\n (e instanceof Error ? e.message : String(e)),\n );\n }\n ids.forEach((id, j) => {\n const v = r[id].trim();\n if (/^(?:nan|none|null)?$/i.test(v)) {\n vv[j].push(NaN);\n return;\n }\n check(\n /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?$/i.test(v),\n \"Invalid numeric CSV value at row \" + (i + 2) + \".\",\n );\n vv[j].push(number(Number(v), \"CSV value\"));\n });\n }\n return o.columns.map((v, j) => series(v.name || v.column, ts, vv[j], v));\n}\n/** Export the union of series timestamps, escaping formula-like text headers. */\nexport function toCSV(\n list: readonly SeriesInput[],\n options: { escapeFormulas?: boolean } = {},\n): string {\n check(\n Array.isArray(list) && list.length <= 128,\n \"Expected an array of series.\",\n );\n const escaped = options.escapeFormulas !== false;\n const ss = list.map((s) => series(s.name, s.timestamps, s.values, s));\n let total = 0;\n for (const s of ss) total += s.timestamps.length;\n check(\n total <= LIMITS.samples,\n \"CSV export exceeds the combined sample limit.\",\n );\n const times = [...new Set(ss.flatMap((s) => s.timestamps))].sort(\n (a, b) => a - b,\n );\n check(\n new Set(ss.map((s) => s.name)).size === ss.length &&\n !ss.some((s) => s.name === \"timestamp\"),\n \"CSV series names must be unique and not timestamp.\",\n );\n const quote = (v: string): string => {\n v = String(v);\n if (escaped && /^[=+\\-@\\t\\r]/.test(v)) v = \"'\" + v;\n return /[,\"\\r\\n]/.test(v) ? '\"' + v.replace(/\"/g, '\"\"') + '\"' : v;\n };\n const lines = [[\"timestamp\", ...ss.map((s) => s.name)].map(quote).join(\",\")],\n indexes = ss.map(() => 0);\n for (const t of times) {\n const cells = [String(t)];\n ss.forEach((s, j) => {\n while (indexes[j] < s.timestamps.length && s.timestamps[indexes[j]] < t)\n indexes[j]++;\n const i = indexes[j];\n cells.push(\n i < s.timestamps.length && s.timestamps[i] === t && finite(s.values[i])\n ? String(s.values[i])\n : \"\",\n );\n });\n lines.push(cells.join(\",\"));\n }\n return lines.join(\"\\r\\n\") + \"\\r\\n\";\n}\n/** Compare RGB pixels without aligning or resizing; alpha is ignored. */\nexport function compareImages(\n reference: RGBAImage | RenderResult<object>,\n actual: RGBAImage | RenderResult<object>,\n options: CompareOptions = {},\n): PixelDifference {\n const a = reference instanceof RenderResult ? reference.image : reference,\n b = actual instanceof RenderResult ? actual.image : actual;\n validateImage(a);\n validateImage(b);\n check(\n a.width === b.width && a.height === b.height,\n \"Image sizes must match; comparison never aligns or resizes.\",\n );\n const tolerance = options.tolerance === undefined ? 0 : options.tolerance;\n integer(tolerance, \"Tolerance\", 0, 255);\n const box = options.box || [0, 0, a.width, a.height];\n check(\n Array.isArray(box) && box.length === 4,\n \"Comparison box needs four coordinates.\",\n );\n box.forEach((v) => integer(v, \"Comparison coordinate\", 0, 65536));\n const [x0, y0, x1, y1] = box;\n check(\n x1 > x0 && y1 > y0 && x1 <= a.width && y1 <= a.height,\n \"Comparison box is out of bounds.\",\n );\n let exact = 0,\n within = 0,\n sum = 0,\n square = 0,\n maxError = 0,\n loX = Infinity,\n loY = Infinity,\n hiX = -Infinity,\n hiY = -Infinity;\n for (let y = y0; y < y1; y++)\n for (let x = x0; x < x1; x++) {\n const i = (y * a.width + x) * 4;\n let err = 0;\n for (let k = 0; k < 3; k++) {\n const d = Math.abs(a.data[i + k] - b.data[i + k]);\n sum += d;\n square += d * d;\n err = Math.max(err, d);\n }\n maxError = Math.max(maxError, err);\n if (err === 0) exact++;\n else {\n loX = Math.min(loX, x - x0);\n loY = Math.min(loY, y - y0);\n hiX = Math.max(hiX, x - x0);\n hiY = Math.max(hiY, y - y0);\n }\n if (err <= tolerance) within++;\n }\n const count = (x1 - x0) * (y1 - y0);\n return {\n pixels: count,\n exactPixels: exact,\n exactRatio: exact / count,\n toleranceRatio: within / count,\n meanAbsoluteError: sum / (count * 3),\n rootMeanSquareError: Math.sqrt(square / (count * 3)),\n maxError,\n differenceBox: loX === Infinity ? null : [loX, loY, hiX + 1, hiY + 1],\n };\n}\n/** Visualize amplified absolute RGB differences in matching images. */\nexport function differenceImage(\n reference: RGBAImage | RenderResult<object>,\n actual: RGBAImage | RenderResult<object>,\n amplify: number = 4,\n): RenderResult<{ imageSize: [number, number]; amplify: number }> {\n number(amplify, \"Difference amplification\", 0, 255);\n const a = reference instanceof RenderResult ? reference.image : reference,\n b = actual instanceof RenderResult ? actual.image : actual;\n compareImages(a, b);\n const out = new Surface(a.width, a.height);\n for (let i = 0; i < a.data.length; i += 4) {\n for (let k = 0; k < 3; k++)\n out.data[i + k] = Math.min(\n 255,\n round(Math.abs(a.data[i + k] - b.data[i + k]) * amplify),\n );\n out.data[i + 3] = 255;\n }\n return new RenderResult(out, { imageSize: [out.width, out.height], amplify });\n}\n/** Copy Canvas2D pixels into independently owned RGBA storage. */\nexport function readCanvas(canvas: Canvas): RGBAImage {\n check(\n canvas && typeof canvas.getContext === \"function\",\n \"Expected a canvas.\",\n );\n const c = canvas.getContext(\"2d\") as Context2D | null;\n check(c, \"Canvas 2D is unavailable.\");\n const data = c.getImageData(0, 0, canvas.width, canvas.height);\n const out = new Surface(data.width, data.height);\n out.data.set(data.data);\n return out;\n}\n/** Check PNG dimensions and decode with the browser image decoder. */\nexport async function decodeImage(blob: Blob): Promise<RGBAImage> {\n check(\n typeof Blob !== \"undefined\" && blob instanceof Blob,\n \"decodeImage expects a Blob or File.\",\n );\n check(blob.size <= 67108864, \"Image file exceeds 64 MiB.\");\n // Header dimensions are checked before a PNG is passed to the browser decoder.\n const head = new Uint8Array(await blob.slice(0, 24).arrayBuffer());\n check(\n head.length >= 24 &&\n [137, 80, 78, 71, 13, 10, 26, 10].every((v, i) => head[i] === v) &&\n head[12] === 73 &&\n head[13] === 72 &&\n head[14] === 68 &&\n head[15] === 82,\n \"decodeImage accepts PNG files only.\",\n );\n const headerView = new DataView(head.buffer),\n width = headerView.getUint32(16),\n height = headerView.getUint32(20);\n check(\n width > 0 && height > 0 && width * height <= LIMITS.pixels,\n \"Decoded PNG exceeds the pixel limit.\",\n );\n check(\n typeof createImageBitmap === \"function\",\n \"This browser does not expose createImageBitmap.\",\n );\n const bitmap = await createImageBitmap(blob);\n try {\n check(\n bitmap.width * bitmap.height <= LIMITS.pixels,\n \"Decoded image exceeds the pixel limit.\",\n );\n const canvas = createCanvas(bitmap.width, bitmap.height);\n const ctx = canvas.getContext(\"2d\") as Context2D | null;\n check(ctx, \"Canvas 2D is unavailable.\");\n ctx.drawImage(bitmap, 0, 0);\n return readCanvas(canvas);\n } finally {\n bitmap.close();\n }\n}\n// Browser controller. Cursor and tooltip live on an overlay, never in exported pixels.\nclass BrowserController implements Controller {\n chart: Chart;\n readonly canvas: MountedCanvas;\n readonly options: MountOptions & { interactive: boolean };\n destroyed: boolean;\n result: RenderResult;\n private readonly handlers: [HTMLCanvasElement, string, EventListener][];\n private cursorTime: number | null;\n private readonly saved: {\n style: string | null;\n role: string | null;\n label: string | null;\n tab: string | null;\n };\n private readonly marker: Comment;\n private readonly wrap: HTMLSpanElement;\n private readonly overlay: HTMLCanvasElement;\n private readonly tip: HTMLDivElement;\n private readonly status: HTMLSpanElement;\n constructor(chart: Chart, canvas: MountedCanvas, options: MountOptions = {}) {\n check(\n typeof document !== \"undefined\" && canvas && canvas.ownerDocument,\n \"mount requires an HTML canvas in a document.\",\n );\n check(canvas.parentNode, \"Attach the canvas to the document before mount.\");\n check(\n !canvas.__bamtiGraphController,\n \"A controller is already mounted on this canvas.\",\n );\n this.chart = chart;\n this.canvas = canvas;\n this.options = { interactive: true, ...options };\n this.destroyed = false;\n this.handlers = [];\n this.cursorTime = null;\n this.result = chart.render();\n this.saved = {\n style: canvas.getAttribute(\"style\"),\n role: canvas.getAttribute(\"role\"),\n label: canvas.getAttribute(\"aria-label\"),\n tab: canvas.getAttribute(\"tabindex\"),\n };\n this.marker = document.createComment(\"canvas position\");\n canvas.parentNode.insertBefore(this.marker, canvas);\n this.wrap = document.createElement(\"span\");\n this.wrap.style.cssText =\n \"position:relative;display:inline-block;vertical-align:top;line-height:0;max-width:none;\";\n canvas.parentNode.insertBefore(this.wrap, canvas);\n this.wrap.appendChild(canvas);\n canvas.style.display = \"block\";\n canvas.style.maxWidth = \"none\";\n canvas.setAttribute(\"role\", \"img\");\n this.overlay = document.createElement(\"canvas\");\n this.overlay.setAttribute(\"aria-hidden\", \"true\");\n this.overlay.style.cssText =\n \"position:absolute;left:0;top:0;pointer-events:none;\";\n this.wrap.appendChild(this.overlay);\n this.tip = document.createElement(\"div\");\n this.tip.hidden = true;\n this.tip.setAttribute(\"role\", \"status\");\n this.tip.style.cssText =\n \"position:absolute;z-index:5;pointer-events:none;background:#111827;color:#fff;border:1px solid #4b5563;padding:9px 11px;border-radius:5px;font:11px/1.65 ui-monospace,monospace;white-space:pre;box-shadow:0 4px 18px #0003;text-align:left;\";\n this.wrap.appendChild(this.tip);\n this.status = document.createElement(\"span\");\n this.status.setAttribute(\"aria-live\", \"polite\");\n this.status.style.cssText =\n \"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;\";\n this.wrap.appendChild(this.status);\n this.apply(this.result);\n canvas.__bamtiGraphController = this;\n if (this.options.interactive) {\n canvas.tabIndex = 0;\n this.on(canvas, \"pointermove\", (e) => {\n const rect = canvas.getBoundingClientRect(),\n x = ((e.clientX - rect.left) * canvas.width) / rect.width,\n y = ((e.clientY - rect.top) * canvas.height) / rect.height,\n m = this.result.metadata,\n s = m.pixelScale,\n [l, t, r, b] = m.plotBox;\n if (x < l * s || x > r * s || y < t * s || y > b * s) {\n this.clear();\n return;\n }\n const time =\n m.timeRange[0] +\n ((x / s - l) / (r - l)) * (m.timeRange[1] - m.timeRange[0]);\n this.show(time, false);\n });\n this.on(canvas, \"pointerleave\", () => this.clear());\n this.on(canvas, \"blur\", () => this.clear());\n this.on(canvas, \"keydown\", (e) => {\n if (\n ![\"ArrowLeft\", \"ArrowRight\", \"Home\", \"End\", \"Escape\"].includes(e.key)\n )\n return;\n e.preventDefault();\n if (e.key === \"Escape\") {\n this.clear();\n return;\n }\n const [a, b] = this.result.metadata.timeRange,\n s = this.chart.config.series.find((s) => s.timestamps.length),\n visible = s\n ? s.timestamps.slice(\n lowerBound(s.timestamps, a),\n upperBound(s.timestamps, b),\n )\n : [];\n let time;\n if (e.key === \"Home\") time = visible[0] === undefined ? a : visible[0];\n else if (e.key === \"End\")\n time = visible.length ? visible[visible.length - 1] : b;\n else if (visible.length) {\n let i =\n this.cursorTime === null\n ? e.key === \"ArrowRight\"\n ? -1\n : visible.length\n : lowerBound(visible, this.cursorTime);\n i = clamp(\n i + (e.key === \"ArrowRight\" ? 1 : -1) * (e.shiftKey ? 10 : 1),\n 0,\n visible.length - 1,\n );\n time = visible[i];\n } else\n time = clamp(\n (this.cursorTime === null ? a : this.cursorTime) +\n ((e.key === \"ArrowRight\" ? 1 : -1) * (b - a)) / 100,\n a,\n b,\n );\n this.show(time, true);\n });\n }\n }\n on<K extends keyof HTMLElementEventMap>(\n target: HTMLCanvasElement,\n type: K,\n fn: (event: HTMLElementEventMap[K]) => void,\n ): void {\n target.addEventListener(type, fn);\n this.handlers.push([target, type, fn as EventListener]);\n }\n apply(r: RenderResult): void {\n this.result = r;\n r.draw(this.canvas);\n this.overlay.width = r.width;\n this.overlay.height = r.height;\n const m = r.metadata;\n this.canvas.setAttribute(\n \"aria-label\",\n this.options.ariaLabel ||\n [\n m.title || \"Time-series chart\",\n m.verticalLabel,\n ...m.statistics.map(\n (s) =>\n s.name +\n \": current \" +\n (s.current === null\n ? \"missing\"\n : formatValue(s.current, m.yUnit, 2)),\n ),\n ].join(\". \"),\n );\n this.wrap.style.width = r.width + \"px\";\n this.wrap.style.height = r.height + \"px\";\n this.clear();\n }\n show(time: number, announce: boolean): void {\n if (this.destroyed) return;\n const m = this.result.metadata,\n s = m.pixelScale,\n [left, top, right, bottom] = m.plotBox,\n ctx = this.overlay.getContext(\"2d\")!,\n x =\n (left +\n ((time - m.timeRange[0]) / (m.timeRange[1] - m.timeRange[0])) *\n (right - left)) *\n s;\n ctx.clearRect(0, 0, this.overlay.width, this.overlay.height);\n ctx.beginPath();\n ctx.strokeStyle = \"#555\";\n ctx.lineWidth = 1;\n ctx.setLineDash([2, 2]);\n ctx.moveTo(round(x) + 0.5, top * s);\n ctx.lineTo(round(x) + 0.5, bottom * s);\n ctx.stroke();\n const nearest = this.chart.nearest(time),\n rows = [\"Nearest samples\"];\n for (const p of nearest)\n rows.push(\n p.name +\n \": \" +\n formatValue(p.value, m.yUnit, 2, this.chart.config.missingLabel) +\n (p.time !== null\n ? \" \" + formatTime(p.time, m.timezone, \"%H:%M:%S\")\n : \" no observation\"),\n );\n this.tip.textContent = rows.join(\"\\n\");\n this.tip.hidden = false;\n this.tip.style.left =\n Math.max(\n 4,\n Math.min(this.result.width - this.tip.offsetWidth - 4, x + 12),\n ) + \"px\";\n this.tip.style.top = top * s + 8 + \"px\";\n this.cursorTime = time;\n if (announce) this.status.textContent = rows.join(\". \");\n if (typeof this.options.onHover === \"function\")\n this.options.onHover({ time, samples: nearest });\n }\n clear(): void {\n if (this.overlay)\n this.overlay\n .getContext(\"2d\")!\n .clearRect(0, 0, this.overlay.width, this.overlay.height);\n if (this.tip) this.tip.hidden = true;\n this.cursorTime = null;\n }\n update(patch: ChartOptions | Chart): RenderResult {\n check(!this.destroyed, \"Controller has been destroyed.\");\n const next = patch instanceof Chart ? patch : this.chart.with(patch),\n result = next.render();\n this.chart = next;\n this.apply(result);\n return result;\n }\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n for (const [el, type, fn] of this.handlers)\n el.removeEventListener(type, fn);\n this.handlers.length = 0;\n if (this.marker.parentNode) {\n this.marker.parentNode.insertBefore(this.canvas, this.marker);\n this.marker.remove();\n } else this.wrap.removeChild(this.canvas);\n this.wrap.remove();\n for (const [key, attr] of [\n [\"style\", \"style\"],\n [\"role\", \"role\"],\n [\"label\", \"aria-label\"],\n [\"tab\", \"tabindex\"],\n ] as const) {\n if (this.saved[key] === null) this.canvas.removeAttribute(attr);\n else this.canvas.setAttribute(attr, this.saved[key]);\n }\n delete this.canvas.__bamtiGraphController;\n }\n}\n\n/** Return a detached copy of every chart default. */\nexport function defaults(): ChartOptions {\n return clone(DEFAULTS);\n}\n/** Render a chart once; bitmap mode does not access browser APIs. */\nexport function render(options: ChartOptions = {}): RenderResult {\n return new Chart(options).render();\n}\n/** Frozen default export, equivalent to the corresponding named exports. */\nexport interface BamtiGraphAPI {\n readonly VERSION: typeof VERSION;\n readonly LIMITS: typeof LIMITS;\n readonly Chart: typeof Chart;\n readonly RenderResult: typeof RenderResult;\n readonly series: typeof series;\n readonly regularSeries: typeof regularSeries;\n readonly traffic: typeof traffic;\n readonly daily: typeof daily;\n readonly weekly: typeof weekly;\n readonly monthly: typeof monthly;\n readonly yearly: typeof yearly;\n readonly dashboard: typeof dashboard;\n readonly counterRate: typeof counterRate;\n readonly aggregate: typeof aggregate;\n readonly parseCSV: typeof parseCSV;\n readonly toCSV: typeof toCSV;\n readonly compareImages: typeof compareImages;\n readonly differenceImage: typeof differenceImage;\n readonly encodePNG: typeof encodePNG;\n readonly decodeImage: typeof decodeImage;\n readonly readCanvas: typeof readCanvas;\n readonly drawImageToCanvas: typeof drawImageToCanvas;\n readonly downloadBytes: typeof downloadBytes;\n readonly formatTime: typeof formatTime;\n readonly formatValue: typeof formatValue;\n readonly epoch: typeof epoch;\n readonly color: typeof color;\n readonly defaults: typeof defaults;\n readonly render: typeof render;\n}\n\n/** The complete BamtiGraph API; importing this module creates no global. */\nconst BamtiGraph: Readonly<BamtiGraphAPI> = Object.freeze({\n VERSION,\n LIMITS,\n Chart,\n RenderResult,\n series,\n regularSeries,\n traffic,\n daily,\n weekly,\n monthly,\n yearly,\n dashboard,\n counterRate,\n aggregate,\n parseCSV,\n toCSV,\n compareImages,\n differenceImage,\n encodePNG,\n decodeImage,\n readCanvas,\n drawImageToCanvas,\n downloadBytes,\n formatTime,\n formatValue,\n epoch,\n color,\n defaults,\n render,\n});\nexport default BamtiGraph;\n"],
4
+ "sourcesContent": ["/*\n * SPDX-License-Identifier: BSD-3-Clause\n * Copyright (c) 2026, GoSuda\n * BamtiGraph TypeScript implementation. See the root LICENSE.\n */\n/** Unix seconds, an explicit Date, or an ISO datetime with a timezone offset. */\nexport type Timestamp = number | Date | string;\n/** RGB or RGBA channels, hexadecimal notation, or a supported named color. */\nexport type Color =\n | string\n | readonly [number, number, number]\n | readonly [number, number, number, number];\nexport type Values = ArrayLike<number | null | undefined>;\n/** Normalized red, green, blue, and alpha bytes. */\nexport type RGBA = [number, number, number, number];\nexport type Interpolation = \"linear\" | \"step-post\";\n/** Mutable preprocessing output, with NaN marking missing samples. */\nexport interface Samples {\n timestamps: number[];\n values: number[];\n}\nexport interface LegendValues {\n current: number | null;\n average: number | null;\n maximum: number | null;\n}\nexport interface SeriesOptions {\n kind?: \"line\" | \"area\";\n color?: Color;\n outline?: Color | null;\n lineWidth?: number;\n baseline?: number;\n interpolation?: Interpolation;\n gapAfter?: number;\n legendValues?: Partial<LegendValues> | null;\n}\nexport interface SeriesInput extends SeriesOptions {\n name: string;\n timestamps: ArrayLike<Timestamp>;\n values: Values;\n}\nexport interface Series extends Readonly<\n Required<Omit<SeriesOptions, \"legendValues\" | \"color\" | \"outline\">>\n> {\n readonly color: Readonly<RGBA>;\n readonly outline: Readonly<RGBA> | null;\n readonly name: string;\n readonly timestamps: readonly number[];\n readonly values: readonly number[];\n readonly legendValues: Readonly<LegendValues> | null;\n}\nexport interface Tick {\n time: Timestamp;\n label: string;\n}\nexport interface TimeAxis {\n start?: Timestamp | null;\n end?: Timestamp | null;\n mode?: \"auto\" | \"daily\" | \"weekly\" | \"monthly\" | \"yearly\" | \"custom\";\n timezone?: string;\n minorSeconds?: number | null;\n majorSeconds?: number | null;\n labelSeconds?: number | null;\n labelFormat?: string | null;\n labelOffsetSeconds?: number;\n ticks?: readonly Tick[] | null;\n minorTicks?: readonly Timestamp[] | null;\n majorTicks?: readonly Timestamp[] | null;\n}\nexport interface YAxis {\n minimum?: number | null;\n maximum?: number | null;\n majorStep?: number | null;\n minorDivisions?: number;\n base?: 1000 | 1024;\n scaleFactor?: number | null;\n suffix?: string | null;\n decimals?: number | null;\n legendDecimals?: number;\n showZeroSuffix?: boolean;\n}\nexport type ColumnAnchors = readonly [\n readonly [number, number],\n readonly [number, number],\n readonly [number, number],\n];\nexport interface LegendLayout {\n nameX?: number;\n swatchX?: number;\n swatchWidth?: number;\n swatchHeight?: number;\n referenceWidth?: number;\n autoScaleColumns?: boolean;\n compact?: ColumnAnchors;\n expanded?: ColumnAnchors;\n aligned?: ColumnAnchors;\n}\nexport interface Layout {\n width?: number;\n plotHeight?: number;\n left?: number;\n right?: number;\n top?: number;\n titleY?: number;\n titleOffsetX?: number;\n unitX?: number;\n xLabelGap?: number;\n yLabelGap?: number;\n legendGap?: number;\n legendRowHeight?: number;\n legendBottom?: number;\n legend?: \"reference\" | \"aligned\" | \"none\";\n legendLayout?: LegendLayout;\n antialias?: number;\n pixelScale?: number;\n}\nexport interface Theme {\n background?: Color;\n canvas?: Color;\n shadeLight?: Color;\n shadeDark?: Color;\n text?: Color;\n minorGrid?: Color;\n majorGrid?: Color;\n axis?: Color;\n arrow?: Color;\n watermark?: Color;\n frame?: Color;\n gridFront?: boolean;\n gridDash?: readonly [number, number];\n titleSize?: number;\n axisSize?: number;\n unitSize?: number;\n legendSize?: number;\n watermarkSize?: number;\n captionSize?: number;\n titleAdvance?: number;\n axisAdvance?: number;\n legendAdvance?: number;\n}\nexport interface FontOptions {\n mode?: \"system\" | \"bitmap\";\n family?: string;\n titleFamily?: string | null;\n unitFamily?: string | null;\n captionFamily?: string | null;\n strictGlyphs?: boolean;\n}\nexport interface RuleStyle {\n color?: Color;\n width?: number;\n dash?: readonly [number, number] | null;\n}\nexport interface HRule extends RuleStyle {\n value: number;\n}\nexport interface VRule extends RuleStyle {\n time: Timestamp;\n}\n/** Immutable chart input. Nested objects merge; arrays replace their defaults. */\nexport interface ChartOptions {\n series?: readonly SeriesInput[];\n title?: string;\n verticalLabel?: string;\n watermark?: string;\n timeAxis?: TimeAxis;\n yAxis?: YAxis;\n layout?: Layout;\n theme?: Theme;\n fonts?: FontOptions;\n legendLabels?: readonly [string, string, string];\n missingLabel?: string;\n hRules?: readonly HRule[];\n vRules?: readonly VRule[];\n}\nexport interface TrafficOptions extends ChartOptions {\n gapAfter?: number;\n}\nexport interface Unit {\n factor: number;\n suffix: string;\n}\nexport interface Statistics {\n name: string;\n current: number | null;\n average: number | null;\n maximum: number | null;\n minimum: number | null;\n count: number;\n missing: number;\n displayOverride: LegendValues | null;\n}\n/** Serializable chart manifest. Missing statistics are null, not NaN. */\nexport interface GraphMetadata {\n version: string;\n imageSize: [number, number];\n logicalSize: [number, number];\n plotBox: [number, number, number, number];\n pixelScale: number;\n title: string;\n verticalLabel: string;\n watermark: string;\n timeRange: [number, number];\n timezone: string;\n timeMode: string;\n yRange: [number, number];\n yStep: number;\n yUnit: Unit;\n xLabels: { time: number; label: string; x: number }[];\n statistics: Statistics[];\n statisticsPolicy: string;\n font: {\n mode: \"system\" | \"bitmap\";\n family: string | null;\n pixelAlphabet: string | null;\n };\n layout: Layout;\n theme: Theme;\n warnings: string[];\n}\n/** Row-major straight-alpha bytes. Pixel storage intentionally remains mutable. */\nexport interface RGBAImage {\n width: number;\n height: number;\n data: Uint8ClampedArray | Uint8Array;\n}\nexport interface PNGOptions {\n metadata?: boolean;\n}\nexport interface NearestSample {\n name: string;\n index: number | null;\n time: number | null;\n value: number | null;\n}\nexport interface MountOptions {\n interactive?: boolean;\n ariaLabel?: string;\n onHover?: (event: { time: number; samples: NearestSample[] }) => void;\n}\n/** Mounted browser lifecycle. Destroy restores the canvas DOM position and attributes. */\nexport interface Controller {\n readonly canvas: HTMLCanvasElement;\n readonly chart: Chart;\n readonly result: RenderResult;\n readonly destroyed: boolean;\n update(patch: ChartOptions | Chart): RenderResult;\n destroy(): void;\n}\nexport interface DashboardOptions {\n gap?: number;\n padding?: readonly [number, number, number, number];\n background?: Color;\n cropHeight?: number | null;\n}\nexport interface DashboardPanel {\n chart: Chart;\n caption?: string;\n}\nexport interface DashboardMetadata {\n version: string;\n imageSize: [number, number];\n pixelScale: number;\n panels: {\n position: [number, number];\n caption: string;\n chart: GraphMetadata;\n }[];\n}\nexport interface CounterOptions {\n factor?: number;\n onDecrease?: \"gap\" | \"wrap\";\n counterBits?: number | null;\n maxRate?: number | null;\n}\nexport interface AggregateOptions {\n interval?: number;\n method?: \"mean\" | \"min\" | \"max\" | \"last\" | \"sum\";\n origin?: number;\n minCoverage?: number;\n expectedStep?: number | null;\n maxBuckets?: number;\n}\nexport interface CSVColumn extends SeriesOptions {\n column: string;\n name?: string;\n}\nexport interface CSVOptions {\n timestampColumn?: string;\n columns?: readonly CSVColumn[];\n maxRows?: number;\n maxBytes?: number;\n}\nexport interface PixelDifference {\n pixels: number;\n exactPixels: number;\n exactRatio: number;\n toleranceRatio: number;\n meanAbsoluteError: number;\n rootMeanSquareError: number;\n maxError: number;\n differenceBox: [number, number, number, number] | null;\n}\nexport interface CompareOptions {\n tolerance?: number;\n box?: readonly [number, number, number, number] | null;\n}\n\n/** All chart fields after default merging and normalization. */\nexport interface ResolvedChartOptions extends Omit<\n Required<ChartOptions>,\n | \"series\"\n | \"timeAxis\"\n | \"yAxis\"\n | \"layout\"\n | \"theme\"\n | \"fonts\"\n | \"hRules\"\n | \"vRules\"\n> {\n series: readonly Series[];\n timeAxis: ResolvedTimeAxis;\n yAxis: Required<YAxis>;\n layout: ResolvedLayout;\n theme: ResolvedTheme;\n fonts: Required<FontOptions>;\n hRules: readonly ResolvedHRule[];\n vRules: readonly ResolvedVRule[];\n}\n/** A calendar axis whose timestamp inputs have been converted to Unix seconds. */\nexport interface ResolvedTimeAxis extends Omit<\n Required<TimeAxis>,\n \"start\" | \"end\" | \"ticks\" | \"minorTicks\" | \"majorTicks\"\n> {\n start: number | null;\n end: number | null;\n ticks: readonly ResolvedTick[] | null;\n minorTicks: readonly number[] | null;\n majorTicks: readonly number[] | null;\n}\n/** A label positioned at a numerical Unix timestamp. */\nexport interface ResolvedTick {\n time: number;\n label: string;\n}\n/** Complete logical-pixel layout including the legend geometry. */\nexport interface ResolvedLayout extends Required<Omit<Layout, \"legendLayout\">> {\n legendLayout: Required<LegendLayout>;\n}\ntype ThemeColorKey =\n | \"background\"\n | \"canvas\"\n | \"shadeLight\"\n | \"shadeDark\"\n | \"text\"\n | \"minorGrid\"\n | \"majorGrid\"\n | \"axis\"\n | \"arrow\"\n | \"watermark\"\n | \"frame\";\n/** Fully specified theme with parsed RGBA colors. */\nexport type ResolvedTheme = Required<Omit<Theme, ThemeColorKey>> & {\n [K in ThemeColorKey]: Readonly<RGBA>;\n};\n/** Normalized horizontal rule in original data units. */\nexport interface ResolvedHRule {\n value: number;\n color: Readonly<RGBA>;\n width: number;\n dash: readonly [number, number] | null;\n}\n/** Normalized vertical rule in Unix seconds. */\nexport interface ResolvedVRule {\n time: number;\n color: Readonly<RGBA>;\n width: number;\n dash: readonly [number, number] | null;\n}\n/** Recursive readonly view of plain chart configuration and metadata. */\nexport type DeepReadonly<T> = T extends object\n ? { readonly [K in keyof T]: DeepReadonly<T[K]> }\n : T;\ntype CompleteChartInput = Omit<\n Required<ChartOptions>,\n \"timeAxis\" | \"yAxis\" | \"layout\" | \"theme\" | \"fonts\"\n> & {\n timeAxis: Required<TimeAxis>;\n yAxis: Required<YAxis>;\n layout: ResolvedLayout;\n theme: Required<Theme>;\n fonts: Required<FontOptions>;\n};\ntype CompleteSeriesInput = Required<Omit<SeriesInput, \"legendValues\">> & {\n legendValues: Partial<LegendValues> | null;\n};\ntype ChartConfig = DeepReadonly<ResolvedChartOptions>;\ntype Point = [number, number];\ntype Canvas = HTMLCanvasElement | OffscreenCanvas;\ntype Context2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\ntype FontRole = \"title\" | \"axis\" | \"unit\" | \"legend\" | \"watermark\" | \"caption\";\ninterface WallParts {\n year: number;\n month: number;\n day: number;\n hour: number;\n minute: number;\n second: number;\n}\ninterface YResolution extends Unit {\n minimum: number;\n maximum: number;\n step: number;\n major: number[];\n minor: number[];\n decimals: number;\n}\ninterface XResolution {\n minor: number[];\n major: number[];\n labels: ResolvedTick[];\n mode: NonNullable<TimeAxis[\"mode\"]>;\n}\ntype MountedCanvas = HTMLCanvasElement & {\n __bamtiGraphController?: BrowserController;\n};\n\n/** BamtiGraph library version. */\nexport const VERSION: string = \"1.1.0\";\n/** Per-operation allocation and enumeration guards. */\nexport const LIMITS: Readonly<{\n pixels: number;\n layerPixels: number;\n ticks: number;\n series: number;\n samples: number;\n text: number;\n}> = Object.freeze({\n pixels: 16000000,\n layerPixels: 40000000,\n ticks: 5000,\n series: 128,\n samples: 2000000,\n text: 4096,\n});\nconst finite = (v: unknown): v is number => Number.isFinite(v);\nconst round = (v: number): number => Math.floor(v + 0.5);\nconst clamp = (v: number, a: number, b: number): number =>\n Math.max(a, Math.min(b, v));\nconst own = (o: object, k: PropertyKey): boolean =>\n Object.prototype.hasOwnProperty.call(o, k);\nconst missing = (v: unknown): boolean =>\n v === null || v === undefined || (typeof v === \"number\" && Number.isNaN(v));\nfunction check(ok: unknown, message: string): asserts ok {\n if (!ok) throw new RangeError(message);\n}\nfunction text(s: unknown, name: string): string {\n check(\n typeof s === \"string\" && s.length <= LIMITS.text && !/[\\r\\n\\u0000]/.test(s),\n name + \" must be a single-line string.\",\n );\n return s;\n}\nfunction number(\n v: unknown,\n name: string,\n lo: number = -Infinity,\n hi: number = Infinity,\n): number {\n check(\n finite(v) && v >= lo && v <= hi,\n name + \" is outside its finite range.\",\n );\n return v;\n}\nfunction integer(v: unknown, name: string, lo: number, hi: number): number {\n check(Number.isInteger(v), name + \" must be an integer.\");\n return number(v, name, lo, hi);\n}\nfunction record(o: unknown): o is Record<string, unknown> {\n return (\n o !== null &&\n typeof o === \"object\" &&\n (Object.getPrototypeOf(o) === Object.prototype ||\n Object.getPrototypeOf(o) === null)\n );\n}\n// Configuration inputs are plain data. Typed views are restored only at this\n// recursive ownership boundary; property values remain unknown while copied.\nfunction clone<T>(v: T): T {\n if (Array.isArray(v) || ArrayBuffer.isView(v))\n return Array.from(v as ArrayLike<unknown>, (value) => clone(value)) as T;\n if (v instanceof Date) return new Date(v.getTime()) as T;\n if (record(v)) {\n const r: Record<string, unknown> = {};\n for (const k of Object.keys(v)) {\n check(\n ![\"__proto__\", \"prototype\", \"constructor\"].includes(k),\n \"Unsafe property name.\",\n );\n r[k] = clone(v[k]);\n }\n return r as T;\n }\n return v;\n}\nfunction merge<T extends object>(a: T, b: object): T {\n check(record(b), \"Options must be a plain object.\");\n const r = clone(a) as Record<string, unknown>;\n for (const k of Object.keys(b)) {\n check(\n ![\"__proto__\", \"prototype\", \"constructor\"].includes(k),\n \"Unsafe property name.\",\n );\n const previous = r[k],\n next = b[k];\n r[k] =\n record(previous) && record(next) ? merge(previous, next) : clone(next);\n }\n return r as T;\n}\nfunction freeze<T>(o: T): T {\n if (o && typeof o === \"object\") {\n for (const v of Object.values(o)) freeze(v);\n Object.freeze(o);\n }\n return o;\n}\n/** Parse a supported color into integer RGBA bytes. */\nexport function color(value: Color): RGBA {\n if (Array.isArray(value) || ArrayBuffer.isView(value)) {\n check(\n value.length === 3 || value.length === 4,\n \"Color needs 3 or 4 channels.\",\n );\n const c = Array.from(value);\n c.forEach((v) => integer(v, \"Color channel\", 0, 255));\n if (c.length === 3) c.push(255);\n return c as RGBA;\n }\n const named: Record<string, string> = {\n black: \"#000000\",\n white: \"#ffffff\",\n red: \"#ff0000\",\n green: \"#008000\",\n blue: \"#0000ff\",\n transparent: \"#00000000\",\n };\n check(\n typeof value === \"string\",\n \"Color must be hexadecimal or an RGB(A) array.\",\n );\n let h = named[value.toLowerCase()] || value;\n check(\n /^#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(h),\n \"Invalid color: \" + value,\n );\n h = h.slice(1);\n if (h.length <= 4) h = [...h].map((c) => c + c).join(\"\");\n if (h.length === 6) h += \"ff\";\n return [0, 2, 4, 6].map((i) => parseInt(h.slice(i, i + 2), 16)) as RGBA;\n}\n/** Normalize a timestamp to Unix seconds; naive dates and invalid calendars fail. */\nexport function epoch(value: Timestamp): number {\n if (value instanceof Date) value = value.getTime() / 1000;\n if (typeof value === \"string\") {\n const v = value.trim();\n if (/^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?$/i.test(v)) value = Number(v);\n else {\n const m =\n /^(\\d{4})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d)(?::(\\d\\d)(\\.\\d{1,3})?)?(Z|[+-]\\d\\d:\\d\\d)$/i.exec(\n v,\n );\n check(\n m,\n \"Datetime strings require ISO 8601 with an explicit offset; numeric timestamps are seconds.\",\n );\n const [y, mo, d, h, mi, s] = [\n m[1],\n m[2],\n m[3],\n m[4],\n m[5],\n m[6] || \"0\",\n ].map(Number);\n check(\n y >= 1 && mo >= 1 && mo <= 12 && d >= 1 && h < 24 && mi < 60 && s < 60,\n \"Invalid calendar date.\",\n );\n const test = new Date(0);\n test.setUTCFullYear(y, mo - 1, d);\n test.setUTCHours(h, mi, s, 0);\n check(\n test.getUTCMonth() === mo - 1 && test.getUTCDate() === d,\n \"Invalid calendar date.\",\n );\n if (m[8].toUpperCase() !== \"Z\")\n check(\n Number(m[8].slice(1, 3)) <= 23 && Number(m[8].slice(4)) <= 59,\n \"Invalid timezone offset.\",\n );\n value = Date.parse(v) / 1000;\n }\n }\n return number(value, \"Timestamp\", -62135596800, 253402300799.999);\n}\nfunction samples(timestamps: ArrayLike<Timestamp>, values: Values): Samples {\n check(\n (Array.isArray(timestamps) || ArrayBuffer.isView(timestamps)) &&\n (Array.isArray(values) || ArrayBuffer.isView(values)),\n \"Timestamps and values must be arrays.\",\n );\n check(\n timestamps.length === values.length && timestamps.length <= LIMITS.samples,\n \"Sample lengths must match and stay within the sample limit.\",\n );\n const ts = Array.from(timestamps, epoch),\n vs = Array.from(values, (v, i) =>\n missing(v) ? NaN : number(v, \"Value at \" + i),\n );\n for (let i = 1; i < ts.length; i++)\n check(\n ts[i] > ts[i - 1],\n \"Timestamps must be strictly increasing (index \" + i + \").\",\n );\n return { timestamps: ts, values: vs };\n}\nconst DEFAULTS: CompleteChartInput = freeze<CompleteChartInput>({\n title: \"\",\n verticalLabel: \"\",\n watermark: \"\",\n series: [],\n timeAxis: {\n start: null,\n end: null,\n mode: \"auto\",\n timezone: \"UTC\",\n minorSeconds: null,\n majorSeconds: null,\n labelSeconds: null,\n labelFormat: null,\n ticks: null,\n majorTicks: null,\n minorTicks: null,\n labelOffsetSeconds: 0,\n },\n yAxis: {\n minimum: 0,\n maximum: null,\n majorStep: null,\n minorDivisions: 5,\n base: 1000,\n scaleFactor: null,\n suffix: null,\n decimals: null,\n legendDecimals: 2,\n showZeroSuffix: false,\n },\n layout: {\n width: 595,\n plotHeight: 122,\n left: 64,\n right: 31,\n top: 34,\n titleY: 8,\n titleOffsetX: 27,\n unitX: 5,\n xLabelGap: 5,\n yLabelGap: 6,\n legendGap: 20,\n legendRowHeight: 14,\n legendBottom: 7,\n legend: \"reference\",\n antialias: 4,\n pixelScale: 1,\n legendLayout: {\n nameX: 30,\n swatchX: 15,\n swatchWidth: 9,\n swatchHeight: 10,\n referenceWidth: 595,\n autoScaleColumns: true,\n compact: [\n [102, 228],\n [244, 370],\n [386, 512],\n ],\n expanded: [\n [124, 250],\n [289, 415],\n [454, 580],\n ],\n aligned: [\n [102, 250],\n [267, 415],\n [432, 580],\n ],\n },\n },\n theme: {\n background: \"#f3f3f3\",\n canvas: \"#ffffff\",\n shadeLight: \"#cfcfcf\",\n shadeDark: \"#9e9e9e\",\n text: \"#000000\",\n minorGrid: \"#8f8f8f3c\",\n majorGrid: \"#df4f4f3c\",\n axis: \"#777777\",\n arrow: \"#7f1f1f\",\n watermark: \"#aaaaaa\",\n frame: \"#000000\",\n gridFront: true,\n gridDash: [1, 1],\n titleSize: 14,\n axisSize: 11,\n unitSize: 10,\n legendSize: 11,\n watermarkSize: 8,\n captionSize: 11,\n titleAdvance: 8,\n axisAdvance: 6,\n legendAdvance: 7,\n },\n fonts: {\n mode: \"system\",\n family: '\"DejaVu Sans Mono\", \"Liberation Mono\", Consolas, monospace',\n titleFamily: null,\n unitFamily: null,\n captionFamily: \"Arial, sans-serif\",\n strictGlyphs: true,\n },\n legendLabels: [\"Current:\", \"Average:\", \"Maximum:\"],\n missingLabel: \"NaN\",\n hRules: [],\n vRules: [],\n});\n/** Copy, validate, and deeply freeze an independently timestamped series. */\nexport function series(\n name: string,\n timestamps: ArrayLike<Timestamp>,\n values: Values,\n options: SeriesOptions = {},\n): Series {\n const s = merge<CompleteSeriesInput>(\n {\n name,\n timestamps,\n values,\n kind: \"line\",\n color: \"#0000cc\",\n lineWidth: 0.7,\n outline: null,\n baseline: 0,\n interpolation: \"linear\",\n gapAfter: 0,\n legendValues: null,\n },\n options,\n );\n text(s.name, \"Series name\");\n const data = samples(s.timestamps, s.values);\n s.timestamps = data.timestamps;\n s.values = data.values;\n check([\"line\", \"area\"].includes(s.kind), \"Series kind must be line or area.\");\n check(\n [\"linear\", \"step-post\"].includes(s.interpolation),\n \"Interpolation must be linear or step-post.\",\n );\n number(s.lineWidth, \"Line width\", 0.01, 128);\n number(s.baseline, \"Baseline\");\n number(s.gapAfter, \"Gap threshold\", 0);\n s.color = color(s.color);\n if (s.outline !== null) s.outline = color(s.outline);\n if (s.legendValues !== null) {\n check(record(s.legendValues), \"Legend overrides must be an object.\");\n for (const k of [\"current\", \"average\", \"maximum\"] as const)\n s.legendValues[k] = missing(s.legendValues[k])\n ? null\n : number(s.legendValues[k], \"Legend override\");\n }\n return freeze(s as Series);\n}\n/** Create a series with fixed elapsed-second spacing and copied observations. */\nexport function regularSeries(\n name: string,\n values: Values,\n start: Timestamp,\n step: number = 300,\n options: SeriesOptions = {},\n): Series {\n start = epoch(start);\n number(step, \"Step\", Number.MIN_VALUE);\n const first = start;\n return series(\n name,\n Array.from(values, (_, i) => first + i * step),\n values,\n options,\n );\n}\nfunction modeAxis(\n mode: NonNullable<TimeAxis[\"mode\"]>,\n options: TimeAxis | string = {},\n): TimeAxis {\n return merge(\n DEFAULTS.timeAxis,\n merge(\n { mode },\n typeof options === \"string\" ? { timezone: options } : options,\n ),\n );\n}\n/** Daily tick presentation, without resampling observations. */\nexport function daily(options: TimeAxis | string = {}): TimeAxis {\n return modeAxis(\"daily\", options);\n}\n/** Weekly calendar-noon labels, without resampling observations. */\nexport function weekly(options: TimeAxis | string = {}): TimeAxis {\n return modeAxis(\"weekly\", options);\n}\n/** Monthly tick presentation, without resampling observations. */\nexport function monthly(options: TimeAxis | string = {}): TimeAxis {\n return modeAxis(\"monthly\", options);\n}\n/** Real calendar-month ticks, without resampling observations. */\nexport function yearly(options: TimeAxis | string = {}): TimeAxis {\n return modeAxis(\"yearly\", options);\n}\nfunction dimensions(c: {\n layout: DeepReadonly<ResolvedLayout>;\n series: readonly unknown[];\n}): [number, number] {\n const l = c.layout;\n return [\n l.width,\n l.top +\n l.plotHeight +\n (l.legend === \"none\"\n ? 18\n : l.legendGap +\n Math.max(1, c.series.length) * l.legendRowHeight +\n l.legendBottom),\n ];\n}\nfunction dash(d: readonly [number, number] | null): void {\n if (d === null) return;\n check(Array.isArray(d) && d.length === 2, \"Dash must be null or [on, off].\");\n d.forEach((v) => integer(v, \"Dash interval\", 1, 16384));\n}\nfunction normalize(options: ChartOptions): ChartConfig {\n const c = merge(DEFAULTS, options);\n check(\n Array.isArray(c.series) && c.series.length <= LIMITS.series,\n \"Invalid series count.\",\n );\n c.series = c.series.map((s) => series(s.name, s.timestamps, s.values, s));\n for (const k of [\n \"title\",\n \"verticalLabel\",\n \"watermark\",\n \"missingLabel\",\n ] as const)\n text(c[k], k);\n check(\n Array.isArray(c.legendLabels) && c.legendLabels.length === 3,\n \"Three statistic labels are required.\",\n );\n c.legendLabels.forEach((v) => text(v, \"Statistic label\"));\n const a = c.timeAxis,\n l = c.layout,\n y = c.yAxis,\n t = c.theme,\n f = c.fonts;\n check(\n [\"auto\", \"daily\", \"weekly\", \"monthly\", \"yearly\", \"custom\"].includes(a.mode),\n \"Unknown time axis mode.\",\n );\n text(a.timezone, \"Timezone\");\n zoneFormatter(a.timezone);\n for (const k of [\"start\", \"end\"] as const)\n if (a[k] !== null) a[k] = epoch(a[k]);\n if (a.start !== null && a.end !== null)\n check(\n (a.end as number) > (a.start as number),\n \"Time end must exceed start.\",\n );\n for (const k of [\"minorSeconds\", \"majorSeconds\", \"labelSeconds\"] as const)\n if (a[k] !== null) number(a[k], k, 0.001);\n number(a.labelOffsetSeconds, \"Label offset\", -31622400, 31622400);\n if (a.labelFormat !== null) {\n text(a.labelFormat, \"Label format\");\n formatTime(0, \"UTC\", a.labelFormat);\n }\n if (a.ticks !== null) {\n check(\n Array.isArray(a.ticks) && a.ticks.length <= LIMITS.ticks,\n \"Too many or invalid ticks.\",\n );\n const ticks = a.ticks.map((v) => ({\n time: epoch(v.time),\n label: text(v.label, \"Tick label\"),\n }));\n for (let i = 1; i < ticks.length; i++)\n check(\n ticks[i].time > ticks[i - 1].time,\n \"Explicit ticks must be strictly increasing.\",\n );\n a.ticks = ticks;\n }\n for (const k of [\"minorTicks\", \"majorTicks\"] as const)\n if (a[k] !== null) {\n const input = a[k];\n check(\n Array.isArray(input) && input.length <= LIMITS.ticks,\n \"Too many or invalid ticks.\",\n );\n const ticks = input.map(epoch);\n for (let i = 1; i < ticks.length; i++)\n check(\n ticks[i] > ticks[i - 1],\n \"Explicit ticks must be strictly increasing.\",\n );\n a[k] = ticks;\n }\n for (const k of [\"minimum\", \"maximum\", \"majorStep\", \"scaleFactor\"] as const)\n if (y[k] !== null) number(y[k], k);\n for (const k of [\"majorStep\", \"scaleFactor\"] as const)\n if (y[k] !== null) check(y[k] > 0, k + \" must be positive.\");\n if (y.minimum !== null && y.maximum !== null)\n check(y.maximum > y.minimum, \"Y maximum must exceed minimum.\");\n check(y.base === 1000 || y.base === 1024, \"Unit base must be 1000 or 1024.\");\n integer(y.minorDivisions, \"Minor divisions\", 1, 100);\n integer(y.legendDecimals, \"Legend decimals\", 0, 12);\n if (y.decimals !== null) integer(y.decimals, \"Decimals\", 0, 12);\n if (y.suffix !== null) text(y.suffix, \"Suffix\");\n integer(l.width, \"Width\", 400, 8192);\n integer(l.plotHeight, \"Plot height\", 30, 4096);\n for (const k of [\n \"left\",\n \"right\",\n \"top\",\n \"titleY\",\n \"unitX\",\n \"xLabelGap\",\n \"yLabelGap\",\n \"legendGap\",\n \"legendRowHeight\",\n \"legendBottom\",\n ] as const)\n integer(l[k], k, 0, 16384);\n check(\n l.left >= 20 &&\n l.right >= 12 &&\n l.top >= 12 &&\n l.width - l.left - l.right >= 100,\n \"Insufficient plot margins.\",\n );\n number(l.titleOffsetX, \"Title offset\", -8192, 8192);\n check(\n [\"reference\", \"aligned\", \"none\"].includes(l.legend),\n \"Invalid legend mode.\",\n );\n if (l.legend !== \"none\")\n check(\n l.legendGap >= 14 && l.legendRowHeight >= 10,\n \"Legend spacing is insufficient.\",\n );\n integer(l.antialias, \"Antialias\", 1, 8);\n integer(l.pixelScale, \"Pixel scale\", 1, 8);\n const ll = l.legendLayout;\n for (const k of [\n \"nameX\",\n \"swatchX\",\n \"swatchWidth\",\n \"swatchHeight\",\n \"referenceWidth\",\n ] as const)\n integer(ll[k], k, 0, 16384);\n check(\n ll.swatchWidth >= 3 && ll.swatchHeight >= 3 && ll.referenceWidth > ll.nameX,\n \"Invalid legend geometry.\",\n );\n for (const key of [\"compact\", \"expanded\", \"aligned\"] as const) {\n const cols = ll[key];\n check(Array.isArray(cols) && cols.length === 3, \"Invalid legend columns.\");\n let last = ll.nameX;\n for (const p of cols) {\n check(\n Array.isArray(p) &&\n p.length === 2 &&\n finite(p[0]) &&\n finite(p[1]) &&\n last < p[0] &&\n p[0] < p[1] &&\n p[1] < ll.referenceWidth,\n \"Legend columns must not overlap.\",\n );\n last = p[1];\n }\n }\n for (const k of [\n \"background\",\n \"canvas\",\n \"shadeLight\",\n \"shadeDark\",\n \"text\",\n \"minorGrid\",\n \"majorGrid\",\n \"axis\",\n \"arrow\",\n \"watermark\",\n \"frame\",\n ] as const)\n t[k] = color(t[k]);\n check(\n t.background[3] === 255 && t.canvas[3] === 255,\n \"Background and canvas must be opaque.\",\n );\n dash(t.gridDash);\n check(t.gridDash !== null, \"Grid dash is required.\");\n for (const k of [\n \"titleSize\",\n \"axisSize\",\n \"unitSize\",\n \"legendSize\",\n \"watermarkSize\",\n \"captionSize\",\n \"titleAdvance\",\n \"axisAdvance\",\n \"legendAdvance\",\n ] as const)\n number(t[k], k, 1, 128);\n check(\n [\"system\", \"bitmap\"].includes(f.mode),\n \"Font mode must be system or bitmap.\",\n );\n text(f.family, \"Font family\");\n for (const k of [\"titleFamily\", \"unitFamily\", \"captionFamily\"] as const)\n if (f[k] !== null) text(f[k], k);\n function rule<R extends HRule | VRule>(\n input: R,\n field: \"time\" | \"value\",\n ): R & Required<RuleStyle> {\n const r = merge(\n { color: \"#990000\", width: 1, dash: [3, 2] },\n input,\n ) as unknown as R & Required<RuleStyle>;\n if (field === \"time\") (r as VRule).time = epoch((r as VRule).time);\n else (r as HRule).value = number((r as HRule).value, \"Rule value\");\n number(r.width, \"Rule width\", 0.1, 128);\n dash(r.dash);\n r.color = color(r.color);\n return r;\n }\n check(\n Array.isArray(c.hRules) && c.hRules.length <= 1000,\n \"Invalid rule count.\",\n );\n c.hRules = c.hRules.map((r) => rule(r, \"value\"));\n check(\n Array.isArray(c.vRules) && c.vRules.length <= 1000,\n \"Invalid rule count.\",\n );\n c.vRules = c.vRules.map((r) => rule(r, \"time\"));\n const [w, h] = dimensions(c);\n check(\n w * h * l.pixelScale ** 2 <= LIMITS.pixels,\n \"Output allocation exceeds the pixel limit.\",\n );\n check(\n (l.width - l.left - l.right + 1) * (l.plotHeight + 1) * l.antialias ** 2 <=\n LIMITS.layerPixels,\n \"Supersampled layer exceeds the pixel limit.\",\n );\n // All timestamp, color, series and rule fields have now been normalized.\n return freeze(c as ResolvedChartOptions);\n}\n// A straight-alpha pixel surface: data geometry never depends on a browser path rasterizer.\nclass Surface implements RGBAImage {\n readonly width: number;\n readonly height: number;\n readonly data: Uint8ClampedArray;\n constructor(\n width: number,\n height: number,\n fill: Readonly<RGBA> | null = null,\n ) {\n integer(width, \"Image width\", 1, 65536);\n integer(height, \"Image height\", 1, 65536);\n check(width * height <= LIMITS.layerPixels, \"Image is too large.\");\n this.width = width;\n this.height = height;\n this.data = new Uint8ClampedArray(width * height * 4);\n if (fill) this.rect(0, 0, width, height, fill);\n }\n pixel(x: number, y: number, c: Readonly<RGBA>, blend: boolean = false): void {\n if (x < 0 || y < 0 || x >= this.width || y >= this.height) return;\n const i = (y * this.width + x) * 4,\n d = this.data;\n if (!blend || c[3] === 255) {\n d[i] = c[0];\n d[i + 1] = c[1];\n d[i + 2] = c[2];\n d[i + 3] = c[3];\n return;\n }\n if (c[3] === 0) return;\n const sa = c[3],\n da = d[i + 3],\n alpha = sa * 255 + da * (255 - sa);\n for (let k = 0; k < 3; k++)\n d[i + k] = Math.floor(\n (c[k] * sa * 255 + d[i + k] * da * (255 - sa) + alpha / 2) / alpha,\n );\n d[i + 3] = Math.floor((alpha + 127) / 255);\n }\n rect(\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n c: Readonly<RGBA>,\n ): void {\n x0 = Math.max(0, Math.ceil(x0));\n y0 = Math.max(0, Math.ceil(y0));\n x1 = Math.min(this.width, Math.ceil(x1));\n y1 = Math.min(this.height, Math.ceil(y1));\n for (let y = y0; y < y1; y++)\n for (let x = x0, i = (y * this.width + x0) * 4; x < x1; x++, i += 4) {\n this.data[i] = c[0];\n this.data[i + 1] = c[1];\n this.data[i + 2] = c[2];\n this.data[i + 3] = c[3];\n }\n }\n over(src: RGBAImage, dx: number = 0, dy: number = 0): void {\n const p: RGBA = [0, 0, 0, 0];\n for (\n let y = Math.max(0, -dy);\n y < Math.min(src.height, this.height - dy);\n y++\n )\n for (\n let x = Math.max(0, -dx);\n x < Math.min(src.width, this.width - dx);\n x++\n ) {\n const i = (y * src.width + x) * 4;\n if (src.data[i + 3]) {\n p[0] = src.data[i];\n p[1] = src.data[i + 1];\n p[2] = src.data[i + 2];\n p[3] = src.data[i + 3];\n this.pixel(x + dx, y + dy, p, true);\n }\n }\n }\n polygon(points: readonly Point[], c: Readonly<RGBA>): void {\n if (points.length < 3) return;\n let lo = Infinity,\n hi = -Infinity;\n for (const p of points) {\n lo = Math.min(lo, p[1]);\n hi = Math.max(hi, p[1]);\n }\n for (\n let y = Math.max(0, Math.ceil(lo));\n y <= Math.min(this.height - 1, Math.floor(hi));\n y++\n ) {\n const xs = [];\n let a = points[points.length - 1];\n for (const b of points) {\n if (a[1] === b[1]) {\n if (y === a[1])\n this.rect(\n Math.ceil(Math.min(a[0], b[0])),\n y,\n Math.floor(Math.max(a[0], b[0])) + 1,\n y + 1,\n c,\n );\n } else if ((a[1] <= y && y < b[1]) || (b[1] <= y && y < a[1]))\n xs.push(a[0] + ((y - a[1]) / (b[1] - a[1])) * (b[0] - a[0]));\n a = b;\n }\n xs.sort((a, b) => a - b);\n for (let i = 0; i + 1 < xs.length; i += 2)\n this.rect(\n Math.ceil(xs[i] - 1e-9),\n y,\n Math.floor(xs[i + 1] + 1e-9) + 1,\n y + 1,\n c,\n );\n }\n }\n line(a: Point, b: Point, c: Readonly<RGBA>, width: number = 1): void {\n let x = round(a[0]),\n y = round(a[1]),\n x1 = round(b[0]),\n y1 = round(b[1]);\n width = Math.max(1, round(width));\n if (width > 1) {\n const r = (width - 1) / 2;\n if (x === x1) {\n this.rect(\n x - Math.floor(width / 2),\n Math.min(y, y1),\n x + Math.floor((width - 1) / 2) + 1,\n Math.max(y, y1) + 1,\n c,\n );\n return;\n }\n if (y === y1) {\n this.rect(\n Math.min(x, x1),\n y - Math.floor(width / 2),\n Math.max(x, x1) + 1,\n y + Math.floor((width - 1) / 2) + 1,\n c,\n );\n return;\n }\n const len = Math.hypot(x1 - x, y1 - y),\n ox = (-(y1 - y) / len) * r,\n oy = ((x1 - x) / len) * r;\n this.polygon(\n [\n [x + ox, y + oy],\n [x1 + ox, y1 + oy],\n [x1 - ox, y1 - oy],\n [x - ox, y - oy],\n ].map((p): Point => [round(p[0]), round(p[1])]),\n c,\n );\n return;\n }\n const dx = Math.abs(x1 - x),\n dy = -Math.abs(y1 - y),\n sx = x < x1 ? 1 : -1,\n sy = y < y1 ? 1 : -1;\n let err = dx + dy;\n for (;;) {\n this.pixel(x, y, c);\n if (x === x1 && y === y1) break;\n const e = 2 * err;\n if (e >= dy) {\n err += dy;\n x += sx;\n }\n if (e <= dx) {\n err += dx;\n y += sy;\n }\n }\n }\n dashed(\n a: Point,\n b: Point,\n c: Readonly<RGBA>,\n pattern: readonly [number, number] | null = [1, 1],\n width: number = 1,\n ): void {\n if (pattern === null) {\n this.line(a, b, c, width);\n return;\n }\n const len = Math.hypot(b[0] - a[0], b[1] - a[1]);\n if (!len) {\n this.pixel(round(a[0]), round(a[1]), c);\n return;\n }\n const dx = (b[0] - a[0]) / len,\n dy = (b[1] - a[1]) / len;\n for (let s = 0; s <= Math.ceil(len); s += pattern[0] + pattern[1]) {\n const e = Math.min(len, s + pattern[0] - 1);\n this.line(\n [a[0] + dx * s, a[1] + dy * s],\n [a[0] + dx * e, a[1] + dy * e],\n c,\n width,\n );\n }\n }\n circle(x: number, y: number, r: number, c: Readonly<RGBA>): void {\n for (\n let yy = Math.max(0, Math.floor(y - r));\n yy <= Math.min(this.height - 1, Math.ceil(y + r));\n yy++\n )\n for (\n let xx = Math.max(0, Math.floor(x - r));\n xx <= Math.min(this.width - 1, Math.ceil(x + r));\n xx++\n )\n if ((xx - x) ** 2 + (yy - y) ** 2 <= r * r) this.pixel(xx, yy, c);\n }\n down(scale: number): Surface {\n if (scale === 1) return this;\n const out = new Surface(this.width / scale, this.height / scale),\n p: RGBA = [0, 0, 0, 0],\n n = scale * scale;\n for (let y = 0; y < out.height; y++)\n for (let x = 0; x < out.width; x++) {\n let a = 0,\n r = 0,\n g = 0,\n b = 0;\n for (let sy = 0; sy < scale; sy++)\n for (let sx = 0; sx < scale; sx++) {\n const i = ((y * scale + sy) * this.width + x * scale + sx) * 4,\n ca = this.data[i + 3];\n a += ca;\n r += this.data[i] * ca;\n g += this.data[i + 1] * ca;\n b += this.data[i + 2] * ca;\n }\n if (a) {\n p[0] = Math.floor(r / a + 0.5);\n p[1] = Math.floor(g / a + 0.5);\n p[2] = Math.floor(b / a + 0.5);\n p[3] = Math.floor(a / n + 0.5);\n out.pixel(x, y, p);\n }\n }\n return out;\n }\n scale(n: number): Surface {\n if (n === 1) return this;\n const out = new Surface(this.width * n, this.height * n);\n for (let y = 0; y < out.height; y++)\n for (let x = 0; x < out.width; x++) {\n const s = (Math.floor(y / n) * this.width + Math.floor(x / n)) * 4,\n i = (y * out.width + x) * 4;\n out.data[i] = this.data[s];\n out.data[i + 1] = this.data[s + 1];\n out.data[i + 2] = this.data[s + 2];\n out.data[i + 3] = this.data[s + 3];\n }\n return out;\n }\n}\nfunction clipLine(\n a: Point,\n b: Point,\n w: number,\n h: number,\n): [Point, Point] | null {\n let lo = 0,\n hi = 1;\n const dx = b[0] - a[0],\n dy = b[1] - a[1];\n for (const [p, q] of [\n [-dx, a[0]],\n [dx, w - a[0]],\n [-dy, a[1]],\n [dy, h - a[1]],\n ]) {\n if (p === 0) {\n if (q < 0) return null;\n } else {\n const u = q / p;\n if (p < 0) lo = Math.max(lo, u);\n else hi = Math.min(hi, u);\n if (lo > hi) return null;\n }\n }\n return [\n [a[0] + lo * dx, a[1] + lo * dy],\n [a[0] + hi * dx, a[1] + hi * dy],\n ];\n}\nfunction clipPolygon(points: Point[], w: number, h: number): Point[] {\n let ps = points;\n for (const [axis, bound, greater] of [\n [0, 0, true],\n [0, w, false],\n [1, 0, true],\n [1, h, false],\n ] as const) {\n if (!ps.length) break;\n const out: Point[] = [],\n inside = (p: Point): boolean =>\n greater ? p[axis] >= bound : p[axis] <= bound;\n let a = ps[ps.length - 1],\n ai = inside(a);\n for (const b of ps) {\n const bi = inside(b);\n if (ai !== bi) {\n const q = (bound - a[axis]) / (b[axis] - a[axis]);\n const p: Point = [a[0] + q * (b[0] - a[0]), a[1] + q * (b[1] - a[1])];\n p[axis] = bound;\n out.push(p);\n }\n if (bi) out.push(b);\n a = b;\n ai = bi;\n }\n ps = out;\n }\n return ps;\n}\nfunction lowerBound(a: readonly number[], x: number): number {\n let l = 0,\n r = a.length;\n while (l < r) {\n const m = (l + r) >>> 1;\n if (a[m] < x) l = m + 1;\n else r = m;\n }\n return l;\n}\nfunction upperBound(a: readonly number[], x: number): number {\n let l = 0,\n r = a.length;\n while (l < r) {\n const m = (l + r) >>> 1;\n if (a[m] <= x) l = m + 1;\n else r = m;\n }\n return l;\n}\nfunction visibleRuns(s: Series, start: number, end: number): Point[][] {\n const ts = s.timestamps,\n vs = s.values,\n result: Point[][] = [];\n let run: Point[] = [];\n const push = () => {\n if (run.length) {\n result.push(run);\n run = [];\n }\n };\n const left = Math.max(0, lowerBound(ts, start) - 1),\n right = Math.min(ts.length, upperBound(ts, end) + 1);\n for (let i = left; i < right; i++) {\n if (!finite(vs[i])) {\n push();\n continue;\n }\n if (i > left && s.gapAfter > 0 && ts[i] - ts[i - 1] > s.gapAfter) push();\n if (run.length && s.interpolation === \"step-post\")\n run.push([ts[i], run[run.length - 1][1]]);\n run.push([ts[i], vs[i]]);\n }\n push();\n const clipped: Point[][] = [];\n for (const r of result) {\n const out: Point[] = [];\n if (r.length === 1) {\n if (r[0][0] >= start && r[0][0] <= end) out.push(r[0]);\n }\n for (let i = 1; i < r.length; i++) {\n const a = r[i - 1],\n b = r[i];\n if (b[0] < start || a[0] > end) continue;\n const interp = (x: number): number =>\n a[1] * (1 - (x - a[0]) / (b[0] - a[0])) +\n b[1] * ((x - a[0]) / (b[0] - a[0]));\n const p: Point = a[0] < start ? [start, interp(start)] : a,\n q: Point = b[0] > end ? [end, interp(end)] : b;\n if (\n !out.length ||\n out[out.length - 1][0] !== p[0] ||\n out[out.length - 1][1] !== p[1]\n )\n out.push(p);\n out.push(q);\n }\n if (out.length) clipped.push(out);\n }\n return clipped;\n}\nfunction decimate(\n ps: Point[],\n start: number,\n end: number,\n width: number,\n): Point[] {\n if (ps.length <= width * 4) return ps;\n const out = [];\n let pos = 0;\n while (pos < ps.length) {\n const col = Math.floor(((ps[pos][0] - start) / (end - start)) * width),\n first = pos;\n let mn = pos,\n mx = pos;\n while (\n pos + 1 < ps.length &&\n Math.floor(((ps[pos + 1][0] - start) / (end - start)) * width) === col\n ) {\n pos++;\n if (ps[pos][1] < ps[mn][1]) mn = pos;\n if (ps[pos][1] > ps[mx][1]) mx = pos;\n }\n for (const i of [...new Set([first, mn, mx, pos])].sort((a, b) => a - b))\n out.push(ps[i]);\n pos++;\n }\n return out;\n}\nfunction stableMean(values: readonly number[]): number | null {\n if (!values.length) return null;\n let max = 0;\n for (const v of values) max = Math.max(max, Math.abs(v));\n if (max === 0) return 0;\n let sum = 0,\n c = 0;\n for (const v of values) {\n const a = v / max - c,\n t = sum + a;\n c = t - sum - a;\n sum = t;\n }\n return clamp(sum / values.length, -1, 1) * max;\n}\nfunction statistics(s: Series, start: number, end: number): Statistics {\n const a = lowerBound(s.timestamps, start),\n b = upperBound(s.timestamps, end),\n values = [];\n let mn = Infinity,\n mx = -Infinity,\n miss = 0;\n for (let i = a; i < b; i++) {\n const v = s.values[i];\n if (!finite(v)) miss++;\n else {\n values.push(v);\n mn = Math.min(mn, v);\n mx = Math.max(mx, v);\n }\n }\n return {\n name: s.name,\n current: b > a && finite(s.values[b - 1]) ? s.values[b - 1] : null,\n average: stableMean(values),\n maximum: values.length ? mx : null,\n minimum: values.length ? mn : null,\n count: values.length,\n missing: miss,\n displayOverride: s.legendValues,\n };\n}\n// Numeric units and ticks. All limits and data use original (unscaled) units.\nfunction multiples(lo: number, hi: number, step: number): number[] {\n check(\n finite(step) &&\n step > 0 &&\n finite((hi - lo) / step) &&\n (hi - lo) / step <= LIMITS.ticks,\n \"Too many ticks or invalid step.\",\n );\n const a = Math.ceil(lo / step - 1e-10),\n b = Math.floor(hi / step + 1e-10);\n check(\n Math.abs(a) < 9e15 && Math.abs(b) < 9e15 && b - a <= LIMITS.ticks,\n \"Tick precision limit exceeded.\",\n );\n return Array.from(\n { length: Math.max(0, b - a + 1) },\n (_, i) => (a + i) * step || 0,\n );\n}\nfunction nice(v: number): number {\n check(finite(v) && v >= 1e-300, \"Unsupported numeric axis span.\");\n const p = 10 ** Math.floor(Math.log10(v));\n for (const m of [1, 2, 5, 10]) if (v <= m * p * (1 + 1e-12)) return m * p;\n return 10 * p;\n}\nfunction unitFor(v: number, base: 1000 | 1024): Unit {\n if (!v) return { factor: 1, suffix: \"\" };\n let i = Math.floor(Math.log(Math.abs(v)) / Math.log(base) + 1e-12);\n i = clamp(i, base === 1024 ? 0 : -8, 8);\n return {\n factor: base ** i,\n suffix: (base === 1024\n ? [\"\", \"Ki\", \"Mi\", \"Gi\", \"Ti\", \"Pi\", \"Ei\", \"Zi\", \"Yi\"]\n : [\n \"y\",\n \"z\",\n \"a\",\n \"f\",\n \"p\",\n \"n\",\n \"u\",\n \"m\",\n \"\",\n \"k\",\n \"M\",\n \"G\",\n \"T\",\n \"P\",\n \"E\",\n \"Z\",\n \"Y\",\n ])[base === 1024 ? i : i + 8],\n };\n}\nfunction resolveY(\n a: Readonly<Required<YAxis>>,\n loData: number,\n hiData: number,\n): YResolution {\n let lo = a.minimum === null ? Math.min(0, loData) : a.minimum,\n hi = a.maximum === null ? Math.max(0, hiData) : a.maximum;\n if (a.maximum === null && hi <= lo)\n hi = lo + Math.max(Math.abs(lo) * 0.05, 1);\n if (a.minimum === null && lo >= hi)\n lo = hi - Math.max(Math.abs(hi) * 0.05, 1);\n const span = hi - lo;\n check(finite(span) && span > 0, \"Invalid Y span.\");\n const af =\n a.scaleFactor === null\n ? unitFor(Math.max(Math.abs(lo), Math.abs(hi)), a.base).factor\n : a.scaleFactor;\n const step = a.majorStep === null ? nice(span / af / 5) * af : a.majorStep,\n q = step / a.minorDivisions;\n check(finite(q) && q > 0, \"Invalid Y quantum.\");\n if (a.minimum === null && lo < 0) lo = Math.floor((lo - span * 0.02) / q) * q;\n if (a.maximum === null) hi = Math.ceil((hi + span * 0.02) / q) * q;\n check(finite(hi - lo) && hi > lo, \"Degenerate Y range.\");\n const major = multiples(lo, hi, step),\n minor = multiples(lo, hi, q).filter(\n (v) => Math.abs(v / step - round(v / step)) > 1e-8,\n );\n const unit = unitFor(Math.max(Math.abs(lo), Math.abs(hi)), a.base);\n if (a.scaleFactor !== null) {\n unit.factor = a.scaleFactor;\n if (a.suffix === null) unit.suffix = \"\";\n }\n if (a.suffix !== null) unit.suffix = a.suffix;\n let decimals = a.decimals;\n if (decimals === null) {\n const s = step / unit.factor;\n decimals = 9;\n for (let d = 0; d < 10; d++)\n if (\n Math.abs(s - round(s * 10 ** d) / 10 ** d) <=\n Math.max(1e-10, Math.abs(s) * 1e-9)\n ) {\n decimals = d;\n break;\n }\n }\n return { minimum: lo, maximum: hi, step, major, minor, ...unit, decimals };\n}\n/** Format a value using an already validated common unit and decimal precision. */\nexport function formatValue(\n value: number | null,\n unit: Unit,\n decimals: number = 2,\n missingText: string = \"NaN\",\n): string {\n if (!finite(value)) return missingText;\n let v = value / unit.factor;\n if (Math.abs(v) < 0.5 * 10 ** -decimals) v = 0;\n return v.toFixed(decimals) + (unit.suffix ? \" \" + unit.suffix : \"\");\n}\nconst formatterCache = new Map<string, Intl.DateTimeFormat>();\nfunction zoneFormatter(zone: string): Intl.DateTimeFormat {\n if (formatterCache.has(zone)) return formatterCache.get(zone)!;\n let f;\n try {\n f = new Intl.DateTimeFormat(\"en-GB-u-ca-gregory-nu-latn\", {\n timeZone: zone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hourCycle: \"h23\",\n });\n } catch (e) {\n throw new RangeError(\"Unsupported time zone: \" + zone);\n }\n if (formatterCache.size >= 32)\n formatterCache.delete(formatterCache.keys().next().value!);\n formatterCache.set(zone, f);\n return f;\n}\nfunction utcFromParts(\n y: number,\n m: number,\n d: number,\n h: number = 0,\n mi: number = 0,\n s: number = 0,\n): number {\n const t = new Date(0);\n t.setUTCFullYear(y, m - 1, d);\n t.setUTCHours(h, mi, s, 0);\n return t.getTime() / 1000;\n}\nfunction wallParts(t: number, zone: string): WallParts {\n if (zone === \"UTC\") {\n const d = new Date(t * 1000);\n return {\n year: d.getUTCFullYear(),\n month: d.getUTCMonth() + 1,\n day: d.getUTCDate(),\n hour: d.getUTCHours(),\n minute: d.getUTCMinutes(),\n second: d.getUTCSeconds(),\n };\n }\n const r = {} as WallParts;\n for (const p of zoneFormatter(zone).formatToParts(new Date(t * 1000)))\n if (p.type !== \"literal\") r[p.type as keyof WallParts] = Number(p.value);\n if (r.hour === 24) r.hour = 0;\n return r;\n}\nfunction wallEpoch(t: number, zone: string): number {\n const p = wallParts(t, zone);\n return (\n utcFromParts(p.year, p.month, p.day, p.hour, p.minute, p.second) +\n (t - Math.floor(t))\n );\n}\nfunction offsetAt(t: number, zone: string): number {\n return Math.round(wallEpoch(t, zone) - t);\n}\nfunction localCandidates(w: number, zone: string): number[] {\n if (zone === \"UTC\") return [w];\n const offsets = new Set(\n [-172800, -86400, 0, 86400, 172800].map((d) => offsetAt(w + d, zone)),\n ),\n out = [];\n for (const off of offsets) {\n const t = w - off;\n if (Math.abs(wallEpoch(t, zone) - w) < 0.001) out.push(t);\n }\n return out.sort((a, b) => a - b);\n}\nfunction wallTicks(\n start: number,\n end: number,\n step: number,\n zone: string,\n): number[] {\n if (zone === \"UTC\") return multiples(start, end, step);\n const sa = wallEpoch(start, zone),\n sb = wallEpoch(end, zone),\n a = Math.floor(Math.min(sa, sb) / step) - 2,\n b = Math.ceil(Math.max(sa, sb) / step) + 2;\n check(\n finite(b - a) &&\n b - a <= LIMITS.ticks &&\n Math.abs(a) < 9e15 &&\n Math.abs(b) < 9e15,\n \"Too many time ticks; increase the interval.\",\n );\n // One offset set for a tick range; 12-hour probes plus endpoint probes preserve ordinary IANA folds.\n const offsets = new Set<number>();\n const probe = Math.max(43200, (end - start) / 4096);\n for (let t = start - 172800; t <= end + 172800; t += probe)\n offsets.add(offsetAt(t, zone));\n offsets.add(offsetAt(end, zone));\n const out = new Set<number>();\n for (let i = 0; i <= b - a; i++) {\n const w = (a + i) * step;\n for (const off of offsets) {\n const t = w - off;\n if (t >= start && t <= end && Math.abs(wallEpoch(t, zone) - w) < 0.001)\n out.add(t);\n }\n }\n return [...out].sort((a, b) => a - b);\n}\nfunction monthTicks(\n start: number,\n end: number,\n zone: string,\n stride: number = 1,\n): number[] {\n const a = wallParts(start, zone),\n b = wallParts(end, zone),\n first = Math.floor((a.year * 12 + a.month - 1) / stride) * stride,\n last = b.year * 12 + b.month - 1 + stride;\n check((last - first) / stride <= LIMITS.ticks, \"Too many calendar ticks.\");\n const out = [];\n for (let i = first; i <= last; i += stride) {\n const y = Math.floor(i / 12),\n m = (i % 12) + 1;\n if (y < 1 || y > 9999) continue;\n for (const t of localCandidates(utcFromParts(y, m, 1), zone))\n if (t >= start && t <= end) out.push(t);\n }\n return out.sort((a, b) => a - b);\n}\nconst MONTHS = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n];\nconst DAYS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\nconst pad = (v: number, n: number = 2): string => String(v).padStart(n, \"0\");\n/** Format a timestamp with fixed English calendar names and IANA timezone rules. */\nexport function formatTime(\n t: Timestamp,\n zone: string = \"UTC\",\n format: string = \"%H:%M\",\n): string {\n t = epoch(t);\n const p = wallParts(t, zone),\n d = new Date(utcFromParts(p.year, p.month, p.day) * 1000),\n off = offsetAt(t, zone),\n day = d.getUTCDay();\n const fields: Record<string, string> = {\n H: pad(p.hour),\n I: pad(p.hour % 12 || 12),\n M: pad(p.minute),\n S: pad(p.second),\n d: pad(p.day),\n e: String(p.day).padStart(2, \" \"),\n m: pad(p.month),\n Y: pad(p.year, 4),\n y: pad(p.year % 100),\n a: DAYS[day],\n A: [\n \"Sunday\",\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n ][day],\n b: MONTHS[p.month - 1],\n h: MONTHS[p.month - 1],\n B: [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ][p.month - 1],\n p: p.hour < 12 ? \"AM\" : \"PM\",\n w: String(day),\n u: String(day || 7),\n j: pad(\n Math.floor((d.getTime() / 1000 - utcFromParts(p.year, 1, 1)) / 86400) + 1,\n 3,\n ),\n z:\n (off < 0 ? \"-\" : \"+\") +\n pad(Math.floor(Math.abs(off) / 3600)) +\n pad(Math.floor((Math.abs(off) % 3600) / 60)),\n Z: zone,\n \"%\": \"%\",\n };\n fields.F = fields.Y + \"-\" + fields.m + \"-\" + fields.d;\n fields.T = fields.H + \":\" + fields.M + \":\" + fields.S;\n fields.R = fields.H + \":\" + fields.M;\n let out = \"\";\n for (let i = 0; i < format.length; i++) {\n if (format[i] !== \"%\") {\n out += format[i];\n continue;\n }\n const k = format[++i];\n check(own(fields, k), \"Unsupported date directive: %\" + (k || \"\"));\n out += fields[k];\n }\n return out;\n}\nfunction resolveX(\n a: DeepReadonly<ResolvedTimeAxis>,\n start: number,\n end: number,\n width: number,\n): XResolution {\n const span = end - start,\n zone = a.timezone,\n mode =\n a.mode === \"auto\"\n ? span <= 172800\n ? \"daily\"\n : span <= 864000\n ? \"weekly\"\n : span <= 5356800\n ? \"monthly\"\n : \"yearly\"\n : a.mode;\n let minor: number[] = [],\n major: number[] = [],\n labelTimes: number[] = [],\n format = \"%H:%M\";\n if (mode === \"yearly\") {\n const stride =\n span > 550 * 86400 ? Math.max(1, Math.ceil(span / (365.25 * 86400))) : 1;\n format = stride > 1 ? \"%b %Y\" : \"%b\";\n if (a.majorTicks === null || a.ticks === null) {\n major = monthTicks(start, end, zone, stride);\n labelTimes = major;\n }\n if (a.minorTicks === null) minor = monthTicks(start, end, zone, 1);\n if (a.majorTicks === null && a.majorSeconds !== null)\n major = wallTicks(start, end, a.majorSeconds, zone);\n if (a.minorTicks === null && a.minorSeconds !== null)\n minor = wallTicks(start, end, a.minorSeconds, zone);\n if (a.ticks === null && a.labelSeconds !== null)\n labelTimes = wallTicks(start, end, a.labelSeconds, zone);\n } else {\n let mi = 1800,\n ma = 7200,\n ls = 7200;\n if (mode === \"weekly\") {\n mi = 21600;\n ma = ls = 86400;\n format = \"%d\";\n }\n if (mode === \"monthly\") {\n mi = 86400;\n ma = ls = 604800;\n format = \"%d %b\";\n }\n if (a.mode === \"auto\" && span < 43200) {\n const target = span / Math.max(2, Math.floor(width / 48));\n ls =\n [1, 5, 10, 15, 30, 60, 120, 300, 600, 900, 1800, 3600, 7200].find(\n (v) => v >= target,\n ) || 7200;\n mi = Math.max(1, ls / 4);\n ma = ls;\n if (ls < 60) format = \"%H:%M:%S\";\n }\n mi = Math.max(mi, span / 2000);\n if (a.minorSeconds !== null) mi = a.minorSeconds;\n if (a.majorSeconds !== null) ma = a.majorSeconds;\n if (a.labelSeconds !== null) ls = a.labelSeconds;\n if (a.minorTicks === null) minor = wallTicks(start, end, mi, zone);\n if (a.majorTicks === null) major = wallTicks(start, end, ma, zone);\n if (a.ticks === null) labelTimes = wallTicks(start, end, ls, zone);\n }\n if (a.minorTicks !== null)\n minor = a.minorTicks.filter((v) => v >= start && v <= end);\n if (a.majorTicks !== null)\n major = a.majorTicks.filter((v) => v >= start && v <= end);\n if (a.labelFormat !== null) format = a.labelFormat;\n let labels: ResolvedTick[] = [];\n if (a.ticks !== null)\n labels = a.ticks.filter((v) => v.time >= start && v.time <= end);\n else if (\n mode === \"weekly\" &&\n a.labelSeconds === null &&\n a.labelOffsetSeconds === 0\n ) {\n for (const t of wallTicks(start - 172800, end, 86400, zone)) {\n const w = wallEpoch(t, zone),\n next = localCandidates(w + 86400, zone);\n if (t < start || !next.length || next[next.length - 1] > end) continue;\n for (const noon of localCandidates(w + 43200, zone))\n if (noon >= start && noon <= end)\n labels.push({ time: noon, label: formatTime(t, zone, format) });\n }\n } else\n for (const t of labelTimes) {\n const pos = t + a.labelOffsetSeconds;\n if (pos >= start && pos <= end)\n labels.push({ time: pos, label: formatTime(t, zone, format) });\n }\n labels.sort((a, b) => a.time - b.time);\n if (a.ticks === null && mode === \"daily\" && span <= 95040) {\n const seen = new Map<string, Set<number>>();\n for (const t of labels) {\n if (!seen.has(t.label)) seen.set(t.label, new Set());\n seen.get(t.label)!.add(offsetAt(t.time, zone));\n }\n labels = labels.map((t) =>\n seen.get(t.label)!.size > 1\n ? {\n time: t.time,\n label: t.label + \" \" + formatTime(t.time, zone, \"%z\"),\n }\n : t,\n );\n }\n const majorSet = new Set(major);\n minor = minor.filter((v) => !majorSet.has(v));\n return { minor, major, labels, mode };\n}\nfunction timeRange(c: ChartConfig): [number, number] {\n let start = Infinity,\n end = -Infinity;\n for (const s of c.series)\n if (s.timestamps.length) {\n start = Math.min(start, s.timestamps[0]);\n end = Math.max(end, s.timestamps[s.timestamps.length - 1]);\n }\n if (c.timeAxis.start !== null) start = c.timeAxis.start;\n if (c.timeAxis.end !== null) end = c.timeAxis.end;\n if (start === end && c.timeAxis.start === null && c.timeAxis.end === null) {\n start -= 150;\n end += 150;\n }\n epoch(start);\n epoch(end);\n check(\n end > start,\n \"Empty data needs explicit start and end; range must be nonzero.\",\n );\n return [start, end];\n}\n// Original 5\u00D77 pixel-letter descriptions. Not extracted from a font, no font asset shipped.\n// This optional ASCII renderer trades typographic likeness for host-independent pixels.\nconst PIXEL_GLYPHS: Readonly<Record<string, readonly string[]>> = {\n \" \": [\"00000\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\"],\n \"0\": [\"01110\", \"10001\", \"10011\", \"10101\", \"11001\", \"10001\", \"01110\"],\n \"1\": [\"00100\", \"01100\", \"00100\", \"00100\", \"00100\", \"00100\", \"01110\"],\n \"2\": [\"01110\", \"10001\", \"00001\", \"00010\", \"00100\", \"01000\", \"11111\"],\n \"3\": [\"11110\", \"00001\", \"00001\", \"01110\", \"00001\", \"00001\", \"11110\"],\n \"4\": [\"00010\", \"00110\", \"01010\", \"10010\", \"11111\", \"00010\", \"00010\"],\n \"5\": [\"11111\", \"10000\", \"10000\", \"11110\", \"00001\", \"00001\", \"11110\"],\n \"6\": [\"01110\", \"10000\", \"10000\", \"11110\", \"10001\", \"10001\", \"01110\"],\n \"7\": [\"11111\", \"00001\", \"00010\", \"00100\", \"01000\", \"01000\", \"01000\"],\n \"8\": [\"01110\", \"10001\", \"10001\", \"01110\", \"10001\", \"10001\", \"01110\"],\n \"9\": [\"01110\", \"10001\", \"10001\", \"01111\", \"00001\", \"00001\", \"01110\"],\n A: [\"01110\", \"10001\", \"10001\", \"11111\", \"10001\", \"10001\", \"10001\"],\n B: [\"11110\", \"10001\", \"10001\", \"11110\", \"10001\", \"10001\", \"11110\"],\n C: [\"01111\", \"10000\", \"10000\", \"10000\", \"10000\", \"10000\", \"01111\"],\n D: [\"11110\", \"10001\", \"10001\", \"10001\", \"10001\", \"10001\", \"11110\"],\n E: [\"11111\", \"10000\", \"10000\", \"11110\", \"10000\", \"10000\", \"11111\"],\n F: [\"11111\", \"10000\", \"10000\", \"11110\", \"10000\", \"10000\", \"10000\"],\n G: [\"01110\", \"10001\", \"10000\", \"10111\", \"10001\", \"10001\", \"01111\"],\n H: [\"10001\", \"10001\", \"10001\", \"11111\", \"10001\", \"10001\", \"10001\"],\n I: [\"01110\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"01110\"],\n J: [\"00111\", \"00010\", \"00010\", \"00010\", \"00010\", \"10010\", \"01100\"],\n K: [\"10001\", \"10010\", \"10100\", \"11000\", \"10100\", \"10010\", \"10001\"],\n L: [\"10000\", \"10000\", \"10000\", \"10000\", \"10000\", \"10000\", \"11111\"],\n M: [\"10001\", \"11011\", \"10101\", \"10101\", \"10001\", \"10001\", \"10001\"],\n N: [\"10001\", \"11001\", \"10101\", \"10011\", \"10001\", \"10001\", \"10001\"],\n O: [\"01110\", \"10001\", \"10001\", \"10001\", \"10001\", \"10001\", \"01110\"],\n P: [\"11110\", \"10001\", \"10001\", \"11110\", \"10000\", \"10000\", \"10000\"],\n Q: [\"01110\", \"10001\", \"10001\", \"10001\", \"10101\", \"10010\", \"01101\"],\n R: [\"11110\", \"10001\", \"10001\", \"11110\", \"10100\", \"10010\", \"10001\"],\n S: [\"01111\", \"10000\", \"10000\", \"01110\", \"00001\", \"00001\", \"11110\"],\n T: [\"11111\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\"],\n U: [\"10001\", \"10001\", \"10001\", \"10001\", \"10001\", \"10001\", \"01110\"],\n V: [\"10001\", \"10001\", \"10001\", \"10001\", \"10001\", \"01010\", \"00100\"],\n W: [\"10001\", \"10001\", \"10001\", \"10101\", \"10101\", \"11011\", \"10001\"],\n X: [\"10001\", \"10001\", \"01010\", \"00100\", \"01010\", \"10001\", \"10001\"],\n Y: [\"10001\", \"10001\", \"01010\", \"00100\", \"00100\", \"00100\", \"00100\"],\n Z: [\"11111\", \"00001\", \"00010\", \"00100\", \"01000\", \"10000\", \"11111\"],\n a: [\"00000\", \"00000\", \"01110\", \"00001\", \"01111\", \"10001\", \"01111\"],\n b: [\"10000\", \"10000\", \"10110\", \"11001\", \"10001\", \"10001\", \"11110\"],\n c: [\"00000\", \"00000\", \"01111\", \"10000\", \"10000\", \"10000\", \"01111\"],\n d: [\"00001\", \"00001\", \"01101\", \"10011\", \"10001\", \"10001\", \"01111\"],\n e: [\"00000\", \"00000\", \"01110\", \"10001\", \"11111\", \"10000\", \"01110\"],\n f: [\"00110\", \"01001\", \"01000\", \"11100\", \"01000\", \"01000\", \"01000\"],\n g: [\"00000\", \"01111\", \"10001\", \"10001\", \"01111\", \"00001\", \"01110\"],\n h: [\"10000\", \"10000\", \"10110\", \"11001\", \"10001\", \"10001\", \"10001\"],\n i: [\"00100\", \"00000\", \"01100\", \"00100\", \"00100\", \"00100\", \"01110\"],\n j: [\"00010\", \"00000\", \"00110\", \"00010\", \"00010\", \"10010\", \"01100\"],\n k: [\"10000\", \"10000\", \"10010\", \"10100\", \"11000\", \"10100\", \"10010\"],\n l: [\"01100\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"01110\"],\n m: [\"00000\", \"00000\", \"11010\", \"10101\", \"10101\", \"10101\", \"10101\"],\n n: [\"00000\", \"00000\", \"10110\", \"11001\", \"10001\", \"10001\", \"10001\"],\n o: [\"00000\", \"00000\", \"01110\", \"10001\", \"10001\", \"10001\", \"01110\"],\n p: [\"00000\", \"00000\", \"11110\", \"10001\", \"11110\", \"10000\", \"10000\"],\n q: [\"00000\", \"00000\", \"01111\", \"10001\", \"01111\", \"00001\", \"00001\"],\n r: [\"00000\", \"00000\", \"10111\", \"11000\", \"10000\", \"10000\", \"10000\"],\n s: [\"00000\", \"00000\", \"01111\", \"10000\", \"01110\", \"00001\", \"11110\"],\n t: [\"01000\", \"01000\", \"11100\", \"01000\", \"01000\", \"01001\", \"00110\"],\n u: [\"00000\", \"00000\", \"10001\", \"10001\", \"10001\", \"10011\", \"01101\"],\n v: [\"00000\", \"00000\", \"10001\", \"10001\", \"10001\", \"01010\", \"00100\"],\n w: [\"00000\", \"00000\", \"10001\", \"10001\", \"10101\", \"10101\", \"01010\"],\n x: [\"00000\", \"00000\", \"10001\", \"01010\", \"00100\", \"01010\", \"10001\"],\n y: [\"00000\", \"00000\", \"10001\", \"10001\", \"01111\", \"00001\", \"01110\"],\n z: [\"00000\", \"00000\", \"11111\", \"00010\", \"00100\", \"01000\", \"11111\"],\n \"-\": [\"00000\", \"00000\", \"00000\", \"11111\", \"00000\", \"00000\", \"00000\"],\n _: [\"00000\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\", \"11111\"],\n \":\": [\"00000\", \"00100\", \"00100\", \"00000\", \"00100\", \"00100\", \"00000\"],\n \".\": [\"00000\", \"00000\", \"00000\", \"00000\", \"00000\", \"00100\", \"00100\"],\n \",\": [\"00000\", \"00000\", \"00000\", \"00000\", \"00100\", \"00100\", \"01000\"],\n \"/\": [\"00001\", \"00010\", \"00010\", \"00100\", \"01000\", \"01000\", \"10000\"],\n \"\\\\\": [\"10000\", \"01000\", \"01000\", \"00100\", \"00010\", \"00010\", \"00001\"],\n \"(\": [\"00010\", \"00100\", \"01000\", \"01000\", \"01000\", \"00100\", \"00010\"],\n \")\": [\"01000\", \"00100\", \"00010\", \"00010\", \"00010\", \"00100\", \"01000\"],\n \"[\": [\"01110\", \"01000\", \"01000\", \"01000\", \"01000\", \"01000\", \"01110\"],\n \"]\": [\"01110\", \"00010\", \"00010\", \"00010\", \"00010\", \"00010\", \"01110\"],\n \"+\": [\"00000\", \"00100\", \"00100\", \"11111\", \"00100\", \"00100\", \"00000\"],\n \"=\": [\"00000\", \"00000\", \"11111\", \"00000\", \"11111\", \"00000\", \"00000\"],\n \"%\": [\"11001\", \"11010\", \"00010\", \"00100\", \"01000\", \"01011\", \"10011\"],\n \"?\": [\"01110\", \"10001\", \"00001\", \"00010\", \"00100\", \"00000\", \"00100\"],\n \"!\": [\"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"00000\", \"00100\"],\n \"#\": [\"01010\", \"01010\", \"11111\", \"01010\", \"11111\", \"01010\", \"01010\"],\n \"*\": [\"00000\", \"10101\", \"01110\", \"11111\", \"01110\", \"10101\", \"00000\"],\n \"<\": [\"00010\", \"00100\", \"01000\", \"10000\", \"01000\", \"00100\", \"00010\"],\n \">\": [\"01000\", \"00100\", \"00010\", \"00001\", \"00010\", \"00100\", \"01000\"],\n \"|\": [\"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\", \"00100\"],\n '\"': [\"01010\", \"01010\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\"],\n \"'\": [\"00100\", \"00100\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\"],\n \";\": [\"00000\", \"00100\", \"00100\", \"00000\", \"00100\", \"00100\", \"01000\"],\n \"@\": [\"01110\", \"10001\", \"10111\", \"10101\", \"10111\", \"10000\", \"01111\"],\n $: [\"00100\", \"01111\", \"10100\", \"01110\", \"00101\", \"11110\", \"00100\"],\n \"&\": [\"01100\", \"10010\", \"10100\", \"01000\", \"10101\", \"10010\", \"01101\"],\n \"^\": [\"00100\", \"01010\", \"10001\", \"00000\", \"00000\", \"00000\", \"00000\"],\n \"`\": [\"01000\", \"00100\", \"00000\", \"00000\", \"00000\", \"00000\", \"00000\"],\n \"~\": [\"00000\", \"00000\", \"01001\", \"10110\", \"00000\", \"00000\", \"00000\"],\n \"{\": [\"00011\", \"00100\", \"00100\", \"01000\", \"00100\", \"00100\", \"00011\"],\n \"}\": [\"11000\", \"00100\", \"00100\", \"00010\", \"00100\", \"00100\", \"11000\"],\n};\nfunction createCanvas(w: number, h: number): Canvas {\n let canvas;\n if (typeof document !== \"undefined\" && document.createElement)\n canvas = document.createElement(\"canvas\");\n else if (typeof OffscreenCanvas !== \"undefined\")\n canvas = new OffscreenCanvas(w, h);\n else\n throw new Error(\n 'System fonts need Canvas 2D. Use fonts: { mode: \"bitmap\" } in a DOM-free runtime.',\n );\n canvas.width = w;\n canvas.height = h;\n return canvas;\n}\nfunction wide(ch: string): boolean {\n const n = ch.codePointAt(0)!;\n return (\n n >= 0x1100 &&\n (n <= 0x115f ||\n (n >= 0x2e80 && n <= 0xa4cf) ||\n (n >= 0xac00 && n <= 0xd7a3) ||\n (n >= 0xf900 && n <= 0xfaff) ||\n (n >= 0xff00 && n <= 0xff60) ||\n n >= 0x1f300)\n );\n}\nclass Fonts {\n readonly config: Readonly<Required<FontOptions>>;\n readonly theme: DeepReadonly<ResolvedTheme>;\n private readonly cache: Map<string, Surface>;\n private canvas!: Canvas;\n private ctx!: Context2D;\n constructor(\n config: Readonly<Required<FontOptions>>,\n theme: DeepReadonly<ResolvedTheme>,\n ) {\n this.config = config;\n this.theme = theme;\n this.cache = new Map();\n if (config.mode === \"system\") {\n this.canvas = createCanvas(8, 8);\n const ctx = this.canvas.getContext(\"2d\", {\n willReadFrequently: true,\n }) as Context2D | null;\n check(ctx, \"Canvas 2D is unavailable.\");\n this.ctx = ctx;\n }\n }\n size(role: FontRole, scale: number = 1): number {\n return this.theme[`${role}Size`] * scale;\n }\n family(role: FontRole): string {\n return (\n (role === \"title\" || role === \"unit\" || role === \"caption\"\n ? this.config[`${role}Family`]\n : null) || this.config.family\n );\n }\n setup(role: FontRole, size: number): void {\n this.ctx.font =\n (role === \"caption\" ? \"bold \" : \"\") + size + \"px \" + this.family(role);\n this.ctx.textBaseline = \"alphabetic\";\n this.ctx.fillStyle = \"#000000\";\n if (\"fontKerning\" in this.ctx) this.ctx.fontKerning = \"none\";\n }\n width(\n value: string,\n role: FontRole,\n advance: number = 0,\n scale: number = 1,\n ): number {\n if (advance > 0)\n return [...value].reduce((n, ch) => n + advance * (wide(ch) ? 2 : 1), 0);\n if (this.config.mode === \"bitmap\")\n return [...value].length * this.size(role, scale) * 0.6;\n this.setup(role, this.size(role, scale));\n return this.ctx.measureText(value).width;\n }\n fit(\n value: string,\n maxWidth: number,\n role: FontRole,\n advance: number,\n scale: number = 1,\n ): string {\n if (this.width(value, role, advance, scale) <= maxWidth) return value;\n const end = \"...\";\n if (this.width(end, role, advance, scale) > maxWidth) return \"\";\n const a = [...value];\n while (\n a.length &&\n this.width(a.join(\"\") + end, role, advance, scale) > maxWidth\n )\n a.pop();\n return a.join(\"\") + end;\n }\n raster(\n value: string,\n role: FontRole,\n advance: number = 0,\n scale: number = 1,\n ): Surface {\n const key = JSON.stringify([value, role, advance, scale]);\n if (this.cache.has(key)) return this.cache.get(key)!;\n const size = this.size(role, scale),\n w = Math.max(1, Math.ceil(this.width(value, role, advance, scale)) + 4);\n let out;\n check(\n w <= 32768 && w * size < LIMITS.pixels,\n \"Text allocation limit exceeded.\",\n );\n if (this.config.mode === \"bitmap\") {\n const h = Math.max(1, round(size * 0.72));\n out = new Surface(w, h + 2);\n let x = 1;\n for (const ch of value) {\n let rows = PIXEL_GLYPHS[ch];\n if (!rows) {\n check(\n !this.config.strictGlyphs,\n \"Bitmap text supports printable ASCII only: \" + ch,\n );\n rows = PIXEL_GLYPHS[\"?\"];\n }\n const cell = advance > 0 ? advance : size * 0.6,\n gw = Math.max(1, Math.min(round(size * 0.5), Math.floor(cell) - 1));\n for (let yy = 0; yy < h; yy++)\n for (let xx = 0; xx < gw; xx++)\n if (\n rows[Math.min(6, Math.floor((yy / h) * 7))][\n Math.min(4, Math.floor((xx / gw) * 5))\n ] === \"1\"\n )\n out.pixel(round(x) + xx, yy + 1, [0, 0, 0, 255]);\n x += cell * (wide(ch) ? 2 : 1);\n }\n } else {\n this.setup(role, size);\n const metric = this.ctx.measureText(value || \"0\");\n const ascent = Math.ceil(metric.actualBoundingBoxAscent || size * 0.8),\n descent = Math.ceil(metric.actualBoundingBoxDescent || 0),\n h = Math.max(1, ascent + descent) + 2;\n this.canvas.width = w;\n this.canvas.height = h;\n this.setup(role, size);\n let x = 1;\n for (const ch of value) {\n this.ctx.fillText(ch, round(x), 1 + ascent);\n x +=\n advance > 0\n ? advance * (wide(ch) ? 2 : 1)\n : this.ctx.measureText(ch).width;\n }\n const d = this.ctx.getImageData(0, 0, w, h);\n out = new Surface(w, h);\n out.data.set(d.data);\n }\n if (this.cache.size >= 512)\n this.cache.delete(this.cache.keys().next().value!);\n this.cache.set(key, out);\n return out;\n }\n draw(\n im: Surface,\n x: number,\n y: number,\n value: string,\n role: FontRole,\n fill: Readonly<RGBA>,\n advance: number = 0,\n align: \"left\" | \"center\" | \"right\" = \"left\",\n centerY: boolean = false,\n scale: number = 1,\n ): void {\n if (!value) return;\n const r = this.raster(value, role, advance, scale),\n width = this.width(value, role, advance, scale);\n if (align === \"center\") x -= width / 2;\n else if (align === \"right\") x -= width;\n if (centerY) y -= (r.height - 2) / 2;\n const xx = round(x) - 1,\n yy = round(y) - 1,\n p: RGBA = [fill[0], fill[1], fill[2], 0];\n for (let sy = 0; sy < r.height; sy++)\n for (let sx = 0; sx < r.width; sx++) {\n const a = r.data[(sy * r.width + sx) * 4 + 3];\n if (a) {\n p[3] = round((a * fill[3]) / 255);\n im.pixel(xx + sx, yy + sy, p, true);\n }\n }\n }\n rotated(\n value: string,\n role: FontRole,\n fill: Readonly<RGBA>,\n clockwise: boolean = false,\n ): Surface {\n const r = this.raster(value, role),\n out = new Surface(r.height, r.width),\n p: RGBA = [fill[0], fill[1], fill[2], 0];\n for (let y = 0; y < r.height; y++)\n for (let x = 0; x < r.width; x++) {\n p[3] = round((r.data[(y * r.width + x) * 4 + 3] * fill[3]) / 255);\n if (p[3])\n out.pixel(\n clockwise ? r.height - 1 - y : y,\n clockwise ? x : r.width - 1 - x,\n p,\n );\n }\n return out;\n }\n}\nfunction renderChart(c: ChartConfig): RenderResult {\n const l = c.layout,\n t = c.theme,\n [width, height] = dimensions(c),\n left = l.left,\n top = l.top,\n right = l.width - l.right,\n bottom = l.top + l.plotHeight,\n pw = right - left,\n ph = bottom - top;\n const [start, end] = timeRange(c);\n const runs = c.series.map((s) => visibleRuns(s, start, end));\n let loData = Infinity,\n hiData = -Infinity;\n for (let i = 0; i < runs.length; i++) {\n for (const run of runs[i])\n for (const p of run) {\n check(finite(p[1]), \"Interpolated value overflow.\");\n loData = Math.min(loData, p[1]);\n hiData = Math.max(hiData, p[1]);\n }\n if (c.series[i].kind === \"area\") {\n loData = Math.min(loData, c.series[i].baseline);\n hiData = Math.max(hiData, c.series[i].baseline);\n }\n }\n if (loData === Infinity) loData = hiData = 0;\n const ys = resolveY(c.yAxis, loData, hiData),\n xs = resolveX(c.timeAxis, start, end, pw),\n fonts = new Fonts(c.fonts, t),\n im = new Surface(width, height, t.background);\n im.rect(left, top, right + 1, bottom + 1, t.canvas);\n const xx = (v: number): number => ((v - start) / (end - start)) * pw,\n yy = (v: number): number =>\n ph *\n (1 -\n (v / (ys.maximum - ys.minimum) -\n ys.minimum / (ys.maximum - ys.minimum)));\n const projected = runs.map((rr) =>\n rr.map((r) =>\n decimate(r, start, end, pw).map((p): Point => {\n const x = xx(p[0]),\n y = yy(p[1]);\n check(\n finite(x) && finite(y) && Math.abs(y) < 1e15,\n \"Data magnitude is too large relative to the Y axis.\",\n );\n return [x, y];\n }),\n ),\n );\n function grid(): void {\n const lay = new Surface(pw + 1, ph + 1);\n for (const [values, col] of [\n [ys.minor, t.minorGrid],\n [ys.major, t.majorGrid],\n ] as const)\n for (const v of values) {\n const y = round(yy(v));\n if (y >= 0 && y <= ph) lay.dashed([0, y], [pw, y], col, t.gridDash);\n }\n for (const [values, col] of [\n [xs.minor, t.minorGrid],\n [xs.major, t.majorGrid],\n ] as const)\n for (const v of values) {\n const x = round(xx(v));\n lay.dashed([x, 0], [x, ph], col, t.gridDash);\n }\n im.over(lay, left, top);\n }\n const aa = l.antialias,\n layerWidth = (pw + 1) * aa,\n layerHeight = (ph + 1) * aa;\n if (!t.gridFront) grid();\n for (let i = 0; i < c.series.length; i++) {\n const s = c.series[i];\n if (s.kind !== \"area\") continue;\n const base = yy(s.baseline);\n check(\n finite(base) && Math.abs(base) < 1e15,\n \"Baseline magnitude is too large.\",\n );\n const layer = new Surface(layerWidth, layerHeight);\n for (const ps of projected[i])\n if (ps.length > 1) {\n const poly = clipPolygon(\n [[ps[0][0], base], ...ps, [ps[ps.length - 1][0], base]],\n pw,\n ph,\n ).map((p): Point => [round(p[0] * aa), round(p[1] * aa)]);\n layer.polygon(poly, s.color);\n }\n im.over(layer.down(aa), left, top);\n }\n if (t.gridFront) grid();\n for (let i = 0; i < c.series.length; i++) {\n const s = c.series[i],\n col = s.kind === \"line\" ? s.color : s.outline;\n if (col === null) continue;\n const layer = new Surface(layerWidth, layerHeight),\n lw = Math.max(1, round(s.lineWidth * aa));\n for (const ps of projected[i]) {\n if (ps.length === 1) {\n const p = ps[0];\n if (p[0] >= 0 && p[0] <= pw && p[1] >= 0 && p[1] <= ph)\n layer.circle(p[0] * aa, p[1] * aa, Math.max(aa / 2, lw / 2), col);\n }\n for (let k = 1; k < ps.length; k++) {\n const seg = clipLine(ps[k - 1], ps[k], pw, ph);\n if (seg)\n layer.line(\n [round(seg[0][0] * aa), round(seg[0][1] * aa)],\n [round(seg[1][0] * aa), round(seg[1][1] * aa)],\n col,\n lw,\n );\n }\n }\n im.over(layer.down(aa), left, top);\n }\n const rules = new Surface(pw + 1, ph + 1);\n for (const r of c.hRules)\n if (r.value >= ys.minimum && r.value <= ys.maximum)\n rules.dashed(\n [0, round(yy(r.value))],\n [pw, round(yy(r.value))],\n r.color,\n r.dash,\n Math.max(1, round(r.width)),\n );\n for (const r of c.vRules)\n if (r.time >= start && r.time <= end)\n rules.dashed(\n [round(xx(r.time)), 0],\n [round(xx(r.time)), ph],\n r.color,\n r.dash,\n Math.max(1, round(r.width)),\n );\n im.over(rules, left, top);\n im.line([left, top - 3], [left, bottom + 4], t.axis);\n im.line([left - 4, bottom], [right + 4, bottom], t.axis);\n im.polygon(\n [\n [left, top - 5],\n [left - 3, top],\n [left + 3, top],\n ],\n t.arrow,\n );\n im.polygon(\n [\n [right + 7, bottom],\n [right + 2, bottom - 3],\n [right + 2, bottom + 3],\n ],\n t.arrow,\n );\n for (const v of ys.major) {\n const y = top + yy(v),\n unit =\n v === 0 && !c.yAxis.showZeroSuffix\n ? { factor: ys.factor, suffix: \"\" }\n : ys,\n label = formatValue(v, unit, ys.decimals);\n check(\n fonts.width(label, \"axis\", t.axisAdvance) <= left - l.yLabelGap - 20,\n \"Y labels overlap the vertical label. Increase layout.left or adjust units.\",\n );\n im.line([left - 3, round(y)], [left, round(y)], t.axis);\n fonts.draw(\n im,\n left - l.yLabelGap,\n y,\n label,\n \"axis\",\n t.text,\n t.axisAdvance,\n \"right\",\n true,\n );\n }\n const xLabels = [];\n let lastRight = -Infinity;\n for (const tick of xs.labels) {\n const x = left + xx(tick.time),\n tw = fonts.width(tick.label, \"axis\", t.axisAdvance),\n a = x - tw / 2,\n b = x + tw / 2;\n if (c.timeAxis.ticks === null && a < lastRight + 3) continue;\n if (a < 2 || b > width - 3) continue;\n im.line(\n [round(x), bottom],\n [round(x), bottom + 3],\n [t.majorGrid[0], t.majorGrid[1], t.majorGrid[2], 255],\n );\n fonts.draw(\n im,\n x,\n bottom + l.xLabelGap,\n tick.label,\n \"axis\",\n t.text,\n t.axisAdvance,\n \"center\",\n );\n lastRight = b;\n xLabels.push({ ...tick, x });\n }\n const titleX = (left + right) / 2 + l.titleOffsetX,\n title = fonts.fit(\n c.title,\n 2 * Math.min(titleX - 5, width - 14 - titleX),\n \"title\",\n t.titleAdvance,\n );\n fonts.draw(\n im,\n titleX,\n l.titleY,\n title,\n \"title\",\n t.text,\n t.titleAdvance,\n \"center\",\n );\n if (c.verticalLabel) {\n const unit = fonts.rotated(c.verticalLabel, \"unit\", t.text);\n check(\n unit.height <= ph + 18 && l.unitX + unit.width <= left - l.yLabelGap,\n \"Vertical label does not fit.\",\n );\n im.over(unit, l.unitX, round((top + bottom - unit.height) / 2));\n }\n if (c.watermark) {\n const mark = fonts.rotated(c.watermark, \"watermark\", t.watermark, true);\n check(\n mark.height <= height - 8 && mark.width <= l.right - 9,\n \"Watermark does not fit.\",\n );\n im.over(mark, width - mark.width - 4, 4);\n }\n const stats = c.series.map((s) => statistics(s, start, end));\n if (l.legend !== \"none\") {\n const scale = Math.min(1, (width - 40) / 555),\n advance = t.legendAdvance * scale,\n ll = l.legendLayout,\n factor = ll.autoScaleColumns\n ? (width - ll.nameX) / (ll.referenceWidth - ll.nameX)\n : 1,\n anchor = (x: number): number => ll.nameX + (x - ll.nameX) * factor;\n c.series.forEach((s, i) => {\n const pairs =\n l.legend === \"aligned\"\n ? ll.aligned\n : l.legend === \"reference\" && i === c.series.length - 1 && i > 0\n ? ll.expanded\n : ll.compact,\n y = bottom + l.legendGap + i * l.legendRowHeight;\n check(\n ll.swatchHeight <= l.legendRowHeight &&\n ll.swatchX + ll.swatchWidth < width &&\n y + ll.swatchHeight <= height - 2,\n \"Legend swatch does not fit.\",\n );\n im.rect(\n ll.swatchX,\n y,\n ll.swatchX + ll.swatchWidth,\n y + ll.swatchHeight,\n t.frame,\n );\n const swatch = new Surface(\n ll.swatchWidth - 2,\n ll.swatchHeight - 2,\n s.color,\n );\n im.over(swatch, ll.swatchX + 1, y + 1);\n const name = fonts.fit(\n s.name,\n anchor(pairs[0][0]) - ll.nameX - 12,\n \"legend\",\n advance,\n scale,\n );\n fonts.draw(\n im,\n ll.nameX,\n y,\n name,\n \"legend\",\n t.text,\n advance,\n \"left\",\n false,\n scale,\n );\n const display = s.legendValues || stats[i];\n ([\"current\", \"average\", \"maximum\"] as const).forEach((key, j) => {\n const label = c.legendLabels[j],\n value = formatValue(\n display[key],\n ys,\n c.yAxis.legendDecimals,\n c.missingLabel,\n ),\n a = anchor(pairs[j][0]),\n b = anchor(pairs[j][1]);\n check(b < width - 3, \"Legend column is outside the panel.\");\n check(\n fonts.width(label, \"legend\", advance, scale) +\n fonts.width(value, \"legend\", advance, scale) +\n 7 * scale <=\n b - a + 1,\n \"Legend statistic does not fit. Increase width, adjust anchors or reduce legendDecimals.\",\n );\n fonts.draw(\n im,\n a,\n y,\n label,\n \"legend\",\n t.text,\n advance,\n \"left\",\n false,\n scale,\n );\n fonts.draw(\n im,\n b,\n y,\n value,\n \"legend\",\n t.text,\n advance,\n \"right\",\n false,\n scale,\n );\n });\n });\n }\n for (const [a, b] of [\n [\n [0, 0],\n [width - 1, 0],\n ],\n [\n [1, 1],\n [width - 2, 1],\n ],\n [\n [0, 0],\n [0, height - 1],\n ],\n [\n [1, 1],\n [1, height - 2],\n ],\n ] as [Point, Point][])\n im.line(a, b, t.shadeLight);\n for (const [a, b] of [\n [\n [width - 2, 1],\n [width - 2, height - 1],\n ],\n [\n [width - 1, 0],\n [width - 1, height - 1],\n ],\n [\n [1, height - 2],\n [width - 1, height - 2],\n ],\n [\n [0, height - 1],\n [width - 1, height - 1],\n ],\n ] as [Point, Point][])\n im.line(a, b, t.shadeDark);\n for (let i = 3; i < im.data.length; i += 4) im.data[i] = 255;\n const out = im.scale(l.pixelScale);\n const metadata: GraphMetadata = {\n version: VERSION,\n imageSize: [out.width, out.height],\n logicalSize: [width, height],\n plotBox: [left, top, right, bottom],\n pixelScale: l.pixelScale,\n title: c.title,\n verticalLabel: c.verticalLabel,\n watermark: c.watermark,\n timeRange: [start, end],\n timezone: c.timeAxis.timezone,\n timeMode: xs.mode,\n yRange: [ys.minimum, ys.maximum],\n yStep: ys.step,\n yUnit: { factor: ys.factor, suffix: ys.suffix },\n xLabels,\n statistics: stats,\n statisticsPolicy:\n \"inclusive viewport; original sample arithmetic mean; current includes final missing sample\",\n font: {\n mode: c.fonts.mode,\n family: c.fonts.mode === \"system\" ? c.fonts.family : null,\n pixelAlphabet: c.fonts.mode === \"bitmap\" ? \"ascii-5x7-v1\" : null,\n },\n layout: clone(l),\n theme: clone(t),\n warnings:\n c.fonts.mode === \"system\"\n ? [\"System font selection and glyph rasterization depend on the host.\"]\n : [],\n };\n return new RenderResult(out, metadata);\n}\n// Dependency-free PNG encoder: adaptive row filters + deterministic fixed-Huffman DEFLATE.\n// No Canvas encoder or compression library is involved in exported PNG bytes.\nconst CRC_TABLE = (() => {\n const t = new Uint32Array(256);\n for (let i = 0; i < 256; i++) {\n let c = i;\n for (let j = 0; j < 8; j++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n t[i] = c >>> 0;\n }\n return t;\n})();\nfunction crc32(bytes: Uint8Array): number {\n let c = 0xffffffff;\n for (const b of bytes) c = CRC_TABLE[(c ^ b) & 255] ^ (c >>> 8);\n return (c ^ 0xffffffff) >>> 0;\n}\nfunction adler32(bytes: Uint8Array): number {\n let a = 1,\n b = 0;\n for (let i = 0; i < bytes.length;) {\n const end = Math.min(i + 5552, bytes.length);\n for (; i < end; i++) {\n a += bytes[i];\n b += a;\n }\n a %= 65521;\n b %= 65521;\n }\n return ((b << 16) | a) >>> 0;\n}\nfunction concat(parts: readonly Uint8Array[]): Uint8Array<ArrayBuffer> {\n const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));\n let at = 0;\n for (const p of parts) {\n out.set(p, at);\n at += p.length;\n }\n return out;\n}\nfunction u32(n: number): Uint8Array<ArrayBuffer> {\n return new Uint8Array([\n (n >>> 24) & 255,\n (n >>> 16) & 255,\n (n >>> 8) & 255,\n n & 255,\n ]);\n}\nfunction chunk(type: string, data: Uint8Array): Uint8Array<ArrayBuffer> {\n const code = Uint8Array.from(type, (c) => c.charCodeAt(0)),\n body = concat([code, data]);\n return concat([u32(data.length), body, u32(crc32(body))]);\n}\nfunction reverseBits(n: number, bits: number): number {\n let out = 0;\n for (let i = 0; i < bits; i++) {\n out = (out << 1) | (n & 1);\n n >>>= 1;\n }\n return out;\n}\nconst FIXED = (() => {\n const out = [];\n for (let i = 0; i < 288; i++) {\n let code, bits;\n if (i <= 143) {\n bits = 8;\n code = 0x30 + i;\n } else if (i <= 255) {\n bits = 9;\n code = 0x190 + i - 144;\n } else if (i <= 279) {\n bits = 7;\n code = i - 256;\n } else {\n bits = 8;\n code = 0xc0 + i - 280;\n }\n out.push([reverseBits(code, bits), bits]);\n }\n return out;\n})();\nconst LEN_BASE = [\n 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67,\n 83, 99, 115, 131, 163, 195, 227, 258,\n];\nconst LEN_EXTRA = [\n 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,\n 5, 5, 0,\n];\nconst DIST_BASE = [\n 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769,\n 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577,\n];\nconst DIST_EXTRA = [\n 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11,\n 11, 12, 12, 13, 13,\n];\nfunction deflate(data: Uint8Array): Uint8Array<ArrayBuffer> {\n let bytes = new Uint8Array(Math.max(128, data.length + 64)),\n len = 0,\n buffer = 0,\n count = 0;\n function byte(b: number): void {\n if (len === bytes.length) {\n const next = new Uint8Array(bytes.length * 2);\n next.set(bytes);\n bytes = next;\n }\n bytes[len++] = b;\n }\n function bits(value: number, n: number): void {\n buffer |= value << count;\n count += n;\n while (count >= 8) {\n byte(buffer & 255);\n buffer >>>= 8;\n count -= 8;\n }\n }\n const sym = (v: number): void => bits(FIXED[v][0], FIXED[v][1]);\n byte(0x78);\n byte(0x01);\n bits(3, 3); // final block, fixed Huffman\n const head = new Int32Array(65536).fill(-1),\n prev = new Int32Array(32768).fill(-1);\n const hash = (i: number): number =>\n ((data[i] * 251 + data[i + 1]) * 251 + data[i + 2]) & 65535;\n function insert(i: number): void {\n if (i + 2 >= data.length) return;\n const h = hash(i);\n prev[i & 32767] = head[h];\n head[h] = i;\n }\n for (let i = 0; i < data.length;) {\n let best = 0,\n dist = 0;\n if (i + 2 < data.length) {\n let candidate = head[hash(i)],\n tries = 64;\n const max = Math.min(258, data.length - i);\n while (\n candidate >= 0 &&\n i - candidate <= 32768 &&\n candidate < i &&\n tries--\n ) {\n if (\n data[candidate] === data[i] &&\n data[candidate + best] === data[i + best]\n ) {\n let n = 0;\n while (n < max && data[candidate + n] === data[i + n]) n++;\n if (n > best && n >= 3) {\n best = n;\n dist = i - candidate;\n if (n === max) break;\n }\n }\n const next = prev[candidate & 32767];\n if (next >= candidate) break;\n candidate = next;\n }\n }\n if (best >= 3) {\n let lc = 0;\n while (lc < 28 && LEN_BASE[lc + 1] <= best) lc++;\n sym(257 + lc);\n bits(best - LEN_BASE[lc], LEN_EXTRA[lc]);\n let dc = 0;\n while (dc < 29 && DIST_BASE[dc + 1] <= dist) dc++;\n bits(reverseBits(dc, 5), 5);\n bits(dist - DIST_BASE[dc], DIST_EXTRA[dc]);\n for (let j = 0; j < best; j++) insert(i + j);\n i += best;\n } else {\n sym(data[i]);\n insert(i);\n i++;\n }\n }\n sym(256);\n if (count) byte(buffer & 255);\n const sum = adler32(data);\n for (const b of u32(sum)) byte(b);\n return bytes.slice(0, len);\n}\nfunction paeth(a: number, b: number, c: number): number {\n const p = a + b - c,\n pa = Math.abs(p - a),\n pb = Math.abs(p - b),\n pc = Math.abs(p - c);\n return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;\n}\n/** Encode RGBA pixels as PNG with optional uncompressed UTF-8 chart metadata. */\nexport function encodePNG(\n image: RGBAImage,\n metadata: object | null = null,\n): Uint8Array<ArrayBuffer> {\n validateImage(image);\n check(\n image.width * image.height <= LIMITS.pixels,\n \"PNG image exceeds output limit.\",\n );\n const w = image.width,\n h = image.height,\n stride = w * 4,\n raw = new Uint8Array((stride + 1) * h),\n candidates = Array.from({ length: 5 }, () => new Uint8Array(stride));\n for (let y = 0; y < h; y++) {\n const scores = [0, 0, 0, 0, 0],\n off = y * stride;\n for (let x = 0; x < stride; x++) {\n const v = image.data[off + x],\n a = x >= 4 ? image.data[off + x - 4] : 0,\n b = y ? image.data[off + x - stride] : 0,\n c = y && x >= 4 ? image.data[off + x - stride - 4] : 0,\n predict = [0, a, b, Math.floor((a + b) / 2), paeth(a, b, c)];\n for (let f = 0; f < 5; f++) {\n const n = (v - predict[f]) & 255;\n candidates[f][x] = n;\n scores[f] += Math.min(n, 256 - n);\n }\n }\n let best = 0;\n for (let f = 1; f < 5; f++) if (scores[f] < scores[best]) best = f;\n raw[y * (stride + 1)] = best;\n raw.set(candidates[best], y * (stride + 1) + 1);\n }\n const ihdr = concat([u32(w), u32(h), new Uint8Array([8, 6, 0, 0, 0])]),\n parts = [\n new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]),\n chunk(\"IHDR\", ihdr),\n chunk(\"sRGB\", new Uint8Array([0])),\n ];\n if (metadata !== null) {\n const json = JSON.stringify(metadata);\n check(json.length <= 1048576, \"PNG metadata is too large.\");\n parts.push(\n chunk(\n \"iTXt\",\n concat([\n new TextEncoder().encode(\"chart\"),\n new Uint8Array([0, 0, 0, 0, 0]),\n new TextEncoder().encode(json),\n ]),\n ),\n );\n }\n parts.push(chunk(\"IDAT\", deflate(raw)), chunk(\"IEND\", new Uint8Array(0)));\n return concat(parts);\n}\nfunction validateImage(im: RGBAImage): void {\n check(\n im &&\n Number.isInteger(im.width) &&\n Number.isInteger(im.height) &&\n im.width > 0 &&\n im.height > 0 &&\n im.width * im.height <= LIMITS.layerPixels &&\n im.data &&\n im.data.length === im.width * im.height * 4,\n \"Expected an RGBA image with matching dimensions.\",\n );\n}\n/** Draw image bytes without browser resampling and return the target canvas. */\nexport function drawImageToCanvas(image: RGBAImage, canvas: Canvas): Canvas {\n validateImage(image);\n check(\n canvas && typeof canvas.getContext === \"function\",\n \"Expected a canvas element.\",\n );\n const ctx = canvas.getContext(\"2d\") as Context2D | null;\n check(ctx, \"Canvas 2D context is unavailable.\");\n canvas.width = image.width;\n canvas.height = image.height;\n const data = ctx.createImageData(image.width, image.height);\n data.data.set(image.data);\n ctx.putImageData(data, 0, 0);\n return canvas;\n}\n/** Download bytes in a browser; filenames may not contain path separators. */\nexport function downloadBytes(\n bytes: Uint8Array,\n name: string,\n type: string = \"application/octet-stream\",\n): void {\n check(\n typeof document !== \"undefined\",\n \"Downloads require a browser document.\",\n );\n text(name, \"Filename\");\n check(\n !/[\\\\/\\x00-\\x1f]/.test(name),\n \"Filename must not contain path separators or controls.\",\n );\n const data =\n bytes.buffer instanceof ArrayBuffer\n ? (bytes as Uint8Array<ArrayBuffer>)\n : new Uint8Array(bytes);\n const blob = new Blob([data], { type }),\n url = URL.createObjectURL(blob),\n a = document.createElement(\"a\");\n a.href = url;\n a.download = name;\n a.hidden = true;\n document.body.appendChild(a);\n a.click();\n a.remove();\n setTimeout(() => URL.revokeObjectURL(url), 30000);\n}\n/** Rendered pixels and a frozen manifest; PNG encoding never requires Canvas. */\nexport class RenderResult<M extends object = GraphMetadata> {\n /** Pixels intentionally remain mutable; exports observe subsequent edits. */\n readonly image: RGBAImage;\n /** Immutable metadata captured at rendering time. */\n readonly metadata: Readonly<M>;\n constructor(image: RGBAImage, metadata: M) {\n this.image = image;\n this.metadata = freeze(metadata);\n }\n get width(): number {\n return this.image.width;\n }\n get height(): number {\n return this.image.height;\n }\n get data(): RGBAImage[\"data\"] {\n return this.image.data;\n }\n draw(canvas: Canvas): Canvas {\n return drawImageToCanvas(this.image, canvas);\n }\n toPNG(options: PNGOptions = {}): Uint8Array<ArrayBuffer> {\n return encodePNG(\n this.image,\n options.metadata === false ? null : this.metadata,\n );\n }\n toBlob(options: PNGOptions = {}): Blob {\n return new Blob([this.toPNG(options)], { type: \"image/png\" });\n }\n download(filename: string = \"chart.png\", options: PNGOptions = {}): void {\n downloadBytes(this.toPNG(options), filename, \"image/png\");\n }\n}\n/** An immutable validated chart. Use with() to derive a changed chart. */\nexport class Chart {\n /** Fully normalized, deeply frozen options used by every render. */\n readonly config: DeepReadonly<ResolvedChartOptions>;\n constructor(options: ChartOptions = {}) {\n this.config = normalize(options);\n Object.freeze(this);\n }\n with(patch: ChartOptions): Chart {\n return new Chart(merge(this.config, patch));\n }\n render(): RenderResult {\n return renderChart(this.config);\n }\n draw(canvas: Canvas): RenderResult {\n const r = this.render();\n r.draw(canvas);\n return r;\n }\n toPNG(options: PNGOptions = {}): Uint8Array<ArrayBuffer> {\n return this.render().toPNG(options);\n }\n mount(canvas: HTMLCanvasElement, options: MountOptions = {}): Controller {\n return new BrowserController(this, canvas, options);\n }\n nearest(input: Timestamp): NearestSample[] {\n const time = epoch(input);\n const [start, end] = timeRange(this.config);\n return this.config.series.map((s) => {\n const lo = lowerBound(s.timestamps, start),\n hi = upperBound(s.timestamps, end);\n if (lo === hi)\n return { name: s.name, index: null, time: null, value: null };\n let i = clamp(lowerBound(s.timestamps, time), lo, hi - 1);\n if (\n i > lo &&\n Math.abs(s.timestamps[i - 1] - time) <= Math.abs(s.timestamps[i] - time)\n )\n i--;\n return {\n name: s.name,\n index: i,\n time: s.timestamps[i],\n value: finite(s.values[i]) ? s.values[i] : null,\n };\n });\n }\n}\n/** Build the conventional inbound area and outbound line without unit conversion. */\nexport function traffic(\n timestamps: ArrayLike<Timestamp>,\n inbound: Values,\n outbound: Values,\n options: TrafficOptions = {},\n): Chart {\n const gap = options.gapAfter === undefined ? 0 : options.gapAfter,\n opts = { ...options };\n delete opts.gapAfter;\n return new Chart(\n merge(\n {\n title: \"Traffic - ether1\",\n verticalLabel: \"bits per second\",\n series: [\n series(\"Inbound\", timestamps, inbound, {\n kind: \"area\",\n color: \"#00cc00\",\n outline: \"#003000\",\n gapAfter: gap,\n }),\n series(\"Outbound\", timestamps, outbound, {\n kind: \"line\",\n color: \"#0000cc\",\n gapAfter: gap,\n }),\n ],\n },\n opts,\n ),\n );\n}\n/** Compose native chart renders and optional captions at a shared pixel scale. */\nexport function dashboard(\n panels: readonly (DashboardPanel | Chart)[],\n options: DashboardOptions = {},\n): RenderResult<DashboardMetadata> {\n check(\n Array.isArray(panels) && panels.length > 0 && panels.length <= 128,\n \"Dashboard requires 1..128 panels.\",\n );\n const o = merge<Required<DashboardOptions>>(\n { gap: 24, padding: [4, 3, 6, 6], background: \"#f3f3f3\", cropHeight: null },\n options,\n );\n integer(o.gap, \"Panel gap\", 0, 4096);\n check(\n Array.isArray(o.padding) && o.padding.length === 4,\n \"Padding is [left, top, right, bottom].\",\n );\n o.padding.forEach((v) => integer(v, \"Padding\", 0, 4096));\n if (o.cropHeight !== null) integer(o.cropHeight, \"Crop height\", 1, 65536);\n const pp = panels.map((p) =>\n p instanceof Chart ? { chart: p, caption: \"\" } : p,\n );\n for (const p of pp) {\n check(p.chart instanceof Chart, \"Panel needs a Chart.\");\n text(p.caption || \"\", \"Caption\");\n }\n const scale = pp[0].chart.config.layout.pixelScale;\n check(\n pp.every((p) => p.chart.config.layout.pixelScale === scale),\n \"Dashboard panels must have equal pixelScale.\",\n );\n const rendered = pp.map((p) => p.chart.render()),\n left = o.padding[0] * scale,\n top = o.padding[1] * scale,\n gap = o.gap * scale;\n const width =\n Math.max(...rendered.map((r) => r.width)) +\n (o.padding[0] + o.padding[2]) * scale;\n let height =\n rendered.reduce((n, r) => n + r.height, 0) +\n (o.padding[1] + o.padding[3]) * scale +\n gap * (pp.length - 1 + (pp[pp.length - 1].caption ? 1 : 0));\n if (o.cropHeight !== null) height = Math.min(height, o.cropHeight * scale);\n check(width * height <= LIMITS.pixels, \"Dashboard is too large.\");\n const out = new Surface(width, height, color(o.background));\n let y = top;\n const meta: DashboardMetadata[\"panels\"] = [];\n for (let i = 0; i < pp.length; i++) {\n const r = rendered[i],\n p = pp[i];\n out.over(r.image, left, y);\n meta.push({\n position: [left, y],\n caption: p.caption || \"\",\n chart: r.metadata,\n });\n y += r.height;\n if (p.caption) {\n const f = new Fonts(p.chart.config.fonts, p.chart.config.theme),\n w = f.width(p.caption, \"caption\"),\n h = p.chart.config.theme.captionSize;\n check(\n w <= width / scale - 8 && h + 4 <= o.gap,\n \"Caption does not fit the dashboard gap.\",\n );\n const line = new Surface(width / scale, o.gap);\n f.draw(\n line,\n width / scale / 2,\n 4,\n p.caption,\n \"caption\",\n p.chart.config.theme.text,\n 0,\n \"center\",\n );\n out.over(line.scale(scale), 0, y);\n }\n y += gap;\n }\n return new RenderResult<DashboardMetadata>(out, {\n version: VERSION,\n imageSize: [width, height],\n pixelScale: scale,\n panels: meta,\n });\n}\n/** Compute right-endpoint rates with exact BigInt counter subtraction. */\nexport function counterRate(\n timestamps: ArrayLike<Timestamp>,\n counters: ArrayLike<number | bigint | null | undefined>,\n options: CounterOptions = {},\n): Samples {\n const o = merge<Required<CounterOptions>>(\n { factor: 1, onDecrease: \"gap\", counterBits: null, maxRate: null },\n options,\n );\n number(o.factor, \"Rate factor\", Number.MIN_VALUE);\n check(\n [\"gap\", \"wrap\"].includes(o.onDecrease),\n \"Decrease policy must be gap or wrap.\",\n );\n if (o.counterBits !== null) integer(o.counterBits, \"Counter bits\", 1, 128);\n if (o.maxRate !== null) number(o.maxRate, \"Maximum rate\", 0);\n check(\n o.onDecrease !== \"wrap\" || o.counterBits !== null,\n \"Wrapping requires an explicit counterBits.\",\n );\n check(\n (Array.isArray(counters) || ArrayBuffer.isView(counters)) &&\n counters.length === timestamps.length,\n \"Counter and timestamp lengths must match.\",\n );\n const s = samples(\n timestamps,\n Array.from(counters, () => 0),\n ),\n max = (1n << BigInt(o.counterBits || 128)) - 1n;\n const cs = Array.from(counters, (v, i) => {\n if (missing(v)) return null;\n if (typeof v === \"number\") {\n check(\n Number.isSafeInteger(v) && v >= 0,\n \"Counter \" +\n i +\n \" must be a safe nonnegative integer; use BigInt for large counters.\",\n );\n v = BigInt(v);\n }\n check(\n typeof v === \"bigint\" && v >= 0n && v <= max,\n \"Counter must fit the configured unsigned bit width.\",\n );\n return v;\n });\n s.values.fill(NaN);\n for (let i = 1; i < cs.length; i++) {\n const current = cs[i],\n previous = cs[i - 1];\n if (current === null || previous === null) continue;\n let d = current - previous;\n if (d < 0n) {\n if (o.onDecrease === \"gap\") continue;\n d += max + 1n;\n }\n const v = (Number(d) * o.factor) / (s.timestamps[i] - s.timestamps[i - 1]);\n check(finite(v), \"Counter rate overflow.\");\n if (o.maxRate === null || v <= o.maxRate) s.values[i] = v;\n }\n return s;\n}\n/** Aggregate elapsed-time buckets, preserving gaps and explicit coverage policy. */\nexport function aggregate(\n timestamps: ArrayLike<Timestamp>,\n values: Values,\n options: AggregateOptions = {},\n): Samples {\n const o = merge<Required<AggregateOptions>>(\n {\n interval: 300,\n method: \"mean\",\n origin: 0,\n minCoverage: 0,\n expectedStep: null,\n maxBuckets: 1000000,\n },\n options,\n );\n number(o.interval, \"Aggregation interval\", 0.001);\n number(o.origin, \"Aggregation origin\");\n number(o.minCoverage, \"Minimum coverage\", 0, 1);\n if (o.expectedStep !== null)\n number(o.expectedStep, \"Expected step\", Number.MIN_VALUE);\n integer(o.maxBuckets, \"Maximum buckets\", 1, 1000000);\n check(\n [\"mean\", \"min\", \"max\", \"last\", \"sum\"].includes(o.method),\n \"Unknown aggregation method.\",\n );\n const s = samples(timestamps, values);\n if (!s.timestamps.length) return s;\n const bucket = (t: number): number => Math.floor((t - o.origin) / o.interval),\n a = bucket(s.timestamps[0]),\n b = bucket(s.timestamps[s.timestamps.length - 1]);\n check(\n Number.isSafeInteger(a) &&\n Number.isSafeInteger(b) &&\n b - a + 1 <= o.maxBuckets,\n \"Aggregation bucket limit or precision exceeded.\",\n );\n const out: Samples = { timestamps: [], values: [] };\n let i = 0;\n for (let k = a; k <= b; k++) {\n const ts = o.origin + k * o.interval;\n epoch(ts);\n out.timestamps.push(ts);\n let total = 0,\n last = NaN,\n mn = Infinity,\n mx = -Infinity;\n const finiteValues = [];\n while (i < s.timestamps.length && bucket(s.timestamps[i]) === k) {\n const v = s.values[i++];\n total++;\n last = v;\n if (finite(v)) {\n finiteValues.push(v);\n mn = Math.min(mn, v);\n mx = Math.max(mx, v);\n }\n }\n const denominator = Math.max(\n total,\n o.expectedStep === null ? 0 : o.interval / o.expectedStep,\n );\n if (\n !finiteValues.length ||\n finiteValues.length / denominator < o.minCoverage\n ) {\n out.values.push(NaN);\n continue;\n }\n let value;\n if (o.method === \"mean\") value = stableMean(finiteValues)!;\n else if (o.method === \"min\") value = mn;\n else if (o.method === \"max\") value = mx;\n else if (o.method === \"last\") value = last;\n else {\n value = stableMean(finiteValues)! * finiteValues.length;\n check(finite(value), \"Aggregation sum overflow.\");\n }\n out.values.push(value);\n }\n return out;\n}\n/** Parse quoted CSV into validated series; timestamps must strictly increase. */\nexport function parseCSV(input: string, options: CSVOptions = {}): Series[] {\n const o = merge<Required<CSVOptions>>(\n {\n timestampColumn: \"timestamp\",\n columns: [\n {\n column: \"inbound\",\n name: \"Inbound\",\n kind: \"area\",\n color: \"#00cc00\",\n outline: \"#003000\",\n },\n {\n column: \"outbound\",\n name: \"Outbound\",\n kind: \"line\",\n color: \"#0000cc\",\n },\n ],\n maxRows: 1000000,\n maxBytes: 16777216,\n },\n options,\n );\n check(typeof input === \"string\", \"CSV must be a string.\");\n integer(o.maxRows, \"Maximum CSV rows\", 1, 2000000);\n integer(o.maxBytes, \"Maximum CSV bytes\", 1, 67108864);\n check(\n input.length <= o.maxBytes &&\n new TextEncoder().encode(input).length <= o.maxBytes,\n \"CSV exceeds the configured byte limit.\",\n );\n check(\n Array.isArray(o.columns) && o.columns.length > 0 && o.columns.length <= 128,\n \"CSV needs at least one column mapping.\",\n );\n if (input.charCodeAt(0) === 0xfeff) input = input.slice(1);\n const rows: string[][] = [];\n let row: string[] = [],\n cell = \"\",\n quoted = false,\n closed = false;\n function endCell(): void {\n row.push(cell);\n cell = \"\";\n closed = false;\n }\n function endRow(): void {\n endCell();\n if (row.some((v) => v !== \"\")) rows.push(row);\n row = [];\n check(rows.length <= o.maxRows + 1, \"CSV row limit exceeded.\");\n }\n for (let i = 0; i < input.length; i++) {\n const ch = input[i];\n if (quoted) {\n if (ch === '\"') {\n if (input[i + 1] === '\"') {\n cell += '\"';\n i++;\n } else {\n quoted = false;\n closed = true;\n }\n } else cell += ch;\n continue;\n }\n if (closed) {\n check(\n ch === \",\" || ch === \"\\r\" || ch === \"\\n\",\n \"Unexpected text after a closing CSV quote.\",\n );\n }\n if (ch === '\"') {\n check(\n cell === \"\" && !closed,\n \"Unexpected quote in an unquoted CSV field.\",\n );\n quoted = true;\n } else if (ch === \",\") endCell();\n else if (ch === \"\\n\" || ch === \"\\r\") {\n if (ch === \"\\r\" && input[i + 1] === \"\\n\") i++;\n endRow();\n } else cell += ch;\n }\n check(!quoted, \"Unterminated quoted CSV field.\");\n if (cell !== \"\" || row.length || closed) endRow();\n check(rows.length >= 1, \"CSV header is missing.\");\n const header = rows.shift()!.map((v) => v.trim());\n check(\n header.every(Boolean) && new Set(header).size === header.length,\n \"CSV headers must be nonempty and unique.\",\n );\n const ti = header.indexOf(o.timestampColumn);\n check(ti >= 0, \"Timestamp column not found: \" + o.timestampColumn);\n const ids = o.columns.map((v) => {\n const i = header.indexOf(v.column);\n check(i >= 0, \"Column not found: \" + v.column);\n return i;\n });\n const ts: number[] = [],\n vv: number[][] = o.columns.map(() => []);\n for (let i = 0; i < rows.length; i++) {\n const r = rows[i];\n check(\n r.length === header.length,\n \"CSV row \" + (i + 2) + \" has the wrong number of columns.\",\n );\n try {\n ts.push(epoch(r[ti]));\n } catch (e) {\n throw new RangeError(\n \"CSV row \" +\n (i + 2) +\n \": \" +\n (e instanceof Error ? e.message : String(e)),\n );\n }\n ids.forEach((id, j) => {\n const v = r[id].trim();\n if (/^(?:nan|none|null)?$/i.test(v)) {\n vv[j].push(NaN);\n return;\n }\n check(\n /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?$/i.test(v),\n \"Invalid numeric CSV value at row \" + (i + 2) + \".\",\n );\n vv[j].push(number(Number(v), \"CSV value\"));\n });\n }\n return o.columns.map((v, j) => series(v.name || v.column, ts, vv[j], v));\n}\n/** Export the union of series timestamps, escaping formula-like text headers. */\nexport function toCSV(\n list: readonly SeriesInput[],\n options: { escapeFormulas?: boolean } = {},\n): string {\n check(\n Array.isArray(list) && list.length <= 128,\n \"Expected an array of series.\",\n );\n const escaped = options.escapeFormulas !== false;\n const ss = list.map((s) => series(s.name, s.timestamps, s.values, s));\n let total = 0;\n for (const s of ss) total += s.timestamps.length;\n check(\n total <= LIMITS.samples,\n \"CSV export exceeds the combined sample limit.\",\n );\n const times = [...new Set(ss.flatMap((s) => s.timestamps))].sort(\n (a, b) => a - b,\n );\n check(\n new Set(ss.map((s) => s.name)).size === ss.length &&\n !ss.some((s) => s.name === \"timestamp\"),\n \"CSV series names must be unique and not timestamp.\",\n );\n const quote = (v: string): string => {\n v = String(v);\n if (escaped && /^[=+\\-@\\t\\r]/.test(v)) v = \"'\" + v;\n return /[,\"\\r\\n]/.test(v) ? '\"' + v.replace(/\"/g, '\"\"') + '\"' : v;\n };\n const lines = [[\"timestamp\", ...ss.map((s) => s.name)].map(quote).join(\",\")],\n indexes = ss.map(() => 0);\n for (const t of times) {\n const cells = [String(t)];\n ss.forEach((s, j) => {\n while (indexes[j] < s.timestamps.length && s.timestamps[indexes[j]] < t)\n indexes[j]++;\n const i = indexes[j];\n cells.push(\n i < s.timestamps.length && s.timestamps[i] === t && finite(s.values[i])\n ? String(s.values[i])\n : \"\",\n );\n });\n lines.push(cells.join(\",\"));\n }\n return lines.join(\"\\r\\n\") + \"\\r\\n\";\n}\n/** Compare RGB pixels without aligning or resizing; alpha is ignored. */\nexport function compareImages(\n reference: RGBAImage | RenderResult<object>,\n actual: RGBAImage | RenderResult<object>,\n options: CompareOptions = {},\n): PixelDifference {\n const a = reference instanceof RenderResult ? reference.image : reference,\n b = actual instanceof RenderResult ? actual.image : actual;\n validateImage(a);\n validateImage(b);\n check(\n a.width === b.width && a.height === b.height,\n \"Image sizes must match; comparison never aligns or resizes.\",\n );\n const tolerance = options.tolerance === undefined ? 0 : options.tolerance;\n integer(tolerance, \"Tolerance\", 0, 255);\n const box = options.box || [0, 0, a.width, a.height];\n check(\n Array.isArray(box) && box.length === 4,\n \"Comparison box needs four coordinates.\",\n );\n box.forEach((v) => integer(v, \"Comparison coordinate\", 0, 65536));\n const [x0, y0, x1, y1] = box;\n check(\n x1 > x0 && y1 > y0 && x1 <= a.width && y1 <= a.height,\n \"Comparison box is out of bounds.\",\n );\n let exact = 0,\n within = 0,\n sum = 0,\n square = 0,\n maxError = 0,\n loX = Infinity,\n loY = Infinity,\n hiX = -Infinity,\n hiY = -Infinity;\n for (let y = y0; y < y1; y++)\n for (let x = x0; x < x1; x++) {\n const i = (y * a.width + x) * 4;\n let err = 0;\n for (let k = 0; k < 3; k++) {\n const d = Math.abs(a.data[i + k] - b.data[i + k]);\n sum += d;\n square += d * d;\n err = Math.max(err, d);\n }\n maxError = Math.max(maxError, err);\n if (err === 0) exact++;\n else {\n loX = Math.min(loX, x - x0);\n loY = Math.min(loY, y - y0);\n hiX = Math.max(hiX, x - x0);\n hiY = Math.max(hiY, y - y0);\n }\n if (err <= tolerance) within++;\n }\n const count = (x1 - x0) * (y1 - y0);\n return {\n pixels: count,\n exactPixels: exact,\n exactRatio: exact / count,\n toleranceRatio: within / count,\n meanAbsoluteError: sum / (count * 3),\n rootMeanSquareError: Math.sqrt(square / (count * 3)),\n maxError,\n differenceBox: loX === Infinity ? null : [loX, loY, hiX + 1, hiY + 1],\n };\n}\n/** Visualize amplified absolute RGB differences in matching images. */\nexport function differenceImage(\n reference: RGBAImage | RenderResult<object>,\n actual: RGBAImage | RenderResult<object>,\n amplify: number = 4,\n): RenderResult<{ imageSize: [number, number]; amplify: number }> {\n number(amplify, \"Difference amplification\", 0, 255);\n const a = reference instanceof RenderResult ? reference.image : reference,\n b = actual instanceof RenderResult ? actual.image : actual;\n compareImages(a, b);\n const out = new Surface(a.width, a.height);\n for (let i = 0; i < a.data.length; i += 4) {\n for (let k = 0; k < 3; k++)\n out.data[i + k] = Math.min(\n 255,\n round(Math.abs(a.data[i + k] - b.data[i + k]) * amplify),\n );\n out.data[i + 3] = 255;\n }\n return new RenderResult(out, { imageSize: [out.width, out.height], amplify });\n}\n/** Copy Canvas2D pixels into independently owned RGBA storage. */\nexport function readCanvas(canvas: Canvas): RGBAImage {\n check(\n canvas && typeof canvas.getContext === \"function\",\n \"Expected a canvas.\",\n );\n const c = canvas.getContext(\"2d\") as Context2D | null;\n check(c, \"Canvas 2D is unavailable.\");\n const data = c.getImageData(0, 0, canvas.width, canvas.height);\n const out = new Surface(data.width, data.height);\n out.data.set(data.data);\n return out;\n}\n/** Check PNG dimensions and decode with the browser image decoder. */\nexport async function decodeImage(blob: Blob): Promise<RGBAImage> {\n check(\n typeof Blob !== \"undefined\" && blob instanceof Blob,\n \"decodeImage expects a Blob or File.\",\n );\n check(blob.size <= 67108864, \"Image file exceeds 64 MiB.\");\n // Header dimensions are checked before a PNG is passed to the browser decoder.\n const head = new Uint8Array(await blob.slice(0, 24).arrayBuffer());\n check(\n head.length >= 24 &&\n [137, 80, 78, 71, 13, 10, 26, 10].every((v, i) => head[i] === v) &&\n head[12] === 73 &&\n head[13] === 72 &&\n head[14] === 68 &&\n head[15] === 82,\n \"decodeImage accepts PNG files only.\",\n );\n const headerView = new DataView(head.buffer),\n width = headerView.getUint32(16),\n height = headerView.getUint32(20);\n check(\n width > 0 && height > 0 && width * height <= LIMITS.pixels,\n \"Decoded PNG exceeds the pixel limit.\",\n );\n check(\n typeof createImageBitmap === \"function\",\n \"This browser does not expose createImageBitmap.\",\n );\n const bitmap = await createImageBitmap(blob);\n try {\n check(\n bitmap.width * bitmap.height <= LIMITS.pixels,\n \"Decoded image exceeds the pixel limit.\",\n );\n const canvas = createCanvas(bitmap.width, bitmap.height);\n const ctx = canvas.getContext(\"2d\") as Context2D | null;\n check(ctx, \"Canvas 2D is unavailable.\");\n ctx.drawImage(bitmap, 0, 0);\n return readCanvas(canvas);\n } finally {\n bitmap.close();\n }\n}\n// Browser controller. Cursor and tooltip live on an overlay, never in exported pixels.\nclass BrowserController implements Controller {\n chart: Chart;\n readonly canvas: MountedCanvas;\n readonly options: MountOptions & { interactive: boolean };\n destroyed: boolean;\n result: RenderResult;\n private readonly handlers: [HTMLCanvasElement, string, EventListener][];\n private cursorTime: number | null;\n private readonly saved: {\n style: string | null;\n role: string | null;\n label: string | null;\n tab: string | null;\n };\n private readonly marker: Comment;\n private readonly wrap: HTMLSpanElement;\n private readonly overlay: HTMLCanvasElement;\n private readonly tip: HTMLDivElement;\n private readonly status: HTMLSpanElement;\n constructor(chart: Chart, canvas: MountedCanvas, options: MountOptions = {}) {\n check(\n typeof document !== \"undefined\" && canvas && canvas.ownerDocument,\n \"mount requires an HTML canvas in a document.\",\n );\n check(canvas.parentNode, \"Attach the canvas to the document before mount.\");\n check(\n !canvas.__bamtiGraphController,\n \"A controller is already mounted on this canvas.\",\n );\n this.chart = chart;\n this.canvas = canvas;\n this.options = { interactive: true, ...options };\n this.destroyed = false;\n this.handlers = [];\n this.cursorTime = null;\n this.result = chart.render();\n this.saved = {\n style: canvas.getAttribute(\"style\"),\n role: canvas.getAttribute(\"role\"),\n label: canvas.getAttribute(\"aria-label\"),\n tab: canvas.getAttribute(\"tabindex\"),\n };\n this.marker = document.createComment(\"canvas position\");\n canvas.parentNode.insertBefore(this.marker, canvas);\n this.wrap = document.createElement(\"span\");\n this.wrap.style.cssText =\n \"position:relative;display:inline-block;vertical-align:top;line-height:0;max-width:none;\";\n canvas.parentNode.insertBefore(this.wrap, canvas);\n this.wrap.appendChild(canvas);\n canvas.style.display = \"block\";\n canvas.style.maxWidth = \"none\";\n canvas.setAttribute(\"role\", \"img\");\n this.overlay = document.createElement(\"canvas\");\n this.overlay.setAttribute(\"aria-hidden\", \"true\");\n this.overlay.style.cssText =\n \"position:absolute;left:0;top:0;pointer-events:none;\";\n this.wrap.appendChild(this.overlay);\n this.tip = document.createElement(\"div\");\n this.tip.hidden = true;\n this.tip.setAttribute(\"role\", \"status\");\n this.tip.style.cssText =\n \"position:absolute;z-index:5;pointer-events:none;background:#111827;color:#fff;border:1px solid #4b5563;padding:9px 11px;border-radius:5px;font:11px/1.65 ui-monospace,monospace;white-space:pre;box-shadow:0 4px 18px #0003;text-align:left;\";\n this.wrap.appendChild(this.tip);\n this.status = document.createElement(\"span\");\n this.status.setAttribute(\"aria-live\", \"polite\");\n this.status.style.cssText =\n \"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;\";\n this.wrap.appendChild(this.status);\n this.apply(this.result);\n canvas.__bamtiGraphController = this;\n if (this.options.interactive) {\n canvas.tabIndex = 0;\n this.on(canvas, \"pointermove\", (e) => {\n const rect = canvas.getBoundingClientRect(),\n x = ((e.clientX - rect.left) * canvas.width) / rect.width,\n y = ((e.clientY - rect.top) * canvas.height) / rect.height,\n m = this.result.metadata,\n s = m.pixelScale,\n [l, t, r, b] = m.plotBox;\n if (x < l * s || x > r * s || y < t * s || y > b * s) {\n this.clear();\n return;\n }\n const time =\n m.timeRange[0] +\n ((x / s - l) / (r - l)) * (m.timeRange[1] - m.timeRange[0]);\n this.show(time, false);\n });\n this.on(canvas, \"pointerleave\", () => this.clear());\n this.on(canvas, \"blur\", () => this.clear());\n this.on(canvas, \"keydown\", (e) => {\n if (\n ![\"ArrowLeft\", \"ArrowRight\", \"Home\", \"End\", \"Escape\"].includes(e.key)\n )\n return;\n e.preventDefault();\n if (e.key === \"Escape\") {\n this.clear();\n return;\n }\n const [a, b] = this.result.metadata.timeRange,\n s = this.chart.config.series.find((s) => s.timestamps.length),\n visible = s\n ? s.timestamps.slice(\n lowerBound(s.timestamps, a),\n upperBound(s.timestamps, b),\n )\n : [];\n let time;\n if (e.key === \"Home\") time = visible[0] === undefined ? a : visible[0];\n else if (e.key === \"End\")\n time = visible.length ? visible[visible.length - 1] : b;\n else if (visible.length) {\n let i =\n this.cursorTime === null\n ? e.key === \"ArrowRight\"\n ? -1\n : visible.length\n : lowerBound(visible, this.cursorTime);\n i = clamp(\n i + (e.key === \"ArrowRight\" ? 1 : -1) * (e.shiftKey ? 10 : 1),\n 0,\n visible.length - 1,\n );\n time = visible[i];\n } else\n time = clamp(\n (this.cursorTime === null ? a : this.cursorTime) +\n ((e.key === \"ArrowRight\" ? 1 : -1) * (b - a)) / 100,\n a,\n b,\n );\n this.show(time, true);\n });\n }\n }\n on<K extends keyof HTMLElementEventMap>(\n target: HTMLCanvasElement,\n type: K,\n fn: (event: HTMLElementEventMap[K]) => void,\n ): void {\n target.addEventListener(type, fn);\n this.handlers.push([target, type, fn as EventListener]);\n }\n apply(r: RenderResult): void {\n this.result = r;\n r.draw(this.canvas);\n this.overlay.width = r.width;\n this.overlay.height = r.height;\n const m = r.metadata;\n this.canvas.setAttribute(\n \"aria-label\",\n this.options.ariaLabel ||\n [\n m.title || \"Time-series chart\",\n m.verticalLabel,\n ...m.statistics.map(\n (s) =>\n s.name +\n \": current \" +\n (s.current === null\n ? \"missing\"\n : formatValue(s.current, m.yUnit, 2)),\n ),\n ].join(\". \"),\n );\n this.wrap.style.width = r.width + \"px\";\n this.wrap.style.height = r.height + \"px\";\n this.clear();\n }\n show(time: number, announce: boolean): void {\n if (this.destroyed) return;\n const m = this.result.metadata,\n s = m.pixelScale,\n [left, top, right, bottom] = m.plotBox,\n ctx = this.overlay.getContext(\"2d\")!,\n x =\n (left +\n ((time - m.timeRange[0]) / (m.timeRange[1] - m.timeRange[0])) *\n (right - left)) *\n s;\n ctx.clearRect(0, 0, this.overlay.width, this.overlay.height);\n ctx.beginPath();\n ctx.strokeStyle = \"#555\";\n ctx.lineWidth = 1;\n ctx.setLineDash([2, 2]);\n ctx.moveTo(round(x) + 0.5, top * s);\n ctx.lineTo(round(x) + 0.5, bottom * s);\n ctx.stroke();\n const nearest = this.chart.nearest(time),\n rows = [\"Nearest samples\"];\n for (const p of nearest)\n rows.push(\n p.name +\n \": \" +\n formatValue(p.value, m.yUnit, 2, this.chart.config.missingLabel) +\n (p.time !== null\n ? \" \" + formatTime(p.time, m.timezone, \"%H:%M:%S\")\n : \" no observation\"),\n );\n this.tip.textContent = rows.join(\"\\n\");\n this.tip.hidden = false;\n this.tip.style.left =\n Math.max(\n 4,\n Math.min(this.result.width - this.tip.offsetWidth - 4, x + 12),\n ) + \"px\";\n this.tip.style.top = top * s + 8 + \"px\";\n this.cursorTime = time;\n if (announce) this.status.textContent = rows.join(\". \");\n if (typeof this.options.onHover === \"function\")\n this.options.onHover({ time, samples: nearest });\n }\n clear(): void {\n if (this.overlay)\n this.overlay\n .getContext(\"2d\")!\n .clearRect(0, 0, this.overlay.width, this.overlay.height);\n if (this.tip) this.tip.hidden = true;\n this.cursorTime = null;\n }\n update(patch: ChartOptions | Chart): RenderResult {\n check(!this.destroyed, \"Controller has been destroyed.\");\n const next = patch instanceof Chart ? patch : this.chart.with(patch),\n result = next.render();\n this.chart = next;\n this.apply(result);\n return result;\n }\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n for (const [el, type, fn] of this.handlers)\n el.removeEventListener(type, fn);\n this.handlers.length = 0;\n if (this.marker.parentNode) {\n this.marker.parentNode.insertBefore(this.canvas, this.marker);\n this.marker.remove();\n } else this.wrap.removeChild(this.canvas);\n this.wrap.remove();\n for (const [key, attr] of [\n [\"style\", \"style\"],\n [\"role\", \"role\"],\n [\"label\", \"aria-label\"],\n [\"tab\", \"tabindex\"],\n ] as const) {\n if (this.saved[key] === null) this.canvas.removeAttribute(attr);\n else this.canvas.setAttribute(attr, this.saved[key]);\n }\n delete this.canvas.__bamtiGraphController;\n }\n}\n\n/** Return a detached copy of every chart default. */\nexport function defaults(): ChartOptions {\n return clone(DEFAULTS);\n}\n/** Render a chart once; bitmap mode does not access browser APIs. */\nexport function render(options: ChartOptions = {}): RenderResult {\n return new Chart(options).render();\n}\n/** Frozen default export, equivalent to the corresponding named exports. */\nexport interface BamtiGraphAPI {\n readonly VERSION: typeof VERSION;\n readonly LIMITS: typeof LIMITS;\n readonly Chart: typeof Chart;\n readonly RenderResult: typeof RenderResult;\n readonly series: typeof series;\n readonly regularSeries: typeof regularSeries;\n readonly traffic: typeof traffic;\n readonly daily: typeof daily;\n readonly weekly: typeof weekly;\n readonly monthly: typeof monthly;\n readonly yearly: typeof yearly;\n readonly dashboard: typeof dashboard;\n readonly counterRate: typeof counterRate;\n readonly aggregate: typeof aggregate;\n readonly parseCSV: typeof parseCSV;\n readonly toCSV: typeof toCSV;\n readonly compareImages: typeof compareImages;\n readonly differenceImage: typeof differenceImage;\n readonly encodePNG: typeof encodePNG;\n readonly decodeImage: typeof decodeImage;\n readonly readCanvas: typeof readCanvas;\n readonly drawImageToCanvas: typeof drawImageToCanvas;\n readonly downloadBytes: typeof downloadBytes;\n readonly formatTime: typeof formatTime;\n readonly formatValue: typeof formatValue;\n readonly epoch: typeof epoch;\n readonly color: typeof color;\n readonly defaults: typeof defaults;\n readonly render: typeof render;\n}\n\n/** The complete BamtiGraph API; importing this module creates no global. */\nconst BamtiGraph: Readonly<BamtiGraphAPI> = Object.freeze({\n VERSION,\n LIMITS,\n Chart,\n RenderResult,\n series,\n regularSeries,\n traffic,\n daily,\n weekly,\n monthly,\n yearly,\n dashboard,\n counterRate,\n aggregate,\n parseCSV,\n toCSV,\n compareImages,\n differenceImage,\n encodePNG,\n decodeImage,\n readCanvas,\n drawImageToCanvas,\n downloadBytes,\n formatTime,\n formatValue,\n epoch,\n color,\n defaults,\n render,\n});\nexport default BamtiGraph;\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4aO,IAAM,UAAkB;AAExB,IAAM,SAOR,OAAO,OAAO;AAAA,EACjB,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AACR,CAAC;AACD,IAAM,SAAS,CAAC,MAA4B,OAAO,SAAS,CAAC;AAC7D,IAAM,QAAQ,CAAC,MAAsB,KAAK,MAAM,IAAI,GAAG;AACvD,IAAM,QAAQ,CAAC,GAAW,GAAW,MACnC,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AAC5B,IAAM,MAAM,CAAC,GAAW,MACtB,OAAO,UAAU,eAAe,KAAK,GAAG,CAAC;AAC3C,IAAM,UAAU,CAAC,MACf,MAAM,QAAQ,MAAM,UAAc,OAAO,MAAM,YAAY,OAAO,MAAM,CAAC;AAC3E,SAAS,MAAM,IAAa,SAA6B;AACvD,MAAI,CAAC,GAAI,OAAM,IAAI,WAAW,OAAO;AACvC;AACA,SAAS,KAAK,GAAY,MAAsB;AAC9C;AAAA,IACE,OAAO,MAAM,YAAY,EAAE,UAAU,OAAO,QAAQ,CAAC,eAAe,KAAK,CAAC;AAAA,IAC1E,OAAO;AAAA,EACT;AACA,SAAO;AACT;AACA,SAAS,OACP,GACA,MACA,KAAa,WACb,KAAa,UACL;AACR;AAAA,IACE,OAAO,CAAC,KAAK,KAAK,MAAM,KAAK;AAAA,IAC7B,OAAO;AAAA,EACT;AACA,SAAO;AACT;AACA,SAAS,QAAQ,GAAY,MAAc,IAAY,IAAoB;AACzE,QAAM,OAAO,UAAU,CAAC,GAAG,OAAO,sBAAsB;AACxD,SAAO,OAAO,GAAG,MAAM,IAAI,EAAE;AAC/B;AACA,SAAS,OAAO,GAA0C;AACxD,SACE,MAAM,QACN,OAAO,MAAM,aACZ,OAAO,eAAe,CAAC,MAAM,OAAO,aACnC,OAAO,eAAe,CAAC,MAAM;AAEnC;AAGA,SAAS,MAAS,GAAS;AACzB,MAAI,MAAM,QAAQ,CAAC,KAAK,YAAY,OAAO,CAAC;AAC1C,WAAO,MAAM,KAAK,GAAyB,CAAC,UAAU,MAAM,KAAK,CAAC;AACpE,MAAI,aAAa,KAAM,QAAO,IAAI,KAAK,EAAE,QAAQ,CAAC;AAClD,MAAI,OAAO,CAAC,GAAG;AACb,UAAM,IAA6B,CAAC;AACpC,eAAW,KAAK,OAAO,KAAK,CAAC,GAAG;AAC9B;AAAA,QACE,CAAC,CAAC,aAAa,aAAa,aAAa,EAAE,SAAS,CAAC;AAAA,QACrD;AAAA,MACF;AACA,QAAE,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;AAAA,IACnB;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AACA,SAAS,MAAwB,GAAM,GAAc;AACnD,QAAM,OAAO,CAAC,GAAG,iCAAiC;AAClD,QAAM,IAAI,MAAM,CAAC;AACjB,aAAW,KAAK,OAAO,KAAK,CAAC,GAAG;AAC9B;AAAA,MACE,CAAC,CAAC,aAAa,aAAa,aAAa,EAAE,SAAS,CAAC;AAAA,MACrD;AAAA,IACF;AACA,UAAM,WAAW,EAAE,CAAC,GAClB,OAAO,EAAE,CAAC;AACZ,MAAE,CAAC,IACD,OAAO,QAAQ,KAAK,OAAO,IAAI,IAAI,MAAM,UAAU,IAAI,IAAI,MAAM,IAAI;AAAA,EACzE;AACA,SAAO;AACT;AACA,SAAS,OAAU,GAAS;AAC1B,MAAI,KAAK,OAAO,MAAM,UAAU;AAC9B,eAAW,KAAK,OAAO,OAAO,CAAC,EAAG,QAAO,CAAC;AAC1C,WAAO,OAAO,CAAC;AAAA,EACjB;AACA,SAAO;AACT;AAEO,SAAS,MAAM,OAAoB;AACxC,MAAI,MAAM,QAAQ,KAAK,KAAK,YAAY,OAAO,KAAK,GAAG;AACrD;AAAA,MACE,MAAM,WAAW,KAAK,MAAM,WAAW;AAAA,MACvC;AAAA,IACF;AACA,UAAM,IAAI,MAAM,KAAK,KAAK;AAC1B,MAAE,QAAQ,CAAC,MAAM,QAAQ,GAAG,iBAAiB,GAAG,GAAG,CAAC;AACpD,QAAI,EAAE,WAAW,EAAG,GAAE,KAAK,GAAG;AAC9B,WAAO;AAAA,EACT;AACA,QAAM,QAAgC;AAAA,IACpC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AACA;AAAA,IACE,OAAO,UAAU;AAAA,IACjB;AAAA,EACF;AACA,MAAI,IAAI,MAAM,MAAM,YAAY,CAAC,KAAK;AACtC;AAAA,IACE,0DAA0D,KAAK,CAAC;AAAA,IAChE,oBAAoB;AAAA,EACtB;AACA,MAAI,EAAE,MAAM,CAAC;AACb,MAAI,EAAE,UAAU,EAAG,KAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,KAAK,EAAE;AACvD,MAAI,EAAE,WAAW,EAAG,MAAK;AACzB,SAAO,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAChE;AAEO,SAAS,MAAM,OAA0B;AAC9C,MAAI,iBAAiB,KAAM,SAAQ,MAAM,QAAQ,IAAI;AACrD,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI,MAAM,KAAK;AACrB,QAAI,4CAA4C,KAAK,CAAC,EAAG,SAAQ,OAAO,CAAC;AAAA,SACpE;AACH,YAAM,IACJ,kFAAkF;AAAA,QAChF;AAAA,MACF;AACF;AAAA,QACE;AAAA,QACA;AAAA,MACF;AACA,YAAM,CAAC,GAAG,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI;AAAA,QAC3B,EAAE,CAAC;AAAA,QACH,EAAE,CAAC;AAAA,QACH,EAAE,CAAC;AAAA,QACH,EAAE,CAAC;AAAA,QACH,EAAE,CAAC;AAAA,QACH,EAAE,CAAC,KAAK;AAAA,MACV,EAAE,IAAI,MAAM;AACZ;AAAA,QACE,KAAK,KAAK,MAAM,KAAK,MAAM,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,IAAI;AAAA,QACpE;AAAA,MACF;AACA,YAAM,OAAO,oBAAI,KAAK,CAAC;AACvB,WAAK,eAAe,GAAG,KAAK,GAAG,CAAC;AAChC,WAAK,YAAY,GAAG,IAAI,GAAG,CAAC;AAC5B;AAAA,QACE,KAAK,YAAY,MAAM,KAAK,KAAK,KAAK,WAAW,MAAM;AAAA,QACvD;AAAA,MACF;AACA,UAAI,EAAE,CAAC,EAAE,YAAY,MAAM;AACzB;AAAA,UACE,OAAO,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,MAAM,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK;AAAA,UAC3D;AAAA,QACF;AACF,cAAQ,KAAK,MAAM,CAAC,IAAI;AAAA,IAC1B;AAAA,EACF;AACA,SAAO,OAAO,OAAO,aAAa,cAAc,kBAAgB;AAClE;AACA,SAAS,QAAQ,YAAkC,QAAyB;AAC1E;AAAA,KACG,MAAM,QAAQ,UAAU,KAAK,YAAY,OAAO,UAAU,OACxD,MAAM,QAAQ,MAAM,KAAK,YAAY,OAAO,MAAM;AAAA,IACrD;AAAA,EACF;AACA;AAAA,IACE,WAAW,WAAW,OAAO,UAAU,WAAW,UAAU,OAAO;AAAA,IACnE;AAAA,EACF;AACA,QAAM,KAAK,MAAM,KAAK,YAAY,KAAK,GACrC,KAAK,MAAM;AAAA,IAAK;AAAA,IAAQ,CAAC,GAAG,MAC1B,QAAQ,CAAC,IAAI,MAAM,OAAO,GAAG,cAAc,CAAC;AAAA,EAC9C;AACF,WAAS,IAAI,GAAG,IAAI,GAAG,QAAQ;AAC7B;AAAA,MACE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;AAAA,MAChB,mDAAmD,IAAI;AAAA,IACzD;AACF,SAAO,EAAE,YAAY,IAAI,QAAQ,GAAG;AACtC;AACA,IAAM,WAA+B,OAA2B;AAAA,EAC9D,OAAO;AAAA,EACP,eAAe;AAAA,EACf,WAAW;AAAA,EACX,QAAQ,CAAC;AAAA,EACT,UAAU;AAAA,IACR,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA,IACV,cAAc;AAAA,IACd,cAAc;AAAA,IACd,cAAc;AAAA,IACd,aAAa;AAAA,IACb,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,oBAAoB;AAAA,EACtB;AAAA,EACA,OAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS;AAAA,IACT,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,EAClB;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,OAAO;AAAA,IACP,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,cAAc;AAAA,MACZ,OAAO;AAAA,MACP,SAAS;AAAA,MACT,aAAa;AAAA,MACb,cAAc;AAAA,MACd,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,SAAS;AAAA,QACP,CAAC,KAAK,GAAG;AAAA,QACT,CAAC,KAAK,GAAG;AAAA,QACT,CAAC,KAAK,GAAG;AAAA,MACX;AAAA,MACA,UAAU;AAAA,QACR,CAAC,KAAK,GAAG;AAAA,QACT,CAAC,KAAK,GAAG;AAAA,QACT,CAAC,KAAK,GAAG;AAAA,MACX;AAAA,MACA,SAAS;AAAA,QACP,CAAC,KAAK,GAAG;AAAA,QACT,CAAC,KAAK,GAAG;AAAA,QACT,CAAC,KAAK,GAAG;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,WAAW;AAAA,IACX,MAAM;AAAA,IACN,OAAO;AAAA,IACP,WAAW;AAAA,IACX,OAAO;AAAA,IACP,WAAW;AAAA,IACX,UAAU,CAAC,GAAG,CAAC;AAAA,IACf,WAAW;AAAA,IACX,UAAU;AAAA,IACV,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,aAAa;AAAA,IACb,cAAc;AAAA,IACd,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,cAAc;AAAA,EAChB;AAAA,EACA,cAAc,CAAC,YAAY,YAAY,UAAU;AAAA,EACjD,cAAc;AAAA,EACd,QAAQ,CAAC;AAAA,EACT,QAAQ,CAAC;AACX,CAAC;AAEM,SAAS,OACd,MACA,YACA,QACA,UAAyB,CAAC,GAClB;AACR,QAAM,IAAI;AAAA,IACR;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,OAAO;AAAA,MACP,WAAW;AAAA,MACX,SAAS;AAAA,MACT,UAAU;AAAA,MACV,eAAe;AAAA,MACf,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,IACA;AAAA,EACF;AACA,OAAK,EAAE,MAAM,aAAa;AAC1B,QAAM,OAAO,QAAQ,EAAE,YAAY,EAAE,MAAM;AAC3C,IAAE,aAAa,KAAK;AACpB,IAAE,SAAS,KAAK;AAChB,QAAM,CAAC,QAAQ,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,mCAAmC;AAC5E;AAAA,IACE,CAAC,UAAU,WAAW,EAAE,SAAS,EAAE,aAAa;AAAA,IAChD;AAAA,EACF;AACA,SAAO,EAAE,WAAW,cAAc,MAAM,GAAG;AAC3C,SAAO,EAAE,UAAU,UAAU;AAC7B,SAAO,EAAE,UAAU,iBAAiB,CAAC;AACrC,IAAE,QAAQ,MAAM,EAAE,KAAK;AACvB,MAAI,EAAE,YAAY,KAAM,GAAE,UAAU,MAAM,EAAE,OAAO;AACnD,MAAI,EAAE,iBAAiB,MAAM;AAC3B,UAAM,OAAO,EAAE,YAAY,GAAG,qCAAqC;AACnE,eAAW,KAAK,CAAC,WAAW,WAAW,SAAS;AAC9C,QAAE,aAAa,CAAC,IAAI,QAAQ,EAAE,aAAa,CAAC,CAAC,IACzC,OACA,OAAO,EAAE,aAAa,CAAC,GAAG,iBAAiB;AAAA,EACnD;AACA,SAAO,OAAO,CAAW;AAC3B;AAEO,SAAS,cACd,MACA,QACA,OACA,OAAe,KACf,UAAyB,CAAC,GAClB;AACR,UAAQ,MAAM,KAAK;AACnB,SAAO,MAAM,QAAQ,OAAO,SAAS;AACrC,QAAM,QAAQ;AACd,SAAO;AAAA,IACL;AAAA,IACA,MAAM,KAAK,QAAQ,CAAC,GAAG,MAAM,QAAQ,IAAI,IAAI;AAAA,IAC7C;AAAA,IACA;AAAA,EACF;AACF;AACA,SAAS,SACP,MACA,UAA6B,CAAC,GACpB;AACV,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,MACE,EAAE,KAAK;AAAA,MACP,OAAO,YAAY,WAAW,EAAE,UAAU,QAAQ,IAAI;AAAA,IACxD;AAAA,EACF;AACF;AAEO,SAAS,MAAM,UAA6B,CAAC,GAAa;AAC/D,SAAO,SAAS,SAAS,OAAO;AAClC;AAEO,SAAS,OAAO,UAA6B,CAAC,GAAa;AAChE,SAAO,SAAS,UAAU,OAAO;AACnC;AAEO,SAAS,QAAQ,UAA6B,CAAC,GAAa;AACjE,SAAO,SAAS,WAAW,OAAO;AACpC;AAEO,SAAS,OAAO,UAA6B,CAAC,GAAa;AAChE,SAAO,SAAS,UAAU,OAAO;AACnC;AACA,SAAS,WAAW,GAGC;AACnB,QAAM,IAAI,EAAE;AACZ,SAAO;AAAA,IACL,EAAE;AAAA,IACF,EAAE,MACA,EAAE,cACD,EAAE,WAAW,SACV,KACA,EAAE,YACF,KAAK,IAAI,GAAG,EAAE,OAAO,MAAM,IAAI,EAAE,kBACjC,EAAE;AAAA,EACV;AACF;AACA,SAAS,KAAK,GAA2C;AACvD,MAAI,MAAM,KAAM;AAChB,QAAM,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,iCAAiC;AAC3E,IAAE,QAAQ,CAAC,MAAM,QAAQ,GAAG,iBAAiB,GAAG,KAAK,CAAC;AACxD;AACA,SAAS,UAAU,SAAoC;AACrD,QAAM,IAAI,MAAM,UAAU,OAAO;AACjC;AAAA,IACE,MAAM,QAAQ,EAAE,MAAM,KAAK,EAAE,OAAO,UAAU,OAAO;AAAA,IACrD;AAAA,EACF;AACA,IAAE,SAAS,EAAE,OAAO,IAAI,CAAC,MAAM,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;AACxE,aAAW,KAAK;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACE,SAAK,EAAE,CAAC,GAAG,CAAC;AACd;AAAA,IACE,MAAM,QAAQ,EAAE,YAAY,KAAK,EAAE,aAAa,WAAW;AAAA,IAC3D;AAAA,EACF;AACA,IAAE,aAAa,QAAQ,CAAC,MAAM,KAAK,GAAG,iBAAiB,CAAC;AACxD,QAAM,IAAI,EAAE,UACV,IAAI,EAAE,QACN,IAAI,EAAE,OACN,IAAI,EAAE,OACN,IAAI,EAAE;AACR;AAAA,IACE,CAAC,QAAQ,SAAS,UAAU,WAAW,UAAU,QAAQ,EAAE,SAAS,EAAE,IAAI;AAAA,IAC1E;AAAA,EACF;AACA,OAAK,EAAE,UAAU,UAAU;AAC3B,gBAAc,EAAE,QAAQ;AACxB,aAAW,KAAK,CAAC,SAAS,KAAK;AAC7B,QAAI,EAAE,CAAC,MAAM,KAAM,GAAE,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;AACtC,MAAI,EAAE,UAAU,QAAQ,EAAE,QAAQ;AAChC;AAAA,MACG,EAAE,MAAkB,EAAE;AAAA,MACvB;AAAA,IACF;AACF,aAAW,KAAK,CAAC,gBAAgB,gBAAgB,cAAc;AAC7D,QAAI,EAAE,CAAC,MAAM,KAAM,QAAO,EAAE,CAAC,GAAG,GAAG,IAAK;AAC1C,SAAO,EAAE,oBAAoB,gBAAgB,WAAW,QAAQ;AAChE,MAAI,EAAE,gBAAgB,MAAM;AAC1B,SAAK,EAAE,aAAa,cAAc;AAClC,eAAW,GAAG,OAAO,EAAE,WAAW;AAAA,EACpC;AACA,MAAI,EAAE,UAAU,MAAM;AACpB;AAAA,MACE,MAAM,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,UAAU,OAAO;AAAA,MACnD;AAAA,IACF;AACA,UAAM,QAAQ,EAAE,MAAM,IAAI,CAAC,OAAO;AAAA,MAChC,MAAM,MAAM,EAAE,IAAI;AAAA,MAClB,OAAO,KAAK,EAAE,OAAO,YAAY;AAAA,IACnC,EAAE;AACF,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ;AAChC;AAAA,QACE,MAAM,CAAC,EAAE,OAAO,MAAM,IAAI,CAAC,EAAE;AAAA,QAC7B;AAAA,MACF;AACF,MAAE,QAAQ;AAAA,EACZ;AACA,aAAW,KAAK,CAAC,cAAc,YAAY;AACzC,QAAI,EAAE,CAAC,MAAM,MAAM;AACjB,YAAM,QAAQ,EAAE,CAAC;AACjB;AAAA,QACE,MAAM,QAAQ,KAAK,KAAK,MAAM,UAAU,OAAO;AAAA,QAC/C;AAAA,MACF;AACA,YAAM,QAAQ,MAAM,IAAI,KAAK;AAC7B,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ;AAChC;AAAA,UACE,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC;AAAA,UACtB;AAAA,QACF;AACF,QAAE,CAAC,IAAI;AAAA,IACT;AACF,aAAW,KAAK,CAAC,WAAW,WAAW,aAAa,aAAa;AAC/D,QAAI,EAAE,CAAC,MAAM,KAAM,QAAO,EAAE,CAAC,GAAG,CAAC;AACnC,aAAW,KAAK,CAAC,aAAa,aAAa;AACzC,QAAI,EAAE,CAAC,MAAM,KAAM,OAAM,EAAE,CAAC,IAAI,GAAG,IAAI,oBAAoB;AAC7D,MAAI,EAAE,YAAY,QAAQ,EAAE,YAAY;AACtC,UAAM,EAAE,UAAU,EAAE,SAAS,gCAAgC;AAC/D,QAAM,EAAE,SAAS,OAAQ,EAAE,SAAS,MAAM,iCAAiC;AAC3E,UAAQ,EAAE,gBAAgB,mBAAmB,GAAG,GAAG;AACnD,UAAQ,EAAE,gBAAgB,mBAAmB,GAAG,EAAE;AAClD,MAAI,EAAE,aAAa,KAAM,SAAQ,EAAE,UAAU,YAAY,GAAG,EAAE;AAC9D,MAAI,EAAE,WAAW,KAAM,MAAK,EAAE,QAAQ,QAAQ;AAC9C,UAAQ,EAAE,OAAO,SAAS,KAAK,IAAI;AACnC,UAAQ,EAAE,YAAY,eAAe,IAAI,IAAI;AAC7C,aAAW,KAAK;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACE,YAAQ,EAAE,CAAC,GAAG,GAAG,GAAG,KAAK;AAC3B;AAAA,IACE,EAAE,QAAQ,MACR,EAAE,SAAS,MACX,EAAE,OAAO,MACT,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAChC;AAAA,EACF;AACA,SAAO,EAAE,cAAc,gBAAgB,OAAO,IAAI;AAClD;AAAA,IACE,CAAC,aAAa,WAAW,MAAM,EAAE,SAAS,EAAE,MAAM;AAAA,IAClD;AAAA,EACF;AACA,MAAI,EAAE,WAAW;AACf;AAAA,MACE,EAAE,aAAa,MAAM,EAAE,mBAAmB;AAAA,MAC1C;AAAA,IACF;AACF,UAAQ,EAAE,WAAW,aAAa,GAAG,CAAC;AACtC,UAAQ,EAAE,YAAY,eAAe,GAAG,CAAC;AACzC,QAAM,KAAK,EAAE;AACb,aAAW,KAAK;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACE,YAAQ,GAAG,CAAC,GAAG,GAAG,GAAG,KAAK;AAC5B;AAAA,IACE,GAAG,eAAe,KAAK,GAAG,gBAAgB,KAAK,GAAG,iBAAiB,GAAG;AAAA,IACtE;AAAA,EACF;AACA,aAAW,OAAO,CAAC,WAAW,YAAY,SAAS,GAAY;AAC7D,UAAM,OAAO,GAAG,GAAG;AACnB,UAAM,MAAM,QAAQ,IAAI,KAAK,KAAK,WAAW,GAAG,yBAAyB;AACzE,QAAI,OAAO,GAAG;AACd,eAAW,KAAK,MAAM;AACpB;AAAA,QACE,MAAM,QAAQ,CAAC,KACb,EAAE,WAAW,KACb,OAAO,EAAE,CAAC,CAAC,KACX,OAAO,EAAE,CAAC,CAAC,KACX,OAAO,EAAE,CAAC,KACV,EAAE,CAAC,IAAI,EAAE,CAAC,KACV,EAAE,CAAC,IAAI,GAAG;AAAA,QACZ;AAAA,MACF;AACA,aAAO,EAAE,CAAC;AAAA,IACZ;AAAA,EACF;AACA,aAAW,KAAK;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACE,MAAE,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;AACnB;AAAA,IACE,EAAE,WAAW,CAAC,MAAM,OAAO,EAAE,OAAO,CAAC,MAAM;AAAA,IAC3C;AAAA,EACF;AACA,OAAK,EAAE,QAAQ;AACf,QAAM,EAAE,aAAa,MAAM,wBAAwB;AACnD,aAAW,KAAK;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACE,WAAO,EAAE,CAAC,GAAG,GAAG,GAAG,GAAG;AACxB;AAAA,IACE,CAAC,UAAU,QAAQ,EAAE,SAAS,EAAE,IAAI;AAAA,IACpC;AAAA,EACF;AACA,OAAK,EAAE,QAAQ,aAAa;AAC5B,aAAW,KAAK,CAAC,eAAe,cAAc,eAAe;AAC3D,QAAI,EAAE,CAAC,MAAM,KAAM,MAAK,EAAE,CAAC,GAAG,CAAC;AACjC,WAAS,KACP,OACA,OACyB;AACzB,UAAM,IAAI;AAAA,MACR,EAAE,OAAO,WAAW,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE;AAAA,MAC3C;AAAA,IACF;AACA,QAAI,UAAU,OAAQ,CAAC,EAAY,OAAO,MAAO,EAAY,IAAI;AAAA,QAC5D,CAAC,EAAY,QAAQ,OAAQ,EAAY,OAAO,YAAY;AACjE,WAAO,EAAE,OAAO,cAAc,KAAK,GAAG;AACtC,SAAK,EAAE,IAAI;AACX,MAAE,QAAQ,MAAM,EAAE,KAAK;AACvB,WAAO;AAAA,EACT;AACA;AAAA,IACE,MAAM,QAAQ,EAAE,MAAM,KAAK,EAAE,OAAO,UAAU;AAAA,IAC9C;AAAA,EACF;AACA,IAAE,SAAS,EAAE,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC;AAC/C;AAAA,IACE,MAAM,QAAQ,EAAE,MAAM,KAAK,EAAE,OAAO,UAAU;AAAA,IAC9C;AAAA,EACF;AACA,IAAE,SAAS,EAAE,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC;AAC9C,QAAM,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;AAC3B;AAAA,IACE,IAAI,IAAI,EAAE,cAAc,KAAK,OAAO;AAAA,IACpC;AAAA,EACF;AACA;AAAA,KACG,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,MAAM,EAAE,aAAa,KAAK,EAAE,aAAa,KACrE,OAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO,OAAO,CAAyB;AACzC;AAEA,IAAM,UAAN,MAAM,SAA6B;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACT,YACE,OACA,QACA,OAA8B,MAC9B;AACA,YAAQ,OAAO,eAAe,GAAG,KAAK;AACtC,YAAQ,QAAQ,gBAAgB,GAAG,KAAK;AACxC,UAAM,QAAQ,UAAU,OAAO,aAAa,qBAAqB;AACjE,SAAK,QAAQ;AACb,SAAK,SAAS;AACd,SAAK,OAAO,IAAI,kBAAkB,QAAQ,SAAS,CAAC;AACpD,QAAI,KAAM,MAAK,KAAK,GAAG,GAAG,OAAO,QAAQ,IAAI;AAAA,EAC/C;AAAA,EACA,MAAM,GAAW,GAAW,GAAmB,QAAiB,OAAa;AAC3E,QAAI,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK,SAAS,KAAK,KAAK,OAAQ;AAC3D,UAAM,KAAK,IAAI,KAAK,QAAQ,KAAK,GAC/B,IAAI,KAAK;AACX,QAAI,CAAC,SAAS,EAAE,CAAC,MAAM,KAAK;AAC1B,QAAE,CAAC,IAAI,EAAE,CAAC;AACV,QAAE,IAAI,CAAC,IAAI,EAAE,CAAC;AACd,QAAE,IAAI,CAAC,IAAI,EAAE,CAAC;AACd,QAAE,IAAI,CAAC,IAAI,EAAE,CAAC;AACd;AAAA,IACF;AACA,QAAI,EAAE,CAAC,MAAM,EAAG;AAChB,UAAM,KAAK,EAAE,CAAC,GACZ,KAAK,EAAE,IAAI,CAAC,GACZ,QAAQ,KAAK,MAAM,MAAM,MAAM;AACjC,aAAS,IAAI,GAAG,IAAI,GAAG;AACrB,QAAE,IAAI,CAAC,IAAI,KAAK;AAAA,SACb,EAAE,CAAC,IAAI,KAAK,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,MAAM,MAAM,QAAQ,KAAK;AAAA,MAC/D;AACF,MAAE,IAAI,CAAC,IAAI,KAAK,OAAO,QAAQ,OAAO,GAAG;AAAA,EAC3C;AAAA,EACA,KACE,IACA,IACA,IACA,IACA,GACM;AACN,SAAK,KAAK,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;AAC9B,SAAK,KAAK,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;AAC9B,SAAK,KAAK,IAAI,KAAK,OAAO,KAAK,KAAK,EAAE,CAAC;AACvC,SAAK,KAAK,IAAI,KAAK,QAAQ,KAAK,KAAK,EAAE,CAAC;AACxC,aAAS,IAAI,IAAI,IAAI,IAAI;AACvB,eAAS,IAAI,IAAI,KAAK,IAAI,KAAK,QAAQ,MAAM,GAAG,IAAI,IAAI,KAAK,KAAK,GAAG;AACnE,aAAK,KAAK,CAAC,IAAI,EAAE,CAAC;AAClB,aAAK,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;AACtB,aAAK,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;AACtB,aAAK,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;AAAA,MACxB;AAAA,EACJ;AAAA,EACA,KAAK,KAAgB,KAAa,GAAG,KAAa,GAAS;AACzD,UAAM,IAAU,CAAC,GAAG,GAAG,GAAG,CAAC;AAC3B,aACM,IAAI,KAAK,IAAI,GAAG,CAAC,EAAE,GACvB,IAAI,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,EAAE,GACzC;AAEA,eACM,IAAI,KAAK,IAAI,GAAG,CAAC,EAAE,GACvB,IAAI,KAAK,IAAI,IAAI,OAAO,KAAK,QAAQ,EAAE,GACvC,KACA;AACA,cAAM,KAAK,IAAI,IAAI,QAAQ,KAAK;AAChC,YAAI,IAAI,KAAK,IAAI,CAAC,GAAG;AACnB,YAAE,CAAC,IAAI,IAAI,KAAK,CAAC;AACjB,YAAE,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC;AACrB,YAAE,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC;AACrB,YAAE,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC;AACrB,eAAK,MAAM,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI;AAAA,QACpC;AAAA,MACF;AAAA,EACJ;AAAA,EACA,QAAQ,QAA0B,GAAyB;AACzD,QAAI,OAAO,SAAS,EAAG;AACvB,QAAI,KAAK,UACP,KAAK;AACP,eAAW,KAAK,QAAQ;AACtB,WAAK,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;AACtB,WAAK,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;AAAA,IACxB;AACA,aACM,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC,GACjC,KAAK,KAAK,IAAI,KAAK,SAAS,GAAG,KAAK,MAAM,EAAE,CAAC,GAC7C,KACA;AACA,YAAM,KAAK,CAAC;AACZ,UAAI,IAAI,OAAO,OAAO,SAAS,CAAC;AAChC,iBAAW,KAAK,QAAQ;AACtB,YAAI,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG;AACjB,cAAI,MAAM,EAAE,CAAC;AACX,iBAAK;AAAA,cACH,KAAK,KAAK,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAAA,cAC9B;AAAA,cACA,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI;AAAA,cACnC,IAAI;AAAA,cACJ;AAAA,YACF;AAAA,QACJ,WAAY,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,KAAO,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;AACzD,aAAG,KAAK,EAAE,CAAC,KAAM,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,MAAO,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE;AAC7D,YAAI;AAAA,MACN;AACA,SAAG,KAAK,CAACA,IAAG,MAAMA,KAAI,CAAC;AACvB,eAAS,IAAI,GAAG,IAAI,IAAI,GAAG,QAAQ,KAAK;AACtC,aAAK;AAAA,UACH,KAAK,KAAK,GAAG,CAAC,IAAI,IAAI;AAAA,UACtB;AAAA,UACA,KAAK,MAAM,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI;AAAA,UAC/B,IAAI;AAAA,UACJ;AAAA,QACF;AAAA,IACJ;AAAA,EACF;AAAA,EACA,KAAK,GAAU,GAAU,GAAmB,QAAgB,GAAS;AACnE,QAAI,IAAI,MAAM,EAAE,CAAC,CAAC,GAChB,IAAI,MAAM,EAAE,CAAC,CAAC,GACd,KAAK,MAAM,EAAE,CAAC,CAAC,GACf,KAAK,MAAM,EAAE,CAAC,CAAC;AACjB,YAAQ,KAAK,IAAI,GAAG,MAAM,KAAK,CAAC;AAChC,QAAI,QAAQ,GAAG;AACb,YAAM,KAAK,QAAQ,KAAK;AACxB,UAAI,MAAM,IAAI;AACZ,aAAK;AAAA,UACH,IAAI,KAAK,MAAM,QAAQ,CAAC;AAAA,UACxB,KAAK,IAAI,GAAG,EAAE;AAAA,UACd,IAAI,KAAK,OAAO,QAAQ,KAAK,CAAC,IAAI;AAAA,UAClC,KAAK,IAAI,GAAG,EAAE,IAAI;AAAA,UAClB;AAAA,QACF;AACA;AAAA,MACF;AACA,UAAI,MAAM,IAAI;AACZ,aAAK;AAAA,UACH,KAAK,IAAI,GAAG,EAAE;AAAA,UACd,IAAI,KAAK,MAAM,QAAQ,CAAC;AAAA,UACxB,KAAK,IAAI,GAAG,EAAE,IAAI;AAAA,UAClB,IAAI,KAAK,OAAO,QAAQ,KAAK,CAAC,IAAI;AAAA,UAClC;AAAA,QACF;AACA;AAAA,MACF;AACA,YAAM,MAAM,KAAK,MAAM,KAAK,GAAG,KAAK,CAAC,GACnC,KAAM,EAAE,KAAK,KAAK,MAAO,GACzB,MAAO,KAAK,KAAK,MAAO;AAC1B,WAAK;AAAA,QACH;AAAA,UACE,CAAC,IAAI,IAAI,IAAI,EAAE;AAAA,UACf,CAAC,KAAK,IAAI,KAAK,EAAE;AAAA,UACjB,CAAC,KAAK,IAAI,KAAK,EAAE;AAAA,UACjB,CAAC,IAAI,IAAI,IAAI,EAAE;AAAA,QACjB,EAAE,IAAI,CAAC,MAAa,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;AAAA,QAC9C;AAAA,MACF;AACA;AAAA,IACF;AACA,UAAM,KAAK,KAAK,IAAI,KAAK,CAAC,GACxB,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GACrB,KAAK,IAAI,KAAK,IAAI,IAClB,KAAK,IAAI,KAAK,IAAI;AACpB,QAAI,MAAM,KAAK;AACf,eAAS;AACP,WAAK,MAAM,GAAG,GAAG,CAAC;AAClB,UAAI,MAAM,MAAM,MAAM,GAAI;AAC1B,YAAM,IAAI,IAAI;AACd,UAAI,KAAK,IAAI;AACX,eAAO;AACP,aAAK;AAAA,MACP;AACA,UAAI,KAAK,IAAI;AACX,eAAO;AACP,aAAK;AAAA,MACP;AAAA,IACF;AAAA,EACF;AAAA,EACA,OACE,GACA,GACA,GACA,UAA4C,CAAC,GAAG,CAAC,GACjD,QAAgB,GACV;AACN,QAAI,YAAY,MAAM;AACpB,WAAK,KAAK,GAAG,GAAG,GAAG,KAAK;AACxB;AAAA,IACF;AACA,UAAM,MAAM,KAAK,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAC/C,QAAI,CAAC,KAAK;AACR,WAAK,MAAM,MAAM,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC;AACtC;AAAA,IACF;AACA,UAAM,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KACzB,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK;AACvB,aAAS,IAAI,GAAG,KAAK,KAAK,KAAK,GAAG,GAAG,KAAK,QAAQ,CAAC,IAAI,QAAQ,CAAC,GAAG;AACjE,YAAM,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC;AAC1C,WAAK;AAAA,QACH,CAAC,EAAE,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC;AAAA,QAC7B,CAAC,EAAE,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC;AAAA,QAC7B;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,OAAO,GAAW,GAAW,GAAW,GAAyB;AAC/D,aACM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC,GACtC,MAAM,KAAK,IAAI,KAAK,SAAS,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,GAChD;AAEA,eACM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC,GACtC,MAAM,KAAK,IAAI,KAAK,QAAQ,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,GAC/C;AAEA,aAAK,KAAK,MAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAG,MAAK,MAAM,IAAI,IAAI,CAAC;AAAA,EACtE;AAAA,EACA,KAAK,OAAwB;AAC3B,QAAI,UAAU,EAAG,QAAO;AACxB,UAAM,MAAM,IAAI,SAAQ,KAAK,QAAQ,OAAO,KAAK,SAAS,KAAK,GAC7D,IAAU,CAAC,GAAG,GAAG,GAAG,CAAC,GACrB,IAAI,QAAQ;AACd,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ;AAC9B,eAAS,IAAI,GAAG,IAAI,IAAI,OAAO,KAAK;AAClC,YAAI,IAAI,GACN,IAAI,GACJ,IAAI,GACJ,IAAI;AACN,iBAAS,KAAK,GAAG,KAAK,OAAO;AAC3B,mBAAS,KAAK,GAAG,KAAK,OAAO,MAAM;AACjC,kBAAM,MAAM,IAAI,QAAQ,MAAM,KAAK,QAAQ,IAAI,QAAQ,MAAM,GAC3D,KAAK,KAAK,KAAK,IAAI,CAAC;AACtB,iBAAK;AACL,iBAAK,KAAK,KAAK,CAAC,IAAI;AACpB,iBAAK,KAAK,KAAK,IAAI,CAAC,IAAI;AACxB,iBAAK,KAAK,KAAK,IAAI,CAAC,IAAI;AAAA,UAC1B;AACF,YAAI,GAAG;AACL,YAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,GAAG;AAC7B,YAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,GAAG;AAC7B,YAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,GAAG;AAC7B,YAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,GAAG;AAC7B,cAAI,MAAM,GAAG,GAAG,CAAC;AAAA,QACnB;AAAA,MACF;AACF,WAAO;AAAA,EACT;AAAA,EACA,MAAM,GAAoB;AACxB,QAAI,MAAM,EAAG,QAAO;AACpB,UAAM,MAAM,IAAI,SAAQ,KAAK,QAAQ,GAAG,KAAK,SAAS,CAAC;AACvD,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ;AAC9B,eAAS,IAAI,GAAG,IAAI,IAAI,OAAO,KAAK;AAClC,cAAM,KAAK,KAAK,MAAM,IAAI,CAAC,IAAI,KAAK,QAAQ,KAAK,MAAM,IAAI,CAAC,KAAK,GAC/D,KAAK,IAAI,IAAI,QAAQ,KAAK;AAC5B,YAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC;AACzB,YAAI,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC;AACjC,YAAI,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC;AACjC,YAAI,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC;AAAA,MACnC;AACF,WAAO;AAAA,EACT;AACF;AACA,SAAS,SACP,GACA,GACA,GACA,GACuB;AACvB,MAAI,KAAK,GACP,KAAK;AACP,QAAM,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,GACnB,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACjB,aAAW,CAAC,GAAG,CAAC,KAAK;AAAA,IACnB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,IACV,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AAAA,IACb,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,IACV,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AAAA,EACf,GAAG;AACD,QAAI,MAAM,GAAG;AACX,UAAI,IAAI,EAAG,QAAO;AAAA,IACpB,OAAO;AACL,YAAM,IAAI,IAAI;AACd,UAAI,IAAI,EAAG,MAAK,KAAK,IAAI,IAAI,CAAC;AAAA,UACzB,MAAK,KAAK,IAAI,IAAI,CAAC;AACxB,UAAI,KAAK,GAAI,QAAO;AAAA,IACtB;AAAA,EACF;AACA,SAAO;AAAA,IACL,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK,EAAE;AAAA,IAC/B,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK,EAAE;AAAA,EACjC;AACF;AACA,SAAS,YAAY,QAAiB,GAAW,GAAoB;AACnE,MAAI,KAAK;AACT,aAAW,CAAC,MAAM,OAAO,OAAO,KAAK;AAAA,IACnC,CAAC,GAAG,GAAG,IAAI;AAAA,IACX,CAAC,GAAG,GAAG,KAAK;AAAA,IACZ,CAAC,GAAG,GAAG,IAAI;AAAA,IACX,CAAC,GAAG,GAAG,KAAK;AAAA,EACd,GAAY;AACV,QAAI,CAAC,GAAG,OAAQ;AAChB,UAAM,MAAe,CAAC,GACpB,SAAS,CAAC,MACR,UAAU,EAAE,IAAI,KAAK,QAAQ,EAAE,IAAI,KAAK;AAC5C,QAAI,IAAI,GAAG,GAAG,SAAS,CAAC,GACtB,KAAK,OAAO,CAAC;AACf,eAAW,KAAK,IAAI;AAClB,YAAM,KAAK,OAAO,CAAC;AACnB,UAAI,OAAO,IAAI;AACb,cAAM,KAAK,QAAQ,EAAE,IAAI,MAAM,EAAE,IAAI,IAAI,EAAE,IAAI;AAC/C,cAAM,IAAW,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE;AACpE,UAAE,IAAI,IAAI;AACV,YAAI,KAAK,CAAC;AAAA,MACZ;AACA,UAAI,GAAI,KAAI,KAAK,CAAC;AAClB,UAAI;AACJ,WAAK;AAAA,IACP;AACA,SAAK;AAAA,EACP;AACA,SAAO;AACT;AACA,SAAS,WAAW,GAAsB,GAAmB;AAC3D,MAAI,IAAI,GACN,IAAI,EAAE;AACR,SAAO,IAAI,GAAG;AACZ,UAAM,IAAK,IAAI,MAAO;AACtB,QAAI,EAAE,CAAC,IAAI,EAAG,KAAI,IAAI;AAAA,QACjB,KAAI;AAAA,EACX;AACA,SAAO;AACT;AACA,SAAS,WAAW,GAAsB,GAAmB;AAC3D,MAAI,IAAI,GACN,IAAI,EAAE;AACR,SAAO,IAAI,GAAG;AACZ,UAAM,IAAK,IAAI,MAAO;AACtB,QAAI,EAAE,CAAC,KAAK,EAAG,KAAI,IAAI;AAAA,QAClB,KAAI;AAAA,EACX;AACA,SAAO;AACT;AACA,SAAS,YAAY,GAAW,OAAe,KAAwB;AACrE,QAAM,KAAK,EAAE,YACX,KAAK,EAAE,QACP,SAAoB,CAAC;AACvB,MAAI,MAAe,CAAC;AACpB,QAAM,OAAO,MAAM;AACjB,QAAI,IAAI,QAAQ;AACd,aAAO,KAAK,GAAG;AACf,YAAM,CAAC;AAAA,IACT;AAAA,EACF;AACA,QAAM,OAAO,KAAK,IAAI,GAAG,WAAW,IAAI,KAAK,IAAI,CAAC,GAChD,QAAQ,KAAK,IAAI,GAAG,QAAQ,WAAW,IAAI,GAAG,IAAI,CAAC;AACrD,WAAS,IAAI,MAAM,IAAI,OAAO,KAAK;AACjC,QAAI,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG;AAClB,WAAK;AACL;AAAA,IACF;AACA,QAAI,IAAI,QAAQ,EAAE,WAAW,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,SAAU,MAAK;AACvE,QAAI,IAAI,UAAU,EAAE,kBAAkB;AACpC,UAAI,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1C,QAAI,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AAAA,EACzB;AACA,OAAK;AACL,QAAM,UAAqB,CAAC;AAC5B,aAAW,KAAK,QAAQ;AACtB,UAAM,MAAe,CAAC;AACtB,QAAI,EAAE,WAAW,GAAG;AAClB,UAAI,EAAE,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC,EAAE,CAAC,KAAK,IAAK,KAAI,KAAK,EAAE,CAAC,CAAC;AAAA,IACvD;AACA,aAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,YAAM,IAAI,EAAE,IAAI,CAAC,GACf,IAAI,EAAE,CAAC;AACT,UAAI,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC,IAAI,IAAK;AAChC,YAAM,SAAS,CAAC,MACd,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,MACpC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;AAClC,YAAM,IAAW,EAAE,CAAC,IAAI,QAAQ,CAAC,OAAO,OAAO,KAAK,CAAC,IAAI,GACvD,IAAW,EAAE,CAAC,IAAI,MAAM,CAAC,KAAK,OAAO,GAAG,CAAC,IAAI;AAC/C,UACE,CAAC,IAAI,UACL,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAC9B,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;AAE9B,YAAI,KAAK,CAAC;AACZ,UAAI,KAAK,CAAC;AAAA,IACZ;AACA,QAAI,IAAI,OAAQ,SAAQ,KAAK,GAAG;AAAA,EAClC;AACA,SAAO;AACT;AACA,SAAS,SACP,IACA,OACA,KACA,OACS;AACT,MAAI,GAAG,UAAU,QAAQ,EAAG,QAAO;AACnC,QAAM,MAAM,CAAC;AACb,MAAI,MAAM;AACV,SAAO,MAAM,GAAG,QAAQ;AACtB,UAAM,MAAM,KAAK,OAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,UAAU,MAAM,SAAU,KAAK,GACnE,QAAQ;AACV,QAAI,KAAK,KACP,KAAK;AACP,WACE,MAAM,IAAI,GAAG,UACb,KAAK,OAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,IAAI,UAAU,MAAM,SAAU,KAAK,MAAM,KACnE;AACA;AACA,UAAI,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,EAAG,MAAK;AACjC,UAAI,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,EAAG,MAAK;AAAA,IACnC;AACA,eAAW,KAAK,CAAC,GAAG,oBAAI,IAAI,CAAC,OAAO,IAAI,IAAI,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACrE,UAAI,KAAK,GAAG,CAAC,CAAC;AAChB;AAAA,EACF;AACA,SAAO;AACT;AACA,SAAS,WAAW,QAA0C;AAC5D,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,MAAI,MAAM;AACV,aAAW,KAAK,OAAQ,OAAM,KAAK,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC;AACvD,MAAI,QAAQ,EAAG,QAAO;AACtB,MAAI,MAAM,GACR,IAAI;AACN,aAAW,KAAK,QAAQ;AACtB,UAAM,IAAI,IAAI,MAAM,GAClB,IAAI,MAAM;AACZ,QAAI,IAAI,MAAM;AACd,UAAM;AAAA,EACR;AACA,SAAO,MAAM,MAAM,OAAO,QAAQ,IAAI,CAAC,IAAI;AAC7C;AACA,SAAS,WAAW,GAAW,OAAe,KAAyB;AACrE,QAAM,IAAI,WAAW,EAAE,YAAY,KAAK,GACtC,IAAI,WAAW,EAAE,YAAY,GAAG,GAChC,SAAS,CAAC;AACZ,MAAI,KAAK,UACP,KAAK,WACL,OAAO;AACT,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,IAAI,EAAE,OAAO,CAAC;AACpB,QAAI,CAAC,OAAO,CAAC,EAAG;AAAA,SACX;AACH,aAAO,KAAK,CAAC;AACb,WAAK,KAAK,IAAI,IAAI,CAAC;AACnB,WAAK,KAAK,IAAI,IAAI,CAAC;AAAA,IACrB;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM,EAAE;AAAA,IACR,SAAS,IAAI,KAAK,OAAO,EAAE,OAAO,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI;AAAA,IAC9D,SAAS,WAAW,MAAM;AAAA,IAC1B,SAAS,OAAO,SAAS,KAAK;AAAA,IAC9B,SAAS,OAAO,SAAS,KAAK;AAAA,IAC9B,OAAO,OAAO;AAAA,IACd,SAAS;AAAA,IACT,iBAAiB,EAAE;AAAA,EACrB;AACF;AAEA,SAAS,UAAU,IAAY,IAAY,MAAwB;AACjE;AAAA,IACE,OAAO,IAAI,KACT,OAAO,KACP,QAAQ,KAAK,MAAM,IAAI,MACtB,KAAK,MAAM,QAAQ,OAAO;AAAA,IAC7B;AAAA,EACF;AACA,QAAM,IAAI,KAAK,KAAK,KAAK,OAAO,KAAK,GACnC,IAAI,KAAK,MAAM,KAAK,OAAO,KAAK;AAClC;AAAA,IACE,KAAK,IAAI,CAAC,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,QAAQ,IAAI,KAAK,OAAO;AAAA,IAC5D;AAAA,EACF;AACA,SAAO,MAAM;AAAA,IACX,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE;AAAA,IACjC,CAAC,GAAG,OAAO,IAAI,KAAK,QAAQ;AAAA,EAC9B;AACF;AACA,SAAS,KAAK,GAAmB;AAC/B,QAAM,OAAO,CAAC,KAAK,KAAK,QAAQ,gCAAgC;AAChE,QAAM,IAAI,MAAM,KAAK,MAAM,KAAK,MAAM,CAAC,CAAC;AACxC,aAAW,KAAK,CAAC,GAAG,GAAG,GAAG,EAAE,EAAG,KAAI,KAAK,IAAI,KAAK,IAAI,OAAQ,QAAO,IAAI;AACxE,SAAO,KAAK;AACd;AACA,SAAS,QAAQ,GAAW,MAAyB;AACnD,MAAI,CAAC,EAAG,QAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG;AACvC,MAAI,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK;AACjE,MAAI,MAAM,GAAG,SAAS,OAAO,IAAI,IAAI,CAAC;AACtC,SAAO;AAAA,IACL,QAAQ,QAAQ;AAAA,IAChB,SAAS,SAAS,OACd,CAAC,IAAI,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI,IACnD;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,GAAG,SAAS,OAAO,IAAI,IAAI,CAAC;AAAA,EAClC;AACF;AACA,SAAS,SACP,GACA,QACA,QACa;AACb,MAAI,KAAK,EAAE,YAAY,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,EAAE,SACpD,KAAK,EAAE,YAAY,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,EAAE;AACpD,MAAI,EAAE,YAAY,QAAQ,MAAM;AAC9B,SAAK,KAAK,KAAK,IAAI,KAAK,IAAI,EAAE,IAAI,MAAM,CAAC;AAC3C,MAAI,EAAE,YAAY,QAAQ,MAAM;AAC9B,SAAK,KAAK,KAAK,IAAI,KAAK,IAAI,EAAE,IAAI,MAAM,CAAC;AAC3C,QAAM,OAAO,KAAK;AAClB,QAAM,OAAO,IAAI,KAAK,OAAO,GAAG,iBAAiB;AACjD,QAAM,KACJ,EAAE,gBAAgB,OACd,QAAQ,KAAK,IAAI,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,SACtD,EAAE;AACR,QAAM,OAAO,EAAE,cAAc,OAAO,KAAK,OAAO,KAAK,CAAC,IAAI,KAAK,EAAE,WAC/D,IAAI,OAAO,EAAE;AACf,QAAM,OAAO,CAAC,KAAK,IAAI,GAAG,oBAAoB;AAC9C,MAAI,EAAE,YAAY,QAAQ,KAAK,EAAG,MAAK,KAAK,OAAO,KAAK,OAAO,QAAQ,CAAC,IAAI;AAC5E,MAAI,EAAE,YAAY,KAAM,MAAK,KAAK,MAAM,KAAK,OAAO,QAAQ,CAAC,IAAI;AACjE,QAAM,OAAO,KAAK,EAAE,KAAK,KAAK,IAAI,qBAAqB;AACvD,QAAM,QAAQ,UAAU,IAAI,IAAI,IAAI,GAClC,QAAQ,UAAU,IAAI,IAAI,CAAC,EAAE;AAAA,IAC3B,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,IAAI,IAAI,CAAC,IAAI;AAAA,EAChD;AACF,QAAM,OAAO,QAAQ,KAAK,IAAI,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI;AACjE,MAAI,EAAE,gBAAgB,MAAM;AAC1B,SAAK,SAAS,EAAE;AAChB,QAAI,EAAE,WAAW,KAAM,MAAK,SAAS;AAAA,EACvC;AACA,MAAI,EAAE,WAAW,KAAM,MAAK,SAAS,EAAE;AACvC,MAAI,WAAW,EAAE;AACjB,MAAI,aAAa,MAAM;AACrB,UAAM,IAAI,OAAO,KAAK;AACtB,eAAW;AACX,aAAS,IAAI,GAAG,IAAI,IAAI;AACtB,UACE,KAAK,IAAI,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,KACzC,KAAK,IAAI,OAAO,KAAK,IAAI,CAAC,IAAI,IAAI,GAClC;AACA,mBAAW;AACX;AAAA,MACF;AAAA,EACJ;AACA,SAAO,EAAE,SAAS,IAAI,SAAS,IAAI,MAAM,OAAO,OAAO,GAAG,MAAM,SAAS;AAC3E;AAEO,SAAS,YACd,OACA,MACA,WAAmB,GACnB,cAAsB,OACd;AACR,MAAI,CAAC,OAAO,KAAK,EAAG,QAAO;AAC3B,MAAI,IAAI,QAAQ,KAAK;AACrB,MAAI,KAAK,IAAI,CAAC,IAAI,MAAM,MAAM,CAAC,SAAU,KAAI;AAC7C,SAAO,EAAE,QAAQ,QAAQ,KAAK,KAAK,SAAS,MAAM,KAAK,SAAS;AAClE;AACA,IAAM,iBAAiB,oBAAI,IAAiC;AAC5D,SAAS,cAAc,MAAmC;AACxD,MAAI,eAAe,IAAI,IAAI,EAAG,QAAO,eAAe,IAAI,IAAI;AAC5D,MAAI;AACJ,MAAI;AACF,QAAI,IAAI,KAAK,eAAe,8BAA8B;AAAA,MACxD,UAAU;AAAA,MACV,MAAM;AAAA,MACN,OAAO;AAAA,MACP,KAAK;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,WAAW;AAAA,IACb,CAAC;AAAA,EACH,SAAS,GAAG;AACV,UAAM,IAAI,WAAW,4BAA4B,IAAI;AAAA,EACvD;AACA,MAAI,eAAe,QAAQ;AACzB,mBAAe,OAAO,eAAe,KAAK,EAAE,KAAK,EAAE,KAAM;AAC3D,iBAAe,IAAI,MAAM,CAAC;AAC1B,SAAO;AACT;AACA,SAAS,aACP,GACA,GACA,GACA,IAAY,GACZ,KAAa,GACb,IAAY,GACJ;AACR,QAAM,IAAI,oBAAI,KAAK,CAAC;AACpB,IAAE,eAAe,GAAG,IAAI,GAAG,CAAC;AAC5B,IAAE,YAAY,GAAG,IAAI,GAAG,CAAC;AACzB,SAAO,EAAE,QAAQ,IAAI;AACvB;AACA,SAAS,UAAU,GAAW,MAAyB;AACrD,MAAI,SAAS,OAAO;AAClB,UAAM,IAAI,IAAI,KAAK,IAAI,GAAI;AAC3B,WAAO;AAAA,MACL,MAAM,EAAE,eAAe;AAAA,MACvB,OAAO,EAAE,YAAY,IAAI;AAAA,MACzB,KAAK,EAAE,WAAW;AAAA,MAClB,MAAM,EAAE,YAAY;AAAA,MACpB,QAAQ,EAAE,cAAc;AAAA,MACxB,QAAQ,EAAE,cAAc;AAAA,IAC1B;AAAA,EACF;AACA,QAAM,IAAI,CAAC;AACX,aAAW,KAAK,cAAc,IAAI,EAAE,cAAc,IAAI,KAAK,IAAI,GAAI,CAAC;AAClE,QAAI,EAAE,SAAS,UAAW,GAAE,EAAE,IAAuB,IAAI,OAAO,EAAE,KAAK;AACzE,MAAI,EAAE,SAAS,GAAI,GAAE,OAAO;AAC5B,SAAO;AACT;AACA,SAAS,UAAU,GAAW,MAAsB;AAClD,QAAM,IAAI,UAAU,GAAG,IAAI;AAC3B,SACE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAC9D,IAAI,KAAK,MAAM,CAAC;AAErB;AACA,SAAS,SAAS,GAAW,MAAsB;AACjD,SAAO,KAAK,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC;AAC1C;AACA,SAAS,gBAAgB,GAAW,MAAwB;AAC1D,MAAI,SAAS,MAAO,QAAO,CAAC,CAAC;AAC7B,QAAM,UAAU,IAAI;AAAA,IAChB,CAAC,SAAS,QAAQ,GAAG,OAAO,MAAM,EAAE,IAAI,CAAC,MAAM,SAAS,IAAI,GAAG,IAAI,CAAC;AAAA,EACtE,GACA,MAAM,CAAC;AACT,aAAW,OAAO,SAAS;AACzB,UAAM,IAAI,IAAI;AACd,QAAI,KAAK,IAAI,UAAU,GAAG,IAAI,IAAI,CAAC,IAAI,KAAO,KAAI,KAAK,CAAC;AAAA,EAC1D;AACA,SAAO,IAAI,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACjC;AACA,SAAS,UACP,OACA,KACA,MACA,MACU;AACV,MAAI,SAAS,MAAO,QAAO,UAAU,OAAO,KAAK,IAAI;AACrD,QAAM,KAAK,UAAU,OAAO,IAAI,GAC9B,KAAK,UAAU,KAAK,IAAI,GACxB,IAAI,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,GAC1C,IAAI,KAAK,KAAK,KAAK,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI;AAC3C;AAAA,IACE,OAAO,IAAI,CAAC,KACV,IAAI,KAAK,OAAO,SAChB,KAAK,IAAI,CAAC,IAAI,QACd,KAAK,IAAI,CAAC,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,QAAQ,KAAK,IAAI,QAAQ,MAAM,SAAS,IAAI;AAClD,WAAS,IAAI,QAAQ,QAAQ,KAAK,MAAM,QAAQ,KAAK;AACnD,YAAQ,IAAI,SAAS,GAAG,IAAI,CAAC;AAC/B,UAAQ,IAAI,SAAS,KAAK,IAAI,CAAC;AAC/B,QAAM,MAAM,oBAAI,IAAY;AAC5B,WAAS,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK;AAC/B,UAAM,KAAK,IAAI,KAAK;AACpB,eAAW,OAAO,SAAS;AACzB,YAAM,IAAI,IAAI;AACd,UAAI,KAAK,SAAS,KAAK,OAAO,KAAK,IAAI,UAAU,GAAG,IAAI,IAAI,CAAC,IAAI;AAC/D,YAAI,IAAI,CAAC;AAAA,IACb;AAAA,EACF;AACA,SAAO,CAAC,GAAG,GAAG,EAAE,KAAK,CAACA,IAAGC,OAAMD,KAAIC,EAAC;AACtC;AACA,SAAS,WACP,OACA,KACA,MACA,SAAiB,GACP;AACV,QAAM,IAAI,UAAU,OAAO,IAAI,GAC7B,IAAI,UAAU,KAAK,IAAI,GACvB,QAAQ,KAAK,OAAO,EAAE,OAAO,KAAK,EAAE,QAAQ,KAAK,MAAM,IAAI,QAC3D,OAAO,EAAE,OAAO,KAAK,EAAE,QAAQ,IAAI;AACrC,SAAO,OAAO,SAAS,UAAU,OAAO,OAAO,0BAA0B;AACzE,QAAM,MAAM,CAAC;AACb,WAAS,IAAI,OAAO,KAAK,MAAM,KAAK,QAAQ;AAC1C,UAAM,IAAI,KAAK,MAAM,IAAI,EAAE,GACzB,IAAK,IAAI,KAAM;AACjB,QAAI,IAAI,KAAK,IAAI,KAAM;AACvB,eAAW,KAAK,gBAAgB,aAAa,GAAG,GAAG,CAAC,GAAG,IAAI;AACzD,UAAI,KAAK,SAAS,KAAK,IAAK,KAAI,KAAK,CAAC;AAAA,EAC1C;AACA,SAAO,IAAI,KAAK,CAACD,IAAGC,OAAMD,KAAIC,EAAC;AACjC;AACA,IAAM,SAAS;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,IAAM,OAAO,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC7D,IAAM,MAAM,CAAC,GAAW,IAAY,MAAc,OAAO,CAAC,EAAE,SAAS,GAAG,GAAG;AAEpE,SAAS,WACd,GACA,OAAe,OACf,SAAiB,SACT;AACR,MAAI,MAAM,CAAC;AACX,QAAM,IAAI,UAAU,GAAG,IAAI,GACzB,IAAI,IAAI,KAAK,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,GAAI,GACxD,MAAM,SAAS,GAAG,IAAI,GACtB,MAAM,EAAE,UAAU;AACpB,QAAM,SAAiC;AAAA,IACrC,GAAG,IAAI,EAAE,IAAI;AAAA,IACb,GAAG,IAAI,EAAE,OAAO,MAAM,EAAE;AAAA,IACxB,GAAG,IAAI,EAAE,MAAM;AAAA,IACf,GAAG,IAAI,EAAE,MAAM;AAAA,IACf,GAAG,IAAI,EAAE,GAAG;AAAA,IACZ,GAAG,OAAO,EAAE,GAAG,EAAE,SAAS,GAAG,GAAG;AAAA,IAChC,GAAG,IAAI,EAAE,KAAK;AAAA,IACd,GAAG,IAAI,EAAE,MAAM,CAAC;AAAA,IAChB,GAAG,IAAI,EAAE,OAAO,GAAG;AAAA,IACnB,GAAG,KAAK,GAAG;AAAA,IACX,GAAG;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,GAAG;AAAA,IACL,GAAG,OAAO,EAAE,QAAQ,CAAC;AAAA,IACrB,GAAG,OAAO,EAAE,QAAQ,CAAC;AAAA,IACrB,GAAG;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,EAAE,QAAQ,CAAC;AAAA,IACb,GAAG,EAAE,OAAO,KAAK,OAAO;AAAA,IACxB,GAAG,OAAO,GAAG;AAAA,IACb,GAAG,OAAO,OAAO,CAAC;AAAA,IAClB,GAAG;AAAA,MACD,KAAK,OAAO,EAAE,QAAQ,IAAI,MAAO,aAAa,EAAE,MAAM,GAAG,CAAC,KAAK,KAAK,IAAI;AAAA,MACxE;AAAA,IACF;AAAA,IACA,IACG,MAAM,IAAI,MAAM,OACjB,IAAI,KAAK,MAAM,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,IACpC,IAAI,KAAK,MAAO,KAAK,IAAI,GAAG,IAAI,OAAQ,EAAE,CAAC;AAAA,IAC7C,GAAG;AAAA,IACH,KAAK;AAAA,EACP;AACA,SAAO,IAAI,OAAO,IAAI,MAAM,OAAO,IAAI,MAAM,OAAO;AACpD,SAAO,IAAI,OAAO,IAAI,MAAM,OAAO,IAAI,MAAM,OAAO;AACpD,SAAO,IAAI,OAAO,IAAI,MAAM,OAAO;AACnC,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,QAAI,OAAO,CAAC,MAAM,KAAK;AACrB,aAAO,OAAO,CAAC;AACf;AAAA,IACF;AACA,UAAM,IAAI,OAAO,EAAE,CAAC;AACpB,UAAM,IAAI,QAAQ,CAAC,GAAG,mCAAmC,KAAK,GAAG;AACjE,WAAO,OAAO,CAAC;AAAA,EACjB;AACA,SAAO;AACT;AACA,SAAS,SACP,GACA,OACA,KACA,OACa;AACb,QAAM,OAAO,MAAM,OACjB,OAAO,EAAE,UACT,OACE,EAAE,SAAS,SACP,QAAQ,SACN,UACA,QAAQ,QACN,WACA,QAAQ,UACN,YACA,WACN,EAAE;AACV,MAAI,QAAkB,CAAC,GACrB,QAAkB,CAAC,GACnB,aAAuB,CAAC,GACxB,SAAS;AACX,MAAI,SAAS,UAAU;AACrB,UAAM,SACJ,OAAO,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,SAAS,MAAM,CAAC,IAAI;AACzE,aAAS,SAAS,IAAI,UAAU;AAChC,QAAI,EAAE,eAAe,QAAQ,EAAE,UAAU,MAAM;AAC7C,cAAQ,WAAW,OAAO,KAAK,MAAM,MAAM;AAC3C,mBAAa;AAAA,IACf;AACA,QAAI,EAAE,eAAe,KAAM,SAAQ,WAAW,OAAO,KAAK,MAAM,CAAC;AACjE,QAAI,EAAE,eAAe,QAAQ,EAAE,iBAAiB;AAC9C,cAAQ,UAAU,OAAO,KAAK,EAAE,cAAc,IAAI;AACpD,QAAI,EAAE,eAAe,QAAQ,EAAE,iBAAiB;AAC9C,cAAQ,UAAU,OAAO,KAAK,EAAE,cAAc,IAAI;AACpD,QAAI,EAAE,UAAU,QAAQ,EAAE,iBAAiB;AACzC,mBAAa,UAAU,OAAO,KAAK,EAAE,cAAc,IAAI;AAAA,EAC3D,OAAO;AACL,QAAI,KAAK,MACP,KAAK,MACL,KAAK;AACP,QAAI,SAAS,UAAU;AACrB,WAAK;AACL,WAAK,KAAK;AACV,eAAS;AAAA,IACX;AACA,QAAI,SAAS,WAAW;AACtB,WAAK;AACL,WAAK,KAAK;AACV,eAAS;AAAA,IACX;AACA,QAAI,EAAE,SAAS,UAAU,OAAO,OAAO;AACrC,YAAM,SAAS,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,EAAE,CAAC;AACxD,WACE,CAAC,GAAG,GAAG,IAAI,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK,KAAK,MAAM,MAAM,IAAI,EAAE;AAAA,QAC3D,CAAC,MAAM,KAAK;AAAA,MACd,KAAK;AACP,WAAK,KAAK,IAAI,GAAG,KAAK,CAAC;AACvB,WAAK;AACL,UAAI,KAAK,GAAI,UAAS;AAAA,IACxB;AACA,SAAK,KAAK,IAAI,IAAI,OAAO,GAAI;AAC7B,QAAI,EAAE,iBAAiB,KAAM,MAAK,EAAE;AACpC,QAAI,EAAE,iBAAiB,KAAM,MAAK,EAAE;AACpC,QAAI,EAAE,iBAAiB,KAAM,MAAK,EAAE;AACpC,QAAI,EAAE,eAAe,KAAM,SAAQ,UAAU,OAAO,KAAK,IAAI,IAAI;AACjE,QAAI,EAAE,eAAe,KAAM,SAAQ,UAAU,OAAO,KAAK,IAAI,IAAI;AACjE,QAAI,EAAE,UAAU,KAAM,cAAa,UAAU,OAAO,KAAK,IAAI,IAAI;AAAA,EACnE;AACA,MAAI,EAAE,eAAe;AACnB,YAAQ,EAAE,WAAW,OAAO,CAAC,MAAM,KAAK,SAAS,KAAK,GAAG;AAC3D,MAAI,EAAE,eAAe;AACnB,YAAQ,EAAE,WAAW,OAAO,CAAC,MAAM,KAAK,SAAS,KAAK,GAAG;AAC3D,MAAI,EAAE,gBAAgB,KAAM,UAAS,EAAE;AACvC,MAAI,SAAyB,CAAC;AAC9B,MAAI,EAAE,UAAU;AACd,aAAS,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,QAAQ,SAAS,EAAE,QAAQ,GAAG;AAAA,WAE/D,SAAS,YACT,EAAE,iBAAiB,QACnB,EAAE,uBAAuB,GACzB;AACA,eAAW,KAAK,UAAU,QAAQ,QAAQ,KAAK,OAAO,IAAI,GAAG;AAC3D,YAAM,IAAI,UAAU,GAAG,IAAI,GACzB,OAAO,gBAAgB,IAAI,OAAO,IAAI;AACxC,UAAI,IAAI,SAAS,CAAC,KAAK,UAAU,KAAK,KAAK,SAAS,CAAC,IAAI,IAAK;AAC9D,iBAAW,QAAQ,gBAAgB,IAAI,OAAO,IAAI;AAChD,YAAI,QAAQ,SAAS,QAAQ;AAC3B,iBAAO,KAAK,EAAE,MAAM,MAAM,OAAO,WAAW,GAAG,MAAM,MAAM,EAAE,CAAC;AAAA,IACpE;AAAA,EACF;AACE,eAAW,KAAK,YAAY;AAC1B,YAAM,MAAM,IAAI,EAAE;AAClB,UAAI,OAAO,SAAS,OAAO;AACzB,eAAO,KAAK,EAAE,MAAM,KAAK,OAAO,WAAW,GAAG,MAAM,MAAM,EAAE,CAAC;AAAA,IACjE;AACF,SAAO,KAAK,CAACD,IAAG,MAAMA,GAAE,OAAO,EAAE,IAAI;AACrC,MAAI,EAAE,UAAU,QAAQ,SAAS,WAAW,QAAQ,OAAO;AACzD,UAAM,OAAO,oBAAI,IAAyB;AAC1C,eAAW,KAAK,QAAQ;AACtB,UAAI,CAAC,KAAK,IAAI,EAAE,KAAK,EAAG,MAAK,IAAI,EAAE,OAAO,oBAAI,IAAI,CAAC;AACnD,WAAK,IAAI,EAAE,KAAK,EAAG,IAAI,SAAS,EAAE,MAAM,IAAI,CAAC;AAAA,IAC/C;AACA,aAAS,OAAO;AAAA,MAAI,CAAC,MACnB,KAAK,IAAI,EAAE,KAAK,EAAG,OAAO,IACtB;AAAA,QACE,MAAM,EAAE;AAAA,QACR,OAAO,EAAE,QAAQ,MAAM,WAAW,EAAE,MAAM,MAAM,IAAI;AAAA,MACtD,IACA;AAAA,IACN;AAAA,EACF;AACA,QAAM,WAAW,IAAI,IAAI,KAAK;AAC9B,UAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;AAC5C,SAAO,EAAE,OAAO,OAAO,QAAQ,KAAK;AACtC;AACA,SAAS,UAAU,GAAkC;AACnD,MAAI,QAAQ,UACV,MAAM;AACR,aAAW,KAAK,EAAE;AAChB,QAAI,EAAE,WAAW,QAAQ;AACvB,cAAQ,KAAK,IAAI,OAAO,EAAE,WAAW,CAAC,CAAC;AACvC,YAAM,KAAK,IAAI,KAAK,EAAE,WAAW,EAAE,WAAW,SAAS,CAAC,CAAC;AAAA,IAC3D;AACF,MAAI,EAAE,SAAS,UAAU,KAAM,SAAQ,EAAE,SAAS;AAClD,MAAI,EAAE,SAAS,QAAQ,KAAM,OAAM,EAAE,SAAS;AAC9C,MAAI,UAAU,OAAO,EAAE,SAAS,UAAU,QAAQ,EAAE,SAAS,QAAQ,MAAM;AACzE,aAAS;AACT,WAAO;AAAA,EACT;AACA,QAAM,KAAK;AACX,QAAM,GAAG;AACT;AAAA,IACE,MAAM;AAAA,IACN;AAAA,EACF;AACA,SAAO,CAAC,OAAO,GAAG;AACpB;AAGA,IAAM,eAA4D;AAAA,EAChE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,MAAM,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACpE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,GAAG,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACjE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,SAAS,OAAO;AAAA,EACnE,KAAK,CAAC,SAAS,SAAS,SAAS,SAAS,SAAS,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",
6
6
  "names": ["a", "b", "s"]
7
7
  }