@trdrs/quickcharts 4.1.0 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +276 -59
  3. package/dist/adapters/rest.d.ts +4 -4
  4. package/dist/adapters/rest.js +1 -1
  5. package/dist/adapters/rest.js.map +1 -1
  6. package/dist/ar-TG26ZCCE.js +1322 -0
  7. package/dist/ar-TG26ZCCE.js.map +1 -0
  8. package/dist/{assets-BF-NDyHl.d.ts → assets-DF3nozNV.d.ts} +161 -17
  9. package/dist/ca_ES-WJWH5BXU.js +1322 -0
  10. package/dist/ca_ES-WJWH5BXU.js.map +1 -0
  11. package/dist/{chunk-D3S26ARP.js → chunk-EXJAJZTN.js} +1 -1
  12. package/dist/chunk-EXJAJZTN.js.map +1 -0
  13. package/dist/{chunk-TBOVLJAK.js → chunk-Q3DCXQDW.js} +85 -19
  14. package/dist/chunk-Q3DCXQDW.js.map +1 -0
  15. package/dist/de-SUDTTPQ3.js +1322 -0
  16. package/dist/de-SUDTTPQ3.js.map +1 -0
  17. package/dist/drawings.d.ts +3 -3
  18. package/dist/drawings.js +1 -1
  19. package/dist/es-FOBXUK2X.js +1322 -0
  20. package/dist/es-FOBXUK2X.js.map +1 -0
  21. package/dist/feature-manifest.json +105 -9
  22. package/dist/fr-7KQC4IJH.js +1322 -0
  23. package/dist/fr-7KQC4IJH.js.map +1 -0
  24. package/dist/he_IL-2T6XBA6D.js +1322 -0
  25. package/dist/he_IL-2T6XBA6D.js.map +1 -0
  26. package/dist/id_ID-SI25N57C.js +1322 -0
  27. package/dist/id_ID-SI25N57C.js.map +1 -0
  28. package/dist/index.d.ts +862 -103
  29. package/dist/index.js +12251 -7910
  30. package/dist/index.js.map +1 -1
  31. package/dist/it-PMSTWZDL.js +1322 -0
  32. package/dist/it-PMSTWZDL.js.map +1 -0
  33. package/dist/ja-PABDRAXV.js +1322 -0
  34. package/dist/ja-PABDRAXV.js.map +1 -0
  35. package/dist/ko-JHRYYFCV.js +1322 -0
  36. package/dist/ko-JHRYYFCV.js.map +1 -0
  37. package/dist/ms_MY-U4EE5Q4V.js +1322 -0
  38. package/dist/ms_MY-U4EE5Q4V.js.map +1 -0
  39. package/dist/pl-4HCG3T3J.js +1322 -0
  40. package/dist/pl-4HCG3T3J.js.map +1 -0
  41. package/dist/pt-6LTNN653.js +1322 -0
  42. package/dist/pt-6LTNN653.js.map +1 -0
  43. package/dist/quickcharts.css +586 -198
  44. package/dist/{resources-C0cYryO9.d.ts → resources-XglhzzW0.d.ts} +4 -2
  45. package/dist/rest-openapi.json +16 -11
  46. package/dist/ru-LFHCSDBV.js +1322 -0
  47. package/dist/ru-LFHCSDBV.js.map +1 -0
  48. package/dist/sv-4XVUXYK6.js +1322 -0
  49. package/dist/sv-4XVUXYK6.js.map +1 -0
  50. package/dist/{symbols-6V22WaRX.d.ts → symbols-DdHLHQFC.d.ts} +77 -8
  51. package/dist/symbols.d.ts +1 -1
  52. package/dist/th-WM2PVA24.js +1322 -0
  53. package/dist/th-WM2PVA24.js.map +1 -0
  54. package/dist/theme-manifest.json +105 -21
  55. package/dist/tr-HMAZXSJM.js +1322 -0
  56. package/dist/tr-HMAZXSJM.js.map +1 -0
  57. package/dist/vi-ITFBV5B7.js +1322 -0
  58. package/dist/vi-ITFBV5B7.js.map +1 -0
  59. package/dist/zh-ZGU2RI7K.js +1322 -0
  60. package/dist/zh-ZGU2RI7K.js.map +1 -0
  61. package/dist/zh_TW-PNINSQ6F.js +1322 -0
  62. package/dist/zh_TW-PNINSQ6F.js.map +1 -0
  63. package/package.json +1 -1
  64. package/dist/ar-VILLYPAA.js +0 -1181
  65. package/dist/ar-VILLYPAA.js.map +0 -1
  66. package/dist/ca_ES-EJXLAXOA.js +0 -1181
  67. package/dist/ca_ES-EJXLAXOA.js.map +0 -1
  68. package/dist/chunk-D3S26ARP.js.map +0 -1
  69. package/dist/chunk-TBOVLJAK.js.map +0 -1
  70. package/dist/de-PHID4SVN.js +0 -1181
  71. package/dist/de-PHID4SVN.js.map +0 -1
  72. package/dist/es-KD4FBLOP.js +0 -1181
  73. package/dist/es-KD4FBLOP.js.map +0 -1
  74. package/dist/fr-KTTX3FF3.js +0 -1181
  75. package/dist/fr-KTTX3FF3.js.map +0 -1
  76. package/dist/he_IL-Z3DXMAKZ.js +0 -1181
  77. package/dist/he_IL-Z3DXMAKZ.js.map +0 -1
  78. package/dist/id_ID-FFX6X4C5.js +0 -1181
  79. package/dist/id_ID-FFX6X4C5.js.map +0 -1
  80. package/dist/it-X2GFCLGU.js +0 -1181
  81. package/dist/it-X2GFCLGU.js.map +0 -1
  82. package/dist/ja-TG3WO2KH.js +0 -1181
  83. package/dist/ja-TG3WO2KH.js.map +0 -1
  84. package/dist/ko-4HHHO7KV.js +0 -1181
  85. package/dist/ko-4HHHO7KV.js.map +0 -1
  86. package/dist/ms_MY-HPVQKVPY.js +0 -1181
  87. package/dist/ms_MY-HPVQKVPY.js.map +0 -1
  88. package/dist/pl-2W2HP34O.js +0 -1181
  89. package/dist/pl-2W2HP34O.js.map +0 -1
  90. package/dist/pt-XQUBSXO7.js +0 -1181
  91. package/dist/pt-XQUBSXO7.js.map +0 -1
  92. package/dist/ru-XKFQPFDM.js +0 -1181
  93. package/dist/ru-XKFQPFDM.js.map +0 -1
  94. package/dist/sv-ZMEGAPCR.js +0 -1181
  95. package/dist/sv-ZMEGAPCR.js.map +0 -1
  96. package/dist/th-4735BUT4.js +0 -1181
  97. package/dist/th-4735BUT4.js.map +0 -1
  98. package/dist/tr-PG3CW2L3.js +0 -1181
  99. package/dist/tr-PG3CW2L3.js.map +0 -1
  100. package/dist/vi-YPRIAJ33.js +0 -1181
  101. package/dist/vi-YPRIAJ33.js.map +0 -1
  102. package/dist/zh-RVHEWNSW.js +0 -1181
  103. package/dist/zh-RVHEWNSW.js.map +0 -1
  104. package/dist/zh_TW-ZFJMDA64.js +0 -1181
  105. package/dist/zh_TW-ZFJMDA64.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/drawings/core/visibility.ts","../src/internal/drawings/core/types.ts","../src/internal/drawings/core/drawing.ts","../src/internal/drawings/core/textEntry.ts","../src/theme/palettes.ts","../src/internal/drawings/core/inks.ts","../src/internal/drawings/render/canvas.ts","../src/internal/drawings/render/pane-view.ts","../src/internal/drawings/render/axis-view.ts","../src/i18n/en/drawing.ts","../src/paneGeometry.ts","../src/internal/drawings/core/manager.ts","../src/internal/drawings/core/magnet.ts","../src/internal/drawings/core/geometry.ts","../src/internal/drawings/render/imageCache.ts","../src/internal/drawings/core/savedLook.ts","../src/internal/drawings/render/lineWords.ts","../src/internal/drawings/render/statsBox.ts","../src/internal/drawings/render/textEntry.ts","../src/internal/drawings/tools/lines.ts","../src/internal/drawings/tools/shapes.ts","../src/internal/drawings/core/bars.ts","../src/internal/drawings/render/glyphArtwork.ts","../src/internal/drawings/tools/annotations.ts","../src/internal/drawings/tools/measurement.ts","../src/internal/drawings/tools/boxLevels.ts","../src/internal/drawings/tools/fibonacci.ts","../src/internal/drawings/tools/channels.ts","../src/internal/drawings/tools/pitchforks.ts","../src/internal/drawings/tools/gann.ts","../src/internal/drawings/core/money.ts","../src/internal/drawings/tools/forecasting.ts","../src/internal/drawings/tools/freehand.ts","../src/internal/drawings/tools/table.ts","../src/internal/drawings/tools/patterns.ts","../src/internal/drawings/tools/elliott.ts","../src/internal/drawings/tools/cycles.ts","../src/internal/drawings/tools/bars.ts","../src/internal/drawings/tools/volume.ts","../src/internal/drawings/tools/content.ts","../src/internal/drawings/registry.ts","../src/internal/drawings/store.ts","../src/drawings/tools.ts","../src/drawings/store.ts","../src/drawings/magnetModel.ts","../src/drawings/drawingToolbarModel.ts","../src/drawings/hideModel.ts","../src/drawings/cursorModel.ts","../src/drawings/lockModel.ts","../src/drawings/favoritesModel.ts","../src/drawings/editModel.ts","../src/theme/color.ts","../src/ui/controls/color/palette.ts","../src/ui/controls/dom.ts","../src/ui/controls/escape.ts","../src/ui/drawings/dom.ts","../src/ui/controls/color/picker.ts","../src/drawings/preferences.ts","../src/drawings/templates.ts","../src/drawings/assets.ts","../src/drawings/capabilities.ts"],"sourcesContent":["/** One timeframe bucket's visibility rule: enabled + the inclusive value range it covers. */\nexport interface VisibilityRange {\n on: boolean\n from: number\n to: number\n}\n\n/**\n * Per-timeframe visibility for one drawing — which chart timeframes it appears on. Buckets and\n * ranges mirror the timeframe vocabulary (seconds/minutes 1–59, hours 1–24, days 1–366,\n * weeks 1–52, months 1–12); ticks is a single switch.\n */\nexport interface TimeframeVisibility {\n ticks: boolean\n seconds: VisibilityRange\n minutes: VisibilityRange\n hours: VisibilityRange\n days: VisibilityRange\n weeks: VisibilityRange\n months: VisibilityRange\n}\n\nexport const DEFAULT_VISIBILITY: TimeframeVisibility = {\n ticks: true,\n seconds: { on: true, from: 1, to: 59 },\n minutes: { on: true, from: 1, to: 59 },\n hours: { on: true, from: 1, to: 24 },\n days: { on: true, from: 1, to: 366 },\n weeks: { on: true, from: 1, to: 52 },\n months: { on: true, from: 1, to: 12 },\n}\n\nexport type TimeframeBucket = 'ticks' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months'\n\n/** The four quick visibility rules, resolved against the chart's CURRENT timeframe. */\nexport type VisibilityPreset = 'current-and-above' | 'current-and-below' | 'current-only' | 'all'\n\nconst RANGE_BUCKETS = ['seconds', 'minutes', 'hours', 'days', 'weeks', 'months'] as const\nconst BUCKET_MAX: Record<(typeof RANGE_BUCKETS)[number], number> = {\n seconds: 59,\n minutes: 59,\n hours: 24,\n days: 366,\n weeks: 52,\n months: 12,\n}\n\n/** Build the visibility tree for one quick rule. \"Above\" means the current timeframe and every\n * COARSER one (a 1h line kept \"and above\" shows on 4h and 1d, never on 5m); \"below\" mirrors it\n * toward the finer timeframes; \"only\" pins the current bucket's value. A fractional context\n * (90m → hours 1.5) rounds OUTWARD so the current chart always satisfies its own rule. With no\n * context (unparseable timeframe) every rule degrades to all — a drawing must never vanish\n * because the timeframe could not be classified. */\nexport function visibilityPreset(kind: VisibilityPreset, ctx: TimeframeContext): TimeframeVisibility {\n const all: TimeframeVisibility = {\n ticks: true,\n seconds: { on: true, from: 1, to: 59 },\n minutes: { on: true, from: 1, to: 59 },\n hours: { on: true, from: 1, to: 24 },\n days: { on: true, from: 1, to: 366 },\n weeks: { on: true, from: 1, to: 52 },\n months: { on: true, from: 1, to: 12 },\n }\n if (kind === 'all' || !ctx) return all\n const order: TimeframeBucket[] = ['ticks', ...RANGE_BUCKETS]\n const at = order.indexOf(ctx.bucket)\n const lo = Math.max(1, Math.floor(ctx.value))\n const hi = Math.max(lo, Math.ceil(ctx.value))\n const out = all\n // Ticks is a single switch and the FINEST bucket: on when ticks IS the current bucket (every\n // rule keeps the current timeframe visible), else only \"and below\" reaches down to it.\n out.ticks = ctx.bucket === 'ticks' || kind === 'current-and-below'\n for (const bucket of RANGE_BUCKETS) {\n const i = order.indexOf(bucket)\n if (i === at) {\n out[bucket] =\n kind === 'current-and-above'\n ? { on: true, from: lo, to: BUCKET_MAX[bucket] }\n : kind === 'current-and-below'\n ? { on: true, from: 1, to: hi }\n : { on: true, from: lo, to: hi }\n } else if (i > at) {\n out[bucket] = { on: kind === 'current-and-above', from: 1, to: BUCKET_MAX[bucket] }\n } else {\n out[bucket] = { on: kind === 'current-and-below', from: 1, to: BUCKET_MAX[bucket] }\n }\n }\n return out\n}\n\n/** The chart's current timeframe, bucketed; null = unknown (drawings then always show). */\nexport type TimeframeContext = { bucket: TimeframeBucket; value: number } | null\n\n/**\n * Parse a timeframe token ('1t', '30s', '45m', '4h', '1d', '1w', '3mo') into a bucket context.\n * Oversized values roll up so custom timeframes land in the range viewers expect (90m → 1.5h).\n */\nexport function parseTimeframeContext(tf: string): TimeframeContext {\n const match = /^(\\d+)(t|s|m|h|d|w|mo)$/.exec(tf.trim().toLowerCase())\n if (!match) return null\n let value = Number(match[1])\n const unit = match[2]\n if (unit === 't') return { bucket: 'ticks', value }\n if (unit === 's') {\n if (value < 60) return { bucket: 'seconds', value }\n value /= 60\n return value < 60 ? { bucket: 'minutes', value } : { bucket: 'hours', value: value / 60 }\n }\n if (unit === 'm') {\n return value < 60 ? { bucket: 'minutes', value } : { bucket: 'hours', value: value / 60 }\n }\n if (unit === 'h') return { bucket: 'hours', value }\n if (unit === 'd') return { bucket: 'days', value }\n if (unit === 'w') return { bucket: 'weeks', value }\n return { bucket: 'months', value }\n}\n\n/** Deep-copied visibility with defaults filled in — configs never alias the shared default. */\nexport function normalizeVisibility(partial?: Partial<TimeframeVisibility>): TimeframeVisibility {\n return {\n ticks: partial?.ticks ?? DEFAULT_VISIBILITY.ticks,\n seconds: { ...DEFAULT_VISIBILITY.seconds, ...partial?.seconds },\n minutes: { ...DEFAULT_VISIBILITY.minutes, ...partial?.minutes },\n hours: { ...DEFAULT_VISIBILITY.hours, ...partial?.hours },\n days: { ...DEFAULT_VISIBILITY.days, ...partial?.days },\n weeks: { ...DEFAULT_VISIBILITY.weeks, ...partial?.weeks },\n months: { ...DEFAULT_VISIBILITY.months, ...partial?.months },\n }\n}\n\n/** Whether a drawing with this visibility config shows at the given timeframe. */\nexport function visibleAt(visibility: TimeframeVisibility, context: TimeframeContext): boolean {\n if (!context) return true\n if (context.bucket === 'ticks') return visibility.ticks\n const range = visibility[context.bucket]\n return range.on && context.value >= range.from && context.value <= range.to\n}\n","import type { Time } from 'lightweight-charts'\nimport type { TimeframeContext, TimeframeVisibility } from './visibility'\nimport { DEFAULT_VISIBILITY } from './visibility'\nimport type { TextDraft, TextEditFrame } from './textEntry'\n\n/** How the host writes a price: the symbol's own formatter, injected so every drawing label,\n * pill and readout carries the market's declared precision. The drawings package never derives a\n * precision from a price's magnitude. */\nexport type PriceFormatPort = (price: number) => string\n\n/** Where a glyph mark's artwork comes from. Platform emoji fonts cannot be trusted on a canvas\n * (Windows draws no flag glyphs at all), so emoji and sticker marks draw a host-supplied image\n * when this answers with a URL. Null falls back to drawing the glyph as text, which is also what\n * icon marks always do, because their ink is tinted by the stroke colour and artwork cannot\n * carry that. */\nexport type GlyphSourcePort = (glyph: string) => string | null\n\n/** A point the drawing is pinned to, in chart coordinates. */\nexport interface Anchor {\n time: Time\n price: number\n}\n\n/** A point in pane-local CSS pixels. */\nexport interface Point {\n x: number\n y: number\n}\n\nexport type LineStyle = 'solid' | 'dashed' | 'dotted'\n\n/**\n * The shared visual vocabulary every tool paints with. `style` is HOW a drawing is painted\n * (what the floating toolbar edits generically); a tool's `props` are WHAT it is (levels,\n * extension flags, text content, …); `options` are lifecycle flags. All style fields are\n * required — constructors merge defaults so tools never carry `?? fallback` chains.\n */\nexport interface DrawingStyle {\n lineColor: string\n lineWidth: number\n lineStyle: LineStyle\n /** Fill paint for tools with a fillable region; fill shows only while `fillOpacity > 0`. */\n fillColor: string\n fillOpacity: number\n /** Text channel for tools that render text (labels, notes, callouts). */\n textColor: string\n fontSize: number\n bold: boolean\n italic: boolean\n}\n\nexport const DEFAULT_STYLE: DrawingStyle = {\n lineColor: '#4c98fb',\n lineWidth: 2,\n lineStyle: 'solid',\n fillColor: '#4c98fb',\n fillOpacity: 0,\n textColor: '#e5e7eb',\n fontSize: 13,\n bold: false,\n italic: false,\n}\n\n/** Lifecycle flags, uniform across tools. Higher `zIndex` hit-tests (and later paints) on top. */\nexport interface DrawingOptions {\n visible: boolean\n locked: boolean\n zIndex: number\n /** Which chart timeframes the drawing shows on (independent of the manual `visible` switch). */\n visibility: TimeframeVisibility\n /** The name the viewer gave the drawing. Absent, the drawing is called by its tool's name. */\n name?: string\n}\n\nexport const DEFAULT_OPTIONS: DrawingOptions = {\n visible: true,\n locked: false,\n zIndex: 0,\n visibility: DEFAULT_VISIBILITY,\n}\n\n/** The format a drawing saves in: its tool's present look. */\nexport const SERIAL_VERSION = 3\n\n/**\n * Wire/persistence format. `props` carries the tool-specific payload — every tool round-trips\n * its COMPLETE state through this shape (the schema exists so nothing is ever dropped on save).\n */\nexport interface SerializedDrawing {\n /** The format's version. A drawing saves at 3. A save at 2 carries the props and style of the\n * looks format 2 painted, and restores with that look: a tool whose factory values, prop\n * meanings or paint rules differ at 3 writes the values that paint the save as it painted. */\n v: 2 | 3\n id: string\n type: string\n anchors: Anchor[]\n style: DrawingStyle\n options: DrawingOptions\n props?: Record<string, unknown>\n /** The chart surface this drawing is LOCAL to, when it is local to one. Absent — the case for\n * every drawing made while sync is on, and for every drawing made before scoping existed —\n * means the drawing is shared by every surface showing this symbol. The host owns the shape of\n * the token; the drawing layer only ever compares it for equality. */\n scope?: string\n}\n\nexport type DrawingState = 'normal' | 'hovered' | 'selected' | 'editing'\n\n/**\n * Pane-local coordinate conversions handed to paint/hit-test code. Width/height are the pane's\n * CSS-pixel size (never a container fallback — extension math depends on the real pane box).\n */\nexport interface Viewport {\n width: number\n height: number\n xOf(time: Time): number | null\n yOf(price: number): number | null\n timeAt(x: number): Time | null\n priceAt(y: number): number | null\n /** Bar-index distance between two times (fractional; null when either falls outside data). */\n barsBetween(a: Time, b: Time): number | null\n /** The bar index a time sits at (fractional; null outside the loaded range). */\n logicalOf(time: Time): number | null\n /** The time at a bar index (null in whitespace beyond the loaded range). */\n timeOfLogical(logical: number): Time | null\n /** Whether the pane's price scale is logarithmic. Absent, it is read as linear. */\n logScale?: boolean\n}\n\n/** A draggable handle over an anchor, in pane-local CSS pixels. */\nexport interface ControlPoint {\n index: number\n x: number\n y: number\n}\n\nexport interface IDrawing {\n readonly id: string\n readonly type: string\n /** The chart surface this drawing is bound to, when it is bound to one; undefined is shared by\n * every surface showing the symbol. The host assigns and compares it; the model only carries it. */\n scope?: string\n anchors: readonly Anchor[]\n style: Readonly<DrawingStyle>\n options: Readonly<DrawingOptions>\n state: DrawingState\n\n setAnchors(anchors: Anchor[]): void\n updateAnchor(index: number, anchor: Anchor): void\n /** The symbol's tick as the host stated it, or null without one. */\n getTickSize?(): number | null\n appendAnchor(anchor: Anchor): void\n removeAnchor(index: number): void\n updateStyle(patch: Partial<DrawingStyle>): void\n updateOptions(patch: Partial<DrawingOptions>): void\n setState(state: DrawingState): void\n\n /** The tool-specific payload (typed per tool; empty object for tools without one). */\n readonly props: Readonly<Record<string, unknown>>\n applyProps(patch: Record<string, unknown>): void\n\n /** True once the drawing has its full anchor set (placement complete, all values finite). */\n isValid(): boolean\n\n /** The chart's current timeframe (the manager broadcasts it on timeframe changes). */\n setTimeframeContext(context: TimeframeContext): void\n /** Chart-wide hide-all switch (transient view state — never serialized). */\n setGlobalHidden(hidden: boolean): void\n /** The symbol's smallest price move (tick-denominated readouts); null omits those readouts. */\n setTickSize(tick: number | null): void\n /** The currency the symbol is quoted in (an amount's unit); null where the host states none. */\n setCurrencyCode(code: string | null): void\n /** The currency the symbol is quoted in, or null where the host states none. */\n getCurrencyCode?(): string | null\n /** The symbol's price formatter (the manager broadcasts it); null returns to the declared\n * stand-in. */\n setPriceFormatter(format: PriceFormatPort | null): void\n /** Where glyph artwork comes from (the manager broadcasts it); null draws glyphs as text. */\n setGlyphSource(source: GlyphSourcePort | null): void\n /** Manual `visible` switch AND hide-all AND the per-timeframe rule, combined. */\n isVisibleNow(): boolean\n\n testHit(point: Point, viewport: Viewport): boolean\n getControlPoints(viewport: Viewport): ControlPoint[]\n anchorToPixel(anchor: Anchor, viewport: Viewport): Point | null\n /** Scale grips beyond the anchors (emoji/image corners); dragging one calls `resizeTo`. */\n resizeHandles(viewport: Viewport): Point[]\n resizeTo(handleIndex: number, point: Point, viewport: Viewport): void\n /** \"+ Add text\" hint above a selected text-capable drawing that has no text yet. */\n paintTextHint(ctx: CanvasRenderingContext2D, viewport: Viewport): void\n hitTextHint(point: Point): boolean\n /** Where the hint last painted — the inline editor opens exactly there (the hint becomes it). */\n textHintAnchor(): { x: number; y: number; angle: number } | null\n /** An inline text editor is open on this drawing — the hint stays hidden underneath it. */\n textEditing: boolean\n /** The draft an open inline edit shows on a drawing that types its words on the chart. */\n readonly textDraft: TextDraft | null\n /** Show an inline edit's draft, or end it with null; `onFrame` hears where the words stand each\n * time a repaint moves them. */\n setTextDraft(draft: TextDraft | null, onFrame?: (frame: TextEditFrame | null) => void): void\n /** Where the drawing's words stand, for an editor laid over them; null for a tool that does not\n * type its words on the chart. */\n textFrame(viewport: Viewport): TextEditFrame | null\n /** Where the words an empty drawing shows come from, read as it paints. */\n setTextPlaceholder(source: (() => string) | null): void\n /** The anchors a drag that grabs the drawing at a point moves: null for all of them. */\n grabbedAnchors(point: Point, viewport: Viewport): number[] | null\n /** Whether a point is on the drawing's words, where a click on the selected drawing types. */\n wordsAt(point: Point, viewport: Viewport): boolean\n /** Move an anchor by its handle: to the point, unless the tool holds a handle to a line. */\n dragAnchorTo(index: number, anchor: Anchor): void\n /** Whether the pointer rests on the drawing. */\n readonly hovered: boolean\n setHovered(on: boolean): void\n /** Where a mouse rests over the chart while the drawing is selected, or null. */\n readonly pointer: Point | null\n setPointer(point: Point | null): void\n\n getViewport(): Viewport | null\n requestUpdate(): void\n toJSON(): SerializedDrawing\n}\n\nexport type ToolCategory =\n | 'lines'\n | 'channels'\n | 'pitchforks'\n | 'fibonacci'\n | 'gann'\n | 'patterns'\n | 'elliott'\n | 'cycles'\n | 'forecasting'\n | 'volume'\n | 'measurement'\n | 'shapes'\n | 'annotation'\n | 'content'\n\nexport type DrawingEventType =\n | 'drawing:added'\n | 'drawing:removed'\n | 'drawing:selected'\n | 'drawing:deselected'\n | 'drawing:cleared'\n\nexport interface DrawingEvent {\n type: DrawingEventType\n drawingId?: string\n drawing?: IDrawing\n}\n\nexport type DrawingEventCallback = (event: DrawingEvent) => void\n","import type {\n IChartApi,\n ISeriesApi,\n IPrimitivePaneView,\n ISeriesPrimitive,\n ISeriesPrimitiveAxisView,\n PrimitiveHoveredItem,\n SeriesAttachedParameter,\n SeriesType,\n Time,\n} from 'lightweight-charts'\nimport { PriceScaleMode } from 'lightweight-charts'\n\nimport type {\n Anchor,\n ControlPoint,\n DrawingOptions,\n DrawingState,\n DrawingStyle,\n IDrawing,\n Point,\n GlyphSourcePort,\n PriceFormatPort,\n SerializedDrawing,\n Viewport,\n} from './types'\nimport { DEFAULT_OPTIONS, DEFAULT_STYLE, SERIAL_VERSION } from './types'\nimport type { TimeframeContext } from './visibility'\nimport { normalizeVisibility, visibleAt } from './visibility'\nimport type { BarSource, SourceBar } from './bars'\nimport { layoutTextBlock, type TextBlock, type TextDraft, type TextEditFrame } from './textEntry'\nimport { DEFAULT_INKS, type DrawingInks } from './inks'\nimport { DrawingPaneView } from '../render/pane-view'\nimport { AxisBandView } from '../render/axis-view'\nimport { withAlpha, type HandleShape } from '../render/canvas'\nimport { drawing as englishWords } from '../../../i18n/en/drawing'\nimport { paneIndexOf } from '../../../paneGeometry'\n\nfunction normalizeOptions(patch: Partial<DrawingOptions>): DrawingOptions {\n return { ...DEFAULT_OPTIONS, ...patch, visibility: normalizeVisibility(patch.visibility) }\n}\n\n/** Any concrete drawing, prop shape erased — the store/registry currency. */\nexport type AnyDrawing = Drawing<Record<string, unknown>>\n\n\n/** Build a Viewport over a chart + series pair, in the pane the series stands in. Null while either\n * is unusable (torn down). */\nexport function viewportOf(chart: IChartApi, series: ISeriesApi<SeriesType>): Viewport | null {\n let width: number\n let height: number\n try {\n width = chart.timeScale().width()\n height = chart.paneSize(paneIndexOf(series)).height\n } catch {\n return null\n }\n if (width <= 0 || height <= 0) return null\n const ts = chart.timeScale()\n\n // ── time ⇄ logical ⇄ x, grounded in the library's MEASURED contract ──\n // Two live measurements define what the time scale can be trusted with:\n // (1) `timeToCoordinate` resolves only times that exist as bars of the CURRENT grid. An anchor\n // placed on a finer timeframe (17:30 on an hourly chart) answers null.\n // (2) `logicalToCoordinate` is exact for INTEGER indices inside the data — even thousands of\n // pixels off-screen (index 0 answered -11448.34px while scrolled far right, and the slope\n // between any two in-range integers equals the live barSpacing to full precision) — but\n // answers 0, the pane's left edge, for EVERY fractional logical and for any integer outside\n // the data. The visible logical range's endpoints are continuous scroll positions,\n // fractional in every real frame, so calibrating a linear map from them reads two poisoned\n // zeros and disables the map — which made every between-bars anchor (i.e. every drawing\n // after a timeframe switch) paint nothing.\n // So the library is consulted only where it is exact — bar times, integer in-range indices, the\n // live barSpacing — and every fractional mapping is computed from the series data directly.\n const data = series.data()\n const lastIndex = data.length - 1\n const numTime = (i: number): number | null => {\n const t = data[i]?.time\n return typeof t === 'number' ? t : null\n }\n const firstTime = data.length > 0 ? numTime(0) : null\n const lastTime = data.length > 0 ? numTime(lastIndex) : null\n // Leading/trailing bar steps extrapolate beyond the loaded range: past the last bar is a\n // projection into empty future space, before the first is unloaded history.\n const prevTime = numTime(lastIndex - 1)\n const trailStep = lastTime !== null && prevTime !== null && lastTime > prevTime ? lastTime - prevTime : null\n const secondTime = numTime(1)\n const leadStep = firstTime !== null && secondTime !== null && secondTime > firstTime ? secondTime - firstTime : null\n\n const logicalOfTime = (time: Time): number | null => {\n // A time that IS a bar of the current grid takes the library's exact mapping. This also covers\n // non-numeric Time shapes, which the data math below cannot address.\n const x = ts.timeToCoordinate(time)\n if (x !== null) {\n const logical = ts.coordinateToLogical(x)\n if (logical !== null) return logical\n }\n if (typeof time !== 'number' || firstTime === null || lastTime === null) return null\n if (time >= lastTime) return trailStep === null ? lastIndex : lastIndex + (time - lastTime) / trailStep\n if (time <= firstTime) return leadStep === null ? 0 : (time - firstTime) / leadStep\n // Between bars: binary-search the straddling pair and interpolate inside it. Bar steps are\n // NOT uniform (session gaps), so proportional placement within the one straddling pair is the\n // only mapping that keeps a finer-grid anchor in place — counting bars at a fixed step from\n // either end would shift it by every gap in between.\n let lo = 0\n let hi = lastIndex\n while (hi - lo > 1) {\n const mid = (lo + hi) >> 1\n const tm = numTime(mid)\n if (tm === null) return null\n if (tm <= time) lo = mid\n else hi = mid\n }\n const tLo = numTime(lo)\n const tHi = numTime(hi)\n if (tLo === null || tHi === null || tHi <= tLo) return null\n return lo + (time - tLo) / (tHi - tLo)\n }\n\n // The inverse, from the same data: fractional logicals interpolate between their neighbouring\n // bars' times, out-of-range logicals extrapolate on the edge step. Never routed through\n // `logicalToCoordinate` — a fractional input there answers 0, and `coordinateToTime(0)` then\n // returns the LEFT EDGE bar's time: a silently wrong answer rather than a null.\n const timeOfLogicalIndex = (logical: number): Time | null => {\n if (firstTime === null || lastTime === null) return null\n if (logical >= lastIndex) return trailStep === null ? (lastTime as Time) : ((lastTime + (logical - lastIndex) * trailStep) as Time)\n if (logical <= 0) return leadStep === null ? (firstTime as Time) : ((firstTime + logical * leadStep) as Time)\n const i = Math.floor(logical)\n const tLo = numTime(i)\n const tHi = numTime(i + 1)\n if (tLo === null || tHi === null) return null\n return (tLo + (logical - i) * (tHi - tLo)) as Time\n }\n\n // logical → x: ONE trustworthy point (integer index 0, exact at any scroll position) plus the\n // live barSpacing; the x axis is linear by construction. Declines only when the chart is empty.\n let xAtLogical: (logical: number) => number | null = () => null\n if (data.length > 0) {\n const x0 = ts.logicalToCoordinate(0 as Parameters<typeof ts.logicalToCoordinate>[0])\n const barSpacing = ts.options().barSpacing\n if (x0 !== null && barSpacing > 0) xAtLogical = (logical) => x0 + logical * barSpacing\n }\n\n // The price scale's mode: a scale that cannot answer is read as linear.\n let logScale = false\n try {\n logScale = series.priceScale().options().mode === PriceScaleMode.Logarithmic\n } catch {\n logScale = false\n }\n\n return {\n width,\n height,\n logScale,\n xOf: (time) => {\n const direct = ts.timeToCoordinate(time)\n if (direct !== null) return direct\n const logical = logicalOfTime(time)\n if (logical === null) return null\n return xAtLogical(logical)\n },\n yOf: (price) => series.priceToCoordinate(price),\n timeAt: (x) => {\n const direct = ts.coordinateToTime(x)\n if (direct !== null) return direct\n const logical = ts.coordinateToLogical(x)\n if (logical === null) return null\n return timeOfLogicalIndex(logical)\n },\n priceAt: (y) => series.coordinateToPrice(y),\n barsBetween: (a, b) => {\n const la = logicalOfTime(a)\n const lb = logicalOfTime(b)\n if (la === null || lb === null) return null\n return lb - la\n },\n logicalOf: logicalOfTime,\n timeOfLogical: timeOfLogicalIndex,\n }\n}\n\n/**\n * Base class for every drawing tool: a lightweight-charts series primitive holding anchors\n * (chart coordinates), shared style, lifecycle options, and a typed tool-specific `props` bag.\n *\n * Deliberate non-features:\n * - No `autoscaleInfo`. Drawings are annotations — they must never stretch the price scale,\n * so the primitive simply does not implement it.\n * - No DOM listeners. Input (placement, dragging, selection gestures) belongs to the host app;\n * this class owns state, geometry, and pixels.\n *\n * Subclasses implement `paint` (canvas, CSS-pixel space) and `testHit`, and override\n * `defaultProps` when they carry tool-specific state. `props` round-trips through\n * `toJSON`/`fromJSON` in full — a tool's serialized form IS its complete state.\n */\n/** What a drawing writes when no host formatter has been injected: cents, a DECLARED stand-in\n * for an unhosted drawing. A host always injects the symbol's formatter; this is never a rule\n * that reads precision off the price. */\nconst UNRESOLVED_PRICE_TEXT: PriceFormatPort = (price) => price.toFixed(2)\n\n/** A time a drawing writes where its chart has no time formatter: its UTC date and time of day. */\nfunction plainTime(time: Time): string {\n const t = Number(time)\n if (!Number.isFinite(t)) return String(time)\n const d = new Date(t * 1000)\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}`\n}\n\n/** A region on the pane a drawing invites a press in: its middle, the angle it turns by, and its\n * half sizes along and across that angle. */\nexport interface HintRegion {\n cx: number\n cy: number\n angle: number\n halfW: number\n halfH: number\n}\n\nexport abstract class Drawing<P extends Record<string, unknown> = Record<string, never>>\n implements IDrawing, ISeriesPrimitive<Time>\n{\n readonly id: string\n /** Set when this drawing belongs to ONE surface; undefined when every surface showing the symbol\n * shares it. Opaque here — the host assigns and compares it. */\n scope?: string\n abstract readonly type: string\n\n protected _anchors: Anchor[]\n protected _style: DrawingStyle\n protected _options: DrawingOptions\n protected _props: P\n protected _state: DrawingState = 'normal'\n private _timeframeContext: TimeframeContext = null\n private _globalHidden = false\n private _barSource: BarSource | null = null\n\n private _chart: IChartApi | null = null\n private _series: ISeriesApi<SeriesType> | null = null\n private _requestUpdate: (() => void) | null = null\n private readonly _paneViews: IPrimitivePaneView[]\n private readonly _priceBands: IPrimitivePaneView[]\n private readonly _timeBands: IPrimitivePaneView[]\n\n constructor(\n id: string,\n anchors: Anchor[] = [],\n style: Partial<DrawingStyle> = {},\n options: Partial<DrawingOptions> = {},\n props: Partial<P> = {},\n ) {\n this.id = id\n this._anchors = this.upgradeAnchors(anchors.map((a) => ({ ...a })))\n this._style = { ...DEFAULT_STYLE, ...style }\n this._options = normalizeOptions(options)\n this._props = { ...this.defaultProps(), ...this.upgradeProps(props) }\n this._paneViews = [new DrawingPaneView(this)]\n this._priceBands = [new AxisBandView({ span: () => this.bandSpan('price') }, 'price')]\n this._timeBands = [new AxisBandView({ span: () => this.bandSpan('time') }, 'time')]\n }\n\n /** Tool-specific defaults. Must not read instance fields (runs during construction). */\n protected defaultProps(): P {\n return {} as P\n }\n\n /** Saved props as this tool reads them now: a tool that renamed a prop maps the name it was saved\n * under to the one it reads, so a drawing saved before keeps its setting. Must not read instance\n * fields (runs during construction). */\n protected upgradeProps(props: Partial<P>): Partial<P> {\n return props\n }\n\n /** Saved anchors as this tool reads them now: a tool that gained a point completes a drawing saved\n * without it, so the drawing keeps its shape. Must not read instance fields (runs during\n * construction). */\n protected upgradeAnchors(anchors: Anchor[]): Anchor[] {\n return anchors\n }\n\n /** A preset's props as this tool reads them: a remembered default or a template written by an\n * earlier format names its setup under the keys and meanings that format read, and the tool reads\n * them as it reads a save's. */\n presetProps(props: Readonly<Record<string, unknown>>): Record<string, unknown> {\n return { ...this.upgradeProps({ ...props } as Partial<P>) } as Record<string, unknown>\n }\n\n /** Paint a save from an earlier format as it painted: the registry calls this once, as it restores\n * a save whose `v` is below the present format, after the props are upgraded. */\n holdSavedLook(saved: SerializedDrawing): void {\n this.keepSavedLook((saved.props ?? {}) as Readonly<Record<string, unknown>>)\n this.requestUpdate()\n }\n\n /** A tool whose factory values, prop meanings or paint rules differ from the ones format 2 painted\n * with writes, from the props the save carries (`saved`, as written) and the style it restored\n * with, the values that paint the save as it painted. */\n protected keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {}\n\n // ============ ISeriesPrimitive ============\n\n attached(params: SeriesAttachedParameter<Time>): void {\n this._chart = params.chart\n this._series = params.series\n this._requestUpdate = params.requestUpdate\n }\n\n detached(): void {\n this._chart = null\n this._series = null\n this._requestUpdate = null\n }\n\n paneViews(): readonly IPrimitivePaneView[] {\n return this._paneViews\n }\n\n priceAxisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this.axisViews()\n }\n\n timeAxisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this.timeViews()\n }\n\n /** Axis pills this drawing contributes (a horizontal line's price marker); default none. */\n protected axisViews(): readonly ISeriesPrimitiveAxisView[] {\n return []\n }\n\n /** Time-axis pills (a vertical line's timestamp marker); default none. */\n protected timeViews(): readonly ISeriesPrimitiveAxisView[] {\n return []\n }\n\n priceAxisPaneViews(): readonly IPrimitivePaneView[] {\n return this._priceBands\n }\n\n timeAxisPaneViews(): readonly IPrimitivePaneView[] {\n return this._timeBands\n }\n\n /** The prices and times a selected drawing marks on the axes with a band across their span, in\n * the accent at a quarter; none by default. */\n protected axisSpans(): { prices: readonly number[] | null; times: readonly Time[] | null } {\n return { prices: null, times: null }\n }\n\n /** The band a selected drawing lays on an axis: the coordinates its marked prices or times stand\n * at, or null where it lays none. */\n private bandSpan(axis: 'price' | 'time'): { coordinates: number[]; color: string } | null {\n if ((this._state !== 'selected' && this._state !== 'editing') || !this.isVisibleNow()) return null\n const viewport = this.getViewport()\n if (!viewport) return null\n const spans = this.axisSpans()\n const raw = axis === 'price' ? (spans.prices ?? []).map((p) => viewport.yOf(p)) : (spans.times ?? []).map((t) => viewport.xOf(t))\n const coordinates = raw.filter((c): c is number => c !== null && Number.isFinite(c))\n return coordinates.length > 0 ? { coordinates, color: withAlpha(this.inks().accent, 0.25) } : null\n }\n\n /** A time as the chart writes it on its time axis: through the chart's own time formatter, or\n * its plain UTC date and time where the chart has none. */\n protected formatTime(time: Time | undefined): string {\n if (time === undefined) return ''\n try {\n const formatter = this._chart?.options().localization?.timeFormatter as ((t: Time) => string) | undefined\n if (formatter) return formatter(time)\n } catch {\n /* a chart torn down */\n }\n return plainTime(time)\n }\n\n hitTest(x: number, y: number): PrimitiveHoveredItem | null {\n if (!this.isVisibleNow()) return null\n const viewport = this.getViewport()\n if (!viewport) return null\n if (!this.testHit({ x, y }, viewport)) return null\n return {\n cursorStyle: this._options.locked ? 'default' : (this.cursorAt({ x, y }, viewport) ?? 'pointer'),\n externalId: this.id,\n zOrder: 'normal',\n }\n }\n\n /** The cursor a point over the drawing wears: a handle's, its words', or null for the plain\n * pointer. */\n cursorFor(point: Point, viewport: Viewport): string | null {\n return this.cursorAt(point, viewport)\n }\n\n /** Position-specific hover cursor (a table divider's col-resize); null = the default pointer. */\n protected cursorAt(_point: Point, _viewport: Viewport): string | null {\n return null\n }\n\n // ============ State ============\n\n get anchors(): readonly Anchor[] {\n return this._anchors\n }\n\n get style(): Readonly<DrawingStyle> {\n return this._style\n }\n\n get options(): Readonly<DrawingOptions> {\n return this._options\n }\n\n get props(): Readonly<P> {\n return this._props\n }\n\n get state(): DrawingState {\n return this._state\n }\n\n set state(value: DrawingState) {\n this.setState(value)\n }\n\n setAnchors(anchors: Anchor[]): void {\n this._anchors = anchors.map((a) => ({ ...a }))\n this.requestUpdate()\n }\n\n updateAnchor(index: number, anchor: Anchor): void {\n if (index < 0 || index >= this._anchors.length) return\n this._anchors[index] = { ...anchor }\n this.requestUpdate()\n }\n\n /** Grow the anchor set (freehand strokes, multi-point paths). */\n appendAnchor(anchor: Anchor): void {\n this._anchors.push({ ...anchor })\n this.requestUpdate()\n }\n\n removeAnchor(index: number): void {\n if (index < 0 || index >= this._anchors.length) return\n this._anchors.splice(index, 1)\n this.requestUpdate()\n }\n\n updateStyle(patch: Partial<DrawingStyle>): void {\n this._style = { ...this._style, ...patch }\n this.requestUpdate()\n }\n\n updateOptions(patch: Partial<DrawingOptions>): void {\n this._options = {\n ...this._options,\n ...patch,\n visibility: patch.visibility ? normalizeVisibility(patch.visibility) : this._options.visibility,\n }\n this.requestUpdate()\n }\n\n setTimeframeContext(context: TimeframeContext): void {\n this._timeframeContext = context\n this.requestUpdate()\n }\n\n /** Chart-wide hide-all switch (transient view state — never serialized). */\n setGlobalHidden(hidden: boolean): void {\n this._globalHidden = hidden\n this.requestUpdate()\n }\n\n /** Host bar feed for data-driven tools (regression, profiles, VWAP, bar patterns). */\n setBarSource(source: BarSource | null): void {\n this._barSource = source\n this.requestUpdate()\n }\n\n protected bars(): readonly SourceBar[] {\n return this._barSource?.() ?? []\n }\n\n private _tickSize: number | null = null\n\n /** The symbol's smallest price move; a tick-denominated readout is omitted without it rather\n * than inferred from the data. */\n setTickSize(tick: number | null): void {\n this._tickSize = tick && tick > 0 ? tick : null\n this.requestUpdate()\n }\n\n /** The symbol's tick as the host stated it, or null without one. */\n getTickSize(): number | null {\n return this.tickSize()\n }\n\n private _currencyCode: string | null = null\n\n /** The currency the symbol is quoted in, the unit an amount is written in. */\n setCurrencyCode(code: string | null): void {\n this._currencyCode = code && code.trim() ? code.trim() : null\n this.requestUpdate()\n }\n\n /** The currency the symbol is quoted in, or null where the host states none. */\n getCurrencyCode(): string | null {\n return this._currencyCode\n }\n\n protected tickSize(): number | null {\n return this._tickSize\n }\n\n private _priceFormat: PriceFormatPort | null = null\n\n /** The symbol's price formatter, from the host. */\n setPriceFormatter(format: PriceFormatPort | null): void {\n this._priceFormat = format\n this.requestUpdate()\n }\n\n /** A price as the symbol writes it: every label, pill and readout comes through here. */\n protected formatPrice(price: number): string {\n return (this._priceFormat ?? UNRESOLVED_PRICE_TEXT)(price)\n }\n\n private _glyphSource: GlyphSourcePort | null = null\n\n /** The host's glyph artwork source. Per instance, not per process: two charts on one page may\n * be handed different asset sets, and a module-level hook could only ever hold one. */\n setGlyphSource(source: GlyphSourcePort | null): void {\n this._glyphSource = source\n this.requestUpdate()\n }\n\n /** The artwork URL for a glyph, or null to draw it as text. */\n protected glyphUrl(glyph: string): string | null {\n return this._glyphSource ? this._glyphSource(glyph) : null\n }\n\n isVisibleNow(): boolean {\n return !this._globalHidden && this._options.visible && visibleAt(this._options.visibility, this._timeframeContext)\n }\n\n applyProps(patch: Partial<P>): void {\n this._props = { ...this._props, ...patch }\n this.requestUpdate()\n }\n\n setState(state: DrawingState): void {\n if (this._state === state) return\n this._state = state\n this.requestUpdate()\n }\n\n requestUpdate(): void {\n this._requestUpdate?.()\n }\n\n // ============ Geometry ============\n\n getViewport(): Viewport | null {\n if (!this._chart || !this._series) return null\n return viewportOf(this._chart, this._series)\n }\n\n anchorToPixel(anchor: Anchor, viewport: Viewport): Point | null {\n const x = viewport.xOf(anchor.time)\n const y = viewport.yOf(anchor.price)\n if (x === null || y === null) return null\n return { x, y }\n }\n\n /** Anchor pixels in order; entries are null while an anchor is outside the loaded range. */\n protected anchorPixels(viewport: Viewport): (Point | null)[] {\n return this._anchors.map((a) => this.anchorToPixel(a, viewport))\n }\n\n getControlPoints(viewport: Viewport): ControlPoint[] {\n const points: ControlPoint[] = []\n for (let i = 0; i < this._anchors.length; i++) {\n const p = this.anchorToPixel(this._anchors[i], viewport)\n if (p) points.push({ index: i, x: p.x, y: p.y })\n }\n return points\n }\n\n isValid(): boolean {\n return (\n this._anchors.length >= this.requiredAnchors() &&\n this._anchors.every((a) => Number.isFinite(a.price))\n )\n }\n\n /** Anchor count that completes placement. */\n abstract requiredAnchors(): number\n\n /** Paint the drawing. CSS-pixel coordinate space; the shared pane view sets the transform. */\n abstract paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void\n\n /**\n * Mid-placement preview, painted while the anchor set is still short of `requiredAnchors`.\n * Default: a dashed construction polyline through the anchors placed so far — the finished\n * geometry only appears once every point exists (a fib projection draws its trend leg first).\n */\n paintConstruction(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.anchorPixels(viewport).filter((p): p is Point => !!p)\n if (points.length < 2) return\n ctx.save()\n ctx.strokeStyle = this._style.lineColor\n ctx.lineWidth = Math.max(1, this._style.lineWidth - 0.5)\n ctx.setLineDash([4, 4])\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n for (let i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y)\n ctx.stroke()\n ctx.restore()\n }\n\n /**\n * Extra grab points beyond the anchors (an emoji's scale corners). Dragging one routes to\n * `resizeTo`. Default: none.\n */\n resizeHandles(_viewport: Viewport): Point[] {\n return []\n }\n\n resizeTo(_handleIndex: number, _point: Point, _viewport: Viewport): void {}\n\n private _textHint: HintRegion | null = null\n\n /** Note where the invitation a paint just laid stands, where a press opens the words' editor; null\n * where none stands. */\n protected noteTextHint(region: HintRegion | null): void {\n this._textHint = region\n }\n\n /** An inline text editor is open on this drawing (transient view state — never serialized). */\n textEditing = false\n\n /**\n * \"+ Add text\" hint above a selected text-capable drawing that has no text yet. Pressing the\n * painted region routes to the inline text editor. Two-point drawings ride the segment's angle\n * (the hint sits along a sloped trend line); everything else sits level above the bounds.\n * Painted as UI chrome (fixed muted paint), not with the drawing's own text style.\n */\n /** The hint label's CENTER: level above the drawing's bounds by default. Tools whose text\n * rides their own geometry override — a trend line's hint slopes with the segment, a\n * rectangle's sits dead-center in the box, an arrow marker's at the butt end. Two corner\n * anchors are NOT a segment (a box tool's hint must stay level). */\n protected textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n return {\n x: points.reduce((sum, p) => sum + p.x, 0) / points.length,\n y: Math.max(12, Math.min(...points.map((p) => p.y)) - 16),\n angle: 0,\n }\n }\n\n paintTextHint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n this._textHint = null\n if (this.textEditing) return\n // The invitation belongs to a tool that DECLARES a label. A stored drawing may carry a text\n // key its tool no longer has, and a stray key is not a channel.\n if (!('text' in (this.defaultProps() as Record<string, unknown>))) return\n const text = (this._props as Record<string, unknown>).text\n if (typeof text !== 'string' || text !== '') return\n const points = this.anchorPixels(viewport).filter((p): p is Point => !!p)\n if (points.length === 0) return\n const { x: mx, y: my, angle } = this.textHintPlacement(points)\n const label = '+ Add text'\n ctx.save()\n ctx.translate(mx, my)\n ctx.rotate(angle)\n ctx.font = '12px ui-sans-serif, system-ui, sans-serif'\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.setLineDash([])\n ctx.fillStyle = 'rgba(178, 181, 190, 0.95)'\n ctx.fillText(label, 0, 0)\n const width = ctx.measureText(label).width\n ctx.restore()\n this._textHint = {\n cx: mx,\n cy: my,\n angle,\n halfW: width / 2 + 6,\n halfH: 10,\n }\n }\n\n hitTextHint(point: Point): boolean {\n const r = this._textHint\n if (!r) return false\n const dx = point.x - r.cx\n const dy = point.y - r.cy\n const cos = Math.cos(-r.angle)\n const sin = Math.sin(-r.angle)\n const rx = dx * cos - dy * sin\n const ry = dx * sin + dy * cos\n return Math.abs(rx) <= r.halfW && Math.abs(ry) <= r.halfH\n }\n\n textHintAnchor(): { x: number; y: number; angle: number } | null {\n const r = this._textHint\n return r ? { x: r.cx, y: r.cy, angle: r.angle } : null\n }\n\n // ============ Words typed on the chart ============\n\n private _textDraft: TextDraft | null = null\n private _onTextFrame: ((frame: TextEditFrame | null) => void) | null = null\n private _textFrameKey: string | null = null\n private _placeholder: (() => string) | null = null\n\n /** The draft an open inline edit shows on this drawing (transient view state, never serialized):\n * a tool that types on the chart paints these words, their selection and the caret in place of\n * its committed words. */\n get textDraft(): TextDraft | null {\n return this._textDraft\n }\n\n /** Show an inline edit's draft, or end it with null. `onFrame` hears where the words stand each\n * time a repaint moves them, until the edit ends. */\n setTextDraft(draft: TextDraft | null, onFrame?: (frame: TextEditFrame | null) => void): void {\n this._textDraft = draft\n if (onFrame) this._onTextFrame = onFrame\n if (!draft) {\n this._onTextFrame = null\n this._textFrameKey = null\n }\n this.requestUpdate()\n }\n\n /** Where this drawing's words stand, for an editor laid over them; null for a tool that does not\n * type on the chart. */\n textFrame(_viewport: Viewport): TextEditFrame | null {\n return null\n }\n\n /** After each paint: an open edit hears where the words stand whenever that moved. */\n noteTextFrame(viewport: Viewport): void {\n if (!this._onTextFrame || !this._textDraft) return\n const frame = this.textFrame(viewport)\n const key = JSON.stringify(frame)\n if (key === this._textFrameKey) return\n this._textFrameKey = key\n this._onTextFrame(frame)\n }\n\n /** Where the words an empty drawing shows come from: the host's catalog, read as it paints. */\n setTextPlaceholder(source: (() => string) | null): void {\n this._placeholder = source\n this.requestUpdate()\n }\n\n /** The words an empty drawing shows: the host's, or the catalog's English where none is set. */\n protected textPlaceholder(): string {\n return this._placeholder?.() ?? englishWords['drawing.addText']\n }\n\n private _inks: (() => DrawingInks) | null = null\n\n /** Where the chart's own inks come from: the host's theme, read as the drawing paints. */\n setInks(source: (() => DrawingInks) | null): void {\n this._inks = source\n this.requestUpdate()\n }\n\n /** The chart's own inks: the host theme's, or the built-in light theme's where none is set. */\n inks(): DrawingInks {\n return this._inks?.() ?? DEFAULT_INKS\n }\n\n /** The shape of this drawing's selection handles. */\n handleShape(): HandleShape {\n return 'circle'\n }\n\n /** The shape its scale grips wear: null for the small square grips, or a handle's shape for a\n * drawing whose grips stand as its selection handles do. */\n gripShape(): HandleShape | null {\n return null\n }\n\n /** Whether the drawing shows its handles, in their thin form, while the pointer rests on it\n * unselected; a press on one then moves its point and selects the drawing. */\n handlesOnHover(): boolean {\n return false\n }\n\n private _hovered = false\n private _pointer: Point | null = null\n\n /** Whether the pointer rests on this drawing (transient view state, never serialized). */\n get hovered(): boolean {\n return this._hovered\n }\n\n setHovered(on: boolean): void {\n if (this._hovered === on) return\n this._hovered = on\n this.requestUpdate()\n }\n\n /** Where a mouse rests over the chart while this drawing is selected, or null (transient view\n * state, never serialized): its handle under the mouse stands out. */\n get pointer(): Point | null {\n return this._pointer\n }\n\n setPointer(point: Point | null): void {\n const was = this._pointer\n if (was === point || (was && point && was.x === point.x && was.y === point.y)) return\n this._pointer = point ? { x: point.x, y: point.y } : null\n this.requestUpdate()\n }\n\n /** The anchors a drag that grabs this drawing at a point moves: null for all of them, as a drag\n * of the whole drawing does. */\n grabbedAnchors(_point: Point, _viewport: Viewport): number[] | null {\n return null\n }\n\n /** Whether a point is on this drawing's words, where a click on the selected drawing types. */\n wordsAt(point: Point, viewport: Viewport): boolean {\n return this.testHit(point, viewport)\n }\n\n /** Move an anchor by its handle: to the point, unless the tool holds a handle to a line. */\n dragAnchorTo(index: number, anchor: Anchor): void {\n this.updateAnchor(index, anchor)\n }\n\n /** The words this drawing shows, in lines: the open edit's draft or the committed words. The\n * placeholder stands in their place only while both are empty, so words emptied during an edit\n * show nothing until the edit ends. */\n protected shownWords(measure: (line: string) => number, wrapWidth: number | null = null): { block: TextBlock; placeholder: TextBlock | null } {\n const own = (this._props as Record<string, unknown>).text\n const committed = typeof own === 'string' ? own : ''\n const value = this._textDraft?.value ?? committed\n return {\n block: layoutTextBlock(value, measure, wrapWidth),\n placeholder: value === '' && committed === '' ? layoutTextBlock(this.textPlaceholder(), measure) : null,\n }\n }\n\n abstract testHit(point: Point, viewport: Viewport): boolean\n\n // ============ Serialization ============\n\n toJSON(): SerializedDrawing {\n const props = this._props as Record<string, unknown>\n return {\n v: SERIAL_VERSION,\n id: this.id,\n type: this.type,\n anchors: this._anchors.map((a) => ({ ...a })),\n style: { ...this._style },\n options: { ...this._options },\n ...(Object.keys(props).length > 0 ? { props: { ...props } } : {}),\n ...(this.scope === undefined ? {} : { scope: this.scope }),\n }\n }\n\n fromJSON(data: SerializedDrawing): void {\n this._anchors = this.upgradeAnchors(data.anchors.map((a) => ({ ...a })))\n this._style = { ...DEFAULT_STYLE, ...data.style }\n this._options = normalizeOptions(data.options)\n this._props = { ...this.defaultProps(), ...this.upgradeProps((data.props ?? {}) as Partial<P>) }\n this.scope = data.scope\n if (!(data.v >= SERIAL_VERSION)) this.keepSavedLook((data.props ?? {}) as Readonly<Record<string, unknown>>)\n this.requestUpdate()\n }\n}\n","// Words typed on the chart. A drawing that takes its words in place paints them itself as they are\n// typed: the words so far, the caret, the selection and the placeholder all stand on the canvas,\n// in the drawing's own type, while an invisible field laid exactly over them takes the keys. The\n// field is the source of the words and the selection; the drawing is where they are seen.\n//\n// This module is the part every such drawing shares: what the field reports (the draft), where\n// the words stand (the frame the field is laid over), and how a block of words falls into lines\n// with each line keeping its place in the words, so a caret offset or a selection becomes a point\n// on the canvas.\n\n/** What an inline edit shows on the chart, as the field reports it: the words typed so far, the\n * selection, the run an input method is composing, and whether the caret is lit. */\nexport interface TextDraft {\n /** The words as they stand in the field. */\n value: string\n /** The selection as offsets into `value`; equal offsets are a caret. */\n selectionStart: number\n selectionEnd: number\n /** The run an input method is composing, as offsets into `value`, or null. */\n composition: { start: number; end: number } | null\n /** Whether the caret paints: the field has the focus and the blink is in its lit half. */\n caret: boolean\n}\n\n/** Where a drawing's words stand on the pane, which is where an inline editor lays its field. */\nexport interface TextEditFrame {\n /** The first line's top-left, in pane-local CSS pixels. */\n x: number\n y: number\n /** The widest line's width. */\n width: number\n /** How many lines the words take. */\n lines: number\n lineHeight: number\n /** The CSS font the words paint in. */\n font: string\n align: 'left' | 'center' | 'right'\n /** The width the words wrap at, or null when each line runs its own length. */\n wrapWidth: number | null\n /** Radians the words turn about their top-left. */\n angle: number\n}\n\n/** One line of a block of words: its text, where it starts and ends in the words (the line break\n * and a space the line wrapped at are in neither line), and its width. */\nexport interface TextLine {\n text: string\n start: number\n end: number\n width: number\n}\n\n/** A block of words in lines, and its widest line's width. */\nexport interface TextBlock {\n lines: TextLine[]\n width: number\n}\n\n/** Lay words out in lines: one per line break and, given a wrap width, broken at the space before\n * a word that would run past it, a word wider than the width breaking where it must. Every line\n * keeps its offsets into the words, so the layout answers where any offset stands. */\nexport function layoutTextBlock(text: string, measure: (line: string) => number, wrapWidth: number | null = null): TextBlock {\n const lines: TextLine[] = []\n let from = 0\n for (const paragraph of text.split('\\n')) {\n if (wrapWidth === null || !(wrapWidth > 0)) lines.push(line(text, from, from + paragraph.length, measure))\n else wrapParagraph(text, from, from + paragraph.length, measure, wrapWidth, lines)\n from += paragraph.length + 1\n }\n return { lines, width: lines.reduce((widest, l) => Math.max(widest, l.width), 0) }\n}\n\nfunction line(text: string, start: number, end: number, measure: (line: string) => number): TextLine {\n const words = text.slice(start, end)\n return { text: words, start, end, width: measure(words) }\n}\n\nfunction wrapParagraph(text: string, start: number, end: number, measure: (line: string) => number, width: number, out: TextLine[]): void {\n let lineStart = start\n let lineEnd = start\n let at = start\n while (at <= end) {\n const space = text.indexOf(' ', at)\n const wordEnd = space === -1 || space > end ? end : space\n if (measure(text.slice(lineStart, wordEnd)) <= width) {\n lineEnd = wordEnd\n } else {\n if (lineEnd > lineStart) {\n out.push(line(text, lineStart, lineEnd, measure))\n lineStart = at\n }\n // A word wider than the width breaks where it must, keeping at least one character a line.\n while (wordEnd - lineStart > 1 && measure(text.slice(lineStart, wordEnd)) > width) {\n let cut = wordEnd - 1\n while (cut > lineStart + 1 && measure(text.slice(lineStart, cut)) > width) cut--\n out.push(line(text, lineStart, cut, measure))\n lineStart = cut\n }\n lineEnd = wordEnd\n }\n at = wordEnd + 1\n }\n out.push(line(text, lineStart, lineEnd, measure))\n}\n\n/** Which line an offset stands on: the first line it does not pass the end of. An offset at a\n * wrap point stands at the end of the line before it. */\nexport function lineOf(block: TextBlock, offset: number): number {\n for (let i = 0; i < block.lines.length; i++) {\n const l = block.lines[i]!\n if (offset <= l.end) return i\n const next = block.lines[i + 1]\n if (next && offset < next.start) return i\n }\n return Math.max(0, block.lines.length - 1)\n}\n\n/** Where a caret at an offset stands: its line, and its distance from the line's start. */\nexport function caretPlace(block: TextBlock, offset: number, measure: (line: string) => number): { line: number; x: number } {\n const index = lineOf(block, offset)\n const l = block.lines[index]\n if (!l) return { line: 0, x: 0 }\n const within = Math.max(0, Math.min(offset, l.end) - l.start)\n return { line: index, x: within === 0 ? 0 : measure(l.text.slice(0, within)) }\n}\n\n/** The stretch of each line a run of the words covers, from the line's start: one span per line\n * the run reaches, empty lines inside the run included. */\nexport function runSpans(block: TextBlock, start: number, end: number, measure: (line: string) => number): { line: number; x0: number; x1: number }[] {\n const from = Math.min(start, end)\n const to = Math.max(start, end)\n if (from === to) return []\n const spans: { line: number; x0: number; x1: number }[] = []\n block.lines.forEach((l, i) => {\n if (to < l.start || from > l.end) return\n if (to === l.start && l.end > l.start) return\n const a = Math.max(from, l.start) - l.start\n const b = Math.min(to, l.end) - l.start\n spans.push({ line: i, x0: a === 0 ? 0 : measure(l.text.slice(0, a)), x1: b === 0 ? 0 : measure(l.text.slice(0, b)) })\n })\n return spans\n}\n\n/** Where a line stands across its block for an alignment, from the block's left. */\nexport function lineLeft(block: TextBlock, index: number, align: 'left' | 'center' | 'right', width = block.width): number {\n const l = block.lines[index]\n if (!l || align === 'left') return 0\n return align === 'center' ? (width - l.width) / 2 : width - l.width\n}\n","// The built-in light and dark palettes: the only place in the package where a theme color is\n// written as a literal. Every other module reads a role.\n//\n// These values are the package's own, chosen for a complete chart UI that holds up in both modes:\n// a light ink of `rgb(15, 15, 15)` and a dark ink of `rgb(219, 219, 219)`, a dialog and menu ground\n// of white and of `rgb(31, 31, 31)`, a header rule of `#ebebeb` and `#4a4a4a`, a hover fill of\n// `#f2f2f2` and `#2e2e2e`, a pressed fill of `#ebebeb` and `#3d3d3d`, the arrow that opens a menu in\n// `#707070` and `#8c8c8c`, a link of `#2962ff` and `#5b9cf6`, a 6px panel radius, floating-surface\n// shadows of `rgba(0, 0, 0, 0.2) 0 2px 4px` in light and `rgba(0, 0, 0, 0.4)` in dark, and a modal\n// veil of `rgba(156, 156, 156, 0.5)` in light and `rgba(0, 0, 0, 0.5)` in dark. The drawing stroke\n// and selection roles are `#2962ff` in both modes. This file is where they live.\n//\n// Readability is a gate, not a preference. Where a value cannot reach the WCAG 2.2 AA ratio the\n// role's `contrast` rules require, on every ground the recipes draw it over, what stands here is\n// the hue-preserving value nearest to it that does, and `theme/contrast.test.ts` and\n// `chrome/contrast.test.ts` recompute every ratio on each run. The status inks are a green of\n// `#089981`, a red of `#f23645` and an orange of `#ff9800`. On white the green reads at 3.57 to 1,\n// the red at 3.90 and the orange at 2.16, so light mode darkens each just far enough to reach 4.5:\n// `#078671`, `#df323f` and `#ac6600`. Dark mode keeps the green and the orange, which clear 4.5 on\n// the dark panel; its red is `#f34452`, because `#f23645` reads at 4.23 to 1 on the dark dialog\n// ground an error notice stands on. The muted ink is a mid grey, `#707070` in light and `#8c8c8c` in\n// dark, held to 4.5 to 1 over the hover and selected fills a menu row wears: those greys reach 4.15\n// and 3.76 over the selected fill, so the muted ink is `#6a6a6a` in light and `#9b9b9b` in dark.\n// The dark match highlight is `#5280ff` rather than light mode's `#2962ff`, which reads at 3.36 to 1\n// on the dark panel; light mode keeps `#2962ff`, which clears 4.5 to 1 on white. The accent is a\n// mark and never words, and the focus ring keeps its value in each mode. The selected fill is a step\n// of the neutral grey ramp, and the selection tint is a blue at an alpha. A field's edge is a step\n// of the same ramp and steps once more under the pointer; the edge of a refused value is one red in\n// both modes, which reads at the non-text ratio on white and on both dark surfaces.\n//\n// The illustration roles are the one set drawn from a cooler grey: an empty state's art is not a\n// control, so it does not have to sit on the ramp the controls share.\n//\n// The series pair is the market's own, green up and red down in both modes, and it is the floor the\n// chart settings paint default candle bodies, borders, wicks, bars and baseline lines from until a\n// host or a viewer names their own. The brand pair below stays with what a host draws on top. A\n// positive TEXT role and a rising SERIES are different jobs, so one does not displace the other.\n//\n// The chart settings' factory look reads its mode-dependent colors from these roles: the canvas\n// background, the grid, the scale text and lines, the crosshair, the watermark and the shading of\n// each trading-hours stretch. Its grid is a 20% ink, and its scale lines are an ink at no opacity,\n// so a viewer who raises the opacity gets a line in the mode's own ink. Every other factory color\n// is the same in both modes and stands in `CHART_FACTORY_COLORS`.\n//\n// The motion roles are the same in both modes, because a mode changes how the chart looks, not how\n// it moves, and this file is where every duration, timing function and motion scale the chart runs\n// is written. A modal dialog opens over the base duration: its backdrop on the out timing, its box on\n// the standard timing from the entrance scale.\n//\n// This module imports no runtime value, only its types. The build script loads it directly under\n// Node's TypeScript stripping, which resolves no extensionless relative specifier.\nimport type { SemanticTheme, ThemeMode } from './schema'\n\n/** The built-in light palette. */\nexport const LIGHT_THEME: SemanticTheme = {\n 'canvas.background': '#ffffff',\n 'canvas.paneBorder': '#ebebeb',\n 'canvas.watermark': 'rgba(80, 83, 94, 0.2)',\n\n 'series.up': '#089981',\n 'series.down': '#f23645',\n 'series.neutral': '#787b86',\n\n 'scale.grid': 'rgba(46, 46, 46, 0.2)',\n 'scale.background': '#ffffff',\n 'scale.border': 'rgba(46, 46, 46, 0)',\n 'scale.text': '#0f0f0f',\n 'scale.crosshair': '#9c9c9c',\n 'scale.crosshairLabelBackground': '#0f0f0f',\n 'scale.crosshairLabelText': '#ffffff',\n 'scale.sessionPreMarket': 'rgba(255, 152, 0, 0.08)',\n 'scale.sessionExtended': 'rgba(213, 0, 249, 0.08)',\n 'scale.sessionAfterHours': 'rgba(41, 98, 255, 0.08)',\n 'scale.sessionClosed': 'rgba(0, 0, 0, 0.05)',\n\n 'text.primary': '#0f0f0f',\n 'text.secondary': '#4a4a4a',\n 'text.muted': '#6a6a6a',\n 'text.caption': '#707070',\n 'text.disabled': '#b8b8b8',\n 'text.inverse': '#ffffff',\n 'text.link': '#2962ff',\n 'text.highlight': '#2962ff',\n 'text.onCanvas': '#0f0f0f',\n 'text.fontFamily': '-apple-system, BlinkMacSystemFont, \"Trebuchet MS\", Roboto, Ubuntu, sans-serif',\n 'text.fontSizeAxis': '13px',\n 'text.fontSizeTitle': '14px',\n 'text.fontSizeBase': '14px',\n 'text.fontSizeSmall': '11px',\n 'text.fontSizeMicro': '10px',\n\n 'chrome.surface': '#ffffff',\n 'chrome.surfaceRaised': '#ffffff',\n 'chrome.border': '#ebebeb',\n 'chrome.borderStrong': '#8c8c8c',\n 'chrome.fieldBorder': '#dbdbdb',\n 'chrome.caret': '#707070',\n 'chrome.grip': '#b8b8b8',\n 'chrome.scrollThumb': '#9c9c9c',\n 'chrome.radius': '6px',\n 'chrome.radiusLarge': '6px',\n\n 'overlay.surface': '#ffffff',\n 'overlay.separator': '#ebebeb',\n 'overlay.shadow': '0 2px 4px rgba(0, 0, 0, 0.2)',\n 'overlay.scrim': 'rgba(156, 156, 156, 0.5)',\n 'overlay.tooltip': '#3d3d3d',\n 'overlay.tooltipInk': '#f2f2f2',\n\n 'state.accent': '#2962ff',\n 'state.hover': '#f2f2f2',\n 'state.hoverInk': '#0f0f0f',\n 'state.pressed': '#ebebeb',\n 'state.pressedHover': '#dbdbdb',\n 'state.selected': '#ebebeb',\n 'state.focusRing': '#2962ff',\n 'state.markInk': '#ffffff',\n 'state.selection': 'rgba(31, 86, 238, 0.18)',\n\n 'control.on': '#2e2e2e',\n 'control.onHover': '#4a4a4a',\n 'control.onPressed': '#707070',\n 'control.off': '#9c9c9c',\n 'control.offHover': '#8c8c8c',\n 'control.offPressed': '#b8b8b8',\n 'control.outline': '#2e2e2e',\n 'control.onInk': '#ffffff',\n 'control.neutral': '#f2f2f2',\n 'control.neutralHover': '#ebebeb',\n 'control.neutralPressed': '#dbdbdb',\n 'control.neutralInk': '#000000',\n 'control.mark': '#ffffff',\n 'control.fieldEdge': '#dbdbdb',\n 'control.fieldEdgeHover': '#a8a8a8',\n 'control.selectEdgeHover': '#a8a8a8',\n 'control.fieldInvalid': '#f23645',\n 'control.fieldFill': '#f2f2f2',\n 'control.tipMark': '#a8a8a8',\n 'control.tipMarkHover': '#707070',\n\n 'status.positive': '#078671',\n 'status.negative': '#df323f',\n 'status.warning': '#ac6600',\n 'status.info': '#1160c4',\n 'status.loading': '#787b86',\n 'status.sessionPreMarket': '#4c98fb',\n 'status.sessionOpen': '#22c55e',\n 'status.sessionExtended': '#4c98fb',\n 'status.sessionAfterHours': '#f5a623',\n 'status.sessionClosed': 'rgba(0, 0, 0, 0.35)',\n\n 'illustration.ink': '#1e222d',\n 'illustration.accent': '#2196f3',\n 'illustration.accentInk': '#ffffff',\n\n 'drawing.line': '#2962ff',\n 'drawing.fill': 'rgba(41, 98, 255, 0.15)',\n 'drawing.text': '#0f0f0f',\n 'drawing.handle': '#ffffff',\n 'drawing.selected': '#2962ff',\n\n 'motion.durationFast': '90ms',\n 'motion.durationBase': '150ms',\n 'motion.durationModerate': '250ms',\n 'motion.durationSlow': '350ms',\n 'motion.durationSlower': '500ms',\n 'motion.durationGlide': '100ms',\n 'motion.easingStandard': 'ease',\n 'motion.easingOut': 'ease-out',\n 'motion.easingLinear': 'linear',\n 'motion.easingSpring': 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',\n 'motion.easingInOut': 'ease-in-out',\n 'motion.scaleEnter': '0.97',\n}\n\n/** The built-in dark palette. */\nexport const DARK_THEME: SemanticTheme = {\n 'canvas.background': '#0f0f0f',\n 'canvas.paneBorder': '#2e2e2e',\n 'canvas.watermark': 'rgba(80, 83, 94, 0.3)',\n\n 'series.up': '#089981',\n 'series.down': '#f23645',\n 'series.neutral': '#787b86',\n\n 'scale.grid': 'rgba(242, 242, 242, 0.2)',\n 'scale.background': '#0f0f0f',\n 'scale.border': 'rgba(242, 242, 242, 0)',\n 'scale.text': '#b8b8b8',\n 'scale.crosshair': '#9c9c9c',\n 'scale.crosshairLabelBackground': '#3d3d3d',\n 'scale.crosshairLabelText': '#ffffff',\n 'scale.sessionPreMarket': 'rgba(255, 152, 0, 0.08)',\n 'scale.sessionExtended': 'rgba(213, 0, 249, 0.08)',\n 'scale.sessionAfterHours': 'rgba(41, 98, 255, 0.08)',\n 'scale.sessionClosed': 'rgba(0, 0, 0, 0.22)',\n\n 'text.primary': '#dbdbdb',\n 'text.secondary': '#b8b8b8',\n 'text.muted': '#9b9b9b',\n 'text.caption': '#8c8c8c',\n 'text.disabled': '#575757',\n 'text.inverse': '#0f0f0f',\n 'text.link': '#5b9cf6',\n 'text.highlight': '#5280ff',\n 'text.onCanvas': '#dbdbdb',\n 'text.fontFamily': '-apple-system, BlinkMacSystemFont, \"Trebuchet MS\", Roboto, Ubuntu, sans-serif',\n 'text.fontSizeAxis': '13px',\n 'text.fontSizeTitle': '14px',\n 'text.fontSizeBase': '14px',\n 'text.fontSizeSmall': '11px',\n 'text.fontSizeMicro': '10px',\n\n 'chrome.surface': '#0f0f0f',\n 'chrome.surfaceRaised': '#2e2e2e',\n 'chrome.border': '#2e2e2e',\n 'chrome.borderStrong': '#707070',\n 'chrome.fieldBorder': '#636363',\n 'chrome.caret': '#8c8c8c',\n 'chrome.grip': '#575757',\n 'chrome.scrollThumb': '#3d3d3d',\n 'chrome.radius': '6px',\n 'chrome.radiusLarge': '6px',\n\n 'overlay.surface': '#1f1f1f',\n 'overlay.separator': '#4a4a4a',\n 'overlay.shadow': '0 2px 4px rgba(0, 0, 0, 0.4)',\n 'overlay.scrim': 'rgba(0, 0, 0, 0.5)',\n 'overlay.tooltip': '#3d3d3d',\n 'overlay.tooltipInk': '#f2f2f2',\n\n 'state.accent': '#2962ff',\n 'state.hover': '#2e2e2e',\n 'state.hoverInk': '#c9c9c9',\n 'state.pressed': '#3d3d3d',\n 'state.pressedHover': '#4a4a4a',\n 'state.selected': '#333333',\n 'state.focusRing': '#2962ff',\n 'state.markInk': '#ffffff',\n 'state.selection': 'rgba(82, 160, 252, 0.22)',\n\n 'control.on': '#f2f2f2',\n 'control.onHover': '#dbdbdb',\n 'control.onPressed': '#8c8c8c',\n 'control.off': '#636363',\n 'control.offHover': '#707070',\n 'control.offPressed': '#636363',\n 'control.outline': '#ffffff',\n 'control.onInk': '#000000',\n 'control.neutral': '#2e2e2e',\n 'control.neutralHover': '#3d3d3d',\n 'control.neutralPressed': '#4a4a4a',\n 'control.neutralInk': '#ffffff',\n 'control.mark': '#2e2e2e',\n 'control.fieldEdge': '#575757',\n 'control.fieldEdgeHover': '#707070',\n 'control.selectEdgeHover': '#808080',\n 'control.fieldInvalid': '#f23645',\n 'control.fieldFill': '#2e2e2e',\n 'control.tipMark': '#575757',\n 'control.tipMarkHover': '#8c8c8c',\n\n 'status.positive': '#089981',\n 'status.negative': '#f34452',\n 'status.warning': '#ff9800',\n 'status.info': '#68a5ff',\n 'status.loading': '#787b86',\n 'status.sessionPreMarket': '#4c98fb',\n 'status.sessionOpen': '#22c55e',\n 'status.sessionExtended': '#4c98fb',\n 'status.sessionAfterHours': '#f5a623',\n 'status.sessionClosed': 'rgba(255, 255, 255, 0.35)',\n\n 'illustration.ink': '#d1d4dc',\n 'illustration.accent': '#1976d2',\n 'illustration.accentInk': '#d1d4dc',\n\n 'drawing.line': '#2962ff',\n 'drawing.fill': 'rgba(41, 98, 255, 0.15)',\n 'drawing.text': '#dbdbdb',\n 'drawing.handle': '#0f0f0f',\n 'drawing.selected': '#1e53e5',\n\n 'motion.durationFast': '90ms',\n 'motion.durationBase': '150ms',\n 'motion.durationModerate': '250ms',\n 'motion.durationSlow': '350ms',\n 'motion.durationSlower': '500ms',\n 'motion.durationGlide': '100ms',\n 'motion.easingStandard': 'ease',\n 'motion.easingOut': 'ease-out',\n 'motion.easingLinear': 'linear',\n 'motion.easingSpring': 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',\n 'motion.easingInOut': 'ease-in-out',\n 'motion.scaleEnter': '0.97',\n}\n\n/** Both built-in palettes, keyed by mode. */\nexport const BUILT_IN_THEMES: Readonly<Record<ThemeMode, SemanticTheme>> = Object.freeze({\n light: LIGHT_THEME,\n dark: DARK_THEME,\n})\n\n/** The chart settings' factory colors that are the same in both modes. */\nexport interface ChartFactoryColors {\n /** A single-value line drawn in one color, and the area style's line. */\n line: string\n /** A single-value line drawn as a gradient: its color at the highest price on screen. */\n lineGradientTop: string\n /** Its color at the lowest price on screen. */\n lineGradientBottom: string\n /** The area style's fill at its line, fading to the second at the pane's foot. */\n areaTop: string\n areaBottom: string\n /** The vertical line at each session's start. */\n sessionBreaks: string\n /** The previous session's close on the price scale. */\n previousClose: string\n /** The visible range's high and low: their lines across the plot, and their labels on the scale,\n * while the setting names no color of its own. */\n highLowLine: string\n highLowLabel: string\n bid: string\n ask: string\n /** The text on every colored value label the price scale wears, and on the tag beside it. */\n scaleLabelText: string\n /** The last values of the pre-market, post-market and overnight stretches on the price scale. */\n preMarketLabel: string\n postMarketLabel: string\n nightLabel: string\n}\n\n/** The factory colors of the chart settings that do not change with the mode. */\nexport const CHART_FACTORY_COLORS: Readonly<ChartFactoryColors> = Object.freeze({\n line: '#2962ff',\n lineGradientTop: '#d500f9',\n lineGradientBottom: '#00bce5',\n areaTop: 'rgba(41, 98, 255, 0.28)',\n areaBottom: 'rgba(41, 98, 255, 0)',\n sessionBreaks: '#4985e7',\n previousClose: '#555555',\n highLowLine: '#808080',\n highLowLabel: '#142e61',\n bid: '#2962ff',\n ask: '#f7525f',\n scaleLabelText: '#ffffff',\n preMarketLabel: '#fb8c00',\n postMarketLabel: '#2962ff',\n nightLabel: '#8e24aa',\n})\n\n/** The brand pair: what a host's own surfaces on the chart read, an extension's lines among them,\n * so a rebrand edits two strings. The candles keep the series pair, because candles are the market\n * and the brand pair marks what a host draws on top of it. */\nexport const BRAND_UP = '#4c98fb'\nexport const BRAND_DOWN = '#f23645'\n","// The chart's own inks a drawing paints with where its tool takes no color of its own, read from\n// the chart's theme: a selection handle's ring and its center, words written in the chart's ink,\n// and a quiet edge.\nimport { LIGHT_THEME } from '../../../theme/palettes'\nimport type { SemanticTheme } from '../../../theme/schema'\n\nexport interface DrawingInks {\n /** A selection handle's ring. */\n handleRing: string\n /** A selection handle's center: the chart's ground, so the handle covers what it stands on. */\n handleCenter: string\n /** Words a drawing writes in the chart's own ink. */\n text: string\n /** A quiet edge, such as a signpost plate's outline. */\n edge: string\n /** The accent the chart marks what is being worked on with, such as the table cell being typed\n * in. */\n accent: string\n}\n\n/** A theme's inks for drawings. */\nexport function drawingInksOf(theme: Pick<SemanticTheme, 'drawing.selected' | 'drawing.handle' | 'drawing.text' | 'canvas.paneBorder' | 'state.accent'>): DrawingInks {\n return { handleRing: theme['drawing.selected'], handleCenter: theme['drawing.handle'], text: theme['drawing.text'], edge: theme['canvas.paneBorder'], accent: theme['state.accent'] }\n}\n\n/** The inks of a drawing no host gave a theme: the built-in light theme's. */\nexport const DEFAULT_INKS: DrawingInks = drawingInksOf(LIGHT_THEME)\n","import type { DrawingStyle, LineStyle, Point } from '../core/types'\nimport { DARK_THEME } from '../../../theme/palettes'\n\n/** Dash pattern for a line style, scaled so dashes stay legible at any width. */\nexport function dashPattern(style: LineStyle, width: number): number[] {\n switch (style) {\n case 'dashed':\n return [Math.max(4, width * 3), Math.max(3, width * 2)]\n case 'dotted':\n return [Math.max(1, width), Math.max(2, width * 2)]\n default:\n return []\n }\n}\n\n/** Apply the stroke channel (color, width, dash) of a drawing's style. */\nexport function applyStroke(ctx: CanvasRenderingContext2D, style: DrawingStyle): void {\n ctx.strokeStyle = style.lineColor\n ctx.lineWidth = style.lineWidth\n ctx.setLineDash(dashPattern(style.lineStyle, style.lineWidth))\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n}\n\n/** Stroke the segment a→b with the current stroke settings. */\nexport function strokeSegment(ctx: CanvasRenderingContext2D, a: Point, b: Point): void {\n ctx.beginPath()\n ctx.moveTo(a.x, a.y)\n ctx.lineTo(b.x, b.y)\n ctx.stroke()\n}\n\n/** The family drawings paint their words in: the chart's own font stack, the one the built-in themes\n * give the chrome and the scales. */\nexport const DRAWING_FONT_FAMILY = DARK_THEME['text.fontFamily']\n\n/** The CSS font string for a drawing's text channel. */\nexport function fontOf(style: DrawingStyle): string {\n const weight = style.bold ? '600 ' : ''\n const slant = style.italic ? 'italic ' : ''\n return `${slant}${weight}${style.fontSize}px ${DRAWING_FONT_FAMILY}`\n}\n\nexport interface LabelOptions {\n align?: CanvasTextAlign\n baseline?: CanvasTextBaseline\n /** Padded pill behind the text; omit for bare text. */\n background?: string\n padding?: number\n}\n\n/** Paint a single-line text label; returns its painted bounds (for hit-testing). */\nexport function paintLabel(\n ctx: CanvasRenderingContext2D,\n text: string,\n at: Point,\n style: DrawingStyle,\n opts: LabelOptions = {},\n): { x: number; y: number; width: number; height: number } {\n const { align = 'left', baseline = 'middle', background, padding = 4 } = opts\n ctx.save()\n ctx.font = fontOf(style)\n ctx.textAlign = align\n ctx.textBaseline = baseline\n const metrics = ctx.measureText(text)\n const width = metrics.width\n const height = style.fontSize + 2\n const left = align === 'right' ? at.x - width : align === 'center' ? at.x - width / 2 : at.x\n const top = baseline === 'bottom' ? at.y - height : baseline === 'top' ? at.y : at.y - height / 2\n if (background) {\n ctx.fillStyle = background\n ctx.beginPath()\n ctx.roundRect(left - padding, top - padding, width + padding * 2, height + padding * 2, 4)\n ctx.fill()\n }\n ctx.fillStyle = style.textColor\n ctx.setLineDash([])\n ctx.fillText(text, at.x, at.y)\n ctx.restore()\n return { x: left - padding, y: top - padding, width: width + padding * 2, height: height + padding * 2 }\n}\n\n/** Filled arrow head at `tip`, oriented along `from`→`tip`. Scales with line width. */\nexport function paintArrowHead(\n ctx: CanvasRenderingContext2D,\n from: Point,\n tip: Point,\n style: DrawingStyle,\n): void {\n const angle = Math.atan2(tip.y - from.y, tip.x - from.x)\n const size = 4 + style.lineWidth * 2.5\n ctx.save()\n ctx.fillStyle = style.lineColor\n ctx.setLineDash([])\n ctx.beginPath()\n ctx.moveTo(tip.x, tip.y)\n ctx.lineTo(tip.x - size * Math.cos(angle - Math.PI / 6), tip.y - size * Math.sin(angle - Math.PI / 6))\n ctx.lineTo(tip.x - size * Math.cos(angle + Math.PI / 6), tip.y - size * Math.sin(angle + Math.PI / 6))\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n}\n\nlet measurer: CanvasRenderingContext2D | null = null\n\n/** How wide a line of words reads in a style's type, measured without a live rendering context. */\nexport function lineMeasure(style: DrawingStyle): (line: string) => number {\n if (!measurer && typeof document !== 'undefined') {\n measurer = document.createElement('canvas').getContext('2d')\n }\n const m = measurer\n if (!m) return (line) => line.length * style.fontSize * 0.6\n const font = fontOf(style)\n // The measurer is shared, so each measure states its own type.\n return (line) => {\n if (m.font !== font) m.font = font\n return m.measureText(line).width\n }\n}\n\n/** Measure a text block (newline-aware) without a live rendering context. */\nexport function measureTextBlock(\n text: string,\n style: DrawingStyle,\n): { width: number; height: number; lineHeight: number } {\n const lines = text.split('\\n')\n const lineHeight = Math.round(style.fontSize * 1.35)\n const measure = lineMeasure(style)\n let width = 0\n for (const line of lines) width = Math.max(width, measure(line))\n return { width, height: lines.length * lineHeight, lineHeight }\n}\n\n/** The words broken into lines no wider than `width` pixels in the style's type: each line breaks\n * at its spaces, and a word wider than the width breaks where it must. */\nexport function wrapText(text: string, style: DrawingStyle, width: number): string {\n if (!(width > 0)) return text\n const measure = lineMeasure(style)\n const lines: string[] = []\n for (const paragraph of text.split('\\n')) {\n let line = ''\n for (const word of paragraph.split(' ')) {\n const joined = line ? `${line} ${word}` : word\n if (measure(joined) <= width) {\n line = joined\n continue\n }\n if (line) lines.push(line)\n let rest = word\n while (rest.length > 1 && measure(rest) > width) {\n let cut = rest.length - 1\n while (cut > 1 && measure(rest.slice(0, cut)) > width) cut--\n lines.push(rest.slice(0, cut))\n rest = rest.slice(cut)\n }\n line = rest\n }\n lines.push(line)\n }\n return lines.join('\\n')\n}\n\n/** The ink that reads on a color: black on a light one, white on a dark one, parted where the two\n * contrast with it equally. */\nexport function inkOn(color: string): string {\n const m = withAlpha(color, 1).match(/^rgba\\(\\s*([\\d.]+),\\s*([\\d.]+),\\s*([\\d.]+)/)\n if (!m) return '#ffffff'\n const [r, g, b] = [m[1], m[2], m[3]].map((v) => {\n const c = Number(v) / 255\n return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4\n }) as [number, number, number]\n return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.179 ? '#000000' : '#ffffff'\n}\n\nexport interface TextBlockOptions {\n background?: string\n borderColor?: string\n /** The border's width; 1 unless given. */\n borderWidth?: number\n padding?: number\n align?: 'left' | 'center'\n}\n\n/** Paint a (possibly multi-line) text block anchored at its top-left; returns painted bounds. */\nexport function paintTextBlock(\n ctx: CanvasRenderingContext2D,\n text: string,\n topLeft: Point,\n style: DrawingStyle,\n opts: TextBlockOptions = {},\n): { x: number; y: number; width: number; height: number } {\n const { background, borderColor, padding = 6, align = 'left' } = opts\n const { width, height, lineHeight } = measureTextBlock(text, style)\n const box = {\n x: topLeft.x,\n y: topLeft.y,\n width: width + padding * 2,\n height: height + padding * 2,\n }\n ctx.save()\n ctx.setLineDash([])\n if (background || borderColor) {\n ctx.beginPath()\n ctx.roundRect(box.x, box.y, box.width, box.height, 4)\n if (background) {\n ctx.fillStyle = background\n ctx.fill()\n }\n if (borderColor) {\n ctx.strokeStyle = borderColor\n ctx.lineWidth = opts.borderWidth ?? 1\n ctx.stroke()\n }\n }\n ctx.font = fontOf(style)\n ctx.fillStyle = style.textColor\n ctx.textBaseline = 'top'\n ctx.textAlign = align\n const textX = align === 'center' ? box.x + box.width / 2 : box.x + padding\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n ctx.fillText(lines[i], textX, box.y + padding + i * lineHeight)\n }\n ctx.restore()\n return box\n}\n\n/** The shape of a drawing's selection handles: the round one most drawings show, a rounded square,\n * or the small thin ring a mark shows on its point. */\nexport type HandleShape = 'circle' | 'square' | 'small'\n\n/** The point of a list nearest a mouse, by its place in the list, within a reach; null for none. */\nexport function hoveredIndex(points: readonly Point[], pointer: Point | null, reach: number): number | null {\n if (!pointer) return null\n let best: number | null = null\n let bestD = reach\n points.forEach((p, i) => {\n const d = Math.hypot(p.x - pointer.x, p.y - pointer.y)\n if (d <= bestD) {\n bestD = d\n best = i\n }\n })\n return best\n}\n\n/** The halo round a handle under the pointer, in its ring ink at 20% and 3px wide: a ring on a\n * radius of 8 round a round handle, a square 16px across with corners rounded at 4.8 round a square\n * one. */\nconst HANDLE_HALO = { radius: 8, half: 8, corner: 4.8, width: 3, alpha: 0.2 }\n\n/** Paint a drawing's handles, one on each point's pixel, filled with the chart's ground so a handle\n * covers what it stands on. Selected, a round handle is a ring of radius 5.5, 2px wide; a square\n * one is 11px across with corners rounded at 3.3, its ring 2px wide; a small one is a ring of\n * radius 3.5, 1px wide; and a round or square one under the pointer stands in a halo. The thin form\n * a hovered drawing shows is a ring of radius 6, or a square 12px across, 1px wide. */\nexport function paintHandles(\n ctx: CanvasRenderingContext2D,\n points: readonly Point[],\n inks: { ring: string; center: string },\n shape: HandleShape = 'circle',\n hovered: number | null = null,\n form: 'selected' | 'thin' = 'selected',\n): void {\n ctx.save()\n ctx.setLineDash([])\n points.forEach((p, i) => {\n const x = Math.round(p.x) + 0.5\n const y = Math.round(p.y) + 0.5\n if (i === hovered && shape !== 'small' && form === 'selected') {\n ctx.globalAlpha = HANDLE_HALO.alpha\n ctx.strokeStyle = inks.ring\n ctx.lineWidth = HANDLE_HALO.width\n ctx.beginPath()\n if (shape === 'square') ctx.roundRect(x - HANDLE_HALO.half, y - HANDLE_HALO.half, HANDLE_HALO.half * 2, HANDLE_HALO.half * 2, HANDLE_HALO.corner)\n else ctx.arc(x, y, HANDLE_HALO.radius, 0, Math.PI * 2)\n ctx.stroke()\n ctx.globalAlpha = 1\n }\n const thin = form === 'thin'\n ctx.fillStyle = inks.center\n ctx.strokeStyle = inks.ring\n ctx.beginPath()\n if (shape === 'square') {\n const half = thin ? 6 : 5.5\n ctx.lineWidth = thin ? 1 : 2\n ctx.roundRect(x - half, y - half, half * 2, half * 2, 3.3)\n } else if (shape === 'small') {\n ctx.lineWidth = 1\n ctx.arc(x, y, 3.5, 0, Math.PI * 2)\n } else {\n ctx.lineWidth = thin ? 1 : 2\n ctx.arc(x, y, thin ? 6 : 5.5, 0, Math.PI * 2)\n }\n ctx.fill()\n ctx.stroke()\n })\n ctx.restore()\n}\n\n/** Square scale grips (emoji/image corners) for a selected drawing. */\nexport function paintResizeGrips(\n ctx: CanvasRenderingContext2D,\n points: readonly Point[],\n accent: string,\n): void {\n ctx.save()\n ctx.setLineDash([])\n ctx.lineWidth = 1.5\n for (const p of points) {\n ctx.fillStyle = '#ffffff'\n ctx.strokeStyle = accent\n ctx.beginPath()\n ctx.rect(p.x - 3.5, p.y - 3.5, 7, 7)\n ctx.fill()\n ctx.stroke()\n }\n ctx.restore()\n}\n\n/** Fill color string with the style's fill opacity applied. */\nexport function fillPaint(style: DrawingStyle): string | null {\n if (style.fillOpacity <= 0) return null\n return withAlpha(style.fillColor, style.fillOpacity)\n}\n\n/** The alpha carried by a color value (rgba's 4th component); opaque formats report 1. */\nexport function alphaOf(color: string): number {\n const m = color.trim().match(/^rgba\\([^,]+,[^,]+,[^,]+,\\s*([0-9.]+)\\s*\\)$/i)\n if (!m) return 1\n const a = Number(m[1])\n return Number.isFinite(a) ? Math.max(0, Math.min(1, a)) : 1\n}\n\n/** Apply an alpha to a #rgb/#rrggbb/rgb()/rgba() color. Unknown formats pass through. */\nexport function withAlpha(color: string, alpha: number): string {\n const a = Math.max(0, Math.min(1, alpha))\n const hex = color.trim().match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i)\n if (hex) {\n const h = hex[1]\n const full = h.length === 3 ? h.split('').map((c) => c + c).join('') : h\n const n = parseInt(full, 16)\n return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${a})`\n }\n const rgb = color.trim().match(/^rgba?\\(([^)]+)\\)$/i)\n if (rgb) {\n const parts = rgb[1].split(',').map((s) => s.trim())\n return `rgba(${parts[0]}, ${parts[1]}, ${parts[2]}, ${a})`\n }\n return color\n}\n","import type { IPrimitivePaneRenderer, IPrimitivePaneView, PrimitivePaneViewZOrder } from 'lightweight-charts'\nimport type { CanvasRenderingTarget2D } from 'fancy-canvas'\n\nimport type { AnyDrawing } from '../core/drawing'\nimport { hoveredIndex, paintHandles, paintResizeGrips } from './canvas'\n\n/** How near a mouse stands a handle out, and a grip: as near as a press grabs each. */\nconst HANDLE_REACH = 11\nconst GRIP_REACH = 9\n\n/**\n * The one pane view every drawing uses. It owns the canvas plumbing (coordinate space,\n * visibility, selection handles) so tool classes only implement `paint` in CSS pixels.\n */\nexport class DrawingPaneView implements IPrimitivePaneView, IPrimitivePaneRenderer {\n private readonly _drawing: AnyDrawing\n\n constructor(drawing: AnyDrawing) {\n this._drawing = drawing\n }\n\n zOrder(): PrimitivePaneViewZOrder {\n return 'normal'\n }\n\n renderer(): IPrimitivePaneRenderer {\n return this\n }\n\n draw(target: CanvasRenderingTarget2D): void {\n const drawing = this._drawing\n if (!drawing.isVisibleNow()) return\n const viewport = drawing.getViewport()\n if (!viewport) return\n\n target.useMediaCoordinateSpace(({ context: ctx }) => {\n ctx.save()\n try {\n if (drawing.isValid()) {\n drawing.paint(ctx, viewport)\n } else {\n drawing.paintConstruction(ctx, viewport)\n }\n const state = drawing.state\n const inks = drawing.inks()\n const handleInks = { ring: inks.handleRing, center: inks.handleCenter }\n if (state === 'selected' || state === 'editing') {\n // The invitation to type stands under the handles, so a handle on it stays whole.\n if (drawing.isValid()) drawing.paintTextHint(ctx, viewport)\n const points = drawing.getControlPoints(viewport)\n if (points.length > 0) paintHandles(ctx, points, handleInks, drawing.handleShape(), hoveredIndex(points, drawing.pointer, HANDLE_REACH))\n const grips = drawing.resizeHandles(viewport)\n const gripShape = drawing.gripShape()\n if (grips.length > 0 && gripShape) paintHandles(ctx, grips, handleInks, gripShape, hoveredIndex(grips, drawing.pointer, GRIP_REACH))\n else if (grips.length > 0) paintResizeGrips(ctx, grips, drawing.style.lineColor)\n } else if (drawing.hovered && drawing.handlesOnHover() && drawing.isValid()) {\n // A drawing that shows its handles under the pointer shows them thin until it is selected.\n const points = drawing.getControlPoints(viewport)\n if (points.length > 0) paintHandles(ctx, points, handleInks, drawing.handleShape(), null, 'thin')\n }\n } finally {\n ctx.restore()\n }\n })\n // An editor laid over the words follows them wherever this paint stood them.\n drawing.noteTextFrame(viewport)\n }\n}\n","import type { IPrimitivePaneRenderer, IPrimitivePaneView, ISeriesPrimitiveAxisView, PrimitivePaneViewZOrder } from 'lightweight-charts'\nimport type { CanvasRenderingTarget2D } from 'fancy-canvas'\n\nexport interface AxisLabelSource {\n coordinate(): number | null\n text(): string\n color(): string\n /** The ink its words are in: white unless given. */\n textColor?(): string\n visible(): boolean\n}\n\n/** A pill on the price/time axis (a drawing's level marker). */\nexport class AxisLabel implements ISeriesPrimitiveAxisView {\n private readonly _source: AxisLabelSource\n\n constructor(source: AxisLabelSource) {\n this._source = source\n }\n\n coordinate(): number {\n return this._source.coordinate() ?? -1_000_000\n }\n\n text(): string {\n return this._source.text()\n }\n\n textColor(): string {\n return this._source.textColor?.() ?? '#ffffff'\n }\n\n backColor(): string {\n return this._source.color()\n }\n\n visible(): boolean {\n return this._source.visible() && this._source.coordinate() !== null\n }\n}\n\n/** What a band on an axis spans: the coordinates of the points it runs between, along the axis,\n * and its color; null where no band shows. */\nexport interface AxisBandSource {\n span(): { coordinates: readonly number[]; color: string } | null\n}\n\n/**\n * The band a selected drawing lays on an axis across the span of its points. On the price axis it\n * runs over the rows strictly between its outermost points' rows, or over the one row above them\n * where none stand between; on the time axis from its leftmost point's column through its\n * rightmost, at least one column wide. It spans the axis across, under the axis's words.\n */\nexport class AxisBandView implements IPrimitivePaneView, IPrimitivePaneRenderer {\n private readonly _source: AxisBandSource\n private readonly _axis: 'price' | 'time'\n\n constructor(source: AxisBandSource, axis: 'price' | 'time') {\n this._source = source\n this._axis = axis\n }\n\n zOrder(): PrimitivePaneViewZOrder {\n return 'bottom'\n }\n\n renderer(): IPrimitivePaneRenderer {\n return this\n }\n\n draw(target: CanvasRenderingTarget2D): void {\n const span = this._source.span()\n if (!span || span.coordinates.length === 0) return\n target.useMediaCoordinateSpace(({ context: ctx, mediaSize }) => {\n paintAxisBand(ctx, this._axis, span.coordinates, span.color, mediaSize)\n })\n }\n}\n\n/** Paint an axis band over a span of coordinates, in an axis box of a size. */\nexport function paintAxisBand(ctx: CanvasRenderingContext2D, axis: 'price' | 'time', coordinates: readonly number[], color: string, size: { width: number; height: number }): void {\n const low = Math.min(...coordinates)\n const high = Math.max(...coordinates)\n ctx.save()\n ctx.fillStyle = color\n if (axis === 'price') {\n const top = Math.round(low) + 1\n const bottom = Math.round(high) - 1\n if (bottom > top) ctx.fillRect(1, top, size.width, bottom - top)\n else ctx.fillRect(1, Math.round(high) - 1, size.width, 1)\n } else {\n const left = Math.floor(low)\n ctx.fillRect(left, 0, Math.max(1, Math.ceil(high) - left), size.height)\n }\n ctx.restore()\n}\n","// The drawing WORKFLOW's vocabulary: the toolbar's groups and section headings, its cursor,\n// magnet, lock, hide, sync, remove and favorites controls, the selected drawing's settings bar\n// and dialog with every property row on it, the color palette, the glyph picker, the image\n// picker, the template dialogs, and the inline text editor.\n//\n// The 90 tool NAMES are not here. They live in `tools` beside this file and are read through\n// `toolName`, so a tool is named once and translated once wherever it appears. What is here is\n// everything around them.\n//\n// Level values, prices, bar indexes, hex colors, template names a viewer typed, emoji and icon\n// glyphs are data and never pass through this catalog.\nexport const drawing = {\n // The toolbar itself, and its tool GROUPS (a button each) with the SECTION headings inside their\n // flyouts. `shapes` and `textNotes` each name both a group and a section: one word, one key.\n 'drawing.toolbar': 'Drawing tools',\n 'drawing.groupTrend': 'Trend tools',\n 'drawing.groupFibGann': 'Fibonacci & Gann',\n 'drawing.groupPatterns': 'Patterns',\n 'drawing.groupForecast': 'Forecast & measure',\n 'drawing.groupGlyphs': 'Emojis & stickers',\n 'drawing.shapes': 'Shapes',\n 'drawing.textNotes': 'Text & notes',\n 'drawing.groupMenu': '{group} menu',\n 'drawing.sectionLines': 'Lines',\n 'drawing.sectionChannels': 'Channels',\n 'drawing.sectionPitchforks': 'Pitchforks',\n 'drawing.sectionFibonacci': 'Fibonacci',\n 'drawing.sectionGann': 'Gann',\n 'drawing.sectionChartPatterns': 'Chart patterns',\n 'drawing.sectionElliott': 'Elliott waves',\n 'drawing.sectionCycles': 'Cycles',\n 'drawing.sectionForecasting': 'Forecasting',\n 'drawing.sectionVolumeBased': 'Volume based',\n 'drawing.sectionMeasures': 'Measures',\n 'drawing.sectionBrushes': 'Brushes',\n 'drawing.sectionArrows': 'Arrows',\n 'drawing.sectionContent': 'Content',\n 'drawing.sectionGlyphs': 'Emojis, stickers, icons',\n\n // The cursor entry and its flyout.\n 'drawing.cursor': 'Cursor',\n 'drawing.cursorMenu': 'Cursor menu',\n 'drawing.cursorCross': 'Cross',\n 'drawing.cursorDot': 'Dot',\n 'drawing.cursorArrow': 'Arrow',\n 'drawing.cursorEraser': 'Eraser',\n\n // The toolbar's actions and switches.\n 'drawing.measure': 'Measure',\n 'drawing.zoomIn': 'Zoom in',\n 'drawing.magnet': 'Magnet',\n 'drawing.magnetMenu': 'Magnet menu',\n 'drawing.magnetWeak': 'Weak magnet',\n 'drawing.magnetStrong': 'Strong magnet',\n 'drawing.stayInDrawingMode': 'Stay in drawing mode',\n 'drawing.lockAll': 'Lock all drawings',\n 'drawing.unlockAll': 'Unlock all drawings',\n\n // The eye's three subjects, each in both states, and the menu that picks which one it acts on.\n // The eye reaches chart-owned layers only, so All means drawings and indicators.\n 'drawing.hideMenu': 'Hide menu',\n 'drawing.hideDrawings': 'Hide drawings',\n 'drawing.showDrawings': 'Show drawings',\n 'drawing.hideIndicators': 'Hide indicators',\n 'drawing.showIndicators': 'Show indicators',\n 'drawing.hideAll': 'Hide all',\n 'drawing.showAll': 'Show all',\n\n // Drawing sync across a split layout.\n 'drawing.syncLabel': 'Sync drawings across the layout',\n 'drawing.syncOnHelp': 'New drawings are replicated to all charts in the layout and shown when the same ticker is selected',\n 'drawing.syncOffHelp': 'New drawings stay on the chart that drew them',\n\n // The remove menu NAMES what each row takes. Two independently counted nouns share one row, so\n // each is its own plural phrase and the carrier sentence decides where the language puts them.\n 'drawing.removeMenu': 'Remove menu',\n 'drawing.removeDrawings': 'Remove drawings',\n 'drawing.countDrawings': { one: '{count} drawing', other: '{count} drawings' },\n 'drawing.countIndicators': { one: '{count} indicator', other: '{count} indicators' },\n 'drawing.removeItems': 'Remove {items}',\n 'drawing.removeBoth': 'Remove {drawings} & {indicators}',\n 'drawing.nothingToRemove': 'Nothing to remove',\n 'drawing.alwaysRemoveLocked': 'Always remove locked drawings',\n\n // Favorites: the toolbar's stars and the floating bar they fill.\n 'drawing.favTools': 'Favorite drawing tools',\n 'drawing.favToolsBar': 'Favorite drawing tools toolbar',\n 'drawing.favAdd': 'Add {tool} to favorites',\n 'drawing.favRemove': 'Remove {tool} from favorites',\n 'drawing.moveToolbar': 'Move toolbar',\n 'drawing.moveFavoritesToolbar': 'Move favorites toolbar',\n\n // The selected drawing's floating settings bar.\n 'drawing.settingsBar': 'Selected drawing',\n 'drawing.templates': 'Templates',\n 'drawing.drawingTemplates': 'Drawing templates',\n 'drawing.saveTemplateAs': 'Save drawing template as...',\n 'drawing.applyDefaultTemplate': 'Apply default drawing template',\n 'drawing.removeTemplateNamed': 'Remove template {name}',\n 'drawing.remove': 'Remove',\n 'drawing.drawingColor': 'Drawing color',\n 'drawing.backgroundColor': 'Background color',\n 'drawing.thickness': 'Thickness',\n 'drawing.lineThickness': 'Line thickness',\n 'drawing.thicknessValue': 'Thickness {n}px',\n 'drawing.lineStyle': 'Line style',\n 'drawing.lineStyleValue': 'Line style {name}',\n 'drawing.lineSolid': 'Line',\n 'drawing.lineDashed': 'Dashed line',\n 'drawing.lineDotted': 'Dotted line',\n 'drawing.settings': 'Settings',\n 'drawing.drawingSettings': 'Drawing settings',\n 'drawing.lock': 'Lock',\n 'drawing.unlock': 'Unlock',\n 'drawing.lockDrawing': 'Lock drawing',\n 'drawing.unlockDrawing': 'Unlock drawing',\n 'drawing.deleteDrawing': 'Delete drawing',\n 'drawing.more': 'More',\n 'drawing.moreActions': 'More drawing actions',\n 'drawing.visualOrder': 'Visual order',\n 'drawing.visibilityOnTimeframes': 'Visibility on timeframes',\n 'drawing.clone': 'Clone',\n 'drawing.copy': 'Copy',\n 'drawing.modifierControl': 'Ctrl',\n 'drawing.modifierCommand': 'Cmd',\n 'drawing.hintClone': '{modifier} + Drag',\n 'drawing.hintCopy': '{modifier} + C',\n 'drawing.hintRemove': 'Del',\n 'drawing.drawingMenu': 'Drawing menu',\n 'drawing.hintPaste': '{modifier} + V',\n 'drawing.deleteWithKey': 'Delete (Del)',\n 'drawing.statusDrawingsHidden': 'Drawings hidden',\n 'drawing.statusDrawingsShown': 'Drawings shown',\n 'drawing.statusIndicatorsHidden': 'Indicators hidden',\n 'drawing.statusIndicatorsShown': 'Indicators shown',\n 'drawing.statusAllHidden': 'Drawings and indicators hidden',\n 'drawing.statusAllShown': 'Drawings and indicators shown',\n 'drawing.statusAllLocked': 'All drawings locked',\n 'drawing.statusAllUnlocked': 'All drawings unlocked',\n 'drawing.hide': 'Hide',\n 'drawing.bringToFront': 'Bring to front',\n 'drawing.sendToBack': 'Send to back',\n 'drawing.bringForward': 'Bring forward',\n 'drawing.sendBackward': 'Send backward',\n 'drawing.visCurrentAndAbove': 'Current timeframe and above',\n 'drawing.visCurrentAndBelow': 'Current timeframe and below',\n 'drawing.visCurrentOnly': 'Current timeframe only',\n 'drawing.visAll': 'All timeframes',\n\n // The template dialogs: naming a new template, and confirming a delete.\n 'drawing.saveTemplate': 'Save drawing template',\n 'drawing.templateName': 'Template name',\n 'drawing.save': 'Save',\n 'drawing.deleteTemplateTitle': 'Delete this template?',\n 'drawing.deleteTemplateBody': 'Doing this will permanently delete your \"{name}\" drawing template.',\n\n // The settings dialog: its title, its pages, and its footer.\n 'drawing.settingsTitle': '{tool} settings',\n 'drawing.rename': 'Rename',\n 'drawing.name': 'Name',\n 'drawing.tabInputs': 'Inputs',\n 'drawing.tabStyle': 'Style',\n 'drawing.tabText': 'Text',\n 'drawing.tabCoordinates': 'Coordinates',\n 'drawing.tabVisibility': 'Visibility',\n 'drawing.template': 'Template',\n 'drawing.saveAs': 'Save as…',\n 'drawing.applyDefaults': 'Apply defaults',\n 'drawing.cancel': 'Cancel',\n 'drawing.ok': 'Ok',\n 'drawing.delete': 'Delete',\n 'drawing.close': 'Close',\n\n // Property labels shared by the bar and the dialog.\n 'drawing.color': 'Color',\n 'drawing.rowLine': 'Line',\n 'drawing.background': 'Background',\n 'drawing.border': 'Border',\n 'drawing.profitColor': 'Target color',\n 'drawing.stopColor': 'Stop color',\n 'drawing.textColor': 'Text color',\n 'drawing.fontSize': 'Font size',\n 'drawing.opacity': 'Opacity',\n 'drawing.transparency': 'Transparency',\n 'drawing.label': 'Label',\n 'drawing.labelColor': 'Label color',\n 'drawing.labels': 'Labels',\n 'drawing.left': 'Left',\n 'drawing.center': 'Center',\n 'drawing.right': 'Right',\n 'drawing.up': 'Up',\n 'drawing.down': 'Down',\n 'drawing.rowVisible': '{name} visible',\n 'drawing.leftEnd': 'Left end',\n 'drawing.rightEnd': 'Right end',\n 'drawing.lineEndNormal': 'Normal',\n 'drawing.lineEndArrow': 'Arrow',\n 'drawing.increase': 'Increase',\n 'drawing.decrease': 'Decrease',\n 'drawing.rangeFrom': 'From',\n 'drawing.rangeTo': 'To',\n 'drawing.pickColor': 'Pick a color',\n\n // Style and Inputs rows, per tool family.\n 'drawing.extend': 'Extend',\n 'drawing.extendNone': \"Don't extend\",\n 'drawing.extendLeft': 'Extend left',\n 'drawing.extendRight': 'Extend right',\n 'drawing.extendBoth': 'Extend both',\n 'drawing.extendLines': 'Extend lines',\n 'drawing.middlePoint': 'Middle point',\n 'drawing.middleLine': 'Middle line',\n 'drawing.priceLabel': 'Price label',\n 'drawing.priceLabels': 'Price labels',\n 'drawing.timeLabel': 'Time label',\n 'drawing.rowStyle': 'Style',\n 'drawing.variantOriginal': 'Original',\n 'drawing.variantSchiff': 'Schiff',\n 'drawing.variantModifiedSchiff': 'Modified Schiff',\n 'drawing.variantInside': 'Inside',\n 'drawing.sectionStats': 'Stats',\n 'drawing.percentChange': 'Percent change',\n 'drawing.dateTimeRange': 'Date/time range',\n 'drawing.volume': 'Volume',\n 'drawing.sectionInfo': 'Info',\n 'drawing.priceRange': 'Price range',\n 'drawing.barsRange': 'Bars range',\n 'drawing.distance': 'Distance',\n 'drawing.angle': 'Angle',\n 'drawing.statsPosition': 'Stats position',\n 'drawing.statsHidden': 'Hidden',\n 'drawing.changeInPips': 'Change in pips',\n 'drawing.alwaysShowStats': 'Always show stats',\n 'drawing.auto': 'Auto',\n 'drawing.extendLeftLine': 'Extend left line',\n 'drawing.extendRightLine': 'Extend right line',\n 'drawing.direction': 'Direction',\n 'drawing.prices': 'Prices',\n 'drawing.levels': 'Levels',\n 'drawing.reverse': 'Reverse',\n 'drawing.fullCircles': 'Full circles',\n 'drawing.coeffsAsPercents': 'Coeffs as percents',\n 'drawing.image': 'Image',\n 'drawing.rowsLayout': 'Rows Layout',\n 'drawing.rowsByNumber': 'Number Of Rows',\n 'drawing.ticksPerRow': 'Ticks Per Row',\n 'drawing.rowSize': 'Row Size',\n 'drawing.upDown': 'Up/Down',\n 'drawing.total': 'Total',\n 'drawing.delta': 'Delta',\n 'drawing.valueAreaVolume': 'Value Area Volume',\n 'drawing.widthPercent': 'Width (% of the box)',\n 'drawing.placement': 'Placement',\n 'drawing.developingPoc': 'Developing POC',\n 'drawing.developingVa': 'Developing VA',\n 'drawing.source': 'Source',\n 'drawing.mode': 'Mode',\n 'drawing.modeHlBars': 'HL bars',\n 'drawing.modeOcBars': 'OC bars',\n 'drawing.modeLineOpen': 'Line - open',\n 'drawing.modeLineHigh': 'Line - high',\n 'drawing.modeLineLow': 'Line - low',\n 'drawing.modeLineClose': 'Line - close',\n 'drawing.modeLineHl2': 'Line - HL/2',\n 'drawing.mirrored': 'Mirrored',\n 'drawing.flipped': 'Flipped',\n 'drawing.avgHlMinticks': 'Avg HL in minticks',\n 'drawing.variance': 'Variance',\n 'drawing.candles': 'Candles',\n 'drawing.borders': 'Borders',\n 'drawing.wick': 'Wick',\n 'drawing.useUpperDeviation': 'Use Upper Deviation',\n 'drawing.useLowerDeviation': 'Use Lower Deviation',\n 'drawing.risk': 'Risk',\n 'drawing.accountSize': 'Account size',\n 'drawing.lotSize': 'Lot size',\n 'drawing.leverage': 'Leverage',\n 'drawing.compactStatsMode': 'Compact stats mode',\n\n // Fibonacci and Gann level rows. A level's own value is data and rides in the slot.\n 'drawing.levelVisible': 'Level {value} visible',\n 'drawing.levelText': 'Level {value} text',\n 'drawing.removeLevel': 'Remove level {value}',\n 'drawing.addLevel': 'Add level',\n\n // A leveled tool's Style page: its trend line, the stroke of every level line, the level grid,\n // the one color, the bands between levels, and what the labels read and where.\n 'drawing.trendLine': 'Trend line',\n 'drawing.levelsLine': 'Levels line',\n 'drawing.extendLinesLeft': 'Extend lines left',\n 'drawing.extendLinesRight': 'Extend lines right',\n 'drawing.levelOn': 'Level {n}',\n 'drawing.levelValue': 'Level {n} value',\n 'drawing.levelColor': 'Level {n} color',\n 'drawing.useOneColor': 'Use one color',\n 'drawing.backgroundOpacity': 'Background opacity',\n 'drawing.values': 'Values',\n 'drawing.percents': 'Percents',\n 'drawing.levelWords': 'Text',\n 'drawing.levelsOnLogScale': 'Fib levels based on log scale',\n 'drawing.median': 'Median',\n 'drawing.counterclockwise': 'Counterclockwise',\n 'drawing.fans': 'Fans',\n 'drawing.arcs': 'Arcs',\n 'drawing.fanOn': 'Fan {n}',\n 'drawing.fanColor': 'Fan {n} color',\n 'drawing.arcOn': 'Arc {n}',\n 'drawing.arcColor': 'Arc {n} color',\n 'drawing.priceBarRatio': 'Price/bar ratio',\n 'drawing.rangesAndRatio': 'Ranges and ratio',\n 'drawing.wave': 'Wave',\n 'drawing.lines': 'Lines',\n 'drawing.degree': 'Degree',\n 'drawing.degreeSupermillennium': 'Supermillennium',\n 'drawing.degreeMillennium': 'Millennium',\n 'drawing.degreeSubmillennium': 'Submillennium',\n 'drawing.degreeGrandSupercycle': 'Grand supercycle',\n 'drawing.degreeSupercycle': 'Supercycle',\n 'drawing.degreeCycle': 'Cycle',\n 'drawing.degreePrimary': 'Primary',\n 'drawing.degreeIntermediate': 'Intermediate',\n 'drawing.degreeMinor': 'Minor',\n 'drawing.degreeMinute': 'Minute',\n 'drawing.degreeMinuette': 'Minuette',\n 'drawing.degreeSubminuette': 'Subminuette',\n 'drawing.degreeMicro': 'Micro',\n 'drawing.degreeSubmicro': 'Submicro',\n 'drawing.degreeMinuscule': 'Minuscule',\n 'drawing.upperDeviation': 'Upper Deviation',\n 'drawing.lowerDeviation': 'Lower Deviation',\n 'drawing.base': 'Base',\n 'drawing.pearsonsR': \"Pearson's R\",\n 'drawing.sourceOpen': 'Open',\n 'drawing.sourceHigh': 'High',\n 'drawing.sourceLow': 'Low',\n 'drawing.sourceClose': 'Close',\n 'drawing.sourceVolume': 'Volume',\n 'drawing.sourceHl2': '(H + L)/2',\n 'drawing.sourceHlc3': '(H + L + C)/3',\n 'drawing.sourceOhlc4': '(O + H + L + C)/4',\n 'drawing.sourceHlcc4': '(H + L + C + C)/4',\n 'drawing.pricesColor': 'Prices color',\n 'drawing.priceOffset': 'Price offset',\n 'drawing.textWrap': 'Text wrap',\n 'drawing.labelBorder': 'Label border',\n 'drawing.labelText': 'Label text',\n 'drawing.lineColor': 'Line color',\n 'drawing.emojiPin': 'Emoji pin',\n 'drawing.emoji': 'Emoji',\n 'drawing.plateColor': 'Plate color',\n 'drawing.arrowMark': 'Arrow',\n 'drawing.flag': 'Flag',\n 'drawing.coordPositionBar': '#{n} (vertical position %, bar)',\n 'drawing.verticalPosition': 'Vertical position %',\n 'drawing.riskUnit': 'Risk unit',\n 'drawing.riskAmount': 'Amount',\n 'drawing.entryPrice': 'Entry price',\n 'drawing.profitLevel': 'Profit level',\n 'drawing.stopLevel': 'Stop level',\n 'drawing.ticks': 'Ticks',\n 'drawing.price': 'Price',\n 'drawing.qtyPrecision': 'QTY precision',\n 'drawing.qtyDefault': 'Default',\n 'drawing.qtyInteger': 'Integer',\n 'drawing.qtyOneDecimal': '1 decimal',\n 'drawing.qtyDecimals': '{n} decimals',\n 'drawing.text': 'Text',\n 'drawing.statTpPriceOffset': 'TP price offset',\n 'drawing.statTpPercentOffset': 'TP percent offset',\n 'drawing.statTpTickOffset': 'TP tick offset',\n 'drawing.statTpAmount': 'TP amount',\n 'drawing.statTpPl': 'TP PL',\n 'drawing.statOpenClosePl': 'Open/closed PL',\n 'drawing.statQty': 'Qty',\n 'drawing.statRiskRewardRatio': 'Risk/reward ratio',\n 'drawing.statSlPriceOffset': 'SL price offset',\n 'drawing.statSlPercentOffset': 'SL percent offset',\n 'drawing.statSlTickOffset': 'SL tick offset',\n 'drawing.statSlAmount': 'SL amount',\n 'drawing.statSlPl': 'SL PL',\n 'drawing.profileExtendRight': 'Extend Right',\n 'drawing.volumeProfile': 'Volume profile',\n 'drawing.valuesColor': 'Values color',\n 'drawing.upVolume': 'Up Volume',\n 'drawing.downVolume': 'Down Volume',\n 'drawing.valueAreaUp': 'Value Area Up',\n 'drawing.valueAreaDown': 'Value Area Down',\n 'drawing.vah': 'VAH',\n 'drawing.val': 'VAL',\n 'drawing.poc': 'POC',\n 'drawing.histogramBox': 'Histogram Box',\n 'drawing.labelsOnPriceScale': 'Labels on price scale',\n 'drawing.bandsSettings': 'Bands Settings',\n 'drawing.bandsMode': 'Bands Calculation Mode',\n 'drawing.bandsStdev': 'Standard Deviation',\n 'drawing.bandsPercent': 'Percentage',\n 'drawing.bandsMultiplier': 'Bands Multiplier #{n}',\n 'drawing.vwap': 'VWAP',\n 'drawing.upperBand': 'Upper band #{n}',\n 'drawing.lowerBand': 'Lower band #{n}',\n 'drawing.bandBackground': 'Background #{n}',\n 'drawing.extendTop': 'Extend top',\n 'drawing.extendBottom': 'Extend bottom',\n 'drawing.labelBackground': 'Label background',\n 'drawing.sourceText': 'Source text',\n 'drawing.sourceBackground': 'Source background',\n 'drawing.sourceBorder': 'Source border',\n 'drawing.targetText': 'Target text',\n 'drawing.targetBackground': 'Target background',\n 'drawing.targetBorder': 'Target border',\n 'drawing.successText': 'Success text',\n 'drawing.successBackground': 'Success background',\n 'drawing.failureText': 'Failure text',\n 'drawing.failureBackground': 'Failure background',\n 'drawing.backgroundFirst': 'First background',\n 'drawing.backgroundSecond': 'Second background',\n 'drawing.priceLevels': 'Price levels',\n 'drawing.timeLevels': 'Time levels',\n 'drawing.priceLevelOn': 'Price level {n}',\n 'drawing.priceLevelValue': 'Price level {n} value',\n 'drawing.priceLevelColor': 'Price level {n} color',\n 'drawing.timeLevelOn': 'Time level {n}',\n 'drawing.timeLevelValue': 'Time level {n} value',\n 'drawing.timeLevelColor': 'Time level {n} color',\n 'drawing.leftLabels': 'Left labels',\n 'drawing.rightLabels': 'Right labels',\n 'drawing.topLabels': 'Top labels',\n 'drawing.bottomLabels': 'Bottom labels',\n 'drawing.grid': 'Grid',\n 'drawing.angles': 'Angles',\n\n // The Text page, and the in-place editor over the chart.\n 'drawing.bold': 'Bold',\n 'drawing.italic': 'Italic',\n 'drawing.addText': 'Add text',\n 'drawing.textAlignment': 'Text alignment',\n 'drawing.top': 'Top',\n 'drawing.middle': 'Middle',\n 'drawing.bottom': 'Bottom',\n 'drawing.inside': 'Inside',\n 'drawing.textOrientation': 'Text orientation',\n 'drawing.horizontal': 'Horizontal',\n 'drawing.vertical': 'Vertical',\n 'drawing.textPlaceholder': 'Text',\n 'drawing.textEditor': 'Drawing text',\n\n // A table's own edits on the chart: a column right of the cell last typed in and a row below it,\n // and the removes of that cell's row and column.\n 'drawing.addColumnRight': 'Add column to right',\n 'drawing.addRowBelow': 'Add row below',\n 'drawing.removeRow': 'Remove row',\n 'drawing.removeColumn': 'Remove column',\n\n // The Coordinates page: one row per anchor, numbered.\n 'drawing.coordBar': '#{n} (bar)',\n 'drawing.coordPrice': '#{n} (price)',\n 'drawing.coordPriceBar': '#{n} (price, bar)',\n\n // The Visibility page: which timeframes paint the drawing.\n 'drawing.unitTicks': 'Ticks',\n 'drawing.unitSeconds': 'Seconds',\n 'drawing.unitMinutes': 'Minutes',\n 'drawing.unitHours': 'Hours',\n 'drawing.unitDays': 'Days',\n 'drawing.unitWeeks': 'Weeks',\n 'drawing.unitMonths': 'Months',\n 'drawing.timeframePinnedNote': 'A drawing stays on at least one timeframe, so it can always be reached again.',\n\n // The color palette: swatches, the custom color panel, the opacity row.\n 'drawing.colorSwatch': 'Color {hex}',\n 'drawing.addCustomColor': 'Add custom color',\n 'drawing.saturationValue': 'Saturation and brightness',\n 'drawing.hue': 'Hue',\n 'drawing.hexColor': 'Hex color',\n 'drawing.add': 'Add',\n\n // The glyph picker. Category HEADINGS are interface; every glyph in them is data.\n 'drawing.glyphPicker': 'Glyph picker',\n 'drawing.kindEmojis': 'Emojis',\n 'drawing.kindStickers': 'Stickers',\n 'drawing.kindIcons': 'Icons',\n 'drawing.recentlyUsed': 'Recently used',\n 'drawing.recentGlyph': 'Recent {glyph}',\n 'drawing.stickersSoon': 'No sticker set is installed.',\n 'drawing.glyphCatSmileys': 'Smileys & People',\n 'drawing.glyphCatNature': 'Animals & Nature',\n 'drawing.glyphCatFood': 'Food & Drink',\n 'drawing.glyphCatActivity': 'Activity',\n 'drawing.glyphCatTravel': 'Travel & Places',\n 'drawing.glyphCatObjects': 'Objects',\n 'drawing.glyphCatSymbols': 'Symbols',\n 'drawing.glyphCatFlags': 'Flags',\n 'drawing.glyphCatIconArrows': 'Arrows',\n 'drawing.glyphCatIconCurrency': 'Currency',\n 'drawing.glyphCatIconGestures': 'Gestures and smileys',\n 'drawing.glyphCatIconNature': 'Nature',\n 'drawing.glyphCatIconSpecial': 'Special',\n 'drawing.glyphCatIconSymbols': 'Symbols and flags',\n\n // The Image tool's picker, and what a refused picture is told.\n 'drawing.imageReading': 'Reading...',\n 'drawing.chooseImage': 'Choose image',\n 'drawing.imageFormats': 'JPG, PNG or WEBP',\n 'drawing.imageMaxSize': 'Max size 2MB',\n 'drawing.imageDimensions': '{width} x {height}',\n 'drawing.imageErrorType': 'That file is not a JPG, PNG or WEBP. Pick one of those three formats.',\n 'drawing.imageErrorSize': 'That image is {size}. The limit is 2MB.',\n 'drawing.imageErrorRead': 'That file could not be read. Try picking it again.',\n 'drawing.imageErrorDecode': 'That image could not be opened. It may be damaged.',\n} as const\n","// Where the panes stand within a chart. A viewer may reorder them, so the pane the main series stands\n// in is not always the first, and nothing laid over the chart may take a pane's top to be the\n// chart's own.\nimport type { IChartApi, ISeriesApi, SeriesType } from 'lightweight-charts'\n\n/** The index of the pane a series stands in, or 0 when the renderer cannot say. */\nexport function paneIndexOf(series: ISeriesApi<SeriesType>): number {\n try {\n const index = series.getPane().paneIndex()\n return Number.isInteger(index) && index >= 0 ? index : 0\n } catch {\n return 0\n }\n}\n\n/** How far the pane at an index stands below the top of an element laid over the chart, in CSS\n * pixels: the pane's own box once the renderer has laid it out, and until then the heights of the\n * panes above it. The first pane stands at the top. */\nexport function paneTopIn(chart: IChartApi, index: number, box: HTMLElement): number {\n if (index <= 0) return 0\n try {\n const panes = chart.panes()\n const rect = panes[index]?.getHTMLElement()?.getBoundingClientRect()\n if (rect && rect.height > 0) return rect.top - box.getBoundingClientRect().top\n let top = 0\n for (let i = 0; i < index && i < panes.length; i++) top += panes[i]!.getHeight()\n return top\n } catch {\n return 0\n }\n}\n\n/** The top of the pane a series stands in, below the top of an element laid over the chart. */\nexport const seriesPaneTop = (chart: IChartApi, series: ISeriesApi<SeriesType>, box: HTMLElement): number =>\n paneTopIn(chart, paneIndexOf(series), box)\n","import type { IChartApi, ISeriesApi, SeriesType } from 'lightweight-charts'\n\nimport type {\n DrawingEvent,\n DrawingEventCallback,\n DrawingEventType,\n IDrawing,\n Point,\n GlyphSourcePort,\n PriceFormatPort,\n SerializedDrawing,\n Viewport,\n} from './types'\nimport type { AnyDrawing } from './drawing'\nimport { viewportOf } from './drawing'\nimport type { DrawingInks } from './inks'\nimport type { TimeframeContext } from './visibility'\nimport type { BarSource } from './bars'\n\n/**\n * The drawing model for one chart: an ordered store of drawings attached to a series, with\n * selection, top-most hit-testing, and serialization. Deliberately input-free — pointer and\n * keyboard handling live in the host app, which calls into this model. Attaching is what makes\n * a drawing render (drawings are series primitives).\n */\nexport class DrawingManager {\n private readonly _drawings = new Map<string, AnyDrawing>()\n private _order: string[] = [] // insertion order; later = painted and hit-tested on top\n private _selectedId: string | null = null\n private _chart: IChartApi | null = null\n private _series: ISeriesApi<SeriesType> | null = null\n private _timeframeContext: TimeframeContext = null\n private _allHidden = false\n private _barSource: BarSource | null = null\n private _tickSize: number | null = null\n private _currencyCode: string | null = null\n private _priceFormat: PriceFormatPort | null = null\n private _glyphSource: GlyphSourcePort | null = null\n private _placeholder: (() => string) | null = null\n private _inks: (() => DrawingInks) | null = null\n private readonly _listeners = new Map<DrawingEventType, Set<DrawingEventCallback>>()\n\n /** Host bar feed, broadcast to every drawing (data-driven tools read it at paint time). */\n setBarSource(source: BarSource | null): void {\n this._barSource = source\n for (const drawing of this._drawings.values()) drawing.setBarSource(source)\n }\n\n /** The symbol's smallest price move, broadcast to every drawing (tick-denominated readouts). */\n setTickSize(tick: number | null): void {\n this._tickSize = tick\n for (const drawing of this._drawings.values()) drawing.setTickSize(tick)\n }\n\n /** The currency the symbol is quoted in, broadcast to every drawing (the unit of an amount). */\n setCurrencyCode(code: string | null): void {\n this._currencyCode = code\n for (const drawing of this._drawings.values()) drawing.setCurrencyCode(code)\n }\n\n /** The symbol's price formatter, broadcast to every drawing: the one port every label, pill\n * and readout writes prices through. The host resolves it from the symbol's declared format. */\n setPriceFormatter(format: PriceFormatPort | null): void {\n this._priceFormat = format\n for (const drawing of this._drawings.values()) drawing.setPriceFormatter(format)\n }\n\n /** The host's glyph artwork source, broadcast to every drawing. Per manager, so two charts in\n * one document can draw different asset sets. */\n setGlyphSource(source: GlyphSourcePort | null): void {\n this._glyphSource = source\n for (const drawing of this._drawings.values()) drawing.setGlyphSource(source)\n }\n\n /** Where the words an empty drawing shows come from, broadcast to every drawing: the host's\n * catalog, read as each paints. */\n setTextPlaceholder(source: (() => string) | null): void {\n this._placeholder = source\n for (const drawing of this._drawings.values()) drawing.setTextPlaceholder(source)\n }\n\n /** Where the chart's own inks come from, broadcast to every drawing: the host's theme, read as\n * each paints. */\n setInks(source: (() => DrawingInks) | null): void {\n this._inks = source\n for (const drawing of this._drawings.values()) drawing.setInks(source)\n }\n\n /** Broadcast the chart's timeframe so per-timeframe visibility rules apply. */\n setTimeframeContext(context: TimeframeContext): void {\n this._timeframeContext = context\n for (const drawing of this._drawings.values()) drawing.setTimeframeContext(context)\n }\n\n /** Chart-wide hide-all: every drawing (and its axis pills) disappears until toggled back. */\n setAllHidden(hidden: boolean): void {\n this._allHidden = hidden\n for (const drawing of this._drawings.values()) drawing.setGlobalHidden(hidden)\n }\n\n allHidden(): boolean {\n return this._allHidden\n }\n\n attach(chart: IChartApi, series: ISeriesApi<SeriesType>): void {\n if (this._chart) this.detach()\n this._chart = chart\n this._series = series\n for (const id of this._order) {\n const drawing = this._drawings.get(id)\n if (drawing) series.attachPrimitive(drawing)\n }\n }\n\n detach(): void {\n if (this._series) {\n for (const drawing of this._drawings.values()) {\n try {\n this._series.detachPrimitive(drawing)\n } catch {\n /* series already disposed */\n }\n }\n }\n this._chart = null\n this._series = null\n }\n\n isAttached(): boolean {\n return this._chart !== null\n }\n\n // ============ Store ============\n\n add(drawing: IDrawing): void {\n if (this._drawings.has(drawing.id)) return\n // Every IDrawing is a Drawing subclass (the registry only makes those); the store needs the\n // class type because attaching requires the series-primitive surface.\n const concrete = drawing as AnyDrawing\n concrete.setTimeframeContext(this._timeframeContext)\n concrete.setGlobalHidden(this._allHidden)\n concrete.setBarSource(this._barSource)\n concrete.setTickSize(this._tickSize)\n concrete.setCurrencyCode(this._currencyCode)\n concrete.setPriceFormatter(this._priceFormat)\n concrete.setGlyphSource(this._glyphSource)\n if (this._placeholder) concrete.setTextPlaceholder(this._placeholder)\n if (this._inks) concrete.setInks(this._inks)\n this._drawings.set(concrete.id, concrete)\n this._order.push(concrete.id)\n this._series?.attachPrimitive(concrete)\n this.emit('drawing:added', { drawingId: concrete.id, drawing: concrete })\n }\n\n remove(id: string): void {\n const drawing = this._drawings.get(id)\n if (!drawing) return\n if (this._selectedId === id) this.deselect()\n if (this._series) {\n try {\n this._series.detachPrimitive(drawing)\n } catch {\n /* series already disposed */\n }\n }\n this._drawings.delete(id)\n this._order = this._order.filter((d) => d !== id)\n this.emit('drawing:removed', { drawingId: id })\n }\n\n get(id: string): IDrawing | undefined {\n return this._drawings.get(id)\n }\n\n /** All drawings in insertion order (bottom-most first). */\n all(): IDrawing[] {\n return this._order\n .map((id) => this._drawings.get(id))\n .filter((d): d is AnyDrawing => !!d)\n }\n\n clear(): void {\n this.deselect()\n if (this._series) {\n for (const drawing of this._drawings.values()) {\n try {\n this._series.detachPrimitive(drawing)\n } catch {\n /* series already disposed */\n }\n }\n }\n this._drawings.clear()\n this._order = []\n this.emit('drawing:cleared', {})\n }\n\n // ============ Selection ============\n\n select(id: string): void {\n const drawing = this._drawings.get(id)\n if (!drawing || this._selectedId === id) return\n if (this._selectedId) this._drawings.get(this._selectedId)?.setState('normal')\n drawing.setState('selected')\n this._selectedId = id\n this.emit('drawing:selected', { drawingId: id, drawing })\n }\n\n deselect(): void {\n if (!this._selectedId) return\n const id = this._selectedId\n this._drawings.get(id)?.setState('normal')\n this._selectedId = null\n this.emit('drawing:deselected', { drawingId: id })\n }\n\n selected(): IDrawing | null {\n return (this._selectedId && this._drawings.get(this._selectedId)) || null\n }\n\n // ============ Stacking ============\n\n /** Paint above everything else (and hit-test first, since hit order follows zIndex). */\n bringToFront(id: string): void {\n const drawing = this._drawings.get(id)\n if (!drawing) return\n const top = Math.max(0, ...this.all().map((d) => d.options.zIndex))\n drawing.updateOptions({ zIndex: top + 1 })\n this.restack()\n }\n\n sendToBack(id: string): void {\n const drawing = this._drawings.get(id)\n if (!drawing) return\n const bottom = Math.min(0, ...this.all().map((d) => d.options.zIndex))\n drawing.updateOptions({ zIndex: bottom - 1 })\n this.restack()\n }\n\n /** One step up in the paint order — swap with the neighbour directly above (no-op at the\n * front). Every step RENUMBERS the whole stack to a dense 0..n-1 sequence: repeated\n * to-front/to-back extremes otherwise drift zIndexes apart until \"one step\" and \"adjacent\n * number\" stop meaning the same thing. */\n bringForward(id: string): void {\n this.stepStack(id, +1)\n }\n\n /** One step down in the paint order — swap with the neighbour directly below (no-op at the back). */\n sendBackward(id: string): void {\n this.stepStack(id, -1)\n }\n\n private stepStack(id: string, dir: 1 | -1): void {\n const sorted = this.visualOrder()\n const at = sorted.findIndex((d) => d.id === id)\n if (at < 0 || at + dir < 0 || at + dir >= sorted.length) return\n const other = sorted[at + dir]!\n sorted[at + dir] = sorted[at]!\n sorted[at] = other\n sorted.forEach((d, i) => {\n if (d.options.zIndex !== i) d.updateOptions({ zIndex: i })\n })\n this.restack()\n }\n\n /** Where a drawing sits in the paint order — menus disable the moves that cannot apply\n * (a drawing already at the back has nothing below it to step behind). */\n stackPosition(id: string): { atFront: boolean; atBack: boolean } {\n const sorted = this.visualOrder()\n const at = sorted.findIndex((d) => d.id === id)\n return { atFront: at < 0 || at === sorted.length - 1, atBack: at <= 0 }\n }\n\n /** The paint order, bottom first: (zIndex, insertion) — the ONE sort restack keys off too. */\n private visualOrder(): AnyDrawing[] {\n return this._order\n .map((oid) => this._drawings.get(oid))\n .filter((d): d is AnyDrawing => !!d)\n .sort((a, b) => a.options.zIndex - b.options.zIndex)\n }\n\n /** Re-attach primitives so PAINT order follows (zIndex, insertion) — the chart paints\n * primitives in attach order, so stacking changes must re-key that order. */\n private restack(): void {\n if (!this._series) return\n const sorted = this.visualOrder()\n for (const drawing of sorted) {\n try {\n this._series.detachPrimitive(drawing)\n this._series.attachPrimitive(drawing)\n } catch {\n /* series disposed mid-restack */\n }\n }\n }\n\n // ============ Hit testing ============\n\n getViewport(): Viewport | null {\n if (!this._chart || !this._series) return null\n return viewportOf(this._chart, this._series)\n }\n\n /**\n * Top-most visible drawing at a pane point: higher zIndex wins, then later insertion.\n * The selected drawing is tried first so a stacked selection stays grabbable.\n */\n hitTest(point: Point): IDrawing | null {\n const viewport = this.getViewport()\n if (!viewport) return null\n const sel = this.selected()\n if (sel && sel.isVisibleNow() && sel.testHit(point, viewport)) return sel\n const byTopmost = [...this._order].reverse().map((id) => this._drawings.get(id))\n byTopmost.sort((a, b) => (b?.options.zIndex ?? 0) - (a?.options.zIndex ?? 0))\n for (const drawing of byTopmost) {\n if (!drawing || !drawing.isVisibleNow()) continue\n if (drawing.testHit(point, viewport)) return drawing\n }\n return null\n }\n\n // ============ Serialization ============\n\n export(): SerializedDrawing[] {\n return this.all().map((d) => d.toJSON())\n }\n\n // ============ Events ============\n\n on(event: DrawingEventType, callback: DrawingEventCallback): () => void {\n let set = this._listeners.get(event)\n if (!set) {\n set = new Set()\n this._listeners.set(event, set)\n }\n set.add(callback)\n return () => {\n set.delete(callback)\n }\n }\n\n private emit(type: DrawingEventType, data: Omit<DrawingEvent, 'type'>): void {\n const listeners = this._listeners.get(type)\n if (!listeners) return\n const event: DrawingEvent = { type, ...data }\n for (const callback of listeners) callback(event)\n }\n}\n","import { MismatchDirection } from 'lightweight-charts'\nimport type { IChartApi, ISeriesApi, SeriesType, Time } from 'lightweight-charts'\n\nimport type { Anchor, Point } from './types'\n\nexport type MagnetMode = 'off' | 'weak' | 'strong'\n\n/** Weak magnet only pulls when the pointer is already this close (px) to an OHLC value. */\nconst WEAK_RADIUS = 14\n\nexport interface OhlcBar {\n time: Time\n open: number\n high: number\n low: number\n close: number\n}\n\n/**\n * The pure snap: nearest OHLC value of one bar, in pixel space. `weak` returns null when every\n * value is farther than the pull radius; `strong` always takes the nearest.\n */\nexport function snapToBar(\n bar: OhlcBar,\n pointerY: number,\n priceToY: (price: number) => number | null,\n mode: Exclude<MagnetMode, 'off'>,\n): number | null {\n let best: number | null = null\n let bestDistance = Infinity\n for (const price of [bar.open, bar.high, bar.low, bar.close]) {\n const y = priceToY(price)\n if (y === null) continue\n const distance = Math.abs(y - pointerY)\n if (distance < bestDistance) {\n bestDistance = distance\n best = price\n }\n }\n if (best === null) return null\n if (mode === 'weak' && bestDistance > WEAK_RADIUS) return null\n return best\n}\n\n/**\n * Snap a pane point to the nearest bar's nearest OHLC value. Returns the snapped anchor (time\n * pinned to the bar, price to the chosen value), or null when nothing pulls — the caller then\n * uses the raw pointer anchor.\n */\nexport function magnetSnap(\n chart: IChartApi,\n series: ISeriesApi<SeriesType>,\n point: Point,\n mode: MagnetMode,\n): Anchor | null {\n if (mode === 'off') return null\n let bar: OhlcBar | null = null\n try {\n const logical = chart.timeScale().coordinateToLogical(point.x)\n if (logical === null) return null\n const item = series.dataByIndex(Math.round(logical), MismatchDirection.NearestLeft)\n if (!item || !('open' in item)) return null\n bar = item as OhlcBar\n } catch {\n return null\n }\n const price = snapToBar(bar, point.y, (p) => series.priceToCoordinate(p), mode)\n if (price === null) return null\n return { time: bar.time, price }\n}\n","import type { Point } from './types'\n\n/** Distance from a point to the segment [a, b]. */\nexport function distanceToSegment(p: Point, a: Point, b: Point): number {\n const dx = b.x - a.x\n const dy = b.y - a.y\n const lengthSq = dx * dx + dy * dy\n if (lengthSq === 0) return Math.hypot(p.x - a.x, p.y - a.y)\n const t = Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / lengthSq))\n return Math.hypot(p.x - (a.x + t * dx), p.y - (a.y + t * dy))\n}\n\n/** Distance from a point to the infinite line through a and b. */\nexport function distanceToLine(p: Point, a: Point, b: Point): number {\n const dx = b.x - a.x\n const dy = b.y - a.y\n const lengthSq = dx * dx + dy * dy\n if (lengthSq === 0) return Math.hypot(p.x - a.x, p.y - a.y)\n return Math.abs(dy * p.x - dx * p.y + b.x * a.y - b.y * a.x) / Math.sqrt(lengthSq)\n}\n\nexport function midpoint(a: Point, b: Point): Point {\n return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 }\n}\n\n/** Angle of a→b in radians, y-down screen space. */\nexport function angleOf(a: Point, b: Point): number {\n return Math.atan2(b.y - a.y, b.x - a.x)\n}\n\n/** Angle of a→b folded into (-90°, 90°] so text painted along the segment always reads upright. */\nexport function segmentTextAngle(a: Point, b: Point): number {\n let angle = angleOf(a, b)\n if (angle > Math.PI / 2) angle -= Math.PI\n if (angle < -Math.PI / 2) angle += Math.PI\n return angle\n}\n\n/**\n * Extend the segment a→b along its own direction to the pane bounds. `left` extends behind `a`\n * (opposite the a→b direction), `right` extends beyond `b`. A zero-length segment is returned\n * unchanged — it has no direction to extend along.\n */\nexport function extendSegment(\n a: Point,\n b: Point,\n width: number,\n height: number,\n left: boolean,\n right: boolean,\n): { a: Point; b: Point } {\n const dx = b.x - a.x\n const dy = b.y - a.y\n if (dx === 0 && dy === 0) return { a, b }\n\n // Parametric p(t) = a + t·d: find the t range where the line crosses the pane box, then clamp\n // the requested sides to it. t=0 is `a`, t=1 is `b`.\n let tMin = -Infinity\n let tMax = Infinity\n if (dx !== 0) {\n const t0 = (0 - a.x) / dx\n const t1 = (width - a.x) / dx\n tMin = Math.min(t0, t1)\n tMax = Math.max(t0, t1)\n } else {\n if (a.x < 0 || a.x > width) return { a, b }\n }\n if (dy !== 0) {\n const t0 = (0 - a.y) / dy\n const t1 = (height - a.y) / dy\n tMin = Math.max(tMin, Math.min(t0, t1))\n tMax = Math.min(tMax, Math.max(t0, t1))\n } else if (a.y < 0 || a.y > height) {\n return { a, b }\n }\n if (tMin > tMax) return { a, b } // the line never crosses the pane\n\n const tA = left ? Math.min(0, tMin) : 0\n const tB = right ? Math.max(1, tMax) : 1\n return {\n a: { x: a.x + tA * dx, y: a.y + tA * dy },\n b: { x: a.x + tB * dx, y: a.y + tB * dy },\n }\n}\n","// Decoded bitmaps, shared between whoever chose the picture and the drawing that paints it.\n//\n// A data URL is not a bitmap: handing one to an <img> costs a base64 parse plus a decode, and that\n// work happens asynchronously, so an unprimed image would appear a beat AFTER the click that placed\n// it, even though the picker already decoded the identical payload a moment earlier to show its\n// preview. Priming the result here means the drawing finds a ready bitmap and paints it on the very\n// first frame.\n//\n// Keyed by the data URL itself, which is exactly the identity that matters: the same payload is the\n// same picture, and two drawings sharing one image share one decode.\n\nconst cache = new Map<string, HTMLImageElement>()\n\n/** Bitmaps are megabytes of decoded pixels, so the map is bounded and evicts oldest-first. Well\n * above any realistic number of images on one chart, low enough that it cannot become a leak. */\nconst MAX_ENTRIES = 24\n\nexport function primeImageBitmap(key: string, image: HTMLImageElement): void {\n if (!key) return\n if (cache.has(key)) cache.delete(key) // re-insert so it counts as most recently used\n cache.set(key, image)\n while (cache.size > MAX_ENTRIES) {\n const oldest = cache.keys().next()\n if (oldest.done) break\n cache.delete(oldest.value)\n }\n}\n\n/** A bitmap already decoded for this payload, or null when it has to be loaded the slow way. */\nexport function cachedImageBitmap(key: string): HTMLImageElement | null {\n if (!key) return null\n const hit = cache.get(key)\n if (!hit) return null\n // A cached element that never finished decoding is no use to a synchronous paint.\n return hit.complete && hit.naturalWidth > 0 ? hit : null\n}\n","// A drawing restored from a format-2 save whose tool's present design cannot paint that save's look\n// carries the save's settings as `savedLook`, and paints them as format 2 did until its settings\n// change: a change through its pages or its bar gives it the present design, with the present props\n// it was restored with as the closest look.\n\n/** The settings a format-2 save painted with, held by a tool whose present design cannot paint them,\n * or null for a drawing in its present design. */\nexport type SavedLook = Readonly<Record<string, unknown>> | null\n\n/** A props patch to a drawing that may hold a saved look: a change to its settings ends the look; a\n * patch that carries the look itself, as a cancelled edit's snapshot does, keeps it. */\nexport function endSavedLook<P extends Record<string, unknown>>(patch: Partial<P>): Partial<P> {\n return 'savedLook' in patch || Object.keys(patch).length === 0 ? patch : { ...patch, savedLook: null }\n}\n\n/** A saved look's levels: the ones it carries, each a value and whether it shows, with the color\n * it carries where it carries one. */\nexport function savedLevels(look: NonNullable<SavedLook>, key = 'levels'): { value: number; visible: boolean; color?: string; text?: string }[] {\n const levels = look[key]\n if (!Array.isArray(levels)) return []\n return levels\n .filter((l): l is Record<string, unknown> => !!l && typeof l === 'object' && typeof (l as Record<string, unknown>).value === 'number')\n .map((l) => ({\n value: l.value as number,\n visible: l.visible !== false,\n ...(typeof l.color === 'string' ? { color: l.color } : {}),\n ...(typeof l.text === 'string' ? { text: l.text } : {}),\n }))\n}\n","// Words a line carries: where they stand along and across it, and the invitation a selected line\n// without words shows where they would stand. A line's words turn with it, so every place here is a\n// point on the pane, the angle the words turn by about it, and how they align there.\nimport type { DrawingStyle, Point } from '../core/types'\nimport { fontOf, withAlpha } from './canvas'\n\n/** Where a line's words stand: the point their middle line meets, turned by `angle` about it, and\n * which end of the words, or their middle, stands on the point. */\nexport interface WordsPlace {\n x: number\n y: number\n angle: number\n align: 'left' | 'center' | 'right'\n}\n\n/** How far the middle of a line's words stands off the line when they stand above or below it:\n * half their size and four pixels more. */\nexport const wordsOffset = (fontSize: number): number => fontSize / 2 + 4\n\n/** The invitation's plus and the room between it and its words, by the words' size: a plus\n * `fontSize / 2 + 5` across, `fontSize / 2 - 3` before the words. */\nconst plusSize = (fontSize: number): number => fontSize / 2 + 5\nconst plusGap = (fontSize: number): number => fontSize / 2 - 3\n\n/** Where a point a distance along and across a place's turned axes stands on the pane. */\nexport function placeAt(place: WordsPlace, along: number, across: number): Point {\n const cos = Math.cos(place.angle)\n const sin = Math.sin(place.angle)\n return { x: place.x + along * cos - across * sin, y: place.y + along * sin + across * cos }\n}\n\n/** The region the invitation covers: its middle, the angle it turns by and its half sizes. */\nexport interface InvitationRegion {\n cx: number\n cy: number\n angle: number\n halfW: number\n halfH: number\n}\n\n/**\n * Paint the invitation a selected line without words shows where its words would stand: a plus,\n * then the placeholder words, both in the line's text color at half strength and in its type. The\n * pair aligns on the place as the words would. A pair that does not turn stands its plus on the\n * pixel grid, so its two strokes read one pixel wide.\n */\nexport function paintInvitation(ctx: CanvasRenderingContext2D, words: string, place: WordsPlace, style: DrawingStyle, measure: (line: string) => number): InvitationRegion {\n const size = style.fontSize\n const plus = plusSize(size)\n const gap = plusGap(size)\n const width = plus + gap + measure(words)\n const left = place.align === 'left' ? 0 : place.align === 'right' ? -width : -width / 2\n const ink = withAlpha(style.textColor, 0.5)\n ctx.save()\n ctx.setLineDash([])\n ctx.translate(place.x, place.y)\n if (place.angle) ctx.rotate(place.angle)\n ctx.font = fontOf(style)\n ctx.fillStyle = ink\n ctx.textAlign = 'left'\n ctx.textBaseline = 'middle'\n ctx.fillText(words, left + plus + gap, 0)\n // The plus stands half a pixel above the words' middle; level, on the grid.\n let px = left + plus / 2\n let py = -0.5\n if (!place.angle) {\n px = Math.round(place.x + px - 0.5) + 0.5 - place.x\n py = Math.round(place.y - 1) + 0.5 - place.y\n }\n ctx.strokeStyle = ink\n ctx.lineWidth = 1\n ctx.lineCap = 'butt'\n ctx.lineJoin = 'miter'\n ctx.beginPath()\n ctx.moveTo(px - plus / 2, py)\n ctx.lineTo(px + plus / 2, py)\n ctx.moveTo(px, py - plus / 2)\n ctx.lineTo(px, py + plus / 2)\n ctx.stroke()\n ctx.restore()\n const middle = placeAt(place, left + width / 2, 0)\n return { cx: middle.x, cy: middle.y, angle: place.angle, halfW: width / 2 + 2, halfH: size / 2 + 2 }\n}\n\n/** Whether a pane point falls inside a turned region. */\nexport function inRegion(point: Point, r: InvitationRegion): boolean {\n const dx = point.x - r.cx\n const dy = point.y - r.cy\n const cos = Math.cos(-r.angle)\n const sin = Math.sin(-r.angle)\n return Math.abs(dx * cos - dy * sin) <= r.halfW && Math.abs(dx * sin + dy * cos) <= r.halfH\n}\n","// A line's stats box: a rounded grey box of up to three rows, its price move, its span and its\n// angle, each led by a small mark of what it reads. The marks are drawn here from lines and one arc,\n// in the box's own ink.\nimport type { Point } from '../core/types'\n\n/** The box's ground, rounded at four, and the ink its rows and marks are in. */\nexport const STATS_GROUND = 'rgba(70, 70, 70, 0.9)'\nexport const STATS_INK = '#ffffff'\nconst MARK_INK = '#f9f9f9'\n/** The size the rows read at. */\nexport const STATS_FONT_SIZE = 12\n\n/** The box's rhythm: eight pixels above and below its rows, a row every 26 pixels, a mark centred\n * 21 pixels in, the words 42 pixels in, and 13 pixels after the widest row. */\nconst PAD_Y = 8\nconst ROW = 26\nconst MARK_X = 21\nconst WORDS_X = 42\nconst PAD_END = 13\n\n/** What a row reads: the price move, the span, or the angle. */\nexport type StatsRow = { kind: 'price' | 'span' | 'angle'; text: string }\n\n/** Where the box stands: its top-left on the pane. */\nexport interface StatsBox {\n x: number\n y: number\n width: number\n height: number\n}\n\n/** The box a set of rows takes, its top-left at a point. */\nexport function statsBoxAt(at: Point, rows: readonly StatsRow[], measure: (text: string) => number): StatsBox {\n const widest = rows.reduce((w, r) => Math.max(w, measure(r.text)), 0)\n return { x: at.x, y: at.y, width: Math.round(WORDS_X + widest + PAD_END), height: PAD_Y * 2 + rows.length * ROW }\n}\n\n/** Paint the box and its rows, each led by its mark. */\nexport function paintStatsBox(ctx: CanvasRenderingContext2D, box: StatsBox, rows: readonly StatsRow[], font: string): void {\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = STATS_GROUND\n ctx.beginPath()\n ctx.roundRect(box.x, box.y, box.width, box.height, 4)\n ctx.fill()\n ctx.font = font\n ctx.textAlign = 'start'\n ctx.textBaseline = 'middle'\n rows.forEach((row, i) => {\n const middle = box.y + PAD_Y + ROW / 2 + i * ROW\n paintMark(ctx, row.kind, box.x + MARK_X, middle)\n ctx.fillStyle = STATS_INK\n ctx.fillText(row.text, box.x + WORDS_X, middle)\n })\n ctx.restore()\n}\n\n/** A row's mark, about its centre: a price move is a double arrow between two levels, a span a\n * double arrow between two bars, an angle two rays from a corner with an arc between them. */\nfunction paintMark(ctx: CanvasRenderingContext2D, kind: StatsRow['kind'], cx: number, cy: number): void {\n ctx.strokeStyle = MARK_INK\n ctx.lineWidth = 1\n ctx.lineCap = 'butt'\n ctx.lineJoin = 'miter'\n ctx.beginPath()\n if (kind === 'price') {\n for (const dy of [-6.5, 6.5]) {\n ctx.moveTo(cx - 6, cy + dy)\n ctx.lineTo(cx + 5, cy + dy)\n }\n ctx.moveTo(cx - 0.5, cy - 5)\n ctx.lineTo(cx - 0.5, cy + 5)\n for (const s of [-1, 1]) {\n ctx.moveTo(cx - 3, cy + s * 2)\n ctx.lineTo(cx - 0.5, cy + s * 4.5)\n ctx.lineTo(cx + 2, cy + s * 2)\n }\n } else if (kind === 'span') {\n for (const x of [-7.5, 5.5]) {\n ctx.rect(cx + x, cy - 3.5, 2, 8)\n ctx.moveTo(cx + x + 1, cy - 6)\n ctx.lineTo(cx + x + 1, cy - 4)\n ctx.moveTo(cx + x + 1, cy + 5)\n ctx.lineTo(cx + x + 1, cy + 7)\n }\n ctx.moveTo(cx - 3.5, cy + 0.5)\n ctx.lineTo(cx + 3.5, cy + 0.5)\n for (const s of [-1, 1]) {\n ctx.moveTo(cx + s, cy - 2)\n ctx.lineTo(cx + s * 3.5, cy + 0.5)\n ctx.lineTo(cx + s, cy + 3)\n }\n } else {\n const corner = { x: cx - 5.5, y: cy + 5.5 }\n const ray = (64.7 * Math.PI) / 180\n ctx.moveTo(cx - 6, corner.y)\n ctx.lineTo(cx + 6, corner.y)\n ctx.moveTo(corner.x, corner.y)\n ctx.lineTo(corner.x + 12.5 * Math.cos(ray), corner.y - 12.5 * Math.sin(ray))\n ctx.moveTo(corner.x + 7, corner.y)\n ctx.arc(corner.x, corner.y, 7, 0, -ray, true)\n }\n ctx.stroke()\n}\n","// Painting words a drawing takes in place: its words or its placeholder, and while an inline edit\n// is open, the selection's wash behind the words, the composing run's underline and the caret.\n// The drawing decides where its words stand; this paints them there, the same way for every tool\n// that types on the chart.\nimport { caretPlace, lineLeft, runSpans, type TextBlock, type TextDraft } from '../core/textEntry'\n\n/** The wash behind selected words: white at a fifth, laid under the words so they keep their own\n * color. */\nexport const SELECTION_WASH = 'rgba(255, 255, 255, 0.2)'\n\n/** How wide the caret is, centred on its place. */\nexport const CARET_WIDTH = 2\n\n/** A block of words as it paints: its first line's box, its line height, its type and color, and\n * the width its lines align within. */\nexport interface TextEntryPaint {\n x: number\n y: number\n width: number\n lineHeight: number\n font: string\n color: string\n align: 'left' | 'center' | 'right'\n /** The words in lines. */\n block: TextBlock\n /** The placeholder in lines, and the alpha it paints at, shown in place of the words; null where\n * it does not show. */\n placeholder: { block: TextBlock; alpha: number } | null\n /** The draft an open inline edit shows, or null. */\n draft: TextDraft | null\n measure: (line: string) => number\n}\n\n/** Where a line's middle stands, from its box's top: half a line down and a pixel more, which is\n * where its words paint with a middle baseline. */\nexport const lineMiddle = (lineHeight: number): number => lineHeight / 2 + 1\n\n/** How tall the caret stands in a line: as tall as the words' type, or the line where that is\n * shorter. */\nconst caretHeight = (font: string, lineHeight: number): number => Math.min(lineHeight, Number(/(\\d+(?:\\.\\d+)?)px/.exec(font)?.[1]) || lineHeight)\n\n/** Paint a block of words, or its placeholder, and while an edit is open on it, its selection,\n * composing run and caret. The pixels a run covers start at the pixel edge nearest its start and\n * run through the pixel its end reaches; the composing run is underlined on its lines' last row of\n * pixels; the caret is two pixels wide on its place and as tall as the type, standing in the\n * middle of its line, in the words' color. */\nexport function paintTextEntry(ctx: CanvasRenderingContext2D, p: TextEntryPaint): void {\n const draft = p.draft\n const shown = p.placeholder ? p.placeholder.block : p.block\n const lineTop = (i: number): number => p.y + i * p.lineHeight\n const left = (block: TextBlock, i: number): number => p.x + lineLeft(block, i, p.align, p.width)\n ctx.save()\n ctx.setLineDash([])\n // The words run left to right as the field over them does, whatever direction the page reads in.\n ctx.direction = 'ltr'\n if (draft && draft.selectionStart !== draft.selectionEnd && !p.placeholder) {\n ctx.fillStyle = SELECTION_WASH\n for (const span of runSpans(p.block, draft.selectionStart, draft.selectionEnd, p.measure)) {\n const from = Math.round(left(p.block, span.line) + span.x0)\n const to = Math.ceil(left(p.block, span.line) + span.x1)\n if (to > from) ctx.fillRect(from, lineTop(span.line), to - from, p.lineHeight)\n }\n }\n ctx.font = p.font\n ctx.fillStyle = p.color\n ctx.textAlign = 'left'\n ctx.textBaseline = 'middle'\n const alpha = ctx.globalAlpha\n if (p.placeholder) ctx.globalAlpha = alpha * p.placeholder.alpha\n shown.lines.forEach((l, i) => {\n if (l.text === '') return\n ctx.fillText(l.text, left(shown, i), lineTop(i) + lineMiddle(p.lineHeight))\n })\n ctx.globalAlpha = alpha\n if (draft?.composition && !p.placeholder) {\n for (const span of runSpans(p.block, draft.composition.start, draft.composition.end, p.measure)) {\n const from = Math.round(left(p.block, span.line) + span.x0)\n const to = Math.ceil(left(p.block, span.line) + span.x1)\n if (to > from) ctx.fillRect(from, lineTop(span.line) + p.lineHeight - 1, to - from, 1)\n }\n }\n if (draft?.caret && draft.selectionStart === draft.selectionEnd) {\n const at = caretPlace(p.block, draft.selectionEnd, p.measure)\n const tall = caretHeight(p.font, p.lineHeight)\n ctx.fillRect(Math.round(left(p.block, at.line) + at.x) - CARET_WIDTH / 2, lineTop(at.line) + Math.round((p.lineHeight - tall) / 2), CARET_WIDTH, tall)\n }\n ctx.restore()\n}\n\n/** A selected drawing's frame around its words: a band two pixels wide just outside the box, in\n * the given color at the given alpha. */\nexport function paintWordsFrame(ctx: CanvasRenderingContext2D, box: { x: number; y: number; width: number; height: number }, color: string, alpha: number): void {\n ctx.save()\n ctx.setLineDash([])\n ctx.globalAlpha = ctx.globalAlpha * alpha\n ctx.strokeStyle = color\n ctx.lineWidth = 2\n ctx.strokeRect(box.x - 1, box.y - 1, box.width + 2, box.height + 2)\n ctx.restore()\n}\n","import type { ISeriesPrimitiveAxisView, Time } from 'lightweight-charts'\n\nimport type { ControlPoint, DrawingStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { angleOf, distanceToSegment, extendSegment, midpoint, segmentTextAngle } from '../core/geometry'\nimport { endSavedLook, type SavedLook } from '../core/savedLook'\nimport type { TextBlock, TextEditFrame } from '../core/textEntry'\nimport { applyStroke, fontOf, inkOn, lineMeasure, paintArrowHead, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\nimport { AxisLabel } from '../render/axis-view'\nimport { inRegion, paintInvitation, placeAt, wordsOffset, type InvitationRegion, type WordsPlace } from '../render/lineWords'\nimport { paintStatsBox, STATS_FONT_SIZE, statsBoxAt, type StatsRow } from '../render/statsBox'\nimport { paintTextEntry } from '../render/textEntry'\n\nexport type LineEnd = 'normal' | 'arrow'\n\n/** Where a line's stats stand along it: near its left end, at its middle, near its right end, or\n * near the right end unless the pane leaves no room there, then near the left. */\nexport type StatsPosition = 'left' | 'center' | 'right' | 'auto'\n\n/** Where a label stands across what carries it: above it, on it, or below it. A box's label stands\n * above it, inside it, or below it. */\nexport type TextVAlign = 'top' | 'middle' | 'bottom'\n\n/** Where a label stands along what carries it. */\nexport type TextHAlign = 'left' | 'center' | 'right'\n\n/** The two-point line family's full option set. Tool identity = these defaults. */\nexport type TrendLineProps = {\n /** The line's words, typed on the chart or in the settings' Text tab. */\n text: string\n extendLeft: boolean\n extendRight: boolean\n leftEnd: LineEnd\n rightEnd: LineEnd\n /** Marker at the segment's midpoint. */\n middlePoint: boolean\n /** Price pill beside each end point. */\n showPriceLabels: boolean\n /** Stats readout items (price delta, percent change, the change counted in the symbol's smallest\n * price move, bar count, span, length on the pane, slope angle). The count shows only where the\n * chart knows that move. */\n showPriceRange: boolean\n showPercentChange: boolean\n showPipsChange: boolean\n showBarsRange: boolean\n showDateTimeRange: boolean\n showDistance: boolean\n showAngle: boolean\n statsPosition: StatsPosition\n /** The stats show whether or not the line is selected. Off, they show while it is. */\n alwaysShowStats: boolean\n /** Where the label stands across the line and along it. */\n textVAlign: TextVAlign\n textHAlign: TextHAlign\n /** A format-2 line's look, its ends, words and stats painted as format 2 did until its settings\n * change. */\n savedLook: SavedLook\n}\n\nconst LINE_PROPS: TrendLineProps = {\n text: '',\n extendLeft: false,\n extendRight: false,\n leftEnd: 'normal',\n rightEnd: 'normal',\n middlePoint: false,\n showPriceLabels: false,\n showPriceRange: false,\n showPercentChange: false,\n showPipsChange: false,\n showBarsRange: false,\n showDateTimeRange: false,\n showDistance: false,\n showAngle: false,\n statsPosition: 'right',\n alwaysShowStats: false,\n textVAlign: 'top',\n textHAlign: 'center',\n savedLook: null,\n}\n\n/** How a format-2 label stood across a line it rode: its offset from the line and the edge of the\n * text that offset is measured to. */\nconst ACROSS: Record<TextVAlign, { y: number; baseline: 'bottom' | 'middle' | 'top' }> = {\n top: { y: -4, baseline: 'bottom' },\n middle: { y: 0, baseline: 'middle' },\n bottom: { y: 4, baseline: 'top' },\n}\n\n/** How far a level's words stand in from the end of the pane they align to. */\nconst LEVEL_WORDS_INSET = 7\n\n/** Where a level line's square handle stands along it: nine tenths of the way across the pane. */\nconst LEVEL_HANDLE_AT = 0.9\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** A coordinate a line of a width strokes on so it lands on whole pixels: a pixel's middle for an\n * odd width, a pixel's edge for an even one. */\nfunction crisp(v: number, width: number): number {\n return Math.round(v) + (Math.round(width) % 2 === 1 ? 0.5 : 0)\n}\n\n/** The open head a line's arrow end wears at its tip: two strokes back from the tip at 45 degrees\n * either side of the line, `5 + 2.5 x width` along and across it, laid into the path being built. */\nfunction openHead(ctx: CanvasRenderingContext2D, from: Point, tip: Point, lineWidth: number): void {\n const length = Math.hypot(tip.x - from.x, tip.y - from.y)\n if (!(length > 0)) return\n const ux = (tip.x - from.x) / length\n const uy = (tip.y - from.y) / length\n const size = 5 + 2.5 * lineWidth\n ctx.moveTo(tip.x - size * ux - size * uy, tip.y - size * uy + size * ux)\n ctx.lineTo(tip.x, tip.y)\n ctx.lineTo(tip.x - size * ux + size * uy, tip.y - size * uy - size * ux)\n}\n\n/** A count written with its thousands grouped. */\nfunction grouped(n: number): string {\n const digits = String(Math.abs(n)).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\n return n < 0 ? `-${digits}` : digits\n}\n\n/** A span of time written in its two largest units. */\nfunction spanText(seconds: number): string {\n const d = Math.floor(seconds / 86400)\n const h = Math.floor((seconds % 86400) / 3600)\n const m = Math.floor((seconds % 3600) / 60)\n return d > 0 ? `${d}d ${h}h` : h > 0 ? `${h}h ${m}m` : `${m}m`\n}\n\n/** A block of words laid on a place: its box's top-left and width, before the place's turn. */\ninterface WordsBox {\n left: number\n top: number\n width: number\n lines: number\n}\n\n/** Where a block of words stands about the point it is placed on: aligned along at its end or\n * middle, and its rows growing away from the line it rides, so the row nearest the line keeps its\n * place as more are typed. */\nfunction wordsBox(place: WordsPlace, block: TextBlock, lineHeight: number, across: TextVAlign): WordsBox {\n const lines = Math.max(1, block.lines.length)\n const width = block.width\n const left = place.align === 'left' ? 0 : place.align === 'right' ? -width : -width / 2\n const first = -lineHeight / 2 - 1\n const top = across === 'top' ? first - (lines - 1) * lineHeight : across === 'bottom' ? first : first - ((lines - 1) * lineHeight) / 2\n return { left, top, width, lines }\n}\n\n/**\n * The words a line family member carries and types on the chart. Every line lays them out the same\n * way about the place its own geometry gives them: the selected line without words invites them\n * there with a plus and its placeholder at half strength, an open edit paints its draft there, and\n * the editor's field is laid over that place, turned with the words.\n */\nabstract class LineWords<P extends Record<string, unknown> & { text: string }> extends Drawing<P> {\n /** Where the words stand, or null where they cannot. */\n protected abstract wordsPlace(viewport: Viewport): WordsPlace | null\n\n /** Which way the words' lines grow away from what carries them. */\n protected abstract wordsAcross(): TextVAlign\n\n /** Whether the line invites words while it is selected without any. */\n protected invites(): boolean {\n return true\n }\n\n protected wordsBlock(): { block: TextBlock; placeholder: TextBlock | null } {\n return this.shownWords(lineMeasure(this.style))\n }\n\n /** Paint the words, or an open edit's draft with its placeholder at half strength while it is\n * empty. */\n protected paintWords(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const draft = this.textDraft\n if (!draft && this.props.text === '') return\n const place = this.wordsPlace(viewport)\n if (!place) return\n const { block, placeholder } = this.wordsBlock()\n const shown = draft ? (placeholder ?? block) : block\n const box = wordsBox(place, shown, this.style.fontSize, this.wordsAcross())\n ctx.save()\n ctx.translate(place.x, place.y)\n if (place.angle) ctx.rotate(place.angle)\n paintTextEntry(ctx, {\n x: box.left,\n y: box.top,\n width: box.width,\n lineHeight: this.style.fontSize,\n font: fontOf(this.style),\n color: this.style.textColor,\n align: place.align,\n block,\n placeholder: draft && placeholder ? { block: placeholder, alpha: 0.5 } : null,\n draft,\n measure: lineMeasure(this.style),\n })\n ctx.restore()\n }\n\n override textFrame(viewport: Viewport): TextEditFrame | null {\n const place = this.wordsPlace(viewport)\n if (!place) return null\n const { block, placeholder } = this.wordsBlock()\n const shown = placeholder ?? block\n const box = wordsBox(place, shown, this.style.fontSize, this.wordsAcross())\n const at = placeAt(place, box.left, box.top)\n return { x: at.x, y: at.y, width: box.width, lines: box.lines, lineHeight: this.style.fontSize, font: fontOf(this.style), align: place.align, wrapWidth: null, angle: place.angle }\n }\n\n /** The region the words cover, turned with them; null without words. */\n protected wordsRegion(viewport: Viewport): InvitationRegion | null {\n if (this.props.text === '' && !this.textDraft) return null\n const place = this.wordsPlace(viewport)\n if (!place) return null\n const { block, placeholder } = this.wordsBlock()\n const shown = this.textDraft && placeholder ? placeholder : block\n const lineHeight = this.style.fontSize\n const box = wordsBox(place, shown, lineHeight, this.wordsAcross())\n const middle = placeAt(place, box.left + box.width / 2, box.top + (box.lines * lineHeight) / 2)\n return { cx: middle.x, cy: middle.y, angle: place.angle, halfW: box.width / 2 + 2, halfH: (box.lines * lineHeight) / 2 + 2 }\n }\n\n override wordsAt(point: Point, viewport: Viewport): boolean {\n const region = this.wordsRegion(viewport)\n return !!region && inRegion(point, region)\n }\n\n /** The selected line without words invites them where they would stand. */\n override paintTextHint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n this.noteTextHint(null)\n if (this.state !== 'selected' || this.textEditing || this.props.text !== '' || !this.invites()) return\n const place = this.wordsPlace(viewport)\n if (!place) return\n this.noteTextHint(paintInvitation(ctx, this.textPlaceholder(), place, this.style, lineMeasure(this.style)))\n }\n\n /** Over its words or its invitation the selected line reads as words, and over a handle as the\n * handle it is. */\n protected override cursorAt(point: Point, viewport: Viewport): string | null {\n const handle = this.handleCursor(point, viewport)\n if (handle) return handle\n if (this.state === 'selected' && (this.wordsAt(point, viewport) || this.hitTextHint(point))) return 'text'\n return null\n }\n\n /** The cursor a handle under a point wears, or null where none is. */\n protected handleCursor(point: Point, viewport: Viewport): string | null {\n const near = this.getControlPoints(viewport).some((p) => Math.hypot(p.x - point.x, p.y - point.y) <= 6.5)\n return near ? this.handleCursorName() : null\n }\n\n protected handleCursorName(): string {\n return 'default'\n }\n\n /** The line's handles show in their thin form while the pointer rests on it. */\n override handlesOnHover(): boolean {\n return true\n }\n\n /** A press on the words or the invitation of the selected line lands on the line. */\n protected hitWords(point: Point, viewport: Viewport): boolean {\n if (this.wordsAt(point, viewport)) return true\n return this.state === 'selected' && this.hitTextHint(point)\n }\n}\n\n/** The look a selected line marks its points on the axes with: the accent's pill, white words. */\nconst pointLabel = (drawing: Drawing<Record<string, unknown>>, coordinate: () => number | null, text: () => string, shown: () => boolean): AxisLabel =>\n new AxisLabel({\n coordinate,\n text,\n color: () => drawing.inks().accent,\n textColor: () => '#ffffff',\n visible: shown,\n })\n\n/**\n * Two-anchor straight line. The whole family (trend line, ray, extended line, arrow, info line,\n * trend angle) is this geometry under different prop defaults and decorations.\n */\nexport class TrendLine extends LineWords<TrendLineProps> {\n readonly type: string = 'trend_line'\n\n private readonly _priceViews: readonly ISeriesPrimitiveAxisView[] = [0, 1].map((i) =>\n pointLabel(\n this as unknown as Drawing<Record<string, unknown>>,\n () => {\n const viewport = this.getViewport()\n const anchor = this.anchors[i]\n return viewport && anchor ? viewport.yOf(anchor.price) : null\n },\n () => this.formatPrice(this.anchors[i]?.price ?? 0),\n () => this.marksAxes() && !!this.anchors[i],\n ),\n )\n\n private readonly _timeViews: readonly ISeriesPrimitiveAxisView[] = [0, 1].map((i) =>\n pointLabel(\n this as unknown as Drawing<Record<string, unknown>>,\n () => {\n const viewport = this.getViewport()\n const anchor = this.anchors[i]\n return viewport && anchor ? viewport.xOf(anchor.time) : null\n },\n () => this.formatTime(this.anchors[i]?.time),\n () => this.marksAxes() && !!this.anchors[i],\n ),\n )\n\n protected override defaultProps(): TrendLineProps {\n return { ...LINE_PROPS }\n }\n\n override applyProps(patch: Partial<TrendLineProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The selected line marks its points' prices and times on the axes. */\n protected marksAxes(): boolean {\n return (this.state === 'selected' || this.state === 'editing') && this.isVisibleNow()\n }\n\n protected override axisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._priceViews\n }\n\n protected override timeViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._timeViews\n }\n\n protected override axisSpans(): { prices: readonly number[] | null; times: readonly Time[] | null } {\n return { prices: this.anchors.map((a) => a.price), times: this.anchors.map((a) => a.time) }\n }\n\n /** While its second point is being placed, the point following the pointer shows no handle. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const points = super.getControlPoints(viewport)\n return this.state === 'editing' ? points.filter((p) => p.index < this.anchors.length - 1) : points\n }\n\n /** The words ride the segment's slope at its middle or at the end they align to, above, on or\n * below it. */\n protected wordsPlace(viewport: Viewport): WordsPlace | null {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return null\n const angle = segmentTextAngle(pa, pb)\n // Left and right are the screen's: the end nearer the left edge is the left one, whichever\n // anchor it is.\n const [left, right] = pa.x <= pb.x ? [pa, pb] : [pb, pa]\n const along = this.props.textHAlign\n const at = along === 'left' ? left : along === 'right' ? right : midpoint(pa, pb)\n const across = this.props.textVAlign === 'top' ? -wordsOffset(this.style.fontSize) : this.props.textVAlign === 'bottom' ? wordsOffset(this.style.fontSize) : 0\n const p = placeAt({ x: at.x, y: at.y, angle, align: along }, 0, across)\n return { x: p.x, y: p.y, angle, align: along }\n }\n\n protected wordsAcross(): TextVAlign {\n return this.props.textVAlign\n }\n\n /** The on-screen segment after extension, the shared basis for painting and hit-testing. */\n protected segment(viewport: Viewport): { a: Point; b: Point } | null {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return null\n const { extendLeft, extendRight } = this.props\n if (!extendLeft && !extendRight) return { a: pa, b: pb }\n return extendSegment(pa, pb, viewport.width, viewport.height, extendLeft, extendRight)\n }\n\n /** A format-2 line showed its stats whether or not it was selected and counted no price moves; a\n * stats position counted its left and right from the first point, and a save naming none stood\n * them at the middle. Its ends, words and stats paint as format 2 painted them. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n const position = (saved.statsPosition ?? 'center') as StatsPosition\n const [a, b] = this._anchors\n const flipped = !!a && !!b && Number(b.time) < Number(a.time)\n const statsPosition: StatsPosition = flipped && position === 'left' ? 'right' : flipped && position === 'right' ? 'left' : position\n this._props = { ...this._props, statsPosition, alwaysShowStats: true, showPipsChange: false, savedLook: {} }\n }\n\n /** The stats stand while the line is selected or edited, or always where the viewer asked. */\n protected statsShown(): boolean {\n return this.props.alwaysShowStats || this.state !== 'normal'\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const seg = this.segment(viewport)\n if (!seg) return\n if (this.props.savedLook) {\n this.paintSavedLook(ctx, viewport, seg)\n return\n }\n // One path: an arrow end's open head, then the shaft from end to end.\n applyStroke(ctx, this.style)\n ctx.beginPath()\n if (this.props.rightEnd === 'arrow') openHead(ctx, seg.a, seg.b, this.style.lineWidth)\n if (this.props.leftEnd === 'arrow') openHead(ctx, seg.b, seg.a, this.style.lineWidth)\n ctx.moveTo(seg.a.x, seg.a.y)\n ctx.lineTo(seg.b.x, seg.b.y)\n ctx.stroke()\n this.paintMarks(ctx, viewport)\n this.paintWords(ctx, viewport)\n this.paintStats(ctx, viewport)\n this.paintDecorations(ctx, viewport)\n }\n\n /** The midpoint marker and the end price pills, as their props ask. */\n private paintMarks(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return\n if (this.props.middlePoint) {\n const mid = midpoint(pa, pb)\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.arc(mid.x, mid.y, Math.max(2.5, this.style.lineWidth), 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n }\n if (this.props.showPriceLabels) {\n const [a, b] = this.anchors\n paintLabel(ctx, this.formatPrice(a.price), { x: pa.x - 8, y: pa.y }, this.style, { align: 'right', background: withAlpha(this.style.lineColor, 0.2) })\n paintLabel(ctx, this.formatPrice(b.price), { x: pb.x + 8, y: pb.y }, this.style, { background: withAlpha(this.style.lineColor, 0.2) })\n }\n }\n\n /** The stats box: rows of the price move, the span and the angle, each led by its mark, standing\n * off the point along the line the stats position names, below and right of a line that rises\n * and above and right of one that falls. */\n private paintStats(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (!this.statsShown()) return\n const rows = this.statsRows(viewport)\n if (rows.length === 0) return\n const at = this.statsPoint(viewport)\n if (!at) return\n const type: DrawingStyle = { ...this.style, fontSize: STATS_FONT_SIZE, bold: false, italic: false }\n const sized = statsBoxAt({ x: 0, y: 0 }, rows, lineMeasure(type))\n const box = { ...sized, x: Math.round(at.point.x + 12), y: Math.round(at.rising ? at.point.y + 11 : at.point.y - 11 - sized.height) }\n paintStatsBox(ctx, box, rows, fontOf(type))\n }\n\n /** Where the stats stand along the line, and whether it rises left to right. */\n private statsPoint(viewport: Viewport): { point: Point; rising: boolean } | null {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return null\n const [left, right] = pa.x <= pb.x ? [pa, pb] : [pb, pa]\n const toRight = (f: number): Point => ({ x: left.x + (right.x - left.x) * f, y: left.y + (right.y - left.y) * f })\n const place = this.props.statsPosition\n const t = place === 'left' ? 0.12 : place === 'center' ? 0.5 : place === 'auto' && toRight(0.88).x > viewport.width * 0.85 ? 0.12 : 0.88\n return { point: toRight(t), rising: right.y <= left.y }\n }\n\n /** The stats rows: the price move with its percent and its count of the symbol's smallest moves;\n * the bars and the time it spans with its length on the pane; and its angle. A row whose items\n * are all off is left out. */\n protected statsRows(viewport: Viewport): StatsRow[] {\n const [a, b] = this.anchors\n if (!a || !b) return []\n const rows: StatsRow[] = []\n const dPrice = b.price - a.price\n const price: string[] = []\n if (this.props.showPriceRange) price.push(this.formatPrice(dPrice))\n if (this.props.showPercentChange) {\n const pct = (a.price !== 0 ? (dPrice / Math.abs(a.price)) * 100 : 0).toFixed(2)\n price.push(price.length ? `(${pct}%)` : `${pct}%`)\n }\n let priceRow = price.join(' ')\n // The count rides only on a host-stated move; without one the row omits it.\n const tick = this.tickSize()\n if (this.props.showPipsChange && tick !== null && tick > 0) {\n const moves = grouped(Math.round(dPrice / tick))\n priceRow = priceRow ? `${priceRow}, ${moves}` : moves\n }\n if (priceRow) rows.push({ kind: 'price', text: priceRow })\n const span: string[] = []\n if (this.props.showBarsRange) {\n const bars = viewport.barsBetween(a.time, b.time)\n if (bars !== null) span.push(`${Math.round(bars)} bars`)\n }\n if (this.props.showDateTimeRange) {\n const secs = Math.abs(Number(b.time) - Number(a.time))\n if (Number.isFinite(secs) && secs > 0) span.push(span.length ? `(${spanText(secs)})` : spanText(secs))\n }\n let spanRow = span.join(' ')\n const [pa, pb] = this.anchorPixels(viewport)\n if (this.props.showDistance && pa && pb) {\n const distance = `distance: ${Math.round(Math.hypot(pb.x - pa.x, pb.y - pa.y))} px`\n spanRow = spanRow ? `${spanRow}, ${distance}` : distance\n }\n if (spanRow) rows.push({ kind: 'span', text: spanRow })\n if (this.props.showAngle && pa && pb) rows.push({ kind: 'angle', text: `${((-angleOf(pa, pb) * 180) / Math.PI).toFixed(1)}°` })\n return rows\n }\n\n /** Extra ink beyond the shared prop set: the family variants override. */\n protected paintDecorations(_ctx: CanvasRenderingContext2D, _viewport: Viewport): void {}\n\n testHit(point: Point, viewport: Viewport): boolean {\n const seg = this.segment(viewport)\n if (!seg) return false\n return distanceToSegment(point, seg.a, seg.b) <= hitTolerance(this.style.lineWidth) || this.hitWords(point, viewport)\n }\n\n // ============ The format-2 look ============\n\n /** A format-2 line: filled arrow heads, its words on a label across it, and its stats on a pill. */\n private paintSavedLook(ctx: CanvasRenderingContext2D, viewport: Viewport, seg: { a: Point; b: Point }): void {\n applyStroke(ctx, this.style)\n strokeSegment(ctx, seg.a, seg.b)\n if (this.props.leftEnd === 'arrow') paintArrowHead(ctx, seg.b, seg.a, this.style)\n if (this.props.rightEnd === 'arrow') paintArrowHead(ctx, seg.a, seg.b, this.style)\n this.paintMarks(ctx, viewport)\n const [pa, pb] = this.anchorPixels(viewport)\n if (pa && pb) {\n const textAngle = segmentTextAngle(pa, pb)\n const [left, right] = pa.x <= pb.x ? [pa, pb] : [pb, pa]\n if (this.textDraft) this.paintWords(ctx, viewport)\n else if (this.props.text) {\n const along = this.props.textHAlign\n const at = along === 'left' ? left : along === 'right' ? right : midpoint(pa, pb)\n const across = ACROSS[this.props.textVAlign] ?? ACROSS.top\n ctx.save()\n ctx.translate(at.x, at.y)\n ctx.rotate(textAngle)\n paintLabel(ctx, this.props.text, { x: 0, y: across.y }, this.style, { align: along === 'left' ? 'left' : along === 'right' ? 'right' : 'center', baseline: across.baseline })\n ctx.restore()\n }\n const stats = this.statsShown() ? this.savedStatsText(viewport) : null\n if (stats) {\n const place = this.props.statsPosition\n const toRight = (f: number): Point => ({ x: left.x + (right.x - left.x) * f, y: left.y + (right.y - left.y) * f })\n const t = place === 'left' ? 0.12 : place === 'center' ? 0.5 : place === 'auto' && toRight(0.88).x > viewport.width * 0.85 ? 0.12 : 0.88\n const at = toRight(t)\n // The stats pill drops below its usual perch when a label already sits above the line\n // where it stands.\n const crowded = !!this.props.text && this.props.textVAlign === 'top' && ((place === 'center' && this.props.textHAlign === 'center') || (t === 0.12 && this.props.textHAlign === 'left') || (t === 0.88 && this.props.textHAlign === 'right'))\n ctx.save()\n ctx.translate(at.x, at.y)\n ctx.rotate(textAngle)\n paintLabel(ctx, stats, { x: 0, y: crowded ? -32 : -14 }, this.style, { align: 'center', background: withAlpha('#1b1f27', 0.92) })\n ctx.restore()\n }\n }\n this.paintDecorations(ctx, viewport)\n }\n\n /** A format-2 line's stats on one line: signed moves, the bars, the span and the angle. */\n private savedStatsText(viewport: Viewport): string | null {\n const [a, b] = this.anchors\n if (!a || !b) return null\n const parts: string[] = []\n const dPrice = b.price - a.price\n if (this.props.showPriceRange) parts.push(`${dPrice >= 0 ? '+' : ''}${this.formatPrice(dPrice)}`)\n if (this.props.showPercentChange) {\n const pct = a.price !== 0 ? (dPrice / Math.abs(a.price)) * 100 : 0\n parts.push(`${pct >= 0 ? '+' : ''}${pct.toFixed(2)}%`)\n }\n if (this.props.showPipsChange) {\n const tick = this.tickSize()\n if (tick !== null && tick > 0) {\n const moves = Math.round(dPrice / tick)\n parts.push(`${moves >= 0 ? '+' : ''}${moves}`)\n }\n }\n if (this.props.showBarsRange) {\n const bars = viewport.barsBetween(a.time, b.time)\n if (bars !== null) parts.push(`${Math.round(bars)} bars`)\n }\n if (this.props.showDateTimeRange) {\n const secs = Math.abs(Number(b.time) - Number(a.time))\n if (Number.isFinite(secs) && secs > 0) parts.push(spanText(secs))\n }\n if (this.props.showAngle) {\n const [pa, pb] = this.anchorPixels(viewport)\n if (pa && pb) parts.push(`${(-angleOf(pa, pb) * (180 / Math.PI)).toFixed(0)}°`)\n }\n return parts.length ? parts.join(' · ') : null\n }\n}\n\nexport class Ray extends TrendLine {\n override readonly type = 'ray'\n\n protected override defaultProps(): TrendLineProps {\n return { ...LINE_PROPS, extendRight: true }\n }\n}\n\nexport class ExtendedLine extends TrendLine {\n override readonly type = 'extended'\n\n protected override defaultProps(): TrendLineProps {\n return { ...LINE_PROPS, extendLeft: true, extendRight: true }\n }\n}\n\n/** A line with an open head at its second point. Selected, its whole body reads as its words. */\nexport class Arrow extends TrendLine {\n override readonly type = 'arrow'\n\n protected override defaultProps(): TrendLineProps {\n return { ...LINE_PROPS, rightEnd: 'arrow' }\n }\n\n protected override cursorAt(point: Point, viewport: Viewport): string | null {\n return super.cursorAt(point, viewport) ?? (this.state === 'selected' ? 'text' : null)\n }\n}\n\n/** Trend line whose identity is the full measurement readout. */\nexport class InfoLine extends TrendLine {\n override readonly type = 'info_line'\n\n protected override defaultProps(): TrendLineProps {\n return {\n ...LINE_PROPS,\n showPriceRange: true,\n showPercentChange: true,\n showPipsChange: true,\n showBarsRange: true,\n showDateTimeRange: true,\n showDistance: true,\n showAngle: true,\n statsPosition: 'center',\n alwaysShowStats: true,\n }\n }\n\n /** A format-2 info line that named no percent change or span showed neither, and no distance. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n super.keepSavedLook(saved)\n const props: Partial<TrendLineProps> = { showDistance: false }\n if (!('showPercentChange' in saved)) props.showPercentChange = false\n if (!('showDateTimeRange' in saved)) props.showDateTimeRange = false\n this._props = { ...this._props, ...props }\n }\n}\n\n/** Trend line that reports its slope: a dotted level 50px long from its first point, an arc of\n * radius 50 swept from the level to the line, and the angle to one place beyond the arc. Its pages\n * offer no ends and no label, since the angle is its reading; a save that carries them draws\n * them. */\nexport class TrendAngle extends TrendLine {\n override readonly type = 'trend_angle'\n\n protected override invites(): boolean {\n return false\n }\n\n protected override paintDecorations(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return\n if (this.props.savedLook) {\n this.paintSavedAngle(ctx, pa, pb)\n return\n }\n const angle = angleOf(pa, pb)\n ctx.save()\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.lineCap = 'butt'\n ctx.lineJoin = 'miter'\n ctx.setLineDash([1, 2])\n ctx.beginPath()\n ctx.moveTo(pa.x, pa.y)\n ctx.lineTo(pa.x + 50, pa.y)\n ctx.arc(pa.x, pa.y, 50, 0, angle, angle < 0)\n ctx.stroke()\n ctx.setLineDash([])\n ctx.font = fontOf(this.style)\n ctx.fillStyle = this.style.lineColor\n ctx.textAlign = 'start'\n ctx.textBaseline = 'middle'\n ctx.fillText(`${((-angle * 180) / Math.PI).toFixed(1)}°`, pa.x + 58.5, pa.y + 1)\n ctx.restore()\n }\n\n /** A format-2 trend angle's mark: a short dotted level and arc, the angle on a pill. */\n private paintSavedAngle(ctx: CanvasRenderingContext2D, pa: Point, pb: Point): void {\n const angle = angleOf(pa, pb)\n const angleDeg = -angle * (180 / Math.PI)\n const radius = Math.min(36, Math.hypot(pb.x - pa.x, pb.y - pa.y) / 2)\n if (radius > 8) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.lineWidth = 1\n ctx.setLineDash([2, 3])\n ctx.beginPath()\n ctx.moveTo(pa.x, pa.y)\n ctx.lineTo(pa.x + radius + 12, pa.y)\n ctx.stroke()\n ctx.beginPath()\n ctx.arc(pa.x, pa.y, radius, 0, angle, angle < 0)\n ctx.stroke()\n ctx.restore()\n }\n paintLabel(ctx, `${angleDeg.toFixed(0)}°`, { x: pa.x + radius + 18, y: pa.y }, this.style, { background: withAlpha('#1b1f27', 0.92) })\n }\n}\n\nexport type HorizontalLineProps = {\n /** The line's words. */\n text: string\n /** Price pill on the axis at the line's level. */\n showPrice: boolean\n /** Where the label stands across the line and along it. */\n textVAlign: TextVAlign\n textHAlign: TextHAlign\n}\n\n/** A level's own pill on an axis, in its line's color: shown while its prop asks, or while the\n * level is selected, then in the accent's pill. */\nconst levelLabel = (drawing: Drawing<Record<string, unknown>>, coordinate: () => number | null, text: () => string, own: () => boolean): AxisLabel => {\n const selected = (): boolean => drawing.state === 'selected' || drawing.state === 'editing'\n const color = (): string => (own() ? drawing.style.lineColor : drawing.inks().accent)\n return new AxisLabel({\n coordinate,\n text,\n color,\n textColor: () => inkOn(color()),\n visible: () => (own() || selected()) && drawing.isVisibleNow(),\n })\n}\n\n/** Full-width horizontal line at one price, its square handle nine tenths of the way across the\n * pane: dragging it sets the level and the time under it. */\nexport class HorizontalLine extends LineWords<HorizontalLineProps> {\n readonly type: string = 'horizontal_line'\n\n private readonly _axisViews: readonly ISeriesPrimitiveAxisView[] = [\n levelLabel(\n this as unknown as Drawing<Record<string, unknown>>,\n () => {\n const anchor = this.anchors[0]\n const viewport = this.getViewport()\n return anchor && viewport ? viewport.yOf(anchor.price) : null\n },\n () => this.formatPrice(this.anchors[0]?.price ?? 0),\n () => this.props.showPrice,\n ),\n ]\n\n protected override defaultProps(): HorizontalLineProps {\n return { text: '', showPrice: true, textVAlign: 'middle', textHAlign: 'center' }\n }\n\n protected override axisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._axisViews\n }\n\n protected override axisSpans(): { prices: readonly number[] | null; times: readonly Time[] | null } {\n return { prices: this.anchors.slice(0, 1).map((a) => a.price), times: null }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n override handleShape(): 'square' | 'circle' {\n return 'square'\n }\n\n protected override handleCursorName(): string {\n return 'ns-resize'\n }\n\n /** The square handle stands nine tenths of the way across the pane at the level. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const y = this.levelY(viewport)\n return y === null ? [] : [{ index: 0, x: viewport.width * LEVEL_HANDLE_AT, y }]\n }\n\n /** The level's height on the pane, or null off the scale. */\n protected levelY(viewport: Viewport): number | null {\n const y = viewport.yOf(this.anchors[0]?.price ?? NaN)\n return y === null || !Number.isFinite(y) ? null : y\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const level = this.levelY(viewport)\n if (level === null) return\n const y = crisp(level, this.style.lineWidth)\n applyStroke(ctx, this.style)\n ctx.lineCap = this.levelCap()\n ctx.lineJoin = 'miter'\n strokeSegment(ctx, { x: this.leftEdge(viewport), y }, { x: viewport.width, y })\n this.paintWords(ctx, viewport)\n }\n\n /** The cap the line's ends wear: square across the pane's edges, round at a ray's point. */\n protected levelCap(): CanvasLineCap {\n return 'butt'\n }\n\n /** The words stand above, on or below the drawn line, in from its left end, at its middle, or in\n * from the pane's right edge. */\n protected wordsPlace(viewport: Viewport): WordsPlace | null {\n const level = this.levelY(viewport)\n if (level === null) return null\n const y = crisp(level, this.style.lineWidth)\n const start = this.leftEdge(viewport)\n const along = this.props.textHAlign\n const x = along === 'left' ? start + LEVEL_WORDS_INSET : along === 'right' ? viewport.width - LEVEL_WORDS_INSET : (start + viewport.width) / 2\n const across = this.props.textVAlign === 'top' ? -wordsOffset(this.style.fontSize) : this.props.textVAlign === 'bottom' ? wordsOffset(this.style.fontSize) : 0\n return { x, y: y + across, angle: 0, align: along }\n }\n\n protected wordsAcross(): TextVAlign {\n return this.props.textVAlign\n }\n\n /** Where the line starts; the ray variant starts at its anchor. */\n protected leftEdge(_viewport: Viewport): number {\n return 0\n }\n\n /** A format-2 line's label stood above its left side. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, textVAlign: 'top', textHAlign: 'left' }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const y = this.levelY(viewport)\n if (y === null) return false\n const onLine = point.x >= this.leftEdge(viewport) - 4 && Math.abs(point.y - y) <= hitTolerance(this.style.lineWidth)\n return onLine || this.hitWords(point, viewport)\n }\n}\n\n/** Horizontal line from its anchor rightward, its round handle on its point. A selected ray\n * invites no words: they are typed in its settings. */\nexport class HorizontalRay extends HorizontalLine {\n override readonly type = 'horizontal_ray'\n\n private readonly _rayTimeViews: readonly ISeriesPrimitiveAxisView[] = [\n pointLabel(\n this as unknown as Drawing<Record<string, unknown>>,\n () => {\n const anchor = this.anchors[0]\n const viewport = this.getViewport()\n return anchor && viewport ? viewport.xOf(anchor.time) : null\n },\n () => this.formatTime(this.anchors[0]?.time),\n () => (this.state === 'selected' || this.state === 'editing') && this.isVisibleNow(),\n ),\n ]\n\n protected override defaultProps(): HorizontalLineProps {\n return { text: '', showPrice: true, textVAlign: 'bottom', textHAlign: 'center' }\n }\n\n protected override timeViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._rayTimeViews\n }\n\n protected override axisSpans(): { prices: readonly number[] | null; times: readonly Time[] | null } {\n const anchor = this.anchors[0]\n return { prices: anchor ? [anchor.price] : null, times: anchor ? [anchor.time] : null }\n }\n\n override handleShape(): 'square' | 'circle' {\n return 'circle'\n }\n\n protected override handleCursorName(): string {\n return 'default'\n }\n\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const anchor = this.anchors[0]\n const p = anchor ? this.anchorToPixel(anchor, viewport) : null\n return p ? [{ index: 0, x: p.x, y: p.y }] : []\n }\n\n protected override invites(): boolean {\n return false\n }\n\n protected override levelCap(): CanvasLineCap {\n return 'round'\n }\n\n protected override leftEdge(viewport: Viewport): number {\n const anchor = this.anchors[0]\n if (!anchor) return 0\n const p = this.anchorToPixel(anchor, viewport)\n return p ? p.x : 0\n }\n}\n\nexport type VerticalLineProps = {\n /** The line's words. */\n text: string\n /** Timestamp pill on the time axis. */\n showTime: boolean\n /** Where the label stands along the line (top, middle, bottom of the pane) and across it (to its\n * left, on it, to its right). */\n textVAlign: TextVAlign\n textHAlign: TextHAlign\n /** Whether the label reads across the line or runs up it. */\n textOrientation: 'horizontal' | 'vertical'\n}\n\n/** Full-height vertical line at one time, its square handle nine tenths of the way down the pane:\n * dragging it sets the time and the price under it. */\nexport class VerticalLine extends LineWords<VerticalLineProps> {\n readonly type = 'vertical_line'\n\n private readonly _timeViews: readonly ISeriesPrimitiveAxisView[] = [\n levelLabel(\n this as unknown as Drawing<Record<string, unknown>>,\n () => {\n const anchor = this.anchors[0]\n const viewport = this.getViewport()\n return anchor && viewport ? viewport.xOf(anchor.time) : null\n },\n () => this.formatTime(this.anchors[0]?.time),\n () => this.props.showTime,\n ),\n ]\n\n protected override defaultProps(): VerticalLineProps {\n return { text: '', showTime: true, textVAlign: 'middle', textHAlign: 'center', textOrientation: 'vertical' }\n }\n\n protected override timeViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._timeViews\n }\n\n protected override axisSpans(): { prices: readonly number[] | null; times: readonly Time[] | null } {\n return { prices: null, times: this.anchors.slice(0, 1).map((a) => a.time) }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n override handleShape(): 'square' | 'circle' {\n return 'square'\n }\n\n protected override handleCursorName(): string {\n return 'ew-resize'\n }\n\n /** The square handle stands on the line nine tenths of the way down the pane. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const x = this.timeX(viewport)\n return x === null ? [] : [{ index: 0, x, y: viewport.height * LEVEL_HANDLE_AT }]\n }\n\n private timeX(viewport: Viewport): number | null {\n const anchor = this.anchors[0]\n return anchor ? viewport.xOf(anchor.time) : null\n }\n\n /** A format-2 line's label read across it, to its right at the top of the pane. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, textOrientation: 'horizontal', textVAlign: 'top', textHAlign: 'right' }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const time = this.timeX(viewport)\n if (time === null) return\n const x = crisp(time, this.style.lineWidth)\n applyStroke(ctx, this.style)\n ctx.lineCap = 'butt'\n ctx.lineJoin = 'miter'\n strokeSegment(ctx, { x, y: 0 }, { x, y: viewport.height })\n this.paintWords(ctx, viewport)\n }\n\n /** The words stand at the top, the middle or the bottom of the pane, to the line's left, on it or\n * to its right. Running up the line they turn a quarter left, so the line's top is where they\n * end; reading across it they stand level. */\n protected wordsPlace(viewport: Viewport): WordsPlace | null {\n const time = this.timeX(viewport)\n if (time === null) return null\n const x = crisp(time, this.style.lineWidth)\n const { textVAlign: along, textHAlign: across, textOrientation } = this.props\n const off = wordsOffset(this.style.fontSize)\n if (textOrientation === 'horizontal') {\n const y = along === 'top' ? off : along === 'bottom' ? viewport.height - off : viewport.height / 2\n const at = across === 'left' ? x - 4 : across === 'right' ? x + 4 : x\n return { x: at, y, angle: 0, align: across === 'left' ? 'right' : across === 'right' ? 'left' : 'center' }\n }\n const y = along === 'top' ? LEVEL_WORDS_INSET : along === 'bottom' ? viewport.height - LEVEL_WORDS_INSET : viewport.height / 2\n const at = across === 'left' ? x - off : across === 'right' ? x + off : x\n return { x: at, y, angle: -Math.PI / 2, align: along === 'top' ? 'right' : along === 'bottom' ? 'left' : 'center' }\n }\n\n protected wordsAcross(): TextVAlign {\n if (this.props.textOrientation === 'horizontal') return this.props.textVAlign === 'top' ? 'bottom' : this.props.textVAlign === 'bottom' ? 'top' : 'middle'\n return this.props.textHAlign === 'left' ? 'top' : this.props.textHAlign === 'right' ? 'bottom' : 'middle'\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const time = this.timeX(viewport)\n if (time === null) return false\n return Math.abs(point.x - time) <= hitTolerance(this.style.lineWidth) || this.hitWords(point, viewport)\n }\n}\n\nexport type CrossLineProps = {\n /** Price pill on the axis at the cross's level. */\n showPrice: boolean\n /** Timestamp pill on the time axis at the cross's time. */\n showTime: boolean\n}\n\n/** Crosshair pinned to one point: a horizontal and a vertical line through the anchor, its round\n * handle on the crossing. */\nexport class CrossLine extends Drawing<CrossLineProps> {\n readonly type = 'cross_line'\n\n private readonly _axisViews: readonly ISeriesPrimitiveAxisView[] = [\n levelLabel(\n this as unknown as Drawing<Record<string, unknown>>,\n () => {\n const anchor = this.anchors[0]\n const viewport = this.getViewport()\n return anchor && viewport ? viewport.yOf(anchor.price) : null\n },\n () => this.formatPrice(this.anchors[0]?.price ?? 0),\n () => this.props.showPrice,\n ),\n ]\n\n private readonly _timeViews: readonly ISeriesPrimitiveAxisView[] = [\n levelLabel(\n this as unknown as Drawing<Record<string, unknown>>,\n () => {\n const anchor = this.anchors[0]\n const viewport = this.getViewport()\n return anchor && viewport ? viewport.xOf(anchor.time) : null\n },\n () => this.formatTime(this.anchors[0]?.time),\n () => this.props.showTime,\n ),\n ]\n\n protected override defaultProps(): CrossLineProps {\n return { showPrice: true, showTime: true }\n }\n\n protected override axisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._axisViews\n }\n\n protected override timeViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._timeViews\n }\n\n protected override axisSpans(): { prices: readonly number[] | null; times: readonly Time[] | null } {\n const anchor = this.anchors[0]\n return { prices: anchor ? [anchor.price] : null, times: anchor ? [anchor.time] : null }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n override handlesOnHover(): boolean {\n return true\n }\n\n protected override cursorAt(point: Point, viewport: Viewport): string | null {\n return this.getControlPoints(viewport).some((p) => Math.hypot(p.x - point.x, p.y - point.y) <= 6.5) ? 'default' : null\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n const width = this.style.lineWidth\n applyStroke(ctx, this.style)\n ctx.lineCap = 'butt'\n ctx.lineJoin = 'miter'\n strokeSegment(ctx, { x: 0, y: crisp(p.y, width) }, { x: viewport.width, y: crisp(p.y, width) })\n strokeSegment(ctx, { x: crisp(p.x, width), y: 0 }, { x: crisp(p.x, width), y: viewport.height })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const anchor = this.anchors[0]\n if (!anchor) return false\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n return Math.abs(point.y - p.y) <= tolerance || Math.abs(point.x - p.x) <= tolerance\n }\n}\n","import type { ControlPoint, LineStyle, Point, Viewport } from '../core/types'\nimport { Drawing, type AnyDrawing } from '../core/drawing'\nimport { distanceToSegment, extendSegment } from '../core/geometry'\nimport { applyStroke, fillPaint, paintArrowHead, paintLabel } from '../render/canvas'\nimport type { LineEnd, TextHAlign, TextVAlign } from './lines'\n\n/** A shape's background shows while it is switched on and its fill has any opacity. Switching it\n * off keeps the color and the opacity, so switching it back on returns the same fill. */\nexport type BackgroundProps = {\n fillBackground: boolean\n}\n\n/** The fill a shape paints, or null while its background is off. */\nfunction backgroundOf(drawing: AnyDrawing): string | null {\n return drawing.props.fillBackground === false ? null : fillPaint(drawing.style)\n}\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\nfunction pointInPolygon(p: Point, polygon: readonly Point[]): boolean {\n let inside = false\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const a = polygon[i]\n const b = polygon[j]\n if (a.y > p.y !== b.y > p.y && p.x < ((b.x - a.x) * (p.y - a.y)) / (b.y - a.y) + a.x) {\n inside = !inside\n }\n }\n return inside\n}\n\nfunction nearPolygonEdge(p: Point, polygon: readonly Point[], tolerance: number, close: boolean): boolean {\n const last = close ? polygon.length : polygon.length - 1\n for (let i = 0; i < last; i++) {\n if (distanceToSegment(p, polygon[i], polygon[(i + 1) % polygon.length]) <= tolerance) return true\n }\n return false\n}\n\n/** Stroke + optional fill for a closed polygon in one pass. */\nfunction paintPolygon(\n ctx: CanvasRenderingContext2D,\n polygon: readonly Point[],\n drawing: AnyDrawing,\n): void {\n if (polygon.length < 2) return\n applyStroke(ctx, drawing.style)\n ctx.beginPath()\n ctx.moveTo(polygon[0].x, polygon[0].y)\n for (let i = 1; i < polygon.length; i++) ctx.lineTo(polygon[i].x, polygon[i].y)\n ctx.closePath()\n const fill = backgroundOf(drawing)\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n ctx.stroke()\n}\n\nexport type RectangleProps = BackgroundProps & {\n /** Free label the box carries. */\n text: string\n /** A horizontal line across the box at its middle, in its own color, width and style. */\n middleLine: boolean\n middleLineColor: string\n middleLineWidth: number\n middleLineStyle: LineStyle\n extendLeft: boolean\n extendRight: boolean\n /** Where the label stands: above the box, inside it or below it, and along it. */\n textVAlign: TextVAlign\n textHAlign: TextHAlign\n}\n\n/** Axis-aligned rectangle spanned by two corner anchors. */\nexport class Rectangle extends Drawing<RectangleProps> {\n readonly type = 'rectangle'\n\n protected override defaultProps(): RectangleProps {\n return {\n text: '',\n fillBackground: true,\n middleLine: false,\n middleLineColor: '#9c27b0',\n middleLineWidth: 1,\n middleLineStyle: 'dashed',\n extendLeft: false,\n extendRight: false,\n textVAlign: 'middle',\n textHAlign: 'center',\n }\n }\n\n /** A format-2 rectangle drew its middle line dashed in its own stroke's color and thickness. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, middleLineColor: this._style.lineColor, middleLineWidth: this._style.lineWidth, middleLineStyle: 'dashed' }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The hint sits level at the box center — exactly where the text itself renders. */\n protected override textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n return {\n x: points.reduce((sum, p) => sum + p.x, 0) / points.length,\n y: points.reduce((sum, p) => sum + p.y, 0) / points.length,\n angle: 0,\n }\n }\n\n protected corners(viewport: Viewport): Point[] | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n // Extension stretches the box horizontally to the pane edge(s).\n const left = this.props.extendLeft ? 0 : Math.min(a.x, b.x)\n const right = this.props.extendRight ? viewport.width : Math.max(a.x, b.x)\n return [\n { x: left, y: a.y },\n { x: right, y: a.y },\n { x: right, y: b.y },\n { x: left, y: b.y },\n ]\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const corners = this.corners(viewport)\n if (!corners) return\n paintPolygon(ctx, corners, this)\n if (this.props.middleLine) {\n const midY = (corners[0].y + corners[2].y) / 2\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: this.props.middleLineColor, lineWidth: this.props.middleLineWidth, lineStyle: this.props.middleLineStyle })\n ctx.beginPath()\n ctx.moveTo(corners[0].x, midY)\n ctx.lineTo(corners[1].x, midY)\n ctx.stroke()\n ctx.restore()\n }\n if (this.props.text) {\n const top = Math.min(corners[0].y, corners[2].y)\n const bottom = Math.max(corners[0].y, corners[2].y)\n const left = Math.min(corners[0].x, corners[1].x)\n const right = Math.max(corners[0].x, corners[1].x)\n const along = this.props.textHAlign\n const place = this.props.textVAlign\n const x = along === 'left' ? left + 4 : along === 'right' ? right - 4 : (left + right) / 2\n const y = place === 'top' ? top - 4 : place === 'bottom' ? bottom + 4 : (top + bottom) / 2\n paintLabel(ctx, this.props.text, { x, y }, this.style, {\n align: along === 'left' ? 'left' : along === 'right' ? 'right' : 'center',\n baseline: place === 'top' ? 'bottom' : place === 'bottom' ? 'top' : 'middle',\n })\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const corners = this.corners(viewport)\n if (!corners) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (nearPolygonEdge(point, corners, tolerance, true)) return true\n return backgroundOf(this) !== null && pointInPolygon(point, corners)\n }\n}\n\n/**\n * Rectangle at an arbitrary angle: anchors 1–2 span one edge, anchor 3 sets the extrusion —\n * the rectangle extends perpendicular from the base edge through the third point.\n */\nexport class RotatedRectangle extends Drawing<BackgroundProps> {\n readonly type = 'rotated_rectangle'\n\n protected override defaultProps(): BackgroundProps {\n return { fillBackground: true }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected corners(viewport: Viewport): Point[] | null {\n const [a, b, c] = this.anchorPixels(viewport)\n if (!a || !b || !c) return null\n const dx = b.x - a.x\n const dy = b.y - a.y\n const lengthSq = dx * dx + dy * dy\n if (lengthSq === 0) return null\n // Perpendicular offset of c from the a→b edge, projected onto the unit normal.\n const t = ((c.x - a.x) * -dy + (c.y - a.y) * dx) / lengthSq\n const nx = -dy * t\n const ny = dx * t\n return [a, b, { x: b.x + nx, y: b.y + ny }, { x: a.x + nx, y: a.y + ny }]\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const corners = this.corners(viewport)\n if (corners) paintPolygon(ctx, corners, this)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const corners = this.corners(viewport)\n if (!corners) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (nearPolygonEdge(point, corners, tolerance, true)) return true\n return backgroundOf(this) !== null && pointInPolygon(point, corners)\n }\n}\n\n/** Three-corner polygon. */\nexport class Triangle extends Drawing<BackgroundProps> {\n readonly type = 'triangle'\n\n protected override defaultProps(): BackgroundProps {\n return { fillBackground: true }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.anchorPixels(viewport).filter((p): p is Point => !!p)\n if (points.length === 3) paintPolygon(ctx, points, this)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const points = this.anchorPixels(viewport).filter((p): p is Point => !!p)\n if (points.length < 3) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (nearPolygonEdge(point, points, tolerance, true)) return true\n return backgroundOf(this) !== null && pointInPolygon(point, points)\n }\n}\n\n/** The free label a round shape carries, centered in it, and its background switch. */\nexport type RoundShapeProps = BackgroundProps & {\n text: string\n}\n\n/** Circle from a center anchor and a radius anchor. */\nexport class Circle extends Drawing<RoundShapeProps> {\n readonly type = 'circle'\n\n protected override defaultProps(): RoundShapeProps {\n return { text: '', fillBackground: true }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The hint sits at the center anchor, which is where the text itself renders. */\n protected override textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n const center = points[0]\n return center ? { x: center.x, y: center.y, angle: 0 } : super.textHintPlacement(points)\n }\n\n protected geometry(viewport: Viewport): { center: Point; radius: number } | null {\n const [center, rim] = this.anchorPixels(viewport)\n if (!center || !rim) return null\n return { center, radius: Math.hypot(rim.x - center.x, rim.y - center.y) }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const geo = this.geometry(viewport)\n if (!geo) return\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.arc(geo.center.x, geo.center.y, geo.radius, 0, Math.PI * 2)\n const fill = backgroundOf(this)\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n ctx.stroke()\n if (this.props.text) paintLabel(ctx, this.props.text, geo.center, this.style, { align: 'center' })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const geo = this.geometry(viewport)\n if (!geo) return false\n const distance = Math.hypot(point.x - geo.center.x, point.y - geo.center.y)\n if (Math.abs(distance - geo.radius) <= hitTolerance(this.style.lineWidth)) return true\n return backgroundOf(this) !== null && distance < geo.radius\n }\n}\n\n/**\n * Axis-aligned ellipse: anchors 1–2 span the horizontal diameter, anchor 3 drags the vertical\n * radius from the diameter's midline.\n */\nexport class Ellipse extends Drawing<RoundShapeProps> {\n readonly type = 'ellipse'\n\n protected override defaultProps(): RoundShapeProps {\n return { text: '', fillBackground: true }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n /** The hint sits on the diameter's midpoint, which is where the text itself renders. */\n protected override textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n const [a, b] = points\n return a && b ? { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2, angle: 0 } : super.textHintPlacement(points)\n }\n\n protected geometry(viewport: Viewport): { center: Point; rx: number; ry: number } | null {\n const [a, b, c] = this.anchorPixels(viewport)\n if (!a || !b || !c) return null\n const center = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 }\n const rx = Math.abs(b.x - a.x) / 2\n const ry = Math.abs(c.y - center.y)\n if (rx === 0 || ry === 0) return null\n return { center, rx, ry }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const geo = this.geometry(viewport)\n if (!geo) return\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.ellipse(geo.center.x, geo.center.y, geo.rx, geo.ry, 0, 0, Math.PI * 2)\n const fill = backgroundOf(this)\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n ctx.stroke()\n if (this.props.text) paintLabel(ctx, this.props.text, geo.center, this.style, { align: 'center' })\n }\n\n /** The third handle stands on the ellipse at its centre's time, where the vertical radius it\n * drags meets the outline: the anchor's own time paints nothing, so a handle at it would stay\n * behind as the diameter moves. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const points = super.getControlPoints(viewport)\n const geo = this.geometry(viewport)\n return geo ? points.map((point) => (point.index === 2 ? { ...point, x: geo.center.x } : point)) : points\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const geo = this.geometry(viewport)\n if (!geo) return false\n // Normalized radial distance: 1 = on the ellipse. Tolerance scales by the smaller radius.\n const nx = (point.x - geo.center.x) / geo.rx\n const ny = (point.y - geo.center.y) / geo.ry\n const radial = Math.sqrt(nx * nx + ny * ny)\n const tolerance = hitTolerance(this.style.lineWidth) / Math.min(geo.rx, geo.ry)\n if (Math.abs(radial - 1) <= tolerance) return true\n return backgroundOf(this) !== null && radial < 1\n }\n}\n\n/** Sampled quadratic/cubic Bézier shared by the curved tools. */\nfunction sampleBezier(controls: readonly Point[], samples = 32): Point[] {\n const out: Point[] = []\n for (let i = 0; i <= samples; i++) {\n const t = i / samples\n if (controls.length === 3) {\n const [p0, p1, p2] = controls\n const u = 1 - t\n out.push({\n x: u * u * p0.x + 2 * u * t * p1.x + t * t * p2.x,\n y: u * u * p0.y + 2 * u * t * p1.y + t * t * p2.y,\n })\n } else {\n const [p0, p1, p2, p3] = controls\n const u = 1 - t\n out.push({\n x: u ** 3 * p0.x + 3 * u * u * t * p1.x + 3 * u * t * t * p2.x + t ** 3 * p3.x,\n y: u ** 3 * p0.y + 3 * u * u * t * p1.y + 3 * u * t * t * p2.y + t ** 3 * p3.y,\n })\n }\n }\n return out\n}\n\nfunction paintSampled(ctx: CanvasRenderingContext2D, drawing: AnyDrawing, samples: Point[]): void {\n if (samples.length < 2) return\n // The background channel fills the area the curve closes over (chord back to the start).\n const fill = backgroundOf(drawing)\n if (fill) {\n ctx.save()\n ctx.fillStyle = fill\n ctx.beginPath()\n ctx.moveTo(samples[0].x, samples[0].y)\n for (let i = 1; i < samples.length; i++) ctx.lineTo(samples[i].x, samples[i].y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n applyStroke(ctx, drawing.style)\n ctx.beginPath()\n ctx.moveTo(samples[0].x, samples[0].y)\n for (let i = 1; i < samples.length; i++) ctx.lineTo(samples[i].x, samples[i].y)\n ctx.stroke()\n}\n\n/** A curve's options: its background, and the ends and extensions of an open curve. */\nexport type CurveProps = BackgroundProps & {\n extendLeft: boolean\n extendRight: boolean\n leftEnd: LineEnd\n rightEnd: LineEnd\n}\n\nconst CURVE_PROPS: CurveProps = { fillBackground: false, extendLeft: false, extendRight: false, leftEnd: 'normal', rightEnd: 'normal' }\n\n/** A format-2 curve filled its body wherever its fill showed. */\nfunction curveSavedLook(drawing: Curve | DoubleCurve): Partial<CurveProps> {\n return { fillBackground: drawing.style.fillOpacity > 0 }\n}\n\n/** The straight runs an open curve extends by: from its first point back along the tangent it\n * starts on, and from its last point on along the tangent it ends on, each to the pane's edge. */\nfunction curveExtensions(samples: Point[], viewport: Viewport, props: CurveProps): { a: Point; b: Point }[] {\n const out: { a: Point; b: Point }[] = []\n const n = samples.length\n if (n < 2) return out\n if (props.extendLeft) {\n const run = extendSegment(samples[0], samples[1], viewport.width, viewport.height, true, false)\n if (run) out.push({ a: run.a, b: samples[0] })\n }\n if (props.extendRight) {\n const run = extendSegment(samples[n - 2], samples[n - 1], viewport.width, viewport.height, false, true)\n if (run) out.push({ a: samples[n - 1], b: run.b })\n }\n return out\n}\n\n/** An open curve: its sampled path, its extensions, and an arrow at either end that asks for one. */\nfunction paintOpenCurve(ctx: CanvasRenderingContext2D, drawing: AnyDrawing, samples: Point[], viewport: Viewport, props: CurveProps): void {\n paintSampled(ctx, drawing, samples)\n const runs = curveExtensions(samples, viewport, props)\n if (runs.length) {\n applyStroke(ctx, drawing.style)\n ctx.beginPath()\n for (const run of runs) {\n ctx.moveTo(run.a.x, run.a.y)\n ctx.lineTo(run.b.x, run.b.y)\n }\n ctx.stroke()\n }\n const n = samples.length\n if (n < 2) return\n if (props.leftEnd === 'arrow') paintArrowHead(ctx, samples[1], samples[0], drawing.style)\n if (props.rightEnd === 'arrow') paintArrowHead(ctx, samples[n - 2], samples[n - 1], drawing.style)\n}\n\nfunction hitSampled(point: Point, samples: Point[], tolerance: number): boolean {\n for (let i = 0; i < samples.length - 1; i++) {\n if (distanceToSegment(point, samples[i], samples[i + 1]) <= tolerance) return true\n }\n return false\n}\n\n/**\n * Bend line: anchors 1–2 are the ends, anchor 3 is the bend — the curve passes THROUGH it\n * (the Bézier control is derived so the midpoint lands on the bend anchor).\n */\nexport class Curve extends Drawing<CurveProps> {\n readonly type = 'curve'\n\n protected override defaultProps(): CurveProps {\n return { ...CURVE_PROPS }\n }\n\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, ...curveSavedLook(this) }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const [a, b, bend] = this.anchorPixels(viewport)\n if (!a || !b || !bend) return null\n const control = { x: 2 * bend.x - (a.x + b.x) / 2, y: 2 * bend.y - (a.y + b.y) / 2 }\n return sampleBezier([a, control, b])\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const samples = this.samples(viewport)\n if (samples) paintOpenCurve(ctx, this, samples, viewport, this.props)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const samples = this.samples(viewport)\n if (!samples) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n return hitSampled(point, samples, tolerance) || curveExtensions(samples, viewport, this.props).some((run) => distanceToSegment(point, run.a, run.b) <= tolerance)\n }\n}\n\n/** S-curve: ends at anchors 1–2, shaped through the two bend anchors 3–4. */\nexport class DoubleCurve extends Drawing<CurveProps> {\n readonly type = 'double_curve'\n\n protected override defaultProps(): CurveProps {\n return { ...CURVE_PROPS }\n }\n\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, ...curveSavedLook(this) }\n }\n\n requiredAnchors(): number {\n return 4\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const [a, b, bend1, bend2] = this.anchorPixels(viewport)\n if (!a || !b || !bend1 || !bend2) return null\n // Cubic through both bends at t=1/3 and t=2/3 (standard interpolation → control points).\n const c1 = {\n x: (-5 * a.x + 18 * bend1.x - 9 * bend2.x + 2 * b.x) / 6,\n y: (-5 * a.y + 18 * bend1.y - 9 * bend2.y + 2 * b.y) / 6,\n }\n const c2 = {\n x: (2 * a.x - 9 * bend1.x + 18 * bend2.x - 5 * b.x) / 6,\n y: (2 * a.y - 9 * bend1.y + 18 * bend2.y - 5 * b.y) / 6,\n }\n return sampleBezier([a, c1, c2, b], 48)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const samples = this.samples(viewport)\n if (samples) paintOpenCurve(ctx, this, samples, viewport, this.props)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const samples = this.samples(viewport)\n if (!samples) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n return hitSampled(point, samples, tolerance) || curveExtensions(samples, viewport, this.props).some((run) => distanceToSegment(point, run.a, run.b) <= tolerance)\n }\n}\n\n/** Circular arc through a chord (anchors 1–2) bent to pass through anchor 3. */\nexport class Arc extends Drawing<BackgroundProps> {\n readonly type = 'arc'\n\n protected override defaultProps(): BackgroundProps {\n return { fillBackground: true }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const [a, b, bend] = this.anchorPixels(viewport)\n if (!a || !b || !bend) return null\n const control = { x: 2 * bend.x - (a.x + b.x) / 2, y: 2 * bend.y - (a.y + b.y) / 2 }\n return sampleBezier([a, control, b])\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const samples = this.samples(viewport)\n if (samples) paintSampled(ctx, this, samples)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const samples = this.samples(viewport)\n return !!samples && hitSampled(point, samples, hitTolerance(this.style.lineWidth))\n }\n}\n","import type { Time } from 'lightweight-charts'\n\n/** One chart bar as the data-driven tools consume it (volume present when the host has it). */\nexport interface SourceBar {\n time: Time\n open: number\n high: number\n low: number\n close: number\n volume?: number\n}\n\n/** Host-injected bar feed. Called at paint time; implementations should be cheap/memoized. */\nexport type BarSource = () => readonly SourceBar[]\n\n/** Bars whose time falls inside [from, to] (inclusive, either anchor order). */\nexport function barsInRange(bars: readonly SourceBar[], a: Time, b: Time): SourceBar[] {\n const from = Math.min(Number(a), Number(b))\n const to = Math.max(Number(a), Number(b))\n if (!Number.isFinite(from) || !Number.isFinite(to)) return []\n return bars.filter((bar) => {\n const t = Number(bar.time)\n return t >= from && t <= to\n })\n}\n\n/** The bar at a time, or null where the feed has none. The feed runs in time order. */\nexport function barAt(bars: readonly SourceBar[], time: Time): SourceBar | null {\n const t = Number(time)\n if (!Number.isFinite(t)) return null\n let lo = 0\n let hi = bars.length - 1\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n const at = Number(bars[mid]!.time)\n if (at === t) return bars[mid]!\n if (at < t) lo = mid + 1\n else hi = mid - 1\n }\n return null\n}\n\n/** The values of a bar a data-driven tool can compute over: its open, high, low or close, its\n * volume, or an average of its prices: `hl2` (H + L)/2, `hlc3` (H + L + C)/3, `ohlc4`\n * (O + H + L + C)/4 and `hlcc4` (H + L + C + C)/4. */\nexport type BarPriceSource = 'open' | 'high' | 'low' | 'close' | 'volume' | 'hl2' | 'hlc3' | 'ohlc4' | 'hlcc4'\n\n/** Every source, in the order a source list offers them. */\nexport const BAR_PRICE_SOURCES: readonly BarPriceSource[] = ['open', 'high', 'low', 'close', 'volume', 'hl2', 'hlc3', 'ohlc4', 'hlcc4']\n\nexport function barPrice(bar: SourceBar, source: BarPriceSource): number {\n switch (source) {\n case 'open':\n return bar.open\n case 'high':\n return bar.high\n case 'low':\n return bar.low\n case 'volume':\n return bar.volume ?? 0\n case 'hl2':\n return (bar.high + bar.low) / 2\n case 'hlc3':\n return (bar.high + bar.low + bar.close) / 3\n case 'ohlc4':\n return (bar.open + bar.high + bar.low + bar.close) / 4\n case 'hlcc4':\n return (bar.high + bar.low + bar.close * 2) / 4\n default:\n return bar.close\n }\n}\n\n/** Least-squares line over the bars' chosen price source, plus the residual σ. */\nexport function linearRegression(\n bars: readonly SourceBar[],\n source: BarPriceSource = 'close',\n): { slope: number; intercept: number; sigma: number } | null {\n const n = bars.length\n if (n < 2) return null\n let sumX = 0\n let sumY = 0\n let sumXY = 0\n let sumXX = 0\n for (let i = 0; i < n; i++) {\n const y = barPrice(bars[i], source)\n sumX += i\n sumY += y\n sumXY += i * y\n sumXX += i * i\n }\n const denominator = n * sumXX - sumX * sumX\n if (denominator === 0) return null\n const slope = (n * sumXY - sumX * sumY) / denominator\n const intercept = (sumY - slope * sumX) / n\n let variance = 0\n for (let i = 0; i < n; i++) {\n const residual = barPrice(bars[i], source) - (intercept + slope * i)\n variance += residual * residual\n }\n return { slope, intercept, sigma: Math.sqrt(variance / n) }\n}\n\n/** A volume written compactly: 12.4M, 3.2K. */\nexport function volumeText(volume: number): string {\n const size = Math.abs(volume)\n if (size >= 1e9) return `${(volume / 1e9).toFixed(2)}B`\n if (size >= 1e6) return `${(volume / 1e6).toFixed(2)}M`\n if (size >= 1e3) return `${(volume / 1e3).toFixed(1)}K`\n return String(Math.round(volume))\n}\n\nexport interface VolumeBin {\n priceLow: number\n priceHigh: number\n volume: number\n upVolume: number\n downVolume: number\n}\n\n/**\n * Volume-by-price histogram: each bar's volume spreads uniformly over the bins its high–low\n * range covers, attributed up/down by close vs open (close > open counts as up volume).\n * Null when the range has no volume data at all.\n */\nexport function volumeProfile(bars: readonly SourceBar[], rows: number): VolumeBin[] | null {\n const withVolume = bars.filter((b) => typeof b.volume === 'number' && b.volume > 0)\n if (!withVolume.length || rows < 1) return null\n let min = Infinity\n let max = -Infinity\n for (const bar of withVolume) {\n min = Math.min(min, bar.low)\n max = Math.max(max, bar.high)\n }\n if (!(max > min)) return null\n const height = (max - min) / rows\n const bins: VolumeBin[] = Array.from({ length: rows }, (_, i) => ({\n priceLow: min + i * height,\n priceHigh: min + (i + 1) * height,\n volume: 0,\n upVolume: 0,\n downVolume: 0,\n }))\n for (const bar of withVolume) {\n const lowBin = Math.max(0, Math.min(rows - 1, Math.floor((bar.low - min) / height)))\n const highBin = Math.max(0, Math.min(rows - 1, Math.floor((bar.high - min) / height)))\n const span = highBin - lowBin + 1\n const share = (bar.volume as number) / span\n const up = bar.close > bar.open\n for (let i = lowBin; i <= highBin; i++) {\n bins[i].volume += share\n if (up) bins[i].upVolume += share\n else bins[i].downVolume += share\n }\n }\n return bins\n}\n","// Decoded glyph artwork, keyed by the URL a glyph source produced. Shared across drawings on purpose:\n// two charts pointing at the same asset set reuse one decode, and two pointing at different ones\n// cannot collide.\n\nconst glyphImages = new Map<string, HTMLImageElement | 'loading' | 'failed'>()\n\n/** The artwork at a URL, decoded, or null while it loads or after it failed to; `onLoad` runs once\n * the load this call started lands, so the drawing that asked paints it. */\nexport function glyphArtwork(url: string, onLoad: () => void): HTMLImageElement | null {\n if (typeof Image === 'undefined') return null\n const cached = glyphImages.get(url)\n if (cached instanceof HTMLImageElement) return cached\n if (cached === undefined) {\n glyphImages.set(url, 'loading')\n const image = new Image()\n image.onload = () => {\n glyphImages.set(url, image)\n onLoad()\n }\n image.onerror = () => glyphImages.set(url, 'failed')\n image.src = url\n }\n return null\n}\n","import type { SeriesAttachedParameter, Time } from 'lightweight-charts'\n\nimport type { Anchor, ControlPoint, DrawingStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { barAt } from '../core/bars'\nimport { distanceToSegment, midpoint, segmentTextAngle } from '../core/geometry'\nimport { applyStroke, fillPaint, fontOf, inkOn, lineMeasure, measureTextBlock, paintLabel, paintTextBlock, strokeSegment, withAlpha, wrapText, type HandleShape } from '../render/canvas'\nimport { endSavedLook, type SavedLook } from '../core/savedLook'\nimport type { TextBlock, TextEditFrame } from '../core/textEntry'\nimport { paintTextEntry, paintWordsFrame } from '../render/textEntry'\nimport { glyphArtwork } from '../render/glyphArtwork'\nimport type { TextHAlign, TextVAlign } from './lines'\n\nexport type TextProps = {\n text: string\n}\n\ntype Box = { x: number; y: number; width: number; height: number }\n\nfunction inBox(p: Point, box: Box, pad = 2): boolean {\n return p.x >= box.x - pad && p.x <= box.x + box.width + pad && p.y >= box.y - pad && p.y <= box.y + box.height + pad\n}\n\n/** The point on a box's edge nearest a target: where a line to the target leaves the box. */\nfunction edgeToward(box: Box, target: Point): Point {\n return { x: Math.max(box.x, Math.min(target.x, box.x + box.width)), y: Math.max(box.y, Math.min(target.y, box.y + box.height)) }\n}\n\n/** How a block's words stand in it: from its left, or centered where a save carries a centered\n * alignment, which the block's pages do not offer. */\nfunction wordsAlign(props: Readonly<Record<string, unknown>>): 'left' | 'center' {\n return props.align === 'center' ? 'center' : 'left'\n}\n\n/** A comment saved with an alignment of its words drops it: a comment's words read from its left. */\nfunction withoutAlign<P>(props: Partial<P>): Partial<P> {\n const saved = props as Partial<P> & { align?: unknown }\n if (!('align' in saved)) return props\n const { align: _align, ...rest } = saved\n void _align\n return rest as Partial<P>\n}\n\n/** A text block's background and border, each switched on its own, and whether its words wrap. */\nexport type TextBoxProps = TextProps & {\n /** The box's background, in the drawing's fill. */\n fillBackground: boolean\n /** The box's border, in the drawing's stroke color. */\n drawBorder: boolean\n /** Whether the words wrap at `wordWrapWidth` pixels; off, each line runs its own length. */\n wordWrap: boolean\n wordWrapWidth: number\n /** A format-2 text's look, its words six pixels into a box rounded at four, painted as format 2\n * did until the text's settings change. */\n savedLook: SavedLook\n}\n\n/** How far a text's words stand in from its point, and how much room its box keeps past the words\n * across and down. */\nconst TEXT_INSET = 2\nconst TEXT_ROOM = 5\n/** The pixel a caret after the last word takes, which a box with words keeps for it. */\nconst CARET_ROOM = 1\n/** The alpha the placeholder paints at, and the frame while an edit holds no words. */\nconst EMPTY_ALPHA = 0.4\n\n/** Where a text's words stand and the box they make. */\ninterface TextPlace {\n /** The first line box's top-left. */\n x: number\n y: number\n lineHeight: number\n /** The width the lines align within. */\n width: number\n align: 'left' | 'center'\n block: TextBlock\n /** The placeholder in lines, where it shows. */\n placeholder: TextBlock | null\n wrapWidth: number | null\n box: Box\n}\n\n/**\n * Free text at a chart point: the point is its box's top-left, and the words stand two pixels in,\n * one line to each `fontSize` pixels. The box takes the widest line, the pixel a caret after it\n * takes, and five pixels more across and down. An empty text shows its placeholder at 40%. While\n * selected a two pixel frame stands just outside the box in the words' color, at 40% while an\n * edit shows the placeholder; the text has no handles, and a drag anywhere on it moves it.\n */\nexport class TextLabel extends Drawing<TextBoxProps> {\n readonly type: string = 'text'\n\n protected override defaultProps(): TextBoxProps {\n return { text: '', fillBackground: false, drawBorder: false, wordWrap: false, wordWrapWidth: 200, savedLook: null }\n }\n\n /** A format-2 text showed its background wherever its fill did, its words six pixels into a box\n * rounded at four at a line height of 1.35; it paints so until its settings change. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, fillBackground: true, savedLook: {} }\n }\n\n override applyProps(patch: Partial<TextBoxProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n protected place(viewport: Viewport): TextPlace | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const wrapWidth = this.props.wordWrap ? this.props.wordWrapWidth : null\n const { block, placeholder } = this.shownWords(lineMeasure(this.style), wrapWidth)\n const shown = placeholder ?? block\n const align = wordsAlign(this.props)\n if (this.props.savedLook) {\n const lineHeight = Math.round(this.style.fontSize * 1.35)\n const width = wrapWidth ?? shown.width\n return {\n x: p.x + 6,\n y: p.y + 6,\n lineHeight,\n width,\n align,\n block,\n placeholder,\n wrapWidth,\n box: { x: p.x, y: p.y, width: width + 12, height: shown.lines.length * lineHeight + 12 },\n }\n }\n const x = Math.round(p.x)\n const y = Math.round(p.y)\n const lineHeight = this.style.fontSize\n const words = wrapWidth ?? (placeholder ? placeholder.width : block.width + CARET_ROOM)\n return {\n x: x + TEXT_INSET,\n y: y + TEXT_INSET,\n lineHeight,\n width: placeholder ? placeholder.width : (wrapWidth ?? block.width),\n align,\n block,\n placeholder,\n wrapWidth,\n box: { x, y, width: Math.floor(words) + TEXT_ROOM, height: shown.lines.length * lineHeight + TEXT_ROOM },\n }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const at = this.place(viewport)\n if (!at) return\n const draft = this.textDraft\n const background = this.props.fillBackground ? (fillPaint(this.style) ?? undefined) : undefined\n const borderColor = this.props.drawBorder ? this.style.lineColor : undefined\n if (this.props.savedLook && !draft) {\n const text = this.props.text || ' '\n paintTextBlock(ctx, this.props.wordWrap ? wrapText(text, this.style, this.props.wordWrapWidth) : text, at.box, this.style, { background, borderColor, align: at.align })\n } else {\n if (background || borderColor) {\n ctx.save()\n ctx.setLineDash([])\n ctx.beginPath()\n if (this.props.savedLook) ctx.roundRect(at.box.x, at.box.y, at.box.width, at.box.height, 4)\n else ctx.rect(at.box.x, at.box.y, at.box.width, at.box.height)\n if (background) {\n ctx.fillStyle = background\n ctx.fill()\n }\n if (borderColor) {\n ctx.strokeStyle = borderColor\n ctx.lineWidth = 1\n ctx.stroke()\n }\n ctx.restore()\n }\n paintTextEntry(ctx, {\n x: at.x,\n y: at.y,\n width: at.width,\n lineHeight: at.lineHeight,\n font: fontOf(this.style),\n color: this.style.textColor,\n align: at.align,\n block: at.block,\n placeholder: at.placeholder ? { block: at.placeholder, alpha: EMPTY_ALPHA } : null,\n draft,\n measure: lineMeasure(this.style),\n })\n }\n if (this.state === 'selected' || this.state === 'editing') paintWordsFrame(ctx, at.box, this.style.textColor, draft && at.placeholder ? EMPTY_ALPHA : 1)\n }\n\n override textFrame(viewport: Viewport): TextEditFrame | null {\n const at = this.place(viewport)\n if (!at) return null\n return {\n x: at.x,\n y: at.y,\n width: at.width,\n lines: (at.placeholder ?? at.block).lines.length,\n lineHeight: at.lineHeight,\n font: fontOf(this.style),\n align: at.align,\n wrapWidth: at.wrapWidth,\n angle: 0,\n }\n }\n\n /** No handles: the frame says the text is selected, and a drag anywhere on it moves it. */\n override getControlPoints(_viewport: Viewport): ControlPoint[] {\n return []\n }\n\n /** An empty text shows its placeholder in its own box, so it needs no hint above it. */\n override paintTextHint(): void {}\n\n testHit(point: Point, viewport: Viewport): boolean {\n const at = this.place(viewport)\n return !!at && inBox(point, at.box)\n }\n}\n\n/** A label's background in the drawing's fill and its border in a color of its own, each switched\n * on its own. */\nexport type LabelBoxProps = TextProps & {\n fillBackground: boolean\n drawBorder: boolean\n borderColor: string\n}\n\nconst LABEL_BOX: LabelBoxProps = { text: '', fillBackground: true, drawBorder: false, borderColor: '#4a4a4a' }\n\n/** A note's label, and a format-2 save's look. */\nexport type NoteProps = LabelBoxProps & {\n /** A format-2 note's look, its label's top-left on its second point, painted as format 2 did\n * until the note's settings change. */\n savedLook: SavedLook\n}\n\n/** How far a note's words stand in from its box's left and top edges, the room the box keeps past\n * them across and down, the radius of its corners and of the dot on the point it notes, and the\n * shadow it casts. */\nconst NOTE_PAD_LEFT = 8\nconst NOTE_PAD_TOP = 6\nconst NOTE_ROOM_ACROSS = 16\nconst NOTE_ROOM_DOWN = 12\nconst NOTE_RADIUS = 4\nconst NOTE_DOT = 3.5\nconst NOTE_SHADOW = { color: 'rgba(0, 0, 0, 0.5)', blur: 6, offsetY: 2 }\n\n/**\n * Note: a label tied to the point it notes. The first point is what it notes, marked by a dot in\n * the drawing's stroke color; the second is where the label stands, the left edge of its box\n * centred on it. A one pixel line in the stroke color runs between them while they part. The box\n * is the drawing's fill with corners rounded at 4 and a soft shadow under it, its words 8px in and\n * 6px down on lines `fontSize` tall, so it is its widest line and 16px wide and 12px more than its\n * lines tall, growing evenly up and down. Selected, it shows a handle on each point; a drag on the\n * box moves the label alone, a drag on the line moves the whole note, and a click on the box of the\n * selected note types.\n */\nexport class Note extends Drawing<NoteProps> {\n readonly type = 'note'\n\n protected override defaultProps(): NoteProps {\n return { ...LABEL_BOX, savedLook: null }\n }\n\n /** A note saved on one point keeps that point and gains its label there, the label's top-left on\n * the point as the note was drawn, until the label is moved off it. */\n protected override upgradeAnchors(anchors: Anchor[]): Anchor[] {\n return anchors.length === 1 ? [anchors[0]!, { ...anchors[0]! }] : anchors\n }\n\n /** A format-2 note showed its background and its border, the border in its stroke color, its\n * label's top-left on its second point; it paints so until its settings change. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, fillBackground: true, drawBorder: true, borderColor: this._style.lineColor, savedLook: {} }\n }\n\n override applyProps(patch: Partial<NoteProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The label's box and its words, and the two points. */\n protected place(viewport: Viewport): (WordsPlace & { target: Point; label: Point }) | null {\n const [noted, at] = this.anchors\n const target = noted && this.anchorToPixel(noted, viewport)\n const label = at && this.anchorToPixel(at, viewport)\n if (!target || !label) return null\n const { block, placeholder } = this.shownWords(lineMeasure(this.style))\n const shown = placeholder ?? block\n if (this.props.savedLook) {\n const lineHeight = Math.round(this.style.fontSize * 1.35)\n const box = { x: label.x, y: label.y, width: shown.width + 12, height: shown.lines.length * lineHeight + 12 }\n return { box, x: box.x + 6, y: box.y + 6, lineHeight, block, placeholder, target, label }\n }\n const lineHeight = this.style.fontSize\n const width = Math.round(shown.width) + NOTE_ROOM_ACROSS\n const height = shown.lines.length * lineHeight + NOTE_ROOM_DOWN\n const box = { x: Math.round(label.x), y: Math.round(label.y - height / 2), width, height }\n return { box, x: box.x + NOTE_PAD_LEFT, y: box.y + NOTE_PAD_TOP, lineHeight, block, placeholder, target, label }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const at = this.place(viewport)\n if (!at) return\n const draft = this.textDraft\n const background = this.props.fillBackground ? (fillPaint(this.style) ?? undefined) : undefined\n const borderColor = this.props.drawBorder ? this.props.borderColor : undefined\n if (this.props.savedLook) {\n // The line shows while the label stands off its point.\n const edge = edgeToward(at.box, at.target)\n if (edge.x !== at.target.x || edge.y !== at.target.y) {\n ctx.save()\n applyStroke(ctx, { ...this.style, lineWidth: 1, lineStyle: 'solid' })\n strokeSegment(ctx, at.target, edge)\n ctx.restore()\n }\n if (!draft) {\n paintTextBlock(ctx, this.props.text || ' ', at.box, this.style, { background, borderColor, align: wordsAlign(this.props) })\n return\n }\n } else {\n const tx = Math.round(at.target.x)\n const ty = Math.round(at.target.y)\n const lx = Math.round(at.label.x)\n const ly = Math.round(at.label.y)\n ctx.save()\n ctx.setLineDash([])\n if (tx !== lx || ty !== ly) {\n // The line rides its points' pixels, so a level line is one pixel tall.\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(tx + 0.5, ty + 0.5)\n ctx.lineTo(lx + 0.5, ly + 0.5)\n ctx.stroke()\n }\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.arc(tx, ty, NOTE_DOT, 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n }\n if (background || borderColor) {\n ctx.save()\n ctx.setLineDash([])\n ctx.beginPath()\n if (this.props.savedLook) ctx.roundRect(at.box.x, at.box.y, at.box.width, at.box.height, 4)\n else ctx.roundRect(at.box.x, at.box.y, at.box.width, at.box.height, NOTE_RADIUS)\n if (background) {\n if (!this.props.savedLook) {\n ctx.shadowColor = NOTE_SHADOW.color\n ctx.shadowBlur = NOTE_SHADOW.blur\n ctx.shadowOffsetY = NOTE_SHADOW.offsetY\n }\n ctx.fillStyle = background\n ctx.fill()\n ctx.shadowColor = 'transparent'\n }\n if (borderColor) {\n ctx.strokeStyle = borderColor\n ctx.lineWidth = 1\n ctx.stroke()\n }\n ctx.restore()\n }\n paintTextEntry(ctx, {\n x: at.x,\n y: at.y,\n width: (at.placeholder ?? at.block).width,\n lineHeight: at.lineHeight,\n font: fontOf(this.style),\n color: this.style.textColor,\n align: this.props.savedLook ? wordsAlign(this.props) : 'left',\n block: at.block,\n placeholder: at.placeholder ? { block: at.placeholder, alpha: PLACEHOLDER_ALPHA } : null,\n draft,\n measure: lineMeasure(this.style),\n })\n }\n\n override textFrame(viewport: Viewport): TextEditFrame | null {\n const at = this.place(viewport)\n return at ? wordsFrame(at, fontOf(this.style), this.props.savedLook ? wordsAlign(this.props) : 'left') : null\n }\n\n /** A drag on the box moves the label alone; the line and the dot move the whole note. */\n override grabbedAnchors(point: Point, viewport: Viewport): number[] | null {\n const at = this.place(viewport)\n return at && inBox(point, at.box) ? [1] : null\n }\n\n /** The words are the box's. */\n override wordsAt(point: Point, viewport: Viewport): boolean {\n const at = this.place(viewport)\n return !!at && inBox(point, at.box)\n }\n\n /** Over the selected note's box the cursor reads as its words. */\n protected override cursorAt(point: Point, viewport: Viewport): string | null {\n return this.state === 'selected' && this.wordsAt(point, viewport) ? 'text' : null\n }\n\n /** An empty note shows its placeholder in its own box, so it needs no hint above it. */\n override paintTextHint(): void {}\n\n testHit(point: Point, viewport: Viewport): boolean {\n const at = this.place(viewport)\n if (!at) return false\n if (inBox(point, at.box)) return true\n if (Math.hypot(point.x - at.target.x, point.y - at.target.y) <= NOTE_DOT + 3) return true\n const edge = this.props.savedLook ? edgeToward(at.box, at.target) : at.label\n return distanceToSegment(point, at.target, edge) <= 6\n }\n}\n\n/** A comment's words, and a format-2 save's look. */\nexport type CommentProps = TextProps & {\n /** A format-2 comment's look, a box above and to the right of its point with a tail down to it,\n * painted as format 2 did until the comment's settings change. */\n savedLook: SavedLook\n}\n\n/** How far a comment's words stand in from its bubble's edges, the radius of the bubble's three\n * round corners, and the near-square corner on its point. */\nconst COMMENT_PAD = 13\nconst COMMENT_RADIUS = 21\nconst COMMENT_POINT_CORNER = 2\n/** The alpha the placeholder of a drawing that types in a box of its own paints at. */\nconst PLACEHOLDER_ALPHA = 0.5\n\n/** Where a drawing's words stand in their box: the first line's box, the line height, the words\n * and the placeholder in lines. */\ninterface WordsPlace {\n box: Box\n x: number\n y: number\n lineHeight: number\n block: TextBlock\n placeholder: TextBlock | null\n}\n\n/** The frame an editor lays its field over, for words placed in a box. */\nfunction wordsFrame(at: WordsPlace, font: string, align: 'left' | 'center' = 'left', width = (at.placeholder ?? at.block).width): TextEditFrame {\n return { x: at.x, y: at.y, width, lines: (at.placeholder ?? at.block).lines.length, lineHeight: at.lineHeight, font, align, wrapWidth: null, angle: 0 }\n}\n\n/**\n * Comment: words in a bubble whose bottom-left corner is the point it comments on. The bubble is\n * the drawing's fill bordered in its stroke color, its other three corners rounded at 21 whatever\n * its size; its words stand 13px in from every edge on lines `fontSize` tall, and it grows right\n * with its widest line and up with each line, the corner on the point never moving. An empty\n * comment shows its placeholder at half strength. Selected, it shows one handle, on its point, and\n * a press on it types.\n */\nexport class Comment extends Drawing<CommentProps> {\n readonly type = 'comment'\n\n protected override defaultProps(): CommentProps {\n return { text: '', savedLook: null }\n }\n\n protected override upgradeProps(props: Partial<CommentProps>): Partial<CommentProps> {\n return withoutAlign(props)\n }\n\n /** A format-2 comment was a box above and to the right of its point, a tail dropping to it; it\n * paints so until its settings change. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, savedLook: {} }\n }\n\n override applyProps(patch: Partial<CommentProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n /** The bubble and its words: the bubble's pixels run from the one left of the point to the one\n * below it. A saved look stands its box above and to the right of the point. */\n protected place(viewport: Viewport): (WordsPlace & { point: Point }) | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const { block, placeholder } = this.shownWords(lineMeasure(this.style))\n const shown = placeholder ?? block\n if (this.props.savedLook) {\n const lineHeight = Math.round(this.style.fontSize * 1.35)\n const width = shown.width + 12\n const height = shown.lines.length * lineHeight + 12\n const box = { x: p.x + 10, y: p.y - 14 - height, width, height }\n return { box, x: box.x + 6, y: box.y + 6, lineHeight, block, placeholder, point: p }\n }\n const lineHeight = this.style.fontSize\n const width = Math.round(shown.width) + COMMENT_PAD * 2\n const height = shown.lines.length * lineHeight + COMMENT_PAD * 2\n const box = { x: Math.round(p.x) - 1, y: Math.round(p.y) + 1 - height, width, height }\n return { box, x: box.x + COMMENT_PAD, y: box.y + COMMENT_PAD, lineHeight, block, placeholder, point: p }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const at = this.place(viewport)\n if (!at) return\n const draft = this.textDraft\n const fill = fillPaint(this.style) ?? 'transparent'\n if (this.props.savedLook && !draft) {\n const box = paintTextBlock(ctx, this.props.text || ' ', at.box, this.style, { background: fill, borderColor: this.style.lineColor })\n this.paintSavedTail(ctx, box, at.point, fill)\n return\n }\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = fill\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.beginPath()\n if (this.props.savedLook) ctx.roundRect(at.box.x, at.box.y, at.box.width, at.box.height, 4)\n // The border's pixel rides the bubble's edge, so the path stands half a pixel in.\n else ctx.roundRect(at.box.x + 0.5, at.box.y + 0.5, at.box.width - 1, at.box.height - 1, [COMMENT_RADIUS, COMMENT_RADIUS, COMMENT_RADIUS, COMMENT_POINT_CORNER])\n ctx.fill()\n ctx.stroke()\n ctx.restore()\n if (this.props.savedLook) this.paintSavedTail(ctx, at.box, at.point, fill)\n const measure = lineMeasure(this.style)\n paintTextEntry(ctx, {\n x: at.x,\n y: at.y,\n width: (at.placeholder ?? at.block).width,\n lineHeight: at.lineHeight,\n font: fontOf(this.style),\n color: this.style.textColor,\n align: 'left',\n block: at.block,\n placeholder: at.placeholder ? { block: at.placeholder, alpha: PLACEHOLDER_ALPHA } : null,\n draft,\n measure,\n })\n }\n\n /** A format-2 comment's tail, from its box down to its point. */\n private paintSavedTail(ctx: CanvasRenderingContext2D, box: Box, point: Point, fill: string): void {\n ctx.save()\n ctx.fillStyle = fill\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.setLineDash([])\n ctx.beginPath()\n ctx.moveTo(box.x + 8, box.y + box.height)\n ctx.lineTo(point.x, point.y)\n ctx.lineTo(box.x + 24, box.y + box.height)\n ctx.closePath()\n ctx.fill()\n ctx.stroke()\n ctx.restore()\n }\n\n override textFrame(viewport: Viewport): TextEditFrame | null {\n const at = this.place(viewport)\n return at ? wordsFrame(at, fontOf(this.style)) : null\n }\n\n /** An empty comment shows its placeholder in its own bubble, so it needs no hint above it. */\n override paintTextHint(): void {}\n\n /** Over a selected comment the pointer reads as typing, which a press there does. */\n protected override cursorAt(point: Point, viewport: Viewport): string | null {\n const at = this.place(viewport)\n return this.state === 'selected' && at && inBox(point, at.box, 0) ? 'text' : null\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const at = this.place(viewport)\n return !!at && inBox(point, at.box)\n }\n}\n\n/** A callout's words, whether they wrap and at what width, its border's width, and a format-2\n * save's look. */\nexport type CalloutProps = TextProps & {\n wordWrap: boolean\n wordWrapWidth: number\n /** The box's border at this width; null takes the drawing's stroke width. */\n borderWidth: number | null\n /** A format-2 callout's look, its box's top-left on its second point and a line tying the box to\n * its first, painted as format 2 did until the callout's settings change. */\n savedLook: SavedLook\n}\n\n/** How far a callout's words stand in from its box's left edge, how far its first line's box\n * stands under its top (which sets a line's tallest letters 10px under it), the room the box keeps\n * past the words across and down, the radius of its corners, and how far its tail's root runs\n * each way along the box from the middle of a side, or from a corner. */\nconst CALLOUT_PAD_LEFT = 10\nconst CALLOUT_LINE_TOP = 9\nconst CALLOUT_ROOM = 20\nconst CALLOUT_RADIUS = 6\nconst CALLOUT_TAIL = 8\n\ntype BoxSide = 'top' | 'right' | 'bottom' | 'left'\ntype BoxCorner = 'top-left' | 'top-right' | 'bottom-right' | 'bottom-left'\n\n/** A callout's tail: where it leaves the box, the two points of its root on the box's outline in\n * the order a clockwise walk round the box meets them, and its tip. */\ninterface CalloutTail {\n root: BoxSide | BoxCorner\n from: Point\n to: Point\n tip: Point\n}\n\n/** The tail from a box to a tip: from the middle of the side the tip lies beyond, its root 8px\n * each way along it, or from the corner the tip lies beyond both sides of, its root 8px along each\n * side from the corner. A tip inside the box has no tail. */\nfunction calloutTail(box: Box, tip: Point): CalloutTail | null {\n const l = box.x\n const t = box.y\n const r = box.x + box.width\n const b = box.y + box.height\n const across = tip.x < l ? 'left' : tip.x > r ? 'right' : null\n const down = tip.y < t ? 'top' : tip.y > b ? 'bottom' : null\n const k = Math.min(CALLOUT_RADIUS, box.width / 2, box.height / 2)\n const w = Math.max(0, Math.min(CALLOUT_TAIL, box.width / 2 - k, box.height / 2 - k))\n const c = Math.min(CALLOUT_TAIL, box.width, box.height)\n const cx = l + box.width / 2\n const cy = t + box.height / 2\n const tail = (root: BoxSide | BoxCorner, from: Point, to: Point): CalloutTail => ({ root, from, to, tip })\n if (down === 'top' && across === 'left') return tail('top-left', { x: l, y: t + c }, { x: l + c, y: t })\n if (down === 'top' && across === 'right') return tail('top-right', { x: r - c, y: t }, { x: r, y: t + c })\n if (down === 'bottom' && across === 'right') return tail('bottom-right', { x: r, y: b - c }, { x: r - c, y: b })\n if (down === 'bottom' && across === 'left') return tail('bottom-left', { x: l + c, y: b }, { x: l, y: b - c })\n if (down === 'top') return tail('top', { x: cx - w, y: t }, { x: cx + w, y: t })\n if (down === 'bottom') return tail('bottom', { x: cx + w, y: b }, { x: cx - w, y: b })\n if (across === 'right') return tail('right', { x: r, y: cy - w }, { x: r, y: cy + w })\n if (across === 'left') return tail('left', { x: l, y: cy + w }, { x: l, y: cy - w })\n return null\n}\n\n/** Trace a callout's box with its corners rounded at 6 and its tail let into its outline: one path\n * that one stroke and one fill cover. */\nfunction traceCallout(ctx: CanvasRenderingContext2D, box: Box, tail: CalloutTail | null): void {\n const l = box.x\n const t = box.y\n const r = box.x + box.width\n const b = box.y + box.height\n const k = Math.min(CALLOUT_RADIUS, box.width / 2, box.height / 2)\n const at = tail?.root\n const out = (): void => {\n ctx.lineTo(tail!.from.x, tail!.from.y)\n ctx.lineTo(tail!.tip.x, tail!.tip.y)\n ctx.lineTo(tail!.to.x, tail!.to.y)\n }\n // The walk starts just past the top-left corner, or where a tail from that corner meets the top.\n if (at === 'top-left') ctx.moveTo(tail!.to.x, tail!.to.y)\n else ctx.moveTo(l + k, t)\n if (at === 'top') out()\n if (at === 'top-right') out()\n else ctx.arcTo(r, t, r, t + k, k)\n if (at === 'right') out()\n if (at === 'bottom-right') out()\n else ctx.arcTo(r, b, r - k, b, k)\n if (at === 'bottom') out()\n if (at === 'bottom-left') out()\n else ctx.arcTo(l, b, l, b - k, k)\n if (at === 'left') out()\n if (at === 'top-left') out()\n else ctx.arcTo(l, t, l + k, t, k)\n ctx.closePath()\n}\n\n/** Whether a point lies in the triangle a tail makes. */\nfunction inTail(p: Point, tail: CalloutTail): boolean {\n const side = (a: Point, b: Point): number => (b.x - a.x) * (p.y - a.y) - (b.y - a.y) * (p.x - a.x)\n const d1 = side(tail.from, tail.tip)\n const d2 = side(tail.tip, tail.to)\n const d3 = side(tail.to, tail.from)\n return (d1 >= 0 && d2 >= 0 && d3 >= 0) || (d1 <= 0 && d2 <= 0 && d3 <= 0)\n}\n\n/**\n * Callout: words in a box with a tail to what they speak of. The first point is the tail's tip and\n * the second the middle of the box's right edge, the box standing to its left, centred on it up and\n * down. The words stand 10px in from the box's left on lines `fontSize` tall, so the box is its\n * widest line, or the wrap width while wrap is on, and 20px wide, and 20px more than its lines tall.\n * The tail leaves the box from the middle of the side its tip lies beyond, or from the corner it\n * lies beyond both sides of. Box and tail are one shape in the drawing's fill, bordered in its\n * stroke color, the border stroked under the fill so its outer half shows. An empty callout shows\n * its placeholder at half strength. Selected, it shows a handle on each point; a drag on the box\n * moves the box alone, and a click on the box of the selected callout types.\n */\nexport class Callout extends Drawing<CalloutProps> {\n readonly type: string = 'callout'\n\n protected override defaultProps(): CalloutProps {\n return { text: '', wordWrap: false, wordWrapWidth: 200, borderWidth: null, savedLook: null }\n }\n\n /** A format-2 callout stood its box's top-left on its second point, tied to its first by a line,\n * and bordered the box at 1px; it paints so until its settings change. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, borderWidth: 1, savedLook: {} }\n }\n\n override applyProps(patch: Partial<CalloutProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The box, the words in it, and the tail's tip. */\n protected place(viewport: Viewport): (WordsPlace & { tip: Point; wrapWidth: number | null }) | null {\n const [pointed, boxed] = this.anchors\n const tip = pointed && this.anchorToPixel(pointed, viewport)\n const at = boxed && this.anchorToPixel(boxed, viewport)\n if (!tip || !at) return null\n const wrapWidth = this.props.wordWrap ? this.props.wordWrapWidth : null\n const { block, placeholder } = this.shownWords(lineMeasure(this.style), wrapWidth)\n const shown = placeholder ?? block\n if (this.props.savedLook) {\n const lineHeight = Math.round(this.style.fontSize * 1.35)\n const box = { x: at.x, y: at.y, width: (wrapWidth ?? shown.width) + 12, height: shown.lines.length * lineHeight + 12 }\n return { box, x: box.x + 6, y: box.y + 6, lineHeight, block, placeholder, tip, wrapWidth }\n }\n const lineHeight = this.style.fontSize\n const width = (wrapWidth ?? shown.width) + CALLOUT_ROOM\n const height = shown.lines.length * lineHeight + CALLOUT_ROOM\n const box = { x: at.x - width, y: at.y - height / 2, width, height }\n return { box, x: box.x + CALLOUT_PAD_LEFT, y: box.y + CALLOUT_LINE_TOP, lineHeight, block, placeholder, tip, wrapWidth }\n }\n\n /** A format-2 callout's words, wrapped as format 2 wrapped them. */\n private savedWords(): string {\n const text = this.props.text || ' '\n return this.props.wordWrap ? wrapText(text, this.style, this.props.wordWrapWidth) : text\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const at = this.place(viewport)\n if (!at) return\n const draft = this.textDraft\n const fill = fillPaint(this.style) ?? 'transparent'\n const borderWidth = this.props.borderWidth ?? this.style.lineWidth\n if (this.props.savedLook) {\n ctx.save()\n applyStroke(ctx, { ...this.style, lineStyle: 'solid' })\n strokeSegment(ctx, at.tip, edgeToward(at.box, at.tip))\n ctx.restore()\n if (!draft) {\n paintTextBlock(ctx, this.savedWords(), at.box, this.style, { background: fill, borderColor: this.style.lineColor, borderWidth })\n return\n }\n ctx.save()\n ctx.setLineDash([])\n ctx.beginPath()\n ctx.roundRect(at.box.x, at.box.y, at.box.width, at.box.height, 4)\n ctx.fillStyle = fill\n ctx.fill()\n if (borderWidth > 0) {\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = borderWidth\n ctx.stroke()\n }\n ctx.restore()\n } else {\n ctx.save()\n ctx.setLineDash([])\n ctx.beginPath()\n traceCallout(ctx, at.box, calloutTail(at.box, at.tip))\n // The border goes under the fill, which covers its inner half.\n if (borderWidth > 0) {\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = borderWidth\n ctx.stroke()\n }\n ctx.fillStyle = fill\n ctx.fill()\n ctx.restore()\n }\n paintTextEntry(ctx, {\n x: at.x,\n y: at.y,\n width: at.wrapWidth ?? (at.placeholder ?? at.block).width,\n lineHeight: at.lineHeight,\n font: fontOf(this.style),\n color: this.style.textColor,\n align: 'left',\n block: at.block,\n placeholder: at.placeholder ? { block: at.placeholder, alpha: PLACEHOLDER_ALPHA } : null,\n draft,\n measure: lineMeasure(this.style),\n })\n }\n\n override textFrame(viewport: Viewport): TextEditFrame | null {\n const at = this.place(viewport)\n if (!at) return null\n return { ...wordsFrame(at, fontOf(this.style), 'left', at.wrapWidth ?? (at.placeholder ?? at.block).width), wrapWidth: at.wrapWidth }\n }\n\n /** A drag on the box moves the box alone; one on the tail moves the whole callout. */\n override grabbedAnchors(point: Point, viewport: Viewport): number[] | null {\n const at = this.place(viewport)\n return at && inBox(point, at.box) ? [1] : null\n }\n\n /** The words are the box's. */\n override wordsAt(point: Point, viewport: Viewport): boolean {\n const at = this.place(viewport)\n return !!at && inBox(point, at.box)\n }\n\n /** An empty callout shows its placeholder in its own box, so it needs no hint above it. */\n override paintTextHint(): void {}\n\n testHit(point: Point, viewport: Viewport): boolean {\n const at = this.place(viewport)\n if (!at) return false\n if (inBox(point, at.box)) return true\n if (this.props.savedLook) return distanceToSegment(point, at.tip, edgeToward(at.box, at.tip)) <= Math.max(6, this.style.lineWidth / 2 + 4)\n const tail = calloutTail(at.box, at.tip)\n if (!tail) return false\n return inTail(point, tail) || distanceToSegment(point, tail.from, tail.tip) <= 4 || distanceToSegment(point, tail.to, tail.tip) <= 4\n }\n}\n\n/** A mark whose present look differs from the one format 2 painted holds a format-2 save's look. */\nexport type SavedLookProps = {\n /** A format-2 save's look, painted as format 2 did until the drawing's settings change. */\n savedLook: SavedLook\n}\n\n/** How a price label stands off its point: its body's outline from 9px right of it, its bottom 15px\n * above it, its corners rounded at 2.5, its price 10px in from each side; its tail's root on the\n * body's bottom from 14px to 21px right of the point; and the dot on the point. */\nconst PRICE_LABEL = { right: 9, up: 15, radius: 2.5, pad: 10, tail: [14, 21], dot: 2 } as const\n\n/** A price tag's height for its type: 24px, or the type and 10px where that is taller, and how far\n * its words' baseline stands under its top. */\nconst tagHeight = (fontSize: number): number => Math.max(24, fontSize + 10)\nconst tagBaseline = (fontSize: number): number => Math.round(tagHeight(fontSize) / 2 + fontSize * 0.3)\n\n/** Price label: its point's price on a body up and to the right of the point, a tail from the\n * body's bottom to the point and a dot on it. Body and tail are the drawing's fill, stroked 2px in\n * its stroke color so each stands a pixel past its outline; the price is in the drawing's text\n * style. Selected, it shows a small ring on its point. */\nexport class PriceLabel extends Drawing<SavedLookProps> {\n readonly type = 'price_label'\n\n protected override defaultProps(): SavedLookProps {\n return { savedLook: null }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n /** A format-2 price label filled a pill centred on its point's right in its stroke color at 18%;\n * it paints so until its settings change. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._style = { ...this._style, fillColor: this._style.lineColor, fillOpacity: 0.18 }\n this._props = { ...this._props, savedLook: {} }\n }\n\n override applyProps(patch: Partial<SavedLookProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n /** The body's outline and the price, and the point. */\n protected body(viewport: Viewport): { box: Box; text: string; point: Point } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const text = this.formatPrice(anchor.price)\n if (this.props.savedLook) {\n const { width, height } = measureTextBlock(text, this.style)\n return { box: { x: p.x + 12, y: p.y - (height + 12) / 2, width: width + 12, height: height + 12 }, text, point: p }\n }\n const height = tagHeight(this.style.fontSize)\n const width = lineMeasure(this.style)(text) + PRICE_LABEL.pad * 2\n return { box: { x: p.x + PRICE_LABEL.right, y: p.y - PRICE_LABEL.up - height, width, height }, text, point: p }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const at = this.body(viewport)\n if (!at) return\n const { box, point: p } = at\n const fill = fillPaint(this.style) ?? 'transparent'\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = fill\n ctx.strokeStyle = this.style.lineColor\n if (this.props.savedLook) {\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(p.x, p.y)\n ctx.lineTo(box.x, box.y + box.height / 2 - 5)\n ctx.lineTo(box.x, box.y + box.height / 2 + 5)\n ctx.closePath()\n ctx.fill()\n ctx.stroke()\n ctx.beginPath()\n ctx.roundRect(box.x, box.y, box.width, box.height, 4)\n ctx.fill()\n ctx.stroke()\n ctx.restore()\n paintTextBlock(ctx, at.text, { x: box.x, y: box.y }, this.style)\n return\n }\n ctx.lineWidth = 2\n const [from, to] = PRICE_LABEL.tail\n ctx.beginPath()\n ctx.moveTo(p.x, p.y)\n ctx.lineTo(p.x + from, p.y - PRICE_LABEL.up)\n ctx.lineTo(p.x + to, p.y - PRICE_LABEL.up)\n ctx.closePath()\n ctx.fill()\n ctx.stroke()\n ctx.beginPath()\n ctx.roundRect(box.x, box.y, box.width, box.height, PRICE_LABEL.radius)\n ctx.fill()\n ctx.stroke()\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.arc(p.x, p.y, PRICE_LABEL.dot, 0, Math.PI * 2)\n ctx.fill()\n ctx.font = fontOf(this.style)\n ctx.fillStyle = this.style.textColor\n ctx.textAlign = 'left'\n ctx.textBaseline = 'alphabetic'\n ctx.fillText(at.text, box.x + PRICE_LABEL.pad, box.y + tagBaseline(this.style.fontSize))\n ctx.restore()\n }\n\n override handleShape(): HandleShape {\n return this.props.savedLook ? 'circle' : 'small'\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const at = this.body(viewport)\n if (!at) return false\n if (inBox(point, at.box, 2)) return true\n // The tail, from the point up to the body.\n const [from, to] = PRICE_LABEL.tail\n const root = { x: at.point.x + (from + to) / 2, y: at.point.y - PRICE_LABEL.up }\n return distanceToSegment(point, at.point, root) <= 5\n }\n}\n\ntype MarkDirection = 'up' | 'down'\n\n/** How an arrow mark stands on its point: its head half 10.5px across and 12px long from the tip,\n * its shaft half 5.5px across, running on to 22px from the tip. */\nconst ARROW_MARK = { head: 10.5, headLength: 12, shaft: 5.5, length: 22 } as const\n\n/** An arrow mark: an arrow whose tip is on its point, in the drawing's stroke color, its words past\n * its tail. An up arrow hangs below its point, a down arrow stands above it. Selected, it shows a\n * small ring on its point. */\nabstract class ArrowMark extends Drawing<TextProps & SavedLookProps> {\n protected abstract direction(): MarkDirection\n\n protected override defaultProps(): TextProps & SavedLookProps {\n return { text: '', savedLook: null }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n /** A format-2 arrow mark was a chevron sized by its stroke width; it paints so until its settings\n * change. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, savedLook: {} }\n }\n\n override applyProps(patch: Partial<TextProps & SavedLookProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n /** The tip, and which way the arrow runs from it: 1 down the pane for an up arrow. */\n private tip(viewport: Viewport): { x: number; y: number; sign: 1 | -1 } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n return { x: Math.round(p.x) + 0.5, y: Math.round(p.y), sign: this.direction() === 'up' ? 1 : -1 }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.props.savedLook) {\n this.paintSaved(ctx, viewport)\n return\n }\n const t = this.tip(viewport)\n if (!t) return\n const { head, headLength, shaft, length } = ARROW_MARK\n const s = t.sign\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.moveTo(t.x, t.y)\n ctx.lineTo(t.x + head, t.y + s * headLength)\n ctx.lineTo(t.x + shaft, t.y + s * headLength)\n ctx.lineTo(t.x + shaft, t.y + s * length)\n ctx.lineTo(t.x - shaft, t.y + s * length)\n ctx.lineTo(t.x - shaft, t.y + s * headLength)\n ctx.lineTo(t.x - head, t.y + s * headLength)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n if (this.props.text) {\n const { width, height } = measureTextBlock(this.props.text, this.style)\n paintTextBlock(ctx, this.props.text, { x: t.x - (width + 12) / 2, y: s > 0 ? t.y + length + 4 : t.y - length - 4 - height - 12 }, this.style)\n }\n }\n\n /** A format-2 arrow mark: a chevron its stroke width sized, its body running away from its tip. */\n private paintSaved(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n const p = anchor && this.anchorToPixel(anchor, viewport)\n if (!p) return\n const size = 7 + this.style.lineWidth * 2\n const up = this.direction() === 'up'\n const sign = up ? 1 : -1\n ctx.save()\n ctx.fillStyle = this.style.lineColor\n ctx.setLineDash([])\n ctx.beginPath()\n ctx.moveTo(p.x, p.y)\n ctx.lineTo(p.x - size, p.y + sign * size)\n ctx.lineTo(p.x - size / 2, p.y + sign * size)\n ctx.lineTo(p.x - size / 2, p.y + sign * size * 2)\n ctx.lineTo(p.x + size / 2, p.y + sign * size * 2)\n ctx.lineTo(p.x + size / 2, p.y + sign * size)\n ctx.lineTo(p.x + size, p.y + sign * size)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n if (this.props.text) {\n const { width, height } = measureTextBlock(this.props.text, this.style)\n paintTextBlock(ctx, this.props.text, { x: p.x - (width + 12) / 2, y: up ? p.y + size * 2 + 4 : p.y - size * 2 - 4 - height - 12 }, this.style)\n }\n }\n\n override handleShape(): HandleShape {\n return this.props.savedLook ? 'circle' : 'small'\n }\n\n /** Its words are typed in its settings, so it shows no invitation to type on the chart. */\n override paintTextHint(): void {}\n\n testHit(point: Point, viewport: Viewport): boolean {\n if (this.props.savedLook) {\n const anchor = this.anchors[0]\n const p = anchor && this.anchorToPixel(anchor, viewport)\n if (!p) return false\n const size = 7 + this.style.lineWidth * 2\n const up = this.direction() === 'up'\n return inBox(point, up ? { x: p.x - size, y: p.y, width: size * 2, height: size * 2 } : { x: p.x - size, y: p.y - size * 2, width: size * 2, height: size * 2 }, 4)\n }\n const t = this.tip(viewport)\n if (!t) return false\n const { head, length } = ARROW_MARK\n return inBox(point, { x: t.x - head, y: t.sign > 0 ? t.y : t.y - length, width: head * 2, height: length }, 3)\n }\n}\n\n/** Upward arrow mark, its tip at the anchor's price. */\nexport class ArrowMarkUp extends ArrowMark {\n readonly type = 'arrow_up'\n\n protected direction(): MarkDirection {\n return 'up'\n }\n}\n\n/** Downward arrow mark, its tip at the anchor's price. */\nexport class ArrowMarkDown extends ArrowMark {\n readonly type = 'arrow_down'\n\n protected direction(): MarkDirection {\n return 'down'\n }\n}\n\n/** How a label stands across a line it rides: its offset from the line and the edge of the text\n * that offset is measured to. */\nconst ACROSS: Record<TextVAlign, { y: number; baseline: 'bottom' | 'middle' | 'top' }> = {\n top: { y: -4, baseline: 'bottom' },\n middle: { y: 0, baseline: 'middle' },\n bottom: { y: 4, baseline: 'top' },\n}\n\n/** A price note's words and their place along its line, and its tag: the tag's words' color, size,\n * weight and slant, its background and its border. */\nexport type PriceNoteProps = TextProps & {\n /** Where the words stand across the line (above it, on it, below it) and along it. */\n textVAlign: TextVAlign\n textHAlign: TextHAlign\n labelTextColor: string\n labelFontSize: number\n labelBold: boolean\n labelItalic: boolean\n labelBackgroundColor: string\n labelBorderColor: string\n /** A format-2 note's look, a box reading the price over the words, tied to the price, painted as\n * format 2 did until the note's settings change. */\n savedLook: SavedLook\n}\n\n/** How a price note's tag stands on its second point: its outline's near edge on the point, centred\n * on it, its corners rounded at 5, its price 8px in, and the outline 17px wider than its price,\n * rounded to a whole pixel; and the dot on its first point. */\nconst PRICE_TAG = { radius: 5, pad: 8, room: 17, dot: 2.5 } as const\n\n/**\n * Price note: a one pixel line from a price to its tag, in the drawing's stroke color. The first\n * point is the price, marked by a dot; the second is the line's other end, where the tag reading\n * the first point's price stands on the side away from the first, its outline stroked 2px in its\n * border color so it stands a pixel past it. The note's own words ride the line, and are typed in\n * its settings.\n */\nexport class PriceNote extends Drawing<PriceNoteProps> {\n readonly type = 'price_note'\n\n protected override defaultProps(): PriceNoteProps {\n return {\n text: '',\n textVAlign: 'top',\n textHAlign: 'center',\n labelTextColor: '#ffffff',\n labelFontSize: 12,\n labelBold: false,\n labelItalic: false,\n labelBackgroundColor: '#2962ff',\n labelBorderColor: '#2962ff',\n savedLook: null,\n }\n }\n\n /** A format-2 price note was a box at its second point reading the first point's price over its\n * words, in the drawing's fill, bordered in its stroke color and tied to the price in its stroke.\n * It paints so until its settings change, and its tag's present props take the box's colors and\n * type. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n const s = this._style\n this._props = {\n ...this._props,\n labelTextColor: s.textColor,\n labelFontSize: s.fontSize,\n labelBold: s.bold,\n labelItalic: s.italic,\n labelBackgroundColor: fillPaint(s) ?? withAlpha(s.lineColor, 0),\n labelBorderColor: s.lineColor,\n savedLook: {},\n }\n }\n\n override applyProps(patch: Partial<PriceNoteProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n /** A saved look's box: at the second point, reading the first point's price over the words. */\n protected savedBox(viewport: Viewport): { box: Box; text: string; target: Point } | null {\n const [price, at] = this.anchors\n const target = price && this.anchorToPixel(price, viewport)\n const p = at && this.anchorToPixel(at, viewport)\n if (!price || !target || !p) return null\n const value = this.formatPrice(price.price)\n const text = this.props.text ? `${value}\\n${this.props.text}` : value\n const { width, height } = measureTextBlock(text || ' ', this.style)\n return { box: { x: p.x, y: p.y, width: width + 12, height: height + 12 }, text, target }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The tag's words in its own text style. */\n protected tagStyle(): DrawingStyle {\n const p = this.props\n return { ...this.style, textColor: p.labelTextColor, fontSize: p.labelFontSize, bold: p.labelBold, italic: p.labelItalic }\n }\n\n /** The tag's outline at the line's second end, on the side away from the first, and its price. */\n protected tag(viewport: Viewport): { box: Box; text: string } | null {\n const [pa, pb] = this.anchorPixels(viewport)\n const price = this.anchors[0]\n if (!pa || !pb || !price) return null\n const text = this.formatPrice(price.price)\n const style = this.tagStyle()\n const width = Math.round(lineMeasure(style)(text) + PRICE_TAG.room)\n const height = tagHeight(style.fontSize)\n return { box: { x: pb.x >= pa.x ? pb.x : pb.x - width, y: pb.y - height / 2, width, height }, text }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.props.savedLook) {\n const saved = this.savedBox(viewport)\n if (!saved) return\n applyStroke(ctx, this.style)\n strokeSegment(ctx, saved.target, edgeToward(saved.box, saved.target))\n paintTextBlock(ctx, saved.text || ' ', saved.box, this.style, { background: fillPaint(this.style) ?? undefined, borderColor: this.style.lineColor })\n return\n }\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return\n ctx.save()\n applyStroke(ctx, { ...this.style, lineWidth: 1, lineStyle: 'solid' })\n strokeSegment(ctx, pa, pb)\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.arc(pa.x, pa.y, PRICE_TAG.dot, 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n const tag = this.tag(viewport)\n if (tag) {\n const style = this.tagStyle()\n ctx.save()\n ctx.setLineDash([])\n ctx.beginPath()\n ctx.roundRect(tag.box.x, tag.box.y, tag.box.width, tag.box.height, PRICE_TAG.radius)\n ctx.fillStyle = this.props.labelBackgroundColor\n ctx.fill()\n ctx.strokeStyle = this.props.labelBorderColor\n ctx.lineWidth = 2\n ctx.stroke()\n ctx.font = fontOf(style)\n ctx.fillStyle = style.textColor\n ctx.textAlign = 'left'\n ctx.textBaseline = 'alphabetic'\n ctx.fillText(tag.text, tag.box.x + PRICE_TAG.pad, tag.box.y + tagBaseline(style.fontSize))\n ctx.restore()\n }\n if (this.props.text) {\n // The words ride the line's slope; left and right are the screen's.\n const [left, right] = pa.x <= pb.x ? [pa, pb] : [pb, pa]\n const along = this.props.textHAlign\n const at = along === 'left' ? left : along === 'right' ? right : midpoint(pa, pb)\n const across = ACROSS[this.props.textVAlign] ?? ACROSS.top\n ctx.save()\n ctx.translate(at.x, at.y)\n ctx.rotate(segmentTextAngle(pa, pb))\n paintLabel(ctx, this.props.text, { x: 0, y: across.y }, this.style, { align: along === 'left' ? 'left' : along === 'right' ? 'right' : 'center', baseline: across.baseline })\n ctx.restore()\n }\n }\n\n /** Its words are typed in its settings, so it shows no invitation to type on the chart. */\n override paintTextHint(): void {}\n\n testHit(point: Point, viewport: Viewport): boolean {\n if (this.props.savedLook) {\n const saved = this.savedBox(viewport)\n return !!saved && (inBox(point, saved.box) || distanceToSegment(point, saved.target, edgeToward(saved.box, saved.target)) <= 6)\n }\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return false\n if (distanceToSegment(point, pa, pb) <= 6) return true\n const tag = this.tag(viewport)\n return !!tag && inBox(point, tag.box)\n }\n}\n\n/** A pin's box, and a format-2 save's look. */\nexport type PinProps = LabelBoxProps & {\n /** A format-2 pin's look, its words in a box under its marker shown at all times, painted as\n * format 2 did until the pin's settings change. */\n savedLook: SavedLook\n}\n\n/** A pin's marker: the radius of its head, of the hole through the head, how far the head's middle\n * stands above the tip, and how far below the head's widest the curves of its sides bend from. */\nconst PIN_MARKER = { head: 11.75, hole: 5, rise: 18, bend: 8 } as const\n/** A pin's box: its width, the width its words wrap at, how far they stand in from its left, how\n * far its first line's box stands under its top, the room it keeps past its lines down, the\n * radius of its corners, how far its bottom stands above the tip, and the pointer under it toward\n * the marker. */\nconst PIN_BOX = { width: 236, wrap: 212, padLeft: 12, lineTop: 9, roomDown: 19, radius: 4, lift: 43.5, pointer: { half: 6.5, depth: 8 } } as const\n\n/**\n * Pin: a map pin marker on a chart point in the drawing's stroke color, its words in a box above it.\n * The marker is a round head with a hole through it and sides that curve in to a tip on the point.\n * The box, the drawing's fill with corners rounded at 4 and a soft shadow, is 236px wide and\n * centred over the marker, with a pointer under it toward the marker; it stands while the pin is\n * hovered, selected or typed into, and grows up a line at a time. Its words stand 12px in, wrap at\n * 212px and run on lines 1.35 times their size, and an empty pin shows its placeholder at half\n * strength there. Selected, it shows a small ring on its point; a click on the box of the selected\n * pin types, a click on its marker only selects it, and a pin left without words stays.\n */\nexport class Pin extends Drawing<PinProps> {\n readonly type = 'pin'\n\n protected override defaultProps(): PinProps {\n return { ...LABEL_BOX, savedLook: null }\n }\n\n /** A format-2 pin set its words on a dark plate at 95% with no border, under its marker and shown\n * at all times; it paints so until its settings change. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._style = { ...this._style, fillColor: '#1b1f27', fillOpacity: 0.95 }\n this._props = { ...this._props, fillBackground: true, drawBorder: false, savedLook: {} }\n }\n\n override applyProps(patch: Partial<PinProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n /** The marker's middle, tip and head on the point's pixel, and the pixel edge left of it, which\n * the box centres on. */\n private marker(viewport: Viewport): { x: number; edge: number; tip: number; head: number } | null {\n const anchor = this.anchors[0]\n const p = anchor && this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const edge = Math.round(p.x)\n const tip = Math.round(p.y) + 0.5\n return { x: edge + 0.5, edge, tip, head: tip - PIN_MARKER.rise }\n }\n\n /** Whether the box stands: while the pin is hovered, selected or typed into. */\n private boxShown(): boolean {\n return this.hovered || this.state === 'selected' || this.state === 'editing' || !!this.textDraft\n }\n\n /** The box and its words over the marker. */\n protected place(viewport: Viewport): (WordsPlace & { tip: number; x0: number }) | null {\n const m = this.marker(viewport)\n if (!m) return null\n const lineHeight = Math.round(this.style.fontSize * 1.35)\n const { block, placeholder } = this.shownWords(lineMeasure(this.style), PIN_BOX.wrap)\n const shown = placeholder ?? block\n const height = shown.lines.length * lineHeight + PIN_BOX.roomDown\n const bottom = m.tip - PIN_BOX.lift\n const box = { x: m.edge - PIN_BOX.width / 2, y: bottom - height, width: PIN_BOX.width, height }\n return { box, x: box.x + PIN_BOX.padLeft, y: box.y + PIN_BOX.lineTop, lineHeight, block, placeholder, tip: m.tip, x0: m.x }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.props.savedLook) {\n this.paintSaved(ctx, viewport)\n return\n }\n const m = this.marker(viewport)\n if (!m) return\n const { head, hole, bend } = PIN_MARKER\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.moveTo(m.x, m.tip)\n ctx.quadraticCurveTo(m.x - head, m.head + bend, m.x - head, m.head)\n ctx.arc(m.x, m.head, head, Math.PI, 0)\n ctx.quadraticCurveTo(m.x + head, m.head + bend, m.x, m.tip)\n ctx.closePath()\n ctx.moveTo(m.x + hole, m.head)\n ctx.arc(m.x, m.head, hole, 0, Math.PI * 2)\n ctx.fill('evenodd')\n ctx.restore()\n if (!this.boxShown()) return\n const at = this.place(viewport)\n if (!at) return\n const { box } = at\n const { half, depth } = PIN_BOX.pointer\n const bottom = box.y + box.height\n const background = this.props.fillBackground ? fillPaint(this.style) : null\n ctx.save()\n ctx.setLineDash([])\n ctx.beginPath()\n ctx.roundRect(box.x, box.y, box.width, box.height, PIN_BOX.radius)\n ctx.moveTo(at.x0 - half, bottom)\n ctx.lineTo(at.x0, bottom + depth)\n ctx.lineTo(at.x0 + half, bottom)\n ctx.closePath()\n if (background) {\n ctx.shadowColor = NOTE_SHADOW.color\n ctx.shadowBlur = NOTE_SHADOW.blur\n ctx.shadowOffsetY = NOTE_SHADOW.offsetY\n ctx.fillStyle = background\n ctx.fill()\n ctx.shadowColor = 'transparent'\n }\n if (this.props.drawBorder) {\n ctx.strokeStyle = this.props.borderColor\n ctx.lineWidth = 1\n ctx.stroke()\n }\n ctx.restore()\n paintTextEntry(ctx, {\n x: at.x,\n y: at.y,\n width: PIN_BOX.wrap,\n lineHeight: at.lineHeight,\n font: fontOf(this.style),\n color: this.style.textColor,\n align: 'left',\n block: at.block,\n placeholder: at.placeholder ? { block: at.placeholder, alpha: PLACEHOLDER_ALPHA } : null,\n draft: this.textDraft,\n measure: lineMeasure(this.style),\n })\n }\n\n /** A format-2 pin: a smaller teardrop in its stroke color, its words in a box under it. */\n private paintSaved(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n const p = anchor && this.anchorToPixel(anchor, viewport)\n if (!p) return\n const r = 7\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.arc(p.x, p.y - r * 2, r, Math.PI * 0.85, Math.PI * 0.15)\n ctx.lineTo(p.x, p.y)\n ctx.closePath()\n ctx.fill()\n ctx.fillStyle = '#ffffff'\n ctx.beginPath()\n ctx.arc(p.x, p.y - r * 2, r / 2.6, 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n if (this.props.text) {\n const { width } = measureTextBlock(this.props.text, this.style)\n paintTextBlock(ctx, this.props.text, { x: p.x - (width + 12) / 2, y: p.y + 6 }, this.style, {\n background: this.props.fillBackground ? (fillPaint(this.style) ?? undefined) : undefined,\n borderColor: this.props.drawBorder ? this.props.borderColor : undefined,\n })\n }\n }\n\n override textFrame(viewport: Viewport): TextEditFrame | null {\n const at = this.place(viewport)\n return at ? { ...wordsFrame(at, fontOf(this.style), 'left', PIN_BOX.wrap), wrapWidth: PIN_BOX.wrap } : null\n }\n\n /** The words are the box's, while it stands. */\n override wordsAt(point: Point, viewport: Viewport): boolean {\n if (this.props.savedLook || !this.boxShown()) return false\n const at = this.place(viewport)\n return !!at && inBox(point, at.box, 0)\n }\n\n /** Over the box of a selected pin the pointer reads as typing, which a press there does. */\n protected override cursorAt(point: Point, viewport: Viewport): string | null {\n return this.state === 'selected' && this.wordsAt(point, viewport) ? 'text' : null\n }\n\n override handleShape(): HandleShape {\n return this.props.savedLook ? 'circle' : 'small'\n }\n\n /** An empty pin shows its placeholder in its own box, so it needs no hint above it. */\n override paintTextHint(): void {}\n\n testHit(point: Point, viewport: Viewport): boolean {\n if (this.props.savedLook) {\n const anchor = this.anchors[0]\n const p = anchor && this.anchorToPixel(anchor, viewport)\n return !!p && inBox(point, { x: p.x - 9, y: p.y - 24, width: 18, height: 26 }, 3)\n }\n const m = this.marker(viewport)\n if (!m) return false\n if (Math.hypot(point.x - m.x, point.y - m.head) <= PIN_MARKER.head + 2) return true\n // The sides, narrowing from the head's widest to the tip.\n const below = point.y - m.head\n if (below >= 0 && point.y <= m.tip + 2 && Math.abs(point.x - m.x) <= PIN_MARKER.head * (1 - below / PIN_MARKER.rise) + 2) return true\n if (!this.boxShown()) return false\n const at = this.place(viewport)\n return !!at && inBox(point, { ...at.box, height: at.box.height + PIN_BOX.pointer.depth }, 2)\n }\n}\n\n/** A signpost's plate: whether it leads with an emoji, the emoji, and how far it stands from its\n * bar. */\nexport type SignpostProps = TextProps & {\n showImage: boolean\n emoji: string\n /** How far the plate stands from its bar, in percent of the pane's height: above the bar's high,\n * or below its low where it is negative. Null until the signpost is first stood on a pane, where\n * the point it was placed at sets it. */\n position: number | null\n /** A format-2 signpost's look, a dark plate over a stem planted at its point, painted as format 2\n * did until the signpost's settings change. */\n savedLook: SavedLook\n}\n\n/** How far a signpost's post stops short of its bar, the room its plate keeps past its words across\n * and down, its corners' radius, and its post's ink. */\nconst POST_GAP = 4\nconst PLATE_ROOM_ACROSS = 18\nconst PLATE_ROOM_DOWN = 11\nconst PLATE_RADIUS = 6\nconst POST_INK = '#808080'\n\n/**\n * Signpost: a plate on a post, planted on a bar. The plate's bottom-centre is the signpost's\n * point, standing its position's share of the pane's height above the bar's high or below its low,\n * so it keeps its height over the bar as the price scale moves. A one pixel post runs from four\n * pixels off the bar to the plate. The plate is an outline in the chart's edge ink with corners\n * rounded at 6, its words centred in the chart's text ink on lines a quarter taller than their\n * size, so it is its widest line and 18px wide and 11px more than its lines tall, growing up. With\n * its emoji shown, the plate is the drawing's stroke color and leads with the emoji. Selected, it\n * shows a square handle on its point, which moves the plate up and down over its bar.\n */\nexport class Signpost extends Drawing<SignpostProps> {\n readonly type = 'signpost'\n\n protected override defaultProps(): SignpostProps {\n return { text: '', showImage: false, emoji: '🙂', position: null, savedLook: null }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n /** A format-2 signpost was a dark plate bordered in its stroke color over a stem from its point,\n * a dot at its foot. It paints so until its settings change, its point where it was saved. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, savedLook: {} }\n }\n\n override applyProps(patch: Partial<SignpostProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n /** A saved look's plate: above the point, the stem's height over it. */\n protected savedPlate(viewport: Viewport): { box: Box; p: Point } | null {\n const anchor = this.anchors[0]\n const p = anchor && super.anchorToPixel(anchor, viewport)\n if (!p) return null\n const { width, height } = measureTextBlock(this.props.text || ' ', this.style)\n return { box: { x: p.x - (width + 12) / 2, y: p.y - 34 - height, width: width + 12, height: height + 12 }, p }\n }\n\n protected paintSavedLook(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const plate = this.savedPlate(viewport)\n if (!plate) return\n const { box, p } = plate\n ctx.save()\n ctx.setLineDash([])\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1.5\n ctx.beginPath()\n ctx.moveTo(p.x, p.y)\n ctx.lineTo(p.x, box.y + box.height)\n ctx.stroke()\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.arc(p.x, p.y, 3, 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n paintTextBlock(ctx, this.props.text || ' ', { x: box.x, y: box.y }, this.style, { background: withAlpha('#1b1f27', 0.95), borderColor: this.style.lineColor })\n }\n\n /** A signpost first stood on a pane takes its position from the point it was placed at. */\n override attached(params: SeriesAttachedParameter<Time>): void {\n super.attached(params)\n const anchor = this.anchors[0]\n const viewport = this.getViewport()\n if (this.props.savedLook || this.props.position !== null || !anchor || !viewport) return\n const stood = this.standAt(anchor, viewport)\n if (!stood) return\n this._props = { ...this._props, position: stood.position }\n this._anchors[0] = stood.anchor\n }\n\n /** A point the plate is moved to, as the signpost holds it: its foot on the bar there, the high\n * unless the point is below the bar's low, and the share of the pane's height between the foot\n * and the point. A point with no bar under it is its own foot. */\n protected standAt(point: Anchor, viewport: Viewport): { anchor: Anchor; position: number } | null {\n const y = viewport.yOf(point.price)\n if (y === null || !(viewport.height > 0)) return null\n const bar = barAt(this.bars(), point.time)\n const highY = bar ? viewport.yOf(bar.high) : null\n const lowY = bar ? viewport.yOf(bar.low) : null\n if (!bar || highY === null || lowY === null) return { anchor: { time: point.time, price: point.price }, position: 0 }\n if (y > lowY) return { anchor: { time: point.time, price: bar.low }, position: -((y - lowY) / viewport.height) * 100 }\n return { anchor: { time: point.time, price: bar.high }, position: (Math.max(0, highY - y) / viewport.height) * 100 }\n }\n\n /** Where the foot and the plate stand on the pane. */\n protected stand(viewport: Viewport, anchor: Anchor | undefined = this.anchors[0]): { foot: Point; plate: Point; above: boolean } | null {\n if (!anchor) return null\n const x = viewport.xOf(anchor.time)\n if (x === null) return null\n const position = this.props.position\n if (position === null) {\n const y = viewport.yOf(anchor.price)\n return y === null ? null : { foot: { x, y }, plate: { x, y }, above: true }\n }\n const bar = barAt(this.bars(), anchor.time)\n const footY = viewport.yOf(bar ? (position >= 0 ? bar.high : bar.low) : anchor.price)\n if (footY === null) return null\n return { foot: { x, y: footY }, plate: { x, y: footY - (position / 100) * viewport.height }, above: position >= 0 }\n }\n\n /** The handle stands where the plate meets its pole, or at the point while the saved look stands. */\n override anchorToPixel(anchor: Anchor, viewport: Viewport): Point | null {\n if (this.props.savedLook) return super.anchorToPixel(anchor, viewport)\n return this.stand(viewport, anchor)?.plate ?? null\n }\n\n /** A move of the plate stands it over the bar under the point, the point's height away. A move\n * that keeps the foot's price, as typing a bar does, keeps the plate's height over the new bar. */\n override updateAnchor(index: number, anchor: Anchor): void {\n const current = this.anchors[0]\n const viewport = this.getViewport()\n if (index !== 0 || !current || this.props.savedLook) {\n super.updateAnchor(index, anchor)\n return\n }\n const position = this.props.position\n if (anchor.price === current.price && position !== null) {\n const bar = barAt(this.bars(), anchor.time)\n super.updateAnchor(0, { time: anchor.time, price: bar ? (position >= 0 ? bar.high : bar.low) : anchor.price })\n return\n }\n const stood = viewport ? this.standAt(anchor, viewport) : null\n if (!stood) {\n super.updateAnchor(0, anchor)\n return\n }\n this._props = { ...this._props, position: stood.position }\n super.updateAnchor(0, stood.anchor)\n }\n\n /** The plate's box and its words, its emoji, and its post's column and ends. */\n protected plate(viewport: Viewport): { box: Box; words: WordsPlace; emoji: { x: number; y: number; size: number } | null; post: { x: number; from: number; to: number } | null } | null {\n const stand = this.stand(viewport)\n if (!stand) return null\n const { block, placeholder } = this.shownWords(lineMeasure(this.style))\n const shown = placeholder ?? block\n const lineHeight = Math.round(this.style.fontSize * 1.25)\n const emoji = this.props.showImage && this.props.emoji ? Math.round(this.style.fontSize * 1.4) : 0\n const gap = emoji && shown.width ? 4 : 0\n const content = emoji + gap + shown.width\n const textHeight = shown.lines.length * lineHeight\n const inner = Math.max(emoji, textHeight)\n const width = Math.round(content + PLATE_ROOM_ACROSS)\n const height = inner + PLATE_ROOM_DOWN\n const ax = Math.round(stand.plate.x)\n const ay = Math.round(stand.plate.y)\n // The plate's bottom row is its point's.\n const box = { x: ax - Math.floor(width / 2), y: ay - height + 1, width, height }\n const start = ax - content / 2\n const top = box.y + PLATE_ROOM_DOWN / 2\n const words = { box, x: start + emoji + gap, y: top + (inner - textHeight) / 2, lineHeight, block, placeholder }\n const footY = Math.round(stand.foot.y)\n const span = stand.above ? { from: ay + 1, to: footY - POST_GAP + 1 } : { from: footY + POST_GAP, to: box.y }\n return {\n box,\n words,\n emoji: emoji ? { x: start, y: top + (inner - emoji) / 2, size: emoji } : null,\n post: span.to > span.from ? { x: ax + 0.5, ...span } : null,\n }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.props.savedLook && !this.textDraft) {\n this.paintSavedLook(ctx, viewport)\n return\n }\n const plate = this.plate(viewport)\n if (!plate) return\n const { box, words } = plate\n const inks = this.inks()\n const filled = !!plate.emoji\n ctx.save()\n ctx.setLineDash([])\n ctx.lineWidth = 1\n if (plate.post) {\n ctx.strokeStyle = POST_INK\n ctx.beginPath()\n ctx.moveTo(plate.post.x, plate.post.from)\n ctx.lineTo(plate.post.x, plate.post.to)\n ctx.stroke()\n }\n // The outline's pixel rides the plate's edge, so the path stands half a pixel in.\n ctx.beginPath()\n ctx.roundRect(box.x + 0.5, box.y + 0.5, box.width - 1, box.height - 1, PLATE_RADIUS)\n if (filled) {\n ctx.fillStyle = this.style.lineColor\n ctx.fill()\n }\n ctx.strokeStyle = filled ? this.style.lineColor : inks.edge\n ctx.stroke()\n ctx.restore()\n if (plate.emoji) {\n const { x, y, size } = plate.emoji\n const url = this.glyphUrl(this.props.emoji)\n const art = url ? glyphArtwork(url, () => this.requestUpdate()) : null\n if (art) ctx.drawImage(art, x, y, size, size)\n else {\n ctx.save()\n ctx.font = `${size}px ui-sans-serif, system-ui, sans-serif`\n ctx.textBaseline = 'top'\n ctx.textAlign = 'left'\n ctx.fillStyle = '#000000'\n ctx.fillText(this.props.emoji, x, y)\n ctx.restore()\n }\n }\n paintTextEntry(ctx, {\n x: words.x,\n y: words.y,\n width: (words.placeholder ?? words.block).width,\n lineHeight: words.lineHeight,\n font: fontOf(this.style),\n color: filled ? inkOn(this.style.lineColor) : inks.text,\n align: 'center',\n block: words.block,\n placeholder: words.placeholder ? { block: words.placeholder, alpha: PLACEHOLDER_ALPHA } : null,\n draft: this.textDraft,\n measure: lineMeasure(this.style),\n })\n }\n\n override textFrame(viewport: Viewport): TextEditFrame | null {\n const plate = this.plate(viewport)\n return plate ? wordsFrame(plate.words, fontOf(this.style), 'center') : null\n }\n\n /** The signpost's handle is square. */\n override handleShape(): HandleShape {\n return 'square'\n }\n\n /** Its handle moves the plate up and down over its bar: the bar stays. */\n override dragAnchorTo(index: number, anchor: Anchor): void {\n const current = this.anchors[index]\n this.updateAnchor(index, current && !this.props.savedLook ? { time: current.time, price: anchor.price } : anchor)\n }\n\n /** The words are the plate's. */\n override wordsAt(point: Point, viewport: Viewport): boolean {\n if (this.props.savedLook) return this.testHit(point, viewport)\n const plate = this.plate(viewport)\n return !!plate && inBox(point, plate.box)\n }\n\n /** Over the plate of a selected signpost the pointer reads as typing, which a press there does. */\n protected override cursorAt(point: Point, viewport: Viewport): string | null {\n return this.state === 'selected' && this.wordsAt(point, viewport) ? 'text' : null\n }\n\n /** An empty signpost shows its placeholder on its own plate, so it needs no hint above it. */\n override paintTextHint(): void {}\n\n testHit(point: Point, viewport: Viewport): boolean {\n if (this.props.savedLook) {\n const saved = this.savedPlate(viewport)\n return !!saved && inBox(point, saved.box)\n }\n const plate = this.plate(viewport)\n if (!plate) return false\n if (inBox(point, plate.box)) return true\n return !!plate.post && Math.abs(point.x - plate.post.x) <= 5 && point.y >= plate.post.from - 2 && point.y <= plate.post.to + 2\n }\n}\n\n/** An arrow marker's proportions to its length: where its head's back stands from its tail, half\n * its shaft's width at the head, half the head's width across its barbs, and half the width it\n * starts at, at its tail. */\nconst ARROW_MARKER = { back: 0.755, shaft: 0.084, barbs: 0.157, tail: 1 } as const\n\n/**\n * Arrow marker: a filled arrow from its first point, its tail, to its second, its tip, in the\n * drawing's stroke color. Its shaft widens from its tail to a broad head whose tip is the second\n * point, every part in proportion to its length. The words sit at the tail, clear of the arrow,\n * and are typed in its settings.\n */\nexport class ArrowMarker extends Drawing<TextProps & SavedLookProps> {\n readonly type = 'arrow_marker'\n\n protected override defaultProps(): TextProps & SavedLookProps {\n return { text: '', savedLook: null }\n }\n\n /** A format-2 arrow marker's first point was its tip and its second its tail, a fat arrow with a\n * head as wide as a third of its length; its points turn to the present order and it paints so\n * until its settings change. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n const [tip, tail] = this._anchors\n if (tip && tail) this._anchors = [tail, tip]\n this._props = { ...this._props, savedLook: {} }\n }\n\n override applyProps(patch: Partial<TextProps & SavedLookProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The tail, the tip, the length between them and the direction from the tail to the tip. */\n private geometry(viewport: Viewport): { tail: Point; tip: Point; length: number; angle: number } | null {\n const [tail, tip] = this.anchorPixels(viewport)\n if (!tail || !tip) return null\n return { tail, tip, length: Math.hypot(tip.x - tail.x, tip.y - tail.y), angle: Math.atan2(tip.y - tail.y, tip.x - tail.x) }\n }\n\n /** The arrow's outline from its tail at the origin to its tip along +x. */\n private outline(length: number): [number, number][] {\n const back = length * ARROW_MARKER.back\n const shaft = length * ARROW_MARKER.shaft\n const barbs = length * ARROW_MARKER.barbs\n const tail = Math.min(ARROW_MARKER.tail, shaft)\n return [\n [0, -tail],\n [back, -shaft],\n [back, -barbs],\n [length, 0],\n [back, barbs],\n [back, shaft],\n [0, tail],\n ]\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.props.savedLook) {\n this.paintSaved(ctx, viewport)\n return\n }\n const g = this.geometry(viewport)\n if (!g) return\n ctx.save()\n ctx.setLineDash([])\n ctx.translate(g.tail.x, g.tail.y)\n ctx.rotate(g.angle)\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n this.outline(g.length).forEach(([x, y], i) => (i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y)))\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n this.paintWords(ctx, g.tail, g.tip)\n }\n\n /** The words at the tail, beyond it from the tip. */\n private paintWords(ctx: CanvasRenderingContext2D, tail: Point, tip: Point): void {\n if (!this.props.text) return\n const { width, height } = measureTextBlock(this.props.text, this.style)\n const above = tail.y <= tip.y\n paintTextBlock(ctx, this.props.text, { x: tail.x - (width + 12) / 2, y: above ? tail.y - height - 12 - 8 : tail.y + 8 }, this.style)\n }\n\n /** A format-2 arrow marker: a fat arrow whose head is as wide as a third of its length. */\n private paintSaved(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const g = this.geometry(viewport)\n if (!g) return\n const len = Math.max(18, g.length)\n const w = Math.max(8, Math.min(46, len * 0.34))\n ctx.save()\n ctx.setLineDash([])\n ctx.translate(g.tip.x, g.tip.y)\n ctx.rotate(g.angle + Math.PI)\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.moveTo(0, 0)\n ctx.lineTo(w, -w)\n ctx.lineTo(w, -w / 2)\n ctx.lineTo(len, -w / 2)\n ctx.lineTo(len, w / 2)\n ctx.lineTo(w, w / 2)\n ctx.lineTo(w, w)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n this.paintWords(ctx, g.tail, g.tip)\n }\n\n /** Its words are typed in its settings, so it shows no invitation to type on the chart. */\n override paintTextHint(): void {}\n\n testHit(point: Point, viewport: Viewport): boolean {\n const g = this.geometry(viewport)\n if (!g) return false\n // The point in the arrow's own frame: along it from the tail, and across it.\n const dx = point.x - g.tail.x\n const dy = point.y - g.tail.y\n const along = dx * Math.cos(g.angle) + dy * Math.sin(g.angle)\n const across = Math.abs(-dx * Math.sin(g.angle) + dy * Math.cos(g.angle))\n if (this.props.savedLook) {\n const w = Math.max(8, Math.min(46, Math.max(18, g.length) * 0.34))\n return along >= -4 && along <= Math.max(18, g.length) + 4 && across <= w + 4\n }\n if (along < -4 || along > g.length + 4) return false\n const back = g.length * ARROW_MARKER.back\n const reach =\n along <= back\n ? ARROW_MARKER.tail + (g.length * ARROW_MARKER.shaft - ARROW_MARKER.tail) * Math.max(0, along / Math.max(back, 1))\n : g.length * ARROW_MARKER.barbs * Math.max(0, (g.length - along) / Math.max(g.length - back, 1))\n return across <= reach + 4\n }\n}\n\n/** A flag mark: its flag's ink, and a format-2 save's look. */\nexport type FlagProps = SavedLookProps\n\n/** How a flag mark stands on its point: its pole runs up 20px from the point, and its flag, from\n * 2px right of the pole to 19px, hangs 10px down from the pole's top, notched 3px in at the middle\n * of its far edge. */\nconst FLAG = { pole: 20, from: 2, to: 19, height: 10, notch: 3 } as const\n\n/**\n * Flag mark: a flag on a one pixel grey pole standing on a chart point, the flag in the drawing's\n * stroke color. Selected, it shows a small ring on its point.\n */\nexport class FlagMark extends Drawing<FlagProps> {\n readonly type = 'flag'\n\n protected override defaultProps(): FlagProps {\n return { savedLook: null }\n }\n\n /** A format-2 flag stood on a 2px pole in its stroke color, a triangle for its flag; it paints so\n * until its settings change. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, savedLook: {} }\n }\n\n override applyProps(patch: Partial<FlagProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n /** The point's pixel. */\n private foot(viewport: Viewport): Point | null {\n const anchor = this.anchors[0]\n const p = anchor && this.anchorToPixel(anchor, viewport)\n return p ? { x: Math.round(p.x), y: Math.round(p.y) } : null\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.props.savedLook) {\n this.paintSaved(ctx, viewport)\n return\n }\n const p = this.foot(viewport)\n if (!p) return\n const top = p.y - FLAG.pole\n ctx.save()\n ctx.setLineDash([])\n ctx.strokeStyle = POST_INK\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(p.x + 0.5, top)\n ctx.lineTo(p.x + 0.5, p.y)\n ctx.stroke()\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.moveTo(p.x + FLAG.from, top)\n ctx.lineTo(p.x + FLAG.to, top)\n ctx.lineTo(p.x + FLAG.to - FLAG.notch, top + FLAG.height / 2)\n ctx.lineTo(p.x + FLAG.to, top + FLAG.height)\n ctx.lineTo(p.x + FLAG.from, top + FLAG.height)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n\n /** A format-2 flag: a triangle on a 2px pole, both in the drawing's stroke color. */\n private paintSaved(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n const p = anchor && this.anchorToPixel(anchor, viewport)\n if (!p) return\n const height = 22\n ctx.save()\n ctx.setLineDash([])\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 2\n ctx.beginPath()\n ctx.moveTo(p.x, p.y)\n ctx.lineTo(p.x, p.y - height)\n ctx.stroke()\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.moveTo(p.x, p.y - height)\n ctx.lineTo(p.x + 16, p.y - height + 5)\n ctx.lineTo(p.x, p.y - height + 10)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n\n override handleShape(): HandleShape {\n return this.props.savedLook ? 'circle' : 'small'\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n if (this.props.savedLook) {\n const anchor = this.anchors[0]\n const p = anchor && this.anchorToPixel(anchor, viewport)\n return !!p && inBox(point, { x: p.x - 4, y: p.y - 24, width: 24, height: 26 })\n }\n const p = this.foot(viewport)\n if (!p) return false\n return inBox(point, { x: p.x - 3, y: p.y - FLAG.pole, width: FLAG.to + 3, height: FLAG.height }, 2) || inBox(point, { x: p.x - 3, y: p.y - FLAG.pole, width: 7, height: FLAG.pole }, 2)\n }\n}\n","import type { DrawingStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { barsInRange, volumeText } from '../core/bars'\nimport { applyStroke, fillPaint, paintArrowHead, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\n\nfunction box(a: Point, b: Point): { x: number; y: number; width: number; height: number } {\n return {\n x: Math.min(a.x, b.x),\n y: Math.min(a.y, b.y),\n width: Math.abs(b.x - a.x),\n height: Math.abs(b.y - a.y),\n }\n}\n\nfunction inBox(p: Point, r: { x: number; y: number; width: number; height: number }, pad = 4): boolean {\n return p.x >= r.x - pad && p.x <= r.x + r.width + pad && p.y >= r.y - pad && p.y <= r.y + r.height + pad\n}\n\n/** What a range meter reads and how: the stats its label reads (a meter offers the ones its axes\n * measure), its span's background, its label's words and background, and the viewer's own words. */\nexport type RangeMeterProps = {\n /** The viewer's own words, at the span's middle, in the drawing's text style. */\n text: string\n showPriceRange: boolean\n showPercentChange: boolean\n showPipsChange: boolean\n showBarsRange: boolean\n showDateTimeRange: boolean\n showVolume: boolean\n /** The span's background, in the drawing's fill. */\n fillBackground: boolean\n /** The stats label's words: their color and size. */\n labelColor: string\n labelFontSize: number\n /** The stats label's background. */\n fillLabelBackground: boolean\n labelBackgroundColor: string\n /** The stats label takes the drawing's text weight and slant. */\n labelTextStyle: boolean\n}\n\n/** A price range runs its span on to the pane's left or right edge. */\nexport type PriceRangeProps = RangeMeterProps & { extendLeft: boolean; extendRight: boolean }\n/** A date range runs its span on to the pane's top or bottom. */\nexport type DateRangeProps = RangeMeterProps & { extendTop: boolean; extendBottom: boolean }\n/** A date and price range draws its span's border on a switch, in a stroke of its own, and runs its\n * span on to the pane's left and right edges where a save carries that, which its pages do not\n * offer. */\nexport type DatePriceRangeProps = RangeMeterProps & { drawBorder: boolean; borderColor: string; borderWidth: number; extendLeft: boolean; extendRight: boolean }\n\nconst METER_PROPS: RangeMeterProps = {\n text: '',\n showPriceRange: false,\n showPercentChange: false,\n showPipsChange: false,\n showBarsRange: false,\n showDateTimeRange: false,\n showVolume: false,\n fillBackground: true,\n labelColor: '#ffffff',\n labelFontSize: 12,\n fillLabelBackground: true,\n labelBackgroundColor: 'rgba(46, 46, 46, 0.4)',\n labelTextStyle: false,\n}\n\n/** The props a meter keeps from a save: its stats under their earlier names, and its one extension\n * as both of the sides it runs on to, where it runs on at all. */\nfunction upgradeMeter<P extends RangeMeterProps>(props: Partial<P>, sides: readonly (keyof P)[]): Partial<P> {\n const saved = props as Partial<P> & { showPriceDelta?: boolean; showPercent?: boolean; showBars?: boolean; showTimeSpan?: boolean; extend?: boolean }\n const out: Record<string, unknown> = { ...saved }\n const renamed: [string, string][] = [\n ['showPriceDelta', 'showPriceRange'],\n ['showPercent', 'showPercentChange'],\n ['showBars', 'showBarsRange'],\n ['showTimeSpan', 'showDateTimeRange'],\n ]\n for (const [from, to] of renamed) {\n if (from in out) {\n if (!(to in out)) out[to] = out[from]\n delete out[from]\n }\n }\n if ('extend' in out) {\n if (out.extend === true) for (const side of sides) if (!(side in out)) out[side as string] = true\n delete out.extend\n }\n return out as Partial<P>\n}\n\n/** Shared skeleton for the range meters: shaded span, measuring arrows and the stats label. */\nabstract class RangeMeter<P extends RangeMeterProps> extends Drawing<P> {\n requiredAnchors(): number {\n return 2\n }\n\n protected pixels(viewport: Viewport): { a: Point; b: Point } | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n return { a, b }\n }\n\n /** The hint sits at the span's center, which is where the text itself renders. */\n protected override textHintPlacement(points: Point[]): { x: number; y: number; angle: number } {\n const [a, b] = points\n return a && b ? { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2, angle: 0 } : super.textHintPlacement(points)\n }\n\n /** The span as it is shaded: the box between the points, run on as the meter extends. */\n protected span(a: Point, b: Point, _viewport: Viewport): { x: number; y: number; width: number; height: number } {\n return box(a, b)\n }\n\n protected stats(viewport: Viewport): string[] {\n const [a, b] = this.anchors\n if (!a || !b) return []\n const out: string[] = []\n if (this.measuresPrice()) {\n const dPrice = b.price - a.price\n const pct = a.price !== 0 ? (dPrice / Math.abs(a.price)) * 100 : 0\n const tick = this.tickSize()\n const parts: string[] = []\n if (this.props.showPriceRange) parts.push(`${dPrice >= 0 ? '+' : ''}${this.formatPrice(dPrice)}`)\n if (this.props.showPercentChange) parts.push(`(${pct >= 0 ? '+' : ''}${pct.toFixed(2)}%)`)\n // A change in pips needs the host's tick; without one it is left out.\n if (this.props.showPipsChange && tick && tick > 0) parts.push(String(Math.round(dPrice / tick)))\n if (parts.length) out.push(parts.join(' '))\n }\n if (this.measuresTime()) {\n if (this.props.showBarsRange) {\n const bars = viewport.barsBetween(a.time, b.time)\n if (bars !== null) out.push(`${Math.round(bars)} bars`)\n }\n if (this.props.showDateTimeRange) {\n const secs = Number(b.time) - Number(a.time)\n if (Number.isFinite(secs) && secs !== 0) out.push(spanText(Math.abs(secs)))\n }\n if (this.props.showVolume) {\n const range = barsInRange(this.bars(), a.time, b.time)\n const total = range.reduce((sum, bar) => sum + (bar.volume ?? 0), 0)\n if (total > 0) out.push(`Vol ${volumeText(total)}`)\n }\n }\n return out\n }\n\n protected abstract measuresPrice(): boolean\n protected abstract measuresTime(): boolean\n\n /** The span's border, where the meter draws one. */\n protected paintBorder(_ctx: CanvasRenderingContext2D, _r: { x: number; y: number; width: number; height: number }): void {}\n\n /** A format-2 meter shaded its span in its stroke color at its fill's opacity, 8% at the least,\n * read no price moves, and wrote its stats in its own text style on a dark plate at 92%. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n const s = this._style\n this._style = { ...s, fillColor: s.lineColor, fillOpacity: Math.max(0.08, s.fillOpacity) }\n this._props = {\n ...this._props,\n fillBackground: true,\n showPipsChange: false,\n labelColor: s.textColor,\n labelFontSize: s.fontSize,\n fillLabelBackground: true,\n labelBackgroundColor: withAlpha('#1b1f27', 0.92),\n labelTextStyle: true,\n }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const px = this.pixels(viewport)\n if (!px) return\n const { a, b } = px\n const r = this.span(a, b, viewport)\n const fill = this.props.fillBackground !== false ? fillPaint(this.style) : null\n if (fill) {\n ctx.save()\n ctx.fillStyle = fill\n ctx.fillRect(r.x, r.y, r.width, r.height)\n ctx.restore()\n }\n this.paintBorder(ctx, r)\n applyStroke(ctx, this.style)\n if (this.measuresPrice()) {\n const x = (a.x + b.x) / 2\n strokeSegment(ctx, { x, y: a.y }, { x, y: b.y })\n paintArrowHead(ctx, { x, y: a.y }, { x, y: b.y }, this.style)\n }\n if (this.measuresTime()) {\n const y = this.measuresPrice() ? Math.max(a.y, b.y) : (a.y + b.y) / 2\n strokeSegment(ctx, { x: a.x, y }, { x: b.x, y })\n paintArrowHead(ctx, { x: a.x, y }, { x: b.x, y }, this.style)\n }\n const stats = this.stats(viewport)\n if (stats.length) {\n const label = box(a, b)\n const plain = !this.props.labelTextStyle\n const ink: DrawingStyle = { ...this.style, textColor: this.props.labelColor, fontSize: this.props.labelFontSize, ...(plain ? { bold: false, italic: false } : {}) }\n paintLabel(ctx, stats.join(' · '), { x: label.x + label.width / 2, y: label.y + label.height + 16 }, ink, {\n align: 'center',\n ...(this.props.fillLabelBackground !== false ? { background: this.props.labelBackgroundColor } : {}),\n })\n }\n if (this.props.text) {\n const middle = box(a, b)\n paintLabel(ctx, this.props.text, { x: middle.x + middle.width / 2, y: middle.y + middle.height / 2 }, this.style, { align: 'center' })\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const px = this.pixels(viewport)\n if (!px) return false\n return inBox(point, box(px.a, px.b))\n }\n}\n\n/** Vertical meter: price delta and % between two levels. */\nexport class PriceRange extends RangeMeter<PriceRangeProps> {\n readonly type = 'price_range'\n\n protected override defaultProps(): PriceRangeProps {\n return { ...METER_PROPS, showPriceRange: true, showPercentChange: true, showPipsChange: true, showVolume: true, extendLeft: false, extendRight: false }\n }\n\n protected override upgradeProps(props: Partial<PriceRangeProps>): Partial<PriceRangeProps> {\n return upgradeMeter(props, ['extendLeft', 'extendRight'])\n }\n\n protected override span(a: Point, b: Point, viewport: Viewport): { x: number; y: number; width: number; height: number } {\n const r = box(a, b)\n const left = this.props.extendLeft ? 0 : r.x\n const right = this.props.extendRight ? viewport.width : r.x + r.width\n return { x: left, y: r.y, width: right - left, height: r.height }\n }\n\n protected measuresPrice(): boolean {\n return true\n }\n\n protected measuresTime(): boolean {\n return false\n }\n}\n\n/** Horizontal meter: bar count and time span between two times. */\nexport class DateRange extends RangeMeter<DateRangeProps> {\n readonly type = 'date_range'\n\n protected override defaultProps(): DateRangeProps {\n return { ...METER_PROPS, showBarsRange: true, showDateTimeRange: true, showVolume: true, extendTop: false, extendBottom: false }\n }\n\n protected override upgradeProps(props: Partial<DateRangeProps>): Partial<DateRangeProps> {\n return upgradeMeter(props, ['extendTop', 'extendBottom'])\n }\n\n protected override span(a: Point, b: Point, viewport: Viewport): { x: number; y: number; width: number; height: number } {\n const r = box(a, b)\n const top = this.props.extendTop ? 0 : r.y\n const bottom = this.props.extendBottom ? viewport.height : r.y + r.height\n return { x: r.x, y: top, width: r.width, height: bottom - top }\n }\n\n protected measuresPrice(): boolean {\n return false\n }\n\n protected measuresTime(): boolean {\n return true\n }\n}\n\n/** Combined meter: price and time deltas of the spanned box. */\nexport class DatePriceRange extends RangeMeter<DatePriceRangeProps> {\n readonly type = 'date_and_price_range'\n\n protected override defaultProps(): DatePriceRangeProps {\n return {\n ...METER_PROPS,\n showPriceRange: true,\n showPercentChange: true,\n showPipsChange: true,\n showBarsRange: true,\n showDateTimeRange: true,\n showVolume: true,\n drawBorder: false,\n borderColor: '#2962ff',\n borderWidth: 1,\n extendLeft: false,\n extendRight: false,\n }\n }\n\n protected override upgradeProps(props: Partial<DatePriceRangeProps>): Partial<DatePriceRangeProps> {\n return upgradeMeter(props, ['extendLeft', 'extendRight'])\n }\n\n protected override span(a: Point, b: Point, viewport: Viewport): { x: number; y: number; width: number; height: number } {\n const r = box(a, b)\n const left = this.props.extendLeft ? 0 : r.x\n const right = this.props.extendRight ? viewport.width : r.x + r.width\n return { x: left, y: r.y, width: right - left, height: r.height }\n }\n\n protected override paintBorder(ctx: CanvasRenderingContext2D, r: { x: number; y: number; width: number; height: number }): void {\n if (!this.props.drawBorder) return\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: this.props.borderColor, lineWidth: this.props.borderWidth, lineStyle: 'solid' })\n ctx.strokeRect(r.x, r.y, r.width, r.height)\n ctx.restore()\n }\n\n protected measuresPrice(): boolean {\n return true\n }\n\n protected measuresTime(): boolean {\n return true\n }\n}\n\nconst MEASURE_UP = '#2962ff'\nconst MEASURE_DOWN = '#f23645'\n\n/**\n * The measure action's readout: a direction-colored zone (blue measuring up, red down) with a\n * vertical arrow spanning it, a horizontal arrow at mid-height, and a solid pill above/below\n * carrying `Δprice (Δ%) Δticks` over `bars, duration`.\n */\nexport class Measure extends Drawing {\n readonly type = 'measure'\n\n requiredAnchors(): number {\n return 2\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [pa, pb] = this.anchorPixels(viewport)\n const [a, b] = this.anchors\n if (!pa || !pb || !a || !b) return\n const up = b.price >= a.price\n const color = up ? MEASURE_UP : MEASURE_DOWN\n const r = box(pa, pb)\n if (r.width < 1 && r.height < 1) return\n const arrowStyle: DrawingStyle = { ...this.style, lineColor: color, lineWidth: 1.5 }\n\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = withAlpha(color, 0.18)\n ctx.fillRect(r.x, r.y, r.width, r.height)\n\n // The cross: price arrow spanning the zone toward the move's direction, time arrow at\n // mid-height toward the drag's direction.\n const cx = r.x + r.width / 2\n const cy = r.y + r.height / 2\n ctx.strokeStyle = color\n ctx.lineWidth = 1.5\n if (r.height >= 8) {\n const from = { x: cx, y: up ? r.y + r.height : r.y }\n const to = { x: cx, y: up ? r.y : r.y + r.height }\n strokeSegment(ctx, from, to)\n paintArrowHead(ctx, from, to, arrowStyle)\n }\n if (r.width >= 8) {\n const rightward = pb.x >= pa.x\n const from = { x: rightward ? r.x : r.x + r.width, y: cy }\n const to = { x: rightward ? r.x + r.width : r.x, y: cy }\n strokeSegment(ctx, from, to)\n paintArrowHead(ctx, from, to, arrowStyle)\n }\n\n // The data pill: solid direction color, white text, two centered lines.\n const dPrice = b.price - a.price\n const pct = a.price !== 0 ? (dPrice / Math.abs(a.price)) * 100 : 0\n // The tick count rides only on a host-stated tick; without one the readout omits it.\n const tick = this.tickSize()\n const ticks = tick !== null && tick > 0 ? Math.round(Math.abs(dPrice) / tick) : 0\n const parts = [`${this.formatPrice(dPrice)} (${pct.toFixed(2)}%)`]\n if (ticks > 0 && Number.isFinite(ticks)) parts[0] += ` ${ticks}`\n const bars = viewport.barsBetween(a.time, b.time)\n const secs = Math.abs(Number(b.time) - Number(a.time))\n const line2: string[] = []\n if (bars !== null) line2.push(`${Math.abs(Math.round(bars))} bars`)\n if (Number.isFinite(secs) && secs > 0) line2.push(spanText(secs))\n const lines = line2.length ? [parts[0], line2.join(', ')] : [parts[0]]\n\n ctx.font = `600 ${this.style.fontSize}px ui-sans-serif, system-ui, sans-serif`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n const lineH = Math.round(this.style.fontSize * 1.35)\n const textW = Math.max(...lines.map((l) => ctx.measureText(l).width))\n const pillW = textW + 20\n const pillH = lines.length * lineH + 10\n const pillX = Math.max(4, Math.min(cx - pillW / 2, viewport.width - pillW - 4))\n const pillY = up ? Math.max(4, r.y - pillH - 10) : Math.min(viewport.height - pillH - 4, r.y + r.height + 10)\n ctx.fillStyle = color\n ctx.beginPath()\n ctx.roundRect(pillX, pillY, pillW, pillH, 4)\n ctx.fill()\n ctx.fillStyle = '#ffffff'\n for (let i = 0; i < lines.length; i++) {\n ctx.fillText(lines[i], pillX + pillW / 2, pillY + 5 + lineH * i + lineH / 2)\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return false\n return inBox(point, box(pa, pb))\n }\n}\n\n/** Human span like \"2d 4h\" / \"3h 12m\" / \"45s\" from a duration in seconds. */\nfunction spanText(seconds: number): string {\n const d = Math.floor(seconds / 86400)\n const h = Math.floor((seconds % 86400) / 3600)\n const m = Math.floor((seconds % 3600) / 60)\n const s = Math.floor(seconds % 60)\n if (d > 0) return h > 0 ? `${d}d ${h}h` : `${d}d`\n if (h > 0) return m > 0 ? `${h}h ${m}m` : `${h}h`\n if (m > 0) return s > 0 ? `${m}m ${s}s` : `${m}m`\n return `${s}s`\n}\n","// The divisions a speed resistance fan and a gann box share: a box between their two points, price\n// divisions across it and time divisions down it, each with its label on either side.\nimport type { DrawingStyle, Point } from '../core/types'\nimport { paintLabel } from '../render/canvas'\nimport type { FibLevel } from './fibonacci'\n\n/** A box's price levels and time levels, and which of their labels show. */\nexport type BoxLevelsProps = {\n priceLevels: FibLevel[]\n timeLevels: FibLevel[]\n showLeftLabels: boolean\n showRightLabels: boolean\n showTopLabels: boolean\n showBottomLabels: boolean\n /** Turn the divisions about the box, the first point's corner taking the second's. */\n reverse: boolean\n}\n\n/** The seven divisions offered on each side, each in its own color. */\nconst BOX_DIVISIONS: readonly [number, string][] = [\n [0, '#808080'],\n [0.25, '#ff9800'],\n [0.382, '#00bcd4'],\n [0.5, '#4caf50'],\n [0.618, '#089981'],\n [0.75, '#2962ff'],\n [1, '#808080'],\n]\n\n/** A fresh set of the seven divisions, every one shown. */\nexport const boxDivisions = (): FibLevel[] => BOX_DIVISIONS.map(([value, color]) => ({ value, visible: true, color }))\n\n/** A box between two points, with the corners the divisions count from: every division stands at\n * `far` at zero and at `origin` at one. */\nexport type LevelBox = { origin: Point; far: Point; left: number; right: number; top: number; bottom: number }\n\nexport function levelBox(a: Point, b: Point, reverse: boolean): LevelBox {\n const [origin, far] = reverse ? [b, a] : [a, b]\n return { origin, far, left: Math.min(a.x, b.x), right: Math.max(a.x, b.x), top: Math.min(a.y, b.y), bottom: Math.max(a.y, b.y) }\n}\n\n/** The y of a price division and the x of a time division. */\nexport const priceY = (box: LevelBox, value: number): number => box.far.y + (box.origin.y - box.far.y) * value\nexport const timeX = (box: LevelBox, value: number): number => box.far.x + (box.origin.x - box.far.x) * value\n\n/** The labels of a box's divisions: a price division's value beside the box's left and right edges,\n * a time division's above its top and below its bottom, each where its switch shows it, in the\n * division's color. */\nexport function paintBoxLabels(ctx: CanvasRenderingContext2D, style: Readonly<DrawingStyle>, props: Readonly<BoxLevelsProps>, box: LevelBox, color: (level: FibLevel, index: number) => string): void {\n props.priceLevels.forEach((level, i) => {\n if (!level.visible) return\n const y = priceY(box, level.value)\n const ink = { ...style, textColor: color(level, i) }\n if (props.showLeftLabels) paintLabel(ctx, String(level.value), { x: box.left - 4, y }, ink, { align: 'right' })\n if (props.showRightLabels) paintLabel(ctx, String(level.value), { x: box.right + 4, y }, ink, { align: 'left' })\n })\n props.timeLevels.forEach((level, i) => {\n if (!level.visible) return\n const x = timeX(box, level.value)\n const ink = { ...style, textColor: color(level, i) }\n if (props.showTopLabels) paintLabel(ctx, String(level.value), { x, y: box.top - 4 }, ink, { align: 'center', baseline: 'bottom' })\n if (props.showBottomLabels) paintLabel(ctx, String(level.value), { x, y: box.bottom + 4 }, ink, { align: 'center', baseline: 'top' })\n })\n}\n\n/** A box tool saved with one set of levels reads them as its price divisions. */\nexport function upgradeBoxLevels<P extends BoxLevelsProps>(props: Partial<P>): Partial<P> {\n const saved = props as Partial<P> & { levels?: unknown }\n if (!Array.isArray(saved.levels) || 'priceLevels' in saved) return props\n const { levels, ...rest } = saved\n return { ...rest, priceLevels: levels } as Partial<P>\n}\n","import type { ControlPoint, DrawingStyle, LineStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { angleOf, distanceToSegment, extendSegment, midpoint } from '../core/geometry'\nimport { alphaOf, applyStroke, dashPattern, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\nimport { endSavedLook, savedLevels, type SavedLook } from '../core/savedLook'\nimport type { TextHAlign, TextVAlign } from './lines'\nimport { boxDivisions, levelBox, paintBoxLabels, priceY, timeX, upgradeBoxLevels, type BoxLevelsProps, type LevelBox } from './boxLevels'\n\n/** One retracement/extension level. Color falls back to the shared palette by position. */\nexport type FibLevel = {\n value: number\n visible: boolean\n color?: string\n /** The level's own words, which it carries where its tool shows them. */\n text?: string\n /** The level's own stroke width and style, where its tool draws each level in a stroke of its\n * own; without them it takes the drawing's. */\n width?: number\n style?: LineStyle\n}\n\n/** Level palette keyed by common ratios; anything else falls back by index. */\nconst LEVEL_COLORS: Record<string, string> = {\n '0': '#787b86',\n '0.236': '#f23645',\n '0.382': '#ff9800',\n '0.5': '#4caf50',\n '0.618': '#089981',\n '0.786': '#00bcd4',\n '1': '#787b86',\n '1.618': '#2962ff',\n '2.618': '#f23645',\n '3.618': '#9c27b0',\n '4.236': '#e91e63',\n}\n\nconst FALLBACK_COLORS = ['#2962ff', '#f23645', '#ff9800', '#4caf50', '#089981', '#00bcd4', '#9c27b0', '#e91e63']\n\nexport function fibLevelColor(level: FibLevel, index: number): string {\n return level.color ?? LEVEL_COLORS[String(level.value)] ?? FALLBACK_COLORS[index % FALLBACK_COLORS.length]\n}\n\n/** The color a leveled tool's one-color control shows while its levels differ, and the second hue\n * its face pairs with it to say so. Picking a color there gives every level that color. */\nexport const MIXED_LEVEL_COLORS: readonly [shown: string, paired: string] = ['#f7525f', '#22ab94']\n\n/** The one color every level of a leveled tool shares, or null while they differ. */\nexport function sharedLevelColor(levels: readonly FibLevel[]): string | null {\n if (!levels.length) return null\n const colors = new Set(levels.map((level, i) => fibLevelColor(level, i).toLowerCase()))\n return colors.size === 1 ? fibLevelColor(levels[0]!, 0) : null\n}\n\n/** The twenty-four levels a retracement, an extension and a fib channel offer: the eleven classic\n * ratios shown, then thirteen more to switch on, each in its own color. */\nconst FIB_LEVELS: readonly FibLevel[] = [\n { value: 0, visible: true, color: '#808080' },\n { value: 0.236, visible: true, color: '#f23645' },\n { value: 0.382, visible: true, color: '#ff9800' },\n { value: 0.5, visible: true, color: '#4caf50' },\n { value: 0.618, visible: true, color: '#089981' },\n { value: 0.786, visible: true, color: '#00bcd4' },\n { value: 1, visible: true, color: '#808080' },\n { value: 1.618, visible: true, color: '#2962ff' },\n { value: 2.618, visible: true, color: '#f23645' },\n { value: 3.618, visible: true, color: '#9c27b0' },\n { value: 4.236, visible: true, color: '#e91e63' },\n { value: 1.272, visible: false, color: '#ff9800' },\n { value: 1.414, visible: false, color: '#f23645' },\n { value: 2.272, visible: false, color: '#ff9800' },\n { value: 2.414, visible: false, color: '#4caf50' },\n { value: 2, visible: false, color: '#089981' },\n { value: 3, visible: false, color: '#00bcd4' },\n { value: 3.272, visible: false, color: '#808080' },\n { value: 3.414, visible: false, color: '#2962ff' },\n { value: 4, visible: false, color: '#f23645' },\n { value: 4.272, visible: false, color: '#9c27b0' },\n { value: 4.414, visible: false, color: '#e91e63' },\n { value: 4.618, visible: false, color: '#ff9800' },\n { value: 4.764, visible: false, color: '#089981' },\n]\n\nconst GOLDEN_RATIO = 1.618033988749895\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** A fib's levels and what its labels read: each level's value as a ratio or as a percent, its\n * price, and where the label stands along the level's line (before it, at its middle, after it)\n * and across it (above it, on it, below it). */\nexport type FibChannelProps = {\n levels: FibLevel[]\n extendLeft: boolean\n extendRight: boolean\n showLevels: boolean\n coeffsAsPercents: boolean\n showPrices: boolean\n labelsHAlign: TextHAlign\n labelsVAlign: TextVAlign\n /** The bands between neighbouring levels, each in the color of the level that closes it, at\n * `backgroundOpacity`. Switched off, the bands keep their opacity for when they return. */\n fillBackground: boolean\n backgroundOpacity: number\n /** Each band takes the color of the level below it on the pane, in place of the level that\n * closes it. */\n bandsByPane: boolean\n /** A level's words lead its label, before its ratio and price, in place of standing on its line. */\n wordsInLabels: boolean\n /** Each label stands 6px before its level line's first point instead, read toward it. */\n labelsAtStart: boolean\n}\n\n/** A retracement's and an extension's own: the trend line through the swing points in a stroke of\n * its own, which swing point is level 0, a level's own words and where they stand on its line, and\n * levels that divide the swing by log price while the pane's price scale is logarithmic. */\nexport type FibRetracementProps = FibChannelProps & {\n trendLine: boolean\n trendLineColor: string\n trendLineWidth: number\n trendLineStyle: LineStyle\n reverse: boolean\n showText: boolean\n textHAlign: TextHAlign\n textVAlign: TextVAlign\n levelsOnLogScale: boolean\n}\n\nconst CHANNEL_PROPS: Omit<FibChannelProps, 'levels'> = {\n extendLeft: false,\n extendRight: false,\n showLevels: true,\n coeffsAsPercents: false,\n showPrices: true,\n labelsHAlign: 'left',\n labelsVAlign: 'middle',\n fillBackground: true,\n backgroundOpacity: 0.2,\n bandsByPane: false,\n wordsInLabels: false,\n labelsAtStart: false,\n}\n\nconst RETRACEMENT_PROPS: Omit<FibRetracementProps, 'levels'> = {\n ...CHANNEL_PROPS,\n trendLine: true,\n trendLineColor: '#808080',\n trendLineWidth: 2,\n trendLineStyle: 'dashed',\n reverse: false,\n showText: true,\n textHAlign: 'center',\n textVAlign: 'middle',\n levelsOnLogScale: false,\n}\n\n/** A saved fib that carries its background switch as `background` reads it as `fillBackground`. */\nfunction upgradeBackground<P extends { fillBackground: boolean }>(props: Partial<P>): Partial<P> {\n const saved = props as Partial<P> & { background?: unknown }\n if (!('background' in saved)) return props\n const { background, ...rest } = saved\n return ('fillBackground' in rest ? rest : { ...rest, fillBackground: background !== false }) as Partial<P>\n}\n\n/** A level's value as its label writes it: the ratio, or the ratio as a percent. */\nfunction levelValueText(value: number, asPercent: boolean): string {\n return asPercent ? `${Number((value * 100).toFixed(4))}%` : String(value)\n}\n\n/** How a fib's words stand across a level's line: above it, on it, or below it. */\nconst ACROSS_LEVEL: Record<TextVAlign, { dy: number; baseline: CanvasTextBaseline }> = {\n top: { dy: -3, baseline: 'bottom' },\n middle: { dy: 0, baseline: 'middle' },\n bottom: { dy: 3, baseline: 'top' },\n}\n\ntype Placement = { at: Point; align: CanvasTextAlign; baseline: CanvasTextBaseline }\n\n/** Where a level's label stands on a level line from `a` to `b`: before the line's start, at its\n * middle or after its end, and above, on or below it. */\nfunction labelPlace(h: TextHAlign, v: TextVAlign, a: Point, b: Point): Placement {\n const across = ACROSS_LEVEL[v]\n const [start, end] = a.x <= b.x ? [a, b] : [b, a]\n if (h === 'left') return { at: { x: start.x - 4, y: start.y + across.dy }, align: 'right', baseline: across.baseline }\n if (h === 'right') return { at: { x: end.x + 4, y: end.y + across.dy }, align: 'left', baseline: across.baseline }\n const mid = midpoint(start, end)\n return { at: { x: mid.x, y: mid.y + across.dy }, align: 'center', baseline: across.baseline }\n}\n\n/** Where a level's own words stand on its line from `a` to `b`: inside its start, at its middle or\n * inside its end, and above, on or below it. */\nfunction textPlace(h: TextHAlign, v: TextVAlign, a: Point, b: Point): Placement {\n const across = ACROSS_LEVEL[v]\n const [start, end] = a.x <= b.x ? [a, b] : [b, a]\n if (h === 'left') return { at: { x: start.x + 4, y: start.y + across.dy }, align: 'left', baseline: across.baseline }\n if (h === 'right') return { at: { x: end.x - 4, y: end.y + across.dy }, align: 'right', baseline: across.baseline }\n const mid = midpoint(start, end)\n return { at: { x: mid.x, y: mid.y + across.dy }, align: 'center', baseline: across.baseline }\n}\n\n/** A price a fraction of the way from one price to another: by price, or by log price where both\n * are positive and the levels divide the swing logarithmically. */\nfunction priceBetween(from: number, to: number, fraction: number, log: boolean): number {\n if (log && from > 0 && to > 0) return Math.exp(Math.log(from) + (Math.log(to) - Math.log(from)) * fraction)\n return from + (to - from) * fraction\n}\n\n/** One level as a tool paints it: the level, its color, its line on the pane and its price. */\ntype LevelLine = { level: FibLevel; color: string; a: Point; b: Point; price: number }\n\n/** What a leveled fib paints its level lines from: its style, its props, and its price formatter. */\ntype LevelLinePainter = {\n style: Readonly<DrawingStyle>\n props: Readonly<FibChannelProps & { showText?: boolean; textHAlign?: TextHAlign; textVAlign?: TextVAlign }>\n format(price: number): string\n}\n\n/** The parts a horizontal or parallel leveled fib paints from its level lines: the bands, the lines\n * in the levels' stroke, and each level's label and words in its own color. */\nfunction paintLevelLines(ctx: CanvasRenderingContext2D, drawing: LevelLinePainter, lines: readonly LevelLine[]): void {\n const { props, style } = drawing\n if (props.fillBackground && props.backgroundOpacity > 0) {\n const ordered = props.bandsByPane ? [...lines].sort((p, q) => p.a.y - q.a.y) : [...lines].sort((p, q) => p.level.value - q.level.value)\n for (let i = 0; i < ordered.length - 1; i++) {\n const from = ordered[i]!\n const to = ordered[i + 1]!\n ctx.fillStyle = withAlpha(to.color, props.backgroundOpacity)\n ctx.beginPath()\n ctx.moveTo(from.a.x, from.a.y)\n ctx.lineTo(from.b.x, from.b.y)\n ctx.lineTo(to.b.x, to.b.y)\n ctx.lineTo(to.a.x, to.a.y)\n ctx.closePath()\n ctx.fill()\n }\n }\n for (const line of lines) {\n ctx.save()\n applyStroke(ctx, { ...style, lineColor: line.color })\n strokeSegment(ctx, line.a, line.b)\n ctx.restore()\n }\n const ink = (color: string): DrawingStyle => ({ ...style, textColor: color })\n for (const line of lines) {\n const parts: string[] = []\n if (props.wordsInLabels && line.level.text) parts.push(line.level.text)\n if (props.showLevels) parts.push(levelValueText(line.level.value, props.coeffsAsPercents))\n if (props.showPrices && Number.isFinite(line.price)) parts.push(`(${drawing.format(line.price)})`)\n if (parts.length) {\n const place: Placement = props.labelsAtStart ? { at: { x: line.a.x - 6, y: line.a.y }, align: 'right', baseline: 'middle' } : labelPlace(props.labelsHAlign, props.labelsVAlign, line.a, line.b)\n paintLabel(ctx, parts.join(' '), place.at, ink(line.color), { align: place.align, baseline: place.baseline })\n }\n if (!props.wordsInLabels && props.showText && line.level.text && props.textHAlign && props.textVAlign) {\n const place = textPlace(props.textHAlign, props.textVAlign, line.a, line.b)\n paintLabel(ctx, line.level.text, place.at, ink(line.color), { align: place.align, baseline: place.baseline })\n }\n }\n}\n\n/** Horizontal retracement levels between two swing points (level 0 at the second anchor). */\nexport class FibRetracement extends Drawing<FibRetracementProps> {\n readonly type: string = 'fib_retracement'\n\n protected override defaultProps(): FibRetracementProps {\n return { levels: FIB_LEVELS.map((l) => ({ ...l })), ...RETRACEMENT_PROPS }\n }\n\n protected override upgradeProps(props: Partial<FibRetracementProps>): Partial<FibRetracementProps> {\n return upgradeBackground(props)\n }\n\n /** A format-2 fib drew no trend line, its bands at 7%, each in the color of the level below it on\n * the pane, and its labels before its levels' left ends with a level's words before its ratio. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, trendLine: false, backgroundOpacity: 0.07, bandsByPane: true, wordsInLabels: true, labelsAtStart: true }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** Whether the levels divide the swing by log price: asked for, and the pane's scale is log. */\n protected logLevels(viewport: Viewport): boolean {\n return this.props.levelsOnLogScale && viewport.logScale === true\n }\n\n /** Price at a ratio (0 = second anchor, 1 = first; reverse swaps). */\n protected priceAt(value: number, viewport: Viewport): number {\n const [a, b] = this.anchors\n const [from, to] = this.props.reverse ? [a, b] : [b, a]\n return priceBetween(from.price, to.price, value, this.logLevels(viewport))\n }\n\n protected span(viewport: Viewport): { minX: number; maxX: number } | null {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return null\n return {\n minX: this.props.extendLeft ? 0 : Math.min(pa.x, pb.x),\n maxX: this.props.extendRight ? viewport.width : Math.max(pa.x, pb.x),\n }\n }\n\n /** The visible levels as lines across the span, in level order. */\n protected levelLines(viewport: Viewport): LevelLine[] {\n const span = this.span(viewport)\n if (!span) return []\n const out: LevelLine[] = []\n this.props.levels.forEach((level, i) => {\n if (!level.visible) return\n const price = this.priceAt(level.value, viewport)\n const y = viewport.yOf(price)\n if (y === null) return\n out.push({ level, color: fibLevelColor(level, i), a: { x: span.minX, y }, b: { x: span.maxX, y }, price })\n })\n return out\n }\n\n /** The trend line's run through the swing points. */\n protected trendPoints(viewport: Viewport): Point[] {\n return this.anchorPixels(viewport).filter((p): p is Point => p !== null)\n }\n\n protected painter(): LevelLinePainter {\n return { style: this.style, props: this.props, format: (price) => this.formatPrice(price) }\n }\n\n /** The trend line's stroke: its own color, thickness and style. */\n protected trendStyle(): DrawingStyle {\n return { ...this.style, lineColor: this.props.trendLineColor, lineWidth: this.props.trendLineWidth, lineStyle: this.props.trendLineStyle }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.anchors.length < this.requiredAnchors()) return\n paintLevelLines(ctx, this.painter(), this.levelLines(viewport))\n if (this.props.trendLine) {\n const points = this.trendPoints(viewport)\n ctx.save()\n applyStroke(ctx, this.trendStyle())\n for (let i = 0; i < points.length - 1; i++) strokeSegment(ctx, points[i]!, points[i + 1]!)\n ctx.restore()\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n if (this.anchors.length < this.requiredAnchors()) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (this.levelLines(viewport).some((line) => distanceToSegment(point, line.a, line.b) <= tolerance)) return true\n if (!this.props.trendLine) return false\n const points = this.trendPoints(viewport)\n const trendTolerance = hitTolerance(this.props.trendLineWidth)\n for (let i = 0; i < points.length - 1; i++) if (distanceToSegment(point, points[i]!, points[i + 1]!) <= trendTolerance) return true\n return false\n }\n}\n\n/** Extension levels projected from a third point by the first swing's price delta. */\nexport class FibExtension extends FibRetracement {\n override readonly type = 'fib_trend_ext'\n\n /** A format-2 extension drew its swing dashed in its own stroke at half its opacity. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n super.keepSavedLook(saved)\n const { lineColor, lineWidth } = this._style\n this._props = { ...this._props, trendLine: true, trendLineColor: withAlpha(lineColor, alphaOf(lineColor) * 0.5), trendLineWidth: lineWidth, trendLineStyle: 'dashed' }\n }\n\n override requiredAnchors(): number {\n return 3\n }\n\n protected override priceAt(value: number, viewport: Viewport): number {\n const [a, b, c] = this.anchors\n const sign = this.props.reverse ? -1 : 1\n if (this.logLevels(viewport) && a.price > 0 && b.price > 0 && c.price > 0) return Math.exp(Math.log(c.price) + (Math.log(b.price) - Math.log(a.price)) * value * sign)\n return c.price + (b.price - a.price) * sign * value\n }\n\n protected override span(viewport: Viewport): { minX: number; maxX: number } | null {\n const [pa, pb, pc] = this.anchorPixels(viewport)\n if (!pa || !pb || !pc) return null\n return {\n minX: this.props.extendLeft ? 0 : pc.x,\n maxX: this.props.extendRight ? viewport.width : pc.x + Math.max(40, Math.abs(pb.x - pa.x)),\n }\n }\n}\n\n/** Parallel channel whose offset repeats at ratio multiples. */\nexport class FibChannel extends Drawing<FibChannelProps> {\n readonly type = 'fib_channel'\n\n protected override defaultProps(): FibChannelProps {\n return { levels: FIB_LEVELS.map((l) => ({ ...l })), ...CHANNEL_PROPS }\n }\n\n protected override upgradeProps(props: Partial<FibChannelProps>): Partial<FibChannelProps> {\n return upgradeBackground(props)\n }\n\n /** A format-2 fib channel drew its bands at 6%, and its labels before its levels' first points\n * with a level's words before its ratio. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, backgroundOpacity: 0.06, wordsInLabels: true, labelsAtStart: true }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected lines(viewport: Viewport): LevelLine[] {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return []\n const slopeT = (p3.x - p1.x) / ((p2.x - p1.x) || 1)\n const dy = p3.y - (p1.y + (p2.y - p1.y) * slopeT)\n const { extendLeft, extendRight } = this.props\n const out: LevelLine[] = []\n this.props.levels.forEach((level, i) => {\n if (!level.visible) return\n const a = { x: p1.x, y: p1.y + dy * level.value }\n const b = { x: p2.x, y: p2.y + dy * level.value }\n const seg = extendLeft || extendRight ? extendSegment(a, b, viewport.width, viewport.height, extendLeft, extendRight) : { a, b }\n // A level's price is where its line leaves the channel's first point, or where its label\n // stands where the labels stand at the lines' starts.\n const priced = this.props.labelsAtStart ? seg.a : a\n out.push({ level, color: fibLevelColor(level, i), a: seg.a, b: seg.b, price: viewport.priceAt(priced.y) ?? Number.NaN })\n })\n return out\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n paintLevelLines(ctx, { style: this.style, props: this.props, format: (price) => this.formatPrice(price) }, this.lines(viewport))\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.lines(viewport).some((line) => distanceToSegment(point, line.a, line.b) <= tolerance)\n }\n}\n\n/** A level's stroke: its own color, and its own width and style where it carries them. */\nfunction levelStroke(style: Readonly<DrawingStyle>, level: FibLevel, color: string): DrawingStyle {\n return { ...style, lineColor: color, lineWidth: level.width ?? style.lineWidth, lineStyle: level.style ?? style.lineStyle }\n}\n\n/** The props a converted fib keeps from a save: the ones it reads, its background switch under\n * either name, and nothing it no longer draws. */\nfunction knownProps<P extends Record<string, unknown>>(props: Partial<P>, defaults: P): Partial<P> {\n const upgraded = upgradeBackground(props as Partial<P & { fillBackground: boolean }>) as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(defaults)) if (key in upgraded) out[key] = upgraded[key]\n return out as Partial<P>\n}\n\n/** Levels drawn one to a line: each level its own color, width and style. */\nconst strokedLevels = (levels: readonly [value: number, color: string, visible: boolean][], width: number): FibLevel[] =>\n levels.map(([value, color, visible]) => ({ value, visible, color, width, style: 'solid' }))\n\n/** Where a vertical level's label stands: before, on or after its line, and at the pane's top, middle\n * or bottom. */\nfunction verticalLabelPlace(h: TextHAlign, v: TextVAlign, x: number, height: number): Placement {\n const at = { x: h === 'left' ? x - 4 : h === 'right' ? x + 4 : x, y: v === 'top' ? 4 : v === 'bottom' ? height - 4 : height / 2 }\n return { at, align: h === 'left' ? 'right' : h === 'right' ? 'left' : 'center', baseline: v === 'top' ? 'top' : v === 'bottom' ? 'bottom' : 'middle' }\n}\n\n/** A vertical level as a tool paints it: the level, its color and its x. */\ntype VerticalLevel = { level: FibLevel; color: string; x: number }\n\n/** What a time fib paints its vertical levels with: the bands between them, the lines in their own\n * strokes, and each level's label. */\nfunction paintVerticalLevels(\n ctx: CanvasRenderingContext2D,\n drawing: { style: Readonly<DrawingStyle>; props: Readonly<{ showLevels: boolean; labelsHAlign: TextHAlign; labelsVAlign: TextVAlign; fillBackground: boolean; backgroundOpacity: number }> },\n levels: readonly VerticalLevel[],\n viewport: Viewport,\n): void {\n const { props, style } = drawing\n if (props.fillBackground && props.backgroundOpacity > 0) {\n const ordered = [...levels].sort((a, b) => a.x - b.x)\n for (let i = 0; i < ordered.length - 1; i++) {\n ctx.fillStyle = withAlpha(ordered[i + 1]!.color, props.backgroundOpacity)\n ctx.fillRect(ordered[i]!.x, 0, ordered[i + 1]!.x - ordered[i]!.x, viewport.height)\n }\n }\n for (const entry of levels) {\n ctx.save()\n applyStroke(ctx, levelStroke(style, entry.level, entry.color))\n strokeSegment(ctx, { x: entry.x, y: 0 }, { x: entry.x, y: viewport.height })\n ctx.restore()\n if (props.showLevels) {\n const place = verticalLabelPlace(props.labelsHAlign, props.labelsVAlign, entry.x, viewport.height)\n paintLabel(ctx, String(entry.level.value), place.at, { ...style, textColor: entry.color }, { align: place.align, baseline: place.baseline })\n }\n }\n}\n\n/** A time zone's levels and their labels: vertical lines at its sequence's multiples of the span\n * between its points, each labelled with its multiple where `labelsHAlign` and `labelsVAlign` put\n * it, and the bands between them. */\nexport type FibTimeZoneProps = {\n levels: FibLevel[]\n showLevels: boolean\n labelsHAlign: TextHAlign\n labelsVAlign: TextVAlign\n fillBackground: boolean\n backgroundOpacity: number\n}\n\nconst TIME_ZONE_LEVELS = strokedLevels(\n [\n [0, '#808080', true],\n [1, '#2962ff', true],\n [2, '#2962ff', true],\n [3, '#2962ff', true],\n [5, '#2962ff', true],\n [8, '#2962ff', true],\n [13, '#2962ff', true],\n [21, '#2962ff', true],\n [34, '#2962ff', true],\n [55, '#2962ff', true],\n [89, '#2962ff', true],\n ],\n 2,\n)\n\n/** Vertical lines at Fibonacci-sequence multiples of the base span. */\nexport class FibTimeZone extends Drawing<FibTimeZoneProps> {\n readonly type = 'fib_timezone'\n\n protected override defaultProps(): FibTimeZoneProps {\n return { levels: TIME_ZONE_LEVELS.map((l) => ({ ...l })), showLevels: true, labelsHAlign: 'right', labelsVAlign: 'bottom', fillBackground: false, backgroundOpacity: 0.2 }\n }\n\n protected override upgradeProps(props: Partial<FibTimeZoneProps>): Partial<FibTimeZoneProps> {\n return knownProps(props, this.defaultProps())\n }\n\n /** A format-2 time zone drew no bands and its labels to the right of its lines at the pane's\n * foot. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, fillBackground: false, labelsHAlign: 'right', labelsVAlign: 'bottom' }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected xs(viewport: Viewport): VerticalLevel[] {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return []\n const unit = p2.x - p1.x\n if (unit === 0) return []\n return this.props.levels\n .map((level, i) => ({ level, color: fibLevelColor(level, i), x: p1.x + unit * level.value }))\n .filter((e) => e.level.visible && e.x >= -viewport.width && e.x <= viewport.width * 2)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n paintVerticalLevels(ctx, this, this.xs(viewport), viewport)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n return this.xs(viewport).some((e) => Math.abs(point.x - e.x) <= hitTolerance(e.level.width ?? this.style.lineWidth))\n }\n}\n\n/** A tool's trend line through its points, in a stroke of its own, switched on and off. */\nexport type FibTrendProps = {\n trendLine: boolean\n trendLineColor: string\n trendLineWidth: number\n trendLineStyle: LineStyle\n}\n\n/** A trend line's stroke. */\nconst trendStroke = (style: Readonly<DrawingStyle>, props: Readonly<FibTrendProps>): DrawingStyle => ({\n ...style,\n lineColor: props.trendLineColor,\n lineWidth: props.trendLineWidth,\n lineStyle: props.trendLineStyle,\n})\n\n/** Stroke a trend line through points, where it is switched on. */\nfunction paintTrend(ctx: CanvasRenderingContext2D, style: Readonly<DrawingStyle>, props: Readonly<FibTrendProps>, points: readonly Point[]): void {\n if (!props.trendLine || points.length < 2) return\n ctx.save()\n applyStroke(ctx, trendStroke(style, props))\n for (let i = 0; i < points.length - 1; i++) strokeSegment(ctx, points[i]!, points[i + 1]!)\n ctx.restore()\n}\n\n/** Whether a point is on a trend line through points, where it is switched on. */\nfunction hitsTrend(point: Point, props: Readonly<FibTrendProps>, points: readonly Point[]): boolean {\n if (!props.trendLine) return false\n const tolerance = hitTolerance(props.trendLineWidth)\n for (let i = 0; i < points.length - 1; i++) if (distanceToSegment(point, points[i]!, points[i + 1]!) <= tolerance) return true\n return false\n}\n\n/** A trend-based time fib: a time zone projected from the third point by the first swing's span,\n * drawn with its trend line. */\nexport type FibTimeExtensionProps = FibTimeZoneProps & FibTrendProps\n\nconst TIME_RATIO_LEVELS = strokedLevels(\n [\n [0, '#808080', true],\n [0.382, '#f23645', true],\n [0.5, '#81c784', false],\n [0.618, '#4caf50', true],\n [1, '#089981', true],\n [1.382, '#00bcd4', true],\n [1.618, '#808080', true],\n [2, '#2962ff', true],\n [2.382, '#e91e63', true],\n [2.618, '#9c27b0', true],\n [3, '#673ab7', true],\n ],\n 2,\n)\n\nconst DASHED_TREND: FibTrendProps = { trendLine: true, trendLineColor: '#808080', trendLineWidth: 2, trendLineStyle: 'dashed' }\n\n/** Vertical time ratios of the first swing projected from the third anchor. */\nexport class FibTimeExtension extends Drawing<FibTimeExtensionProps> {\n readonly type = 'fib_trend_time'\n\n protected override defaultProps(): FibTimeExtensionProps {\n return { levels: TIME_RATIO_LEVELS.map((l) => ({ ...l })), ...DASHED_TREND, showLevels: true, labelsHAlign: 'right', labelsVAlign: 'bottom', fillBackground: true, backgroundOpacity: 0.2 }\n }\n\n protected override upgradeProps(props: Partial<FibTimeExtensionProps>): Partial<FibTimeExtensionProps> {\n return knownProps(props, this.defaultProps())\n }\n\n /** A format-2 trend-based time fib drew no trend line, no bands, and its labels to the right of its\n * lines at the pane's foot. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, trendLine: false, fillBackground: false, labelsHAlign: 'right', labelsVAlign: 'bottom' }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected xs(viewport: Viewport): VerticalLevel[] {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return []\n const unit = p2.x - p1.x\n if (unit === 0) return []\n return this.props.levels.map((level, i) => ({ level, color: fibLevelColor(level, i), x: p3.x + unit * level.value })).filter((e) => e.level.visible)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n paintVerticalLevels(ctx, this, this.xs(viewport), viewport)\n paintTrend(ctx, this.style, this.props, this.anchorPixels(viewport).filter((p): p is Point => p !== null))\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n if (this.xs(viewport).some((e) => Math.abs(point.x - e.x) <= hitTolerance(e.level.width ?? this.style.lineWidth))) return true\n return hitsTrend(point, this.props, this.anchorPixels(viewport).filter((p): p is Point => p !== null))\n }\n}\n\n/** The ring levels of a circle or arc fib: each ratio of its trend line's length, with its trend\n * line, its labels reading the ratio or its percent, and the bands between rings. */\nexport type FibRingProps = FibTrendProps & {\n levels: FibLevel[]\n showLevels: boolean\n fillBackground: boolean\n backgroundOpacity: number\n}\n\nexport type FibCirclesProps = FibRingProps & {\n /** Label the ratios as percentages (0.618 → 61.8%). */\n coeffsAsPercents: boolean\n /** A percent reads to the whole number (0.618 → 62%). */\n roundPercents: boolean\n}\n\nconst RING_LEVELS: readonly [number, string, boolean][] = [\n [0.236, '#f23645', true],\n [0.382, '#ff9800', true],\n [0.5, '#089981', true],\n [0.618, '#4caf50', true],\n [0.786, '#00bcd4', true],\n [1, '#808080', true],\n [1.618, '#2962ff', true],\n [2.618, '#e91e63', true],\n [3.618, '#2962ff', true],\n [4.236, '#e91e63', true],\n [4.618, '#f23645', true],\n]\n\n/** Fill the band between two rings around a center, an outer ring's color at an opacity. */\nfunction fillRing(ctx: CanvasRenderingContext2D, center: Point, inner: number, outer: number, color: string, opacity: number, from = 0, to = Math.PI * 2): void {\n ctx.save()\n ctx.fillStyle = withAlpha(color, opacity)\n ctx.beginPath()\n ctx.arc(center.x, center.y, outer, from, to)\n ctx.arc(center.x, center.y, inner, to, from, true)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n}\n\n/** Circles about the first point at ratios of the trend line's length. */\nexport class FibCircles extends Drawing<FibCirclesProps> {\n readonly type = 'fib_circles'\n\n protected override defaultProps(): FibCirclesProps {\n return { levels: strokedLevels(RING_LEVELS, 2), ...DASHED_TREND, showLevels: true, coeffsAsPercents: false, roundPercents: false, fillBackground: true, backgroundOpacity: 0.2 }\n }\n\n protected override upgradeProps(props: Partial<FibCirclesProps>): Partial<FibCirclesProps> {\n return knownProps(props, this.defaultProps())\n }\n\n /** A format-2 circle fib drew no trend line, no bands, and its percents to the whole number. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, trendLine: false, fillBackground: false, roundPercents: true }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return\n const base = Math.hypot(p2.x - p1.x, p2.y - p1.y)\n if (base === 0) return\n const shown = this.props.levels.map((level, i) => ({ level, color: fibLevelColor(level, i), r: base * level.value })).filter((e) => e.level.visible && e.r > 0)\n if (this.props.fillBackground && this.props.backgroundOpacity > 0) {\n const ordered = [...shown].sort((a, b) => a.r - b.r)\n for (let i = 0; i < ordered.length; i++) fillRing(ctx, p1, i === 0 ? 0 : ordered[i - 1]!.r, ordered[i]!.r, ordered[i]!.color, this.props.backgroundOpacity)\n }\n for (const entry of shown) {\n ctx.save()\n applyStroke(ctx, levelStroke(this.style, entry.level, entry.color))\n ctx.beginPath()\n ctx.arc(p1.x, p1.y, entry.r, 0, Math.PI * 2)\n ctx.stroke()\n ctx.restore()\n if (this.props.showLevels) {\n const label = this.props.coeffsAsPercents && this.props.roundPercents ? `${Math.round(entry.level.value * 100)}%` : levelValueText(entry.level.value, this.props.coeffsAsPercents)\n paintLabel(ctx, label, { x: p1.x + entry.r + 4, y: p1.y }, { ...this.style, textColor: entry.color })\n }\n }\n paintTrend(ctx, this.style, this.props, [p1, p2])\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return false\n const base = Math.hypot(p2.x - p1.x, p2.y - p1.y)\n if (base === 0) return false\n const d = Math.hypot(point.x - p1.x, point.y - p1.y)\n if (this.props.levels.some((l) => l.visible && Math.abs(d - base * l.value) <= hitTolerance(l.width ?? this.style.lineWidth))) return true\n return hitsTrend(point, this.props, [p1, p2])\n }\n}\n\n/** Half-circle arcs at ratio radii, centered on the trend line's end and facing its origin. */\nexport type FibArcsProps = FibRingProps & {\n /** Complete each arc into a full circle. */\n fullCircles: boolean\n}\n\n/** Arcs about the trend line's end at ratios of its length, bowed back toward its start. */\nexport class FibArcs extends Drawing<FibArcsProps> {\n readonly type = 'fib_speed_resist_arcs'\n\n protected override defaultProps(): FibArcsProps {\n return { levels: strokedLevels(RING_LEVELS, 2), ...DASHED_TREND, showLevels: true, fullCircles: false, fillBackground: true, backgroundOpacity: 0.2 }\n }\n\n protected override upgradeProps(props: Partial<FibArcsProps>): Partial<FibArcsProps> {\n return knownProps(props, this.defaultProps())\n }\n\n /** A format-2 arc fib drew its trend line dashed in its own stroke at 45% of its opacity, and no\n * bands. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n const { lineColor, lineWidth } = this._style\n this._props = { ...this._props, trendLine: true, trendLineColor: withAlpha(lineColor, alphaOf(lineColor) * 0.45), trendLineWidth: lineWidth, trendLineStyle: 'dashed', fillBackground: false }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return\n const base = Math.hypot(p2.x - p1.x, p2.y - p1.y)\n if (base === 0) return\n // The arcs bow back toward the origin: a half circle perpendicular to the trend segment.\n const back = angleOf(p2, p1)\n const [from, to] = this.props.fullCircles ? [0, Math.PI * 2] : [back - Math.PI / 2, back + Math.PI / 2]\n const shown = this.props.levels.map((level, i) => ({ level, color: fibLevelColor(level, i), r: base * level.value })).filter((e) => e.level.visible && e.r > 0)\n if (this.props.fillBackground && this.props.backgroundOpacity > 0) {\n const ordered = [...shown].sort((a, b) => a.r - b.r)\n for (let i = 0; i < ordered.length; i++) fillRing(ctx, p2, i === 0 ? 0 : ordered[i - 1]!.r, ordered[i]!.r, ordered[i]!.color, this.props.backgroundOpacity, from, to)\n }\n for (const entry of shown) {\n ctx.save()\n applyStroke(ctx, levelStroke(this.style, entry.level, entry.color))\n ctx.beginPath()\n ctx.arc(p2.x, p2.y, entry.r, from, to)\n ctx.stroke()\n ctx.restore()\n if (this.props.showLevels) {\n const lx = p2.x + Math.cos(back) * entry.r\n const ly = p2.y + Math.sin(back) * entry.r\n paintLabel(ctx, String(entry.level.value), { x: lx, y: ly - 8 }, { ...this.style, textColor: entry.color }, { align: 'center' })\n }\n }\n paintTrend(ctx, this.style, this.props, [p1, p2])\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return false\n const base = Math.hypot(p2.x - p1.x, p2.y - p1.y)\n if (base === 0) return false\n const d = Math.hypot(point.x - p2.x, point.y - p2.y)\n if (this.props.levels.some((l) => l.visible && Math.abs(d - base * l.value) <= hitTolerance(l.width ?? this.style.lineWidth))) return true\n return hitsTrend(point, this.props, [p1, p2])\n }\n}\n\n/** A wedge's levels: arcs at ratios of its first ray's length between its two rays, with the rays\n * as its trend line, the arcs' labels, and the bands between arcs. */\nexport type FibWedgeProps = FibTrendProps & {\n levels: FibLevel[]\n showLevels: boolean\n fillBackground: boolean\n backgroundOpacity: number\n}\n\nconst WEDGE_LEVELS: readonly [number, string, boolean][] = [\n [0.236, '#f23645', true],\n [0.382, '#ff9800', true],\n [0.5, '#4caf50', true],\n [0.618, '#089981', true],\n [0.786, '#00bcd4', true],\n [1, '#808080', true],\n [1.618, '#2962ff', false],\n [2.618, '#f23645', false],\n [3.618, '#673ab7', false],\n [4.236, '#e91e63', false],\n [4.618, '#e91e63', false],\n]\n\n/** Wedge: two rays from an apex with ratio arcs spanning the angle between them. */\nexport class FibWedge extends Drawing<FibWedgeProps> {\n readonly type = 'fib_wedge'\n\n protected override defaultProps(): FibWedgeProps {\n return { levels: strokedLevels(WEDGE_LEVELS, 2), trendLine: true, trendLineColor: '#808080', trendLineWidth: 2, trendLineStyle: 'solid', showLevels: true, fillBackground: true, backgroundOpacity: 0.2 }\n }\n\n protected override upgradeProps(props: Partial<FibWedgeProps>): Partial<FibWedgeProps> {\n return knownProps(props, this.defaultProps())\n }\n\n /** A format-2 wedge drew its rays in its own stroke, and no bands. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n const { lineColor, lineWidth, lineStyle } = this._style\n this._props = { ...this._props, trendLine: true, trendLineColor: lineColor, trendLineWidth: lineWidth, trendLineStyle: lineStyle, fillBackground: false }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n /** The apex, the first ray's length, the rays' angles, and the arcs' sweep the short way between\n * the rays, as a clockwise run from `start` to `end`. */\n protected geometry(viewport: Viewport): { apex: Point; radius: number; a1: number; a2: number; start: number; end: number; bisector: number } | null {\n const [apex, p2, p3] = this.anchorPixels(viewport)\n if (!apex || !p2 || !p3) return null\n const radius = Math.hypot(p2.x - apex.x, p2.y - apex.y)\n if (radius === 0) return null\n const a1 = angleOf(apex, p2)\n const a2 = angleOf(apex, p3)\n const [start, end] = Math.sin(a2 - a1) < 0 ? [a2, a1] : [a1, a2]\n const sweep = (((end - start) % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2)\n return { apex, radius, a1, a2, start, end: start + sweep, bisector: start + sweep / 2 }\n }\n\n /** The two rays, each as long as the first. */\n protected rays(geo: { apex: Point; radius: number; a1: number; a2: number }): Point[][] {\n const end = (a: number): Point => ({ x: geo.apex.x + Math.cos(a) * geo.radius, y: geo.apex.y + Math.sin(a) * geo.radius })\n return [\n [geo.apex, end(geo.a1)],\n [geo.apex, end(geo.a2)],\n ]\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const geo = this.geometry(viewport)\n if (!geo) return\n const shown = this.props.levels.map((level, i) => ({ level, color: fibLevelColor(level, i), r: geo.radius * level.value })).filter((e) => e.level.visible && e.r > 0)\n if (this.props.fillBackground && this.props.backgroundOpacity > 0) {\n const ordered = [...shown].sort((a, b) => a.r - b.r)\n for (let i = 0; i < ordered.length; i++) fillRing(ctx, geo.apex, i === 0 ? 0 : ordered[i - 1]!.r, ordered[i]!.r, ordered[i]!.color, this.props.backgroundOpacity, geo.start, geo.end)\n }\n for (const entry of shown) {\n ctx.save()\n applyStroke(ctx, levelStroke(this.style, entry.level, entry.color))\n ctx.beginPath()\n ctx.arc(geo.apex.x, geo.apex.y, entry.r, geo.start, geo.end)\n ctx.stroke()\n ctx.restore()\n if (this.props.showLevels) {\n // Labels sit along the wedge's bisector, just past each arc.\n const r = entry.r + 9\n paintLabel(ctx, String(entry.level.value), { x: geo.apex.x + Math.cos(geo.bisector) * r, y: geo.apex.y + Math.sin(geo.bisector) * r }, { ...this.style, textColor: entry.color }, { align: 'center' })\n }\n }\n for (const ray of this.rays(geo)) paintTrend(ctx, this.style, this.props, ray)\n }\n\n /** The third handle stands at the end of the second ray: that ray runs as long as the first, at\n * the third anchor's angle, so the anchor's own distance from the apex paints nothing and a\n * handle at it would float off the ray's end as the first ray changes length. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const points = super.getControlPoints(viewport)\n const geo = this.geometry(viewport)\n if (!geo) return points\n const end = this.rays(geo)[1]![1]!\n return points.map((point) => (point.index === 2 ? { ...point, ...end } : point))\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const geo = this.geometry(viewport)\n if (!geo) return false\n const d = Math.hypot(point.x - geo.apex.x, point.y - geo.apex.y)\n const angle = Math.atan2(point.y - geo.apex.y, point.x - geo.apex.x)\n const rel = (((angle - geo.start) % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2)\n if (rel <= geo.end - geo.start + 0.05 && this.props.levels.some((l) => l.visible && Math.abs(d - geo.radius * l.value) <= hitTolerance(l.width ?? this.style.lineWidth))) return true\n return this.rays(geo).some((ray) => hitsTrend(point, this.props, ray))\n }\n}\n\n/** A pitchfan's median and levels: the median from the first point through the middle of the other\n * two in a stroke of its own, rays through each level's point on either side of it, and the bands\n * between rays. */\nexport type PitchfanProps = {\n medianColor: string\n medianWidth: number\n medianStyle: LineStyle\n levels: FibLevel[]\n fillBackground: boolean\n backgroundOpacity: number\n /** A format-2 pitchfan's levels and labels, painted as format 2 did until the fan's settings\n * change. */\n savedLook: SavedLook\n}\n\nconst FORK_LEVELS: readonly [number, string, boolean][] = [\n [0.25, '#ffb74d', false],\n [0.382, '#81c784', false],\n [0.5, '#00bcd4', true],\n [0.618, '#089981', false],\n [0.75, '#00bcd4', false],\n [1, '#2962ff', true],\n [1.5, '#9c27b0', false],\n [1.75, '#e91e63', false],\n [2, '#f77c80', false],\n]\n\n/** The levels a format-2 pitchfan save that names none drew. */\nconst SAVED_PITCHFAN_LEVELS: readonly FibLevel[] = [0, 0.25, 0.5, 0.75, 1].map((value) => ({ value, visible: true }))\n\n/** Fan of rays from the pitchfork origin through the fork's level points. */\nexport class Pitchfan extends Drawing<PitchfanProps> {\n readonly type = 'pitchfan'\n\n protected override defaultProps(): PitchfanProps {\n return { medianColor: '#f23645', medianWidth: 2, medianStyle: 'solid', levels: strokedLevels(FORK_LEVELS, 2), fillBackground: true, backgroundOpacity: 0.2, savedLook: null }\n }\n\n protected override upgradeProps(props: Partial<PitchfanProps>): Partial<PitchfanProps> {\n const known = knownProps(props, this.defaultProps())\n // The median stands on its own, so a level at zero draws nothing more.\n if (Array.isArray(known.levels)) known.levels = known.levels.filter((l) => l.value !== 0)\n return known\n }\n\n /** A format-2 pitchfan drew a ray for each level in its own stroke and the level's palette color,\n * its zero level as the median, and each ray's ratio near its end. It paints so until its\n * settings change, and its present props hold the same levels, colors and stroke. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n const look = { levels: Array.isArray(saved.levels) ? saved.levels : SAVED_PITCHFAN_LEVELS, showLevels: saved.showLevels !== false }\n const levels = savedLevels(look)\n const { lineColor, lineWidth, lineStyle } = this._style\n const zero = levels.findIndex((l) => l.value === 0)\n this._props = {\n ...this._props,\n medianColor: zero >= 0 ? fibLevelColor(levels[zero]!, zero) : lineColor,\n medianWidth: lineWidth,\n medianStyle: lineStyle,\n levels: levels.flatMap((l, i) => (l.value === 0 ? [] : [{ value: l.value, visible: l.visible, color: fibLevelColor(l, i), width: lineWidth, style: lineStyle }])),\n fillBackground: false,\n savedLook: look,\n }\n }\n\n override applyProps(patch: Partial<PitchfanProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n /** A saved look's rays: one for the zero level, a pair for each other, each run to the pane's\n * edge. */\n protected savedRays(look: NonNullable<SavedLook>, viewport: Viewport): { value: number; color: string; a: Point; b: Point }[] {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return []\n const mid = midpoint(p2, p3)\n return savedLevels(look)\n .map((level, i) => ({ level, color: fibLevelColor(level, i) }))\n .filter((e) => e.level.visible)\n .flatMap((e) => (e.level.value === 0 ? [0] : [e.level.value, -e.level.value]).map((k) => {\n const through = { x: mid.x + (p3.x - mid.x) * k, y: mid.y + (p3.y - mid.y) * k }\n return { value: e.level.value, color: e.color, a: p1, b: extendSegment(p1, through, viewport.width, viewport.height, false, true).b }\n }))\n }\n\n protected paintSavedLook(ctx: CanvasRenderingContext2D, look: NonNullable<SavedLook>, viewport: Viewport): void {\n for (const ray of this.savedRays(look, viewport)) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = ray.color\n strokeSegment(ctx, ray.a, ray.b)\n ctx.restore()\n if (look.showLevels !== false) {\n const t = 0.92\n paintLabel(ctx, String(ray.value), { x: ray.a.x + (ray.b.x - ray.a.x) * t, y: ray.a.y + (ray.b.y - ray.a.y) * t - 8 }, { ...this.style, textColor: ray.color }, { align: 'center' })\n }\n }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n /** The ray from the origin through a point, to the pane's edge. */\n protected rayThrough(origin: Point, through: Point, viewport: Viewport): { a: Point; b: Point } {\n return { a: origin, b: extendSegment(origin, through, viewport.width, viewport.height, false, true).b }\n }\n\n /** The median and each visible level's two rays, one on either side of the median. */\n protected fan(viewport: Viewport): { median: { a: Point; b: Point }; rays: { level: FibLevel; color: string; side: 1 | -1; a: Point; b: Point }[] } | null {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return null\n const mid = midpoint(p2, p3)\n if (mid.x === p1.x && mid.y === p1.y) return null\n const rays: { level: FibLevel; color: string; side: 1 | -1; a: Point; b: Point }[] = []\n this.props.levels.forEach((level, i) => {\n if (!level.visible || level.value === 0) return\n for (const side of [1, -1] as const) {\n const k = level.value * side\n rays.push({ level, color: fibLevelColor(level, i), side, ...this.rayThrough(p1, { x: mid.x + (p3.x - mid.x) * k, y: mid.y + (p3.y - mid.y) * k }, viewport) })\n }\n })\n return { median: this.rayThrough(p1, mid, viewport), rays }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.props.savedLook) {\n this.paintSavedLook(ctx, this.props.savedLook, viewport)\n return\n }\n const fan = this.fan(viewport)\n if (!fan) return\n if (this.props.fillBackground && this.props.backgroundOpacity > 0) {\n for (const side of [1, -1] as const) {\n const ordered = fan.rays.filter((r) => r.side === side).sort((a, b) => a.level.value - b.level.value)\n let inner = fan.median\n for (const ray of ordered) {\n ctx.save()\n ctx.fillStyle = withAlpha(ray.color, this.props.backgroundOpacity)\n ctx.beginPath()\n ctx.moveTo(ray.a.x, ray.a.y)\n ctx.lineTo(inner.b.x, inner.b.y)\n ctx.lineTo(ray.b.x, ray.b.y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n inner = ray\n }\n }\n }\n for (const ray of fan.rays) {\n ctx.save()\n applyStroke(ctx, levelStroke(this.style, ray.level, ray.color))\n strokeSegment(ctx, ray.a, ray.b)\n ctx.restore()\n }\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: this.props.medianColor, lineWidth: this.props.medianWidth, lineStyle: this.props.medianStyle })\n strokeSegment(ctx, fan.median.a, fan.median.b)\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n if (this.props.savedLook) {\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.savedRays(this.props.savedLook, viewport).some((ray) => distanceToSegment(point, ray.a, ray.b) <= tolerance)\n }\n const fan = this.fan(viewport)\n if (!fan) return false\n if (distanceToSegment(point, fan.median.a, fan.median.b) <= hitTolerance(this.props.medianWidth)) return true\n return fan.rays.some((ray) => distanceToSegment(point, ray.a, ray.b) <= hitTolerance(ray.level.width ?? this.style.lineWidth))\n }\n}\n\n/** A speed resistance fan: rays from its first point through each price division of the box's far\n * edge and each time division of its far side, the bands between rays, a grid at the divisions in\n * a stroke of its own, and each division's labels. */\nexport type FibSpeedFanProps = BoxLevelsProps & {\n fillBackground: boolean\n backgroundOpacity: number\n grid: boolean\n gridColor: string\n gridWidth: number\n gridStyle: LineStyle\n /** A format-2 fan's levels and labels, painted as format 2 did until the fan's settings change. */\n savedLook: SavedLook\n}\n\n/** The levels a format-2 speed fan save that names none drew. */\nconst SAVED_SPEED_FAN_LEVELS: readonly FibLevel[] = [0.25, 0.382, 0.5, 0.618, 0.75, 1].map((value) => ({ value, visible: true }))\n\n/** Fan rays from the first anchor through ratio points of the spanned box's far edge. */\nexport class FibSpeedFan extends Drawing<FibSpeedFanProps> {\n readonly type = 'fib_speed_resist_fan'\n\n protected override defaultProps(): FibSpeedFanProps {\n return {\n priceLevels: boxDivisions(),\n timeLevels: boxDivisions(),\n showLeftLabels: true,\n showRightLabels: true,\n showTopLabels: true,\n showBottomLabels: true,\n fillBackground: true,\n backgroundOpacity: 0.2,\n grid: true,\n gridColor: 'rgba(21, 56, 153, 0.8)',\n gridWidth: 1,\n gridStyle: 'solid',\n reverse: false,\n savedLook: null,\n }\n }\n\n protected override upgradeProps(props: Partial<FibSpeedFanProps>): Partial<FibSpeedFanProps> {\n return knownProps(upgradeBoxLevels(props), this.defaultProps())\n }\n\n /** A format-2 fan drew its box dashed at 45% of its stroke, a ray from its first point through each\n * level's share of the box's height at its far side, and each level's ratio and price beside that\n * side. It paints so until its settings change, and its present props hold its price levels with\n * the time levels, the grid, the bands and the other sides' labels off. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n const look = {\n levels: Array.isArray(saved.levels) ? saved.levels : SAVED_SPEED_FAN_LEVELS,\n showLevels: saved.showLevels !== false,\n showPrices: saved.showPrices !== false,\n }\n this._props = {\n ...this._props,\n timeLevels: this._props.timeLevels.map((l) => ({ ...l, visible: false })),\n grid: false,\n fillBackground: false,\n showLeftLabels: false,\n showTopLabels: false,\n showBottomLabels: false,\n savedLook: look,\n }\n }\n\n override applyProps(patch: Partial<FibSpeedFanProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n /** A saved look's rays, from the first point through each shown level's share of the box's height\n * at its far side, run to the pane's edge. */\n protected savedRays(look: NonNullable<SavedLook>, viewport: Viewport): { level: FibLevel; color: string; y: number; a: Point; b: Point }[] {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2 || p1.x === p2.x) return []\n return savedLevels(look)\n .map((level, i) => ({ level, color: fibLevelColor(level, i) }))\n .filter((e) => e.level.visible)\n .map((e) => {\n const y = p1.y + (p2.y - p1.y) * e.level.value\n return { ...e, y, a: p1, b: extendSegment(p1, { x: p2.x, y }, viewport.width, viewport.height, false, true).b }\n })\n }\n\n protected paintSavedLook(ctx: CanvasRenderingContext2D, look: NonNullable<SavedLook>, viewport: Viewport): void {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.globalAlpha = 0.45\n ctx.setLineDash(dashPattern('dashed', this.style.lineWidth))\n ctx.strokeRect(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y), Math.abs(p2.x - p1.x), Math.abs(p2.y - p1.y))\n ctx.restore()\n for (const ray of this.savedRays(look, viewport)) {\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = ray.color\n strokeSegment(ctx, ray.a, ray.b)\n ctx.restore()\n if (look.showLevels !== false || look.showPrices !== false || ray.level.text) {\n const price = viewport.priceAt(ray.y)\n const parts = [\n ray.level.text || null,\n look.showLevels !== false ? String(ray.level.value) : null,\n look.showPrices !== false && price !== null ? `(${this.formatPrice(price)})` : null,\n ].filter((s): s is string => s !== null)\n paintLabel(ctx, parts.join(' '), { x: p2.x + 6, y: ray.y }, { ...this.style, textColor: ray.color })\n }\n }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected box(viewport: Viewport): LevelBox | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b || a.x === b.x || a.y === b.y) return null\n return levelBox(a, b, this.props.reverse)\n }\n\n /** The fan's rays: a price division's through the far edge at its height, a time division's\n * through the far side at its place, each run to the pane's edge. */\n protected rays(box: LevelBox, viewport: Viewport): { level: FibLevel; color: string; kind: 'price' | 'time'; a: Point; b: Point }[] {\n const out: { level: FibLevel; color: string; kind: 'price' | 'time'; a: Point; b: Point }[] = []\n const ray = (through: Point): { a: Point; b: Point } => ({ a: box.origin, b: extendSegment(box.origin, through, viewport.width, viewport.height, false, true).b })\n this.props.priceLevels.forEach((level, i) => {\n if (level.visible) out.push({ level, color: fibLevelColor(level, i), kind: 'price', ...ray({ x: box.far.x, y: priceY(box, level.value) }) })\n })\n this.props.timeLevels.forEach((level, i) => {\n if (level.visible) out.push({ level, color: fibLevelColor(level, i), kind: 'time', ...ray({ x: timeX(box, level.value), y: box.far.y }) })\n })\n return out\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.props.savedLook) {\n this.paintSavedLook(ctx, this.props.savedLook, viewport)\n return\n }\n const box = this.box(viewport)\n if (!box) return\n const rays = this.rays(box, viewport)\n if (this.props.fillBackground && this.props.backgroundOpacity > 0) {\n for (const kind of ['price', 'time'] as const) {\n const ordered = rays.filter((r) => r.kind === kind).sort((p, q) => p.level.value - q.level.value)\n for (let i = 1; i < ordered.length; i++) {\n ctx.save()\n ctx.fillStyle = withAlpha(ordered[i]!.color, this.props.backgroundOpacity)\n ctx.beginPath()\n ctx.moveTo(box.origin.x, box.origin.y)\n ctx.lineTo(ordered[i - 1]!.b.x, ordered[i - 1]!.b.y)\n ctx.lineTo(ordered[i]!.b.x, ordered[i]!.b.y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n }\n }\n if (this.props.grid) {\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: this.props.gridColor, lineWidth: this.props.gridWidth, lineStyle: this.props.gridStyle })\n for (const level of this.props.priceLevels) if (level.visible) strokeSegment(ctx, { x: box.left, y: priceY(box, level.value) }, { x: box.right, y: priceY(box, level.value) })\n for (const level of this.props.timeLevels) if (level.visible) strokeSegment(ctx, { x: timeX(box, level.value), y: box.top }, { x: timeX(box, level.value), y: box.bottom })\n ctx.restore()\n }\n for (const r of rays) {\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: r.color })\n strokeSegment(ctx, r.a, r.b)\n ctx.restore()\n }\n paintBoxLabels(ctx, this.style, this.props, box, fibLevelColor)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n if (this.props.savedLook) return this.savedRays(this.props.savedLook, viewport).some((r) => distanceToSegment(point, r.a, r.b) <= tolerance)\n const box = this.box(viewport)\n if (!box) return false\n return this.rays(box, viewport).some((r) => distanceToSegment(point, r.a, r.b) <= tolerance)\n }\n}\n\n/** Which way a fib spiral winds out from its first point. */\nexport type FibSpiralProps = {\n /** Wind counterclockwise on the pane rather than clockwise. */\n counterclockwise: boolean\n}\n\n/** Golden-ratio spiral wound from the first anchor out through the second. */\nexport class FibSpiral extends Drawing<FibSpiralProps> {\n readonly type = 'fib_spiral'\n\n protected override defaultProps(): FibSpiralProps {\n return { counterclockwise: false }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return null\n const target = Math.hypot(p2.x - p1.x, p2.y - p1.y)\n if (target === 0) return null\n const growth = Math.log(GOLDEN_RATIO) / (Math.PI / 2)\n const baseAngle = angleOf(p1, p2)\n // The pane's y runs down, so a growing angle turns clockwise on the pane.\n const turn = this.props.counterclockwise ? -1 : 1\n const points: Point[] = []\n // Wind 2.5 turns inward and 1 turn outward around the anchor pair.\n for (let theta = -Math.PI * 5; theta <= Math.PI * 2; theta += Math.PI / 24) {\n const r = target * Math.exp(growth * theta)\n if (r < 0.5) continue\n points.push({ x: p1.x + Math.cos(baseAngle + turn * theta) * r, y: p1.y + Math.sin(baseAngle + turn * theta) * r })\n }\n return points\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.samples(viewport)\n if (!points || points.length < 2) return\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n for (let i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y)\n ctx.stroke()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const points = this.samples(viewport)\n if (!points) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n for (let i = 0; i < points.length - 1; i++) {\n if (distanceToSegment(point, points[i], points[i + 1]) <= tolerance) return true\n }\n return false\n }\n}\n\n","import type { ControlPoint, DrawingStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment, extendSegment } from '../core/geometry'\nimport { applyStroke, fillPaint, paintArrowHead, paintLabel, strokeSegment } from '../render/canvas'\nimport { fibLevelColor, type FibLevel } from './fibonacci'\nimport type { LineEnd, TextHAlign, TextVAlign } from './lines'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** A channel's label: its words, where they stand across the channel (above it, inside it, below\n * it) and along it, in the drawing's text channel. */\nexport type ChannelLabelProps = {\n text: string\n textVAlign: TextVAlign\n textHAlign: TextHAlign\n /** The words stand over the first side's start instead, 6px in and 12px up. */\n textAtStart: boolean\n}\n\n/** Paint a channel's words over its first side's start. */\nfunction paintWordsAtStart(ctx: CanvasRenderingContext2D, text: string, first: Segment, style: Readonly<DrawingStyle>): void {\n paintLabel(ctx, text, { x: first.a.x + 6, y: first.a.y - 12 }, style)\n}\n\n/** A channel's background switch: off, the channel keeps its fill's color and opacity for when it\n * is switched back on. */\nexport type ChannelFillProps = {\n fillBackground: boolean\n}\n\ntype Segment = { a: Point; b: Point }\n\n/** Where a channel's label stands: across it above its upper side, inside it at the middle, or\n * below its lower side, and along it at the start, the middle or the end. */\nfunction labelAt(upper: Segment, lower: Segment, v: TextVAlign, h: TextHAlign): { at: Point; align: CanvasTextAlign; baseline: CanvasTextBaseline } {\n const along = h === 'left' ? 0 : h === 'right' ? 1 : 0.5\n const on = (s: Segment): Point => ({ x: s.a.x + (s.b.x - s.a.x) * along, y: s.a.y + (s.b.y - s.a.y) * along })\n const top = on(upper)\n const bottom = on(lower)\n const align: CanvasTextAlign = h === 'left' ? 'left' : h === 'right' ? 'right' : 'center'\n if (v === 'top') return { at: { x: top.x, y: Math.min(top.y, bottom.y) - 4 }, align, baseline: 'bottom' }\n if (v === 'bottom') return { at: { x: bottom.x, y: Math.max(top.y, bottom.y) + 4 }, align, baseline: 'top' }\n return { at: { x: (top.x + bottom.x) / 2, y: (top.y + bottom.y) / 2 }, align, baseline: 'middle' }\n}\n\n/** A channel side, the upper of two by the pane's y at their middles. */\nconst upperOf = (p: Segment, q: Segment): [Segment, Segment] => ((p.a.y + p.b.y) / 2 <= (q.a.y + q.b.y) / 2 ? [p, q] : [q, p])\n\n/** Fill a channel's body between two sides with its background. */\nfunction fillBody(ctx: CanvasRenderingContext2D, fill: string, p: Segment, q: Segment): void {\n ctx.save()\n ctx.fillStyle = fill\n ctx.beginPath()\n ctx.moveTo(p.a.x, p.a.y)\n ctx.lineTo(p.b.x, p.b.y)\n ctx.lineTo(q.b.x, q.b.y)\n ctx.lineTo(q.a.x, q.a.y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n}\n\n/**\n * A parallel channel's settings: its levels at ratios of its width (0 the line through its first\n * two points, 1 the parallel through its third), each in a stroke of its own, its extensions, its\n * background between the 0 and 1 lines, and its label.\n */\nexport type ParallelChannelProps = ChannelLabelProps &\n ChannelFillProps & {\n levels: FibLevel[]\n extendLeft: boolean\n extendRight: boolean\n }\n\nconst PARALLEL_LEVELS: FibLevel[] = [\n { value: -0.25, visible: false, color: '#2962ff', width: 1, style: 'solid' },\n { value: 0, visible: true, color: '#2962ff', width: 2, style: 'solid' },\n { value: 0.25, visible: false, color: '#2962ff', width: 1, style: 'solid' },\n { value: 0.5, visible: true, color: '#2962ff', width: 1, style: 'dashed' },\n { value: 0.75, visible: false, color: '#2962ff', width: 1, style: 'solid' },\n { value: 1, visible: true, color: '#2962ff', width: 2, style: 'solid' },\n { value: 1.25, visible: false, color: '#2962ff', width: 1, style: 'solid' },\n]\n\n/**\n * Parallel channel: the first two anchors span the baseline, and the third sets how far the parallel\n * stands from it, at the same slope over the same times.\n */\nexport class ParallelChannel extends Drawing<ParallelChannelProps> {\n readonly type = 'parallel_channel'\n\n protected override defaultProps(): ParallelChannelProps {\n return { text: '', textVAlign: 'top', textHAlign: 'left', textAtStart: false, levels: PARALLEL_LEVELS.map((l) => ({ ...l })), extendLeft: false, extendRight: false, fillBackground: true }\n }\n\n /** A channel saved with its middle line as `showMiddle` shows or hides its half level by it. */\n protected override upgradeProps(props: Partial<ParallelChannelProps>): Partial<ParallelChannelProps> {\n const saved = props as Partial<ParallelChannelProps> & { showMiddle?: unknown }\n if (!('showMiddle' in saved)) return props\n const { showMiddle, ...rest } = saved\n if ('levels' in rest) return rest\n return { ...rest, levels: PARALLEL_LEVELS.map((l) => (l.value === 0.5 ? { ...l, visible: showMiddle === true } : { ...l })) }\n }\n\n /** A format-2 channel drew its sides, and its middle where it showed one, in its own stroke, the\n * middle dashed, and its words over its first side's start. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n const { lineColor, lineWidth, lineStyle } = this._style\n const middle = saved.showMiddle === true\n const levels = PARALLEL_LEVELS.map((l): FibLevel => ({\n ...l,\n visible: l.value === 0 || l.value === 1 || (l.value === 0.5 && middle),\n color: lineColor,\n width: lineWidth,\n style: l.value === 0.5 ? 'dashed' : lineStyle,\n }))\n this._props = { ...this._props, levels, textAtStart: true }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n /** The pane offset from the baseline to the parallel through the third point. */\n protected offset(viewport: Viewport): { p1: Point; p2: Point; dy: number } | null {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return null\n return { p1, p2, dy: p3.y - (p1.y + (p2.y - p1.y) * ((p3.x - p1.x) / ((p2.x - p1.x) || 1))) }\n }\n\n /** The line at a level's ratio of the channel's width, after extension. */\n protected levelLine(o: { p1: Point; p2: Point; dy: number }, value: number, viewport: Viewport): Segment {\n const a = { x: o.p1.x, y: o.p1.y + o.dy * value }\n const b = { x: o.p2.x, y: o.p2.y + o.dy * value }\n const { extendLeft, extendRight } = this.props\n return extendLeft || extendRight ? extendSegment(a, b, viewport.width, viewport.height, extendLeft, extendRight) : { a, b }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const o = this.offset(viewport)\n if (!o) return\n const zero = this.levelLine(o, 0, viewport)\n const one = this.levelLine(o, 1, viewport)\n const fill = this.props.fillBackground !== false ? fillPaint(this.style) : null\n if (fill) fillBody(ctx, fill, zero, one)\n this.props.levels.forEach((level, i) => {\n if (!level.visible) return\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: fibLevelColor(level, i), lineWidth: level.width ?? this.style.lineWidth, lineStyle: level.style ?? this.style.lineStyle })\n const line = this.levelLine(o, level.value, viewport)\n strokeSegment(ctx, line.a, line.b)\n ctx.restore()\n })\n if (this.props.text && this.props.textAtStart) paintWordsAtStart(ctx, this.props.text, zero, this.style)\n else if (this.props.text) {\n const [upper, lower] = upperOf(zero, one)\n const place = labelAt(upper, lower, this.props.textVAlign, this.props.textHAlign)\n paintLabel(ctx, this.props.text, place.at, this.style, { align: place.align, baseline: place.baseline })\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const o = this.offset(viewport)\n if (!o) return false\n for (const level of this.props.levels) {\n if (!level.visible) continue\n const line = this.levelLine(o, level.value, viewport)\n if (distanceToSegment(point, line.a, line.b) <= hitTolerance(level.width ?? this.style.lineWidth)) return true\n }\n // Inside the channel body counts as a hit: that is how the whole channel is grabbed.\n const zero = this.levelLine(o, 0, viewport)\n const one = this.levelLine(o, 1, viewport)\n const minX = Math.min(zero.a.x, zero.b.x)\n const maxX = Math.max(zero.a.x, zero.b.x)\n if (point.x < minX || point.x > maxX) return false\n const t = (point.x - zero.a.x) / (zero.b.x - zero.a.x || 1)\n const yZero = zero.a.y + (zero.b.y - zero.a.y) * t\n const yOne = one.a.y + (one.b.y - one.a.y) * t\n return point.y >= Math.min(yZero, yOne) && point.y <= Math.max(yZero, yOne)\n }\n}\n\n/** A flat top/bottom's and a disjoint channel's settings: their sides' ends and extensions, their\n * sides' prices in a text style of their own, their background, and their label. */\nexport type ChannelProps = ChannelLabelProps &\n ChannelFillProps & {\n extendLeft: boolean\n extendRight: boolean\n leftEnd: LineEnd\n rightEnd: LineEnd\n showPrices: boolean\n pricesColor: string\n pricesFontSize: number\n pricesBold: boolean\n pricesItalic: boolean\n }\n\nconst channelProps = (hue: string): ChannelProps => ({\n text: '',\n textVAlign: 'top',\n textHAlign: 'left',\n textAtStart: false,\n fillBackground: true,\n extendLeft: false,\n extendRight: false,\n leftEnd: 'normal',\n rightEnd: 'normal',\n showPrices: false,\n pricesColor: hue,\n pricesFontSize: 12,\n pricesBold: false,\n pricesItalic: false,\n})\n\n/** A channel saved before its middle line was a setting of its own carries none. */\nfunction upgradeChannel(props: Partial<ChannelProps>): Partial<ChannelProps> {\n const saved = props as Partial<ChannelProps> & { showMiddle?: unknown }\n if (!('showMiddle' in saved)) return props\n const { showMiddle: _showMiddle, ...rest } = saved\n void _showMiddle\n return rest\n}\n\n/** Paint a channel's two sides with their ends, its body, its prices and its label. */\nfunction paintChannel(ctx: CanvasRenderingContext2D, drawing: { style: Readonly<DrawingStyle>; props: Readonly<ChannelProps>; format(price: number): string }, sides: [Segment, Segment], prices: [number, number][]): void {\n const { style, props } = drawing\n const fill = props.fillBackground !== false ? fillPaint(style) : null\n if (fill) fillBody(ctx, fill, sides[0], sides[1])\n applyStroke(ctx, style)\n for (const side of sides) {\n strokeSegment(ctx, side.a, side.b)\n if (props.leftEnd === 'arrow') paintArrowHead(ctx, side.b, side.a, style)\n if (props.rightEnd === 'arrow') paintArrowHead(ctx, side.a, side.b, style)\n }\n if (props.showPrices) {\n const ink: DrawingStyle = { ...style, textColor: props.pricesColor, fontSize: props.pricesFontSize, bold: props.pricesBold, italic: props.pricesItalic }\n sides.forEach((side, i) => {\n const [left, right] = prices[i]!\n paintLabel(ctx, drawing.format(left), { x: side.a.x - 4, y: side.a.y }, ink, { align: 'right' })\n paintLabel(ctx, drawing.format(right), { x: side.b.x + 4, y: side.b.y }, ink, { align: 'left' })\n })\n }\n if (props.text && props.textAtStart) paintWordsAtStart(ctx, props.text, sides[0], style)\n else if (props.text) {\n const [upper, lower] = upperOf(sides[0], sides[1])\n const place = labelAt(upper, lower, props.textVAlign, props.textHAlign)\n paintLabel(ctx, props.text, place.at, style, { align: place.align, baseline: place.baseline })\n }\n}\n\n/**\n * Flat top/bottom: the first two anchors span a sloped side and the third sets a flat one, a channel\n * with one sloped and one flat side.\n */\nexport class FlatTopBottom extends Drawing<ChannelProps> {\n readonly type = 'flat_top_bottom'\n\n protected override defaultProps(): ChannelProps {\n return channelProps('#ff9800')\n }\n\n protected override upgradeProps(props: Partial<ChannelProps>): Partial<ChannelProps> {\n return upgradeChannel(props)\n }\n\n /** A format-2 channel set its words over its first side's start. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, textAtStart: true }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected boundaries(viewport: Viewport): { slope: Segment; flat: Segment } | null {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return null\n const { extendLeft, extendRight } = this.props\n const slope = extendLeft || extendRight ? extendSegment(p1, p2, viewport.width, viewport.height, extendLeft, extendRight) : { a: p1, b: p2 }\n return { slope, flat: { a: { x: slope.a.x, y: p3.y }, b: { x: slope.b.x, y: p3.y } } }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const b = this.boundaries(viewport)\n if (!b) return\n const [a1, a2, a3] = this.anchors\n paintChannel(ctx, { style: this.style, props: this.props, format: (p) => this.formatPrice(p) }, [b.slope, b.flat], [\n [a1!.price, a2!.price],\n [a3!.price, a3!.price],\n ])\n }\n\n /** The flat side's handle stands at the flat side's end under the second anchor: the flat side\n * spans the sloped side's times at the third anchor's price, and that anchor's own time paints\n * nothing, so a handle at it would drift off the side as the sloped side moves. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const points = super.getControlPoints(viewport)\n const end = points.find((point) => point.index === 1)\n return end ? points.map((point) => (point.index === 2 ? { ...point, x: end.x } : point)) : points\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const b = this.boundaries(viewport)\n if (!b) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n if (distanceToSegment(point, b.slope.a, b.slope.b) <= tolerance) return true\n if (distanceToSegment(point, b.flat.a, b.flat.b) <= tolerance) return true\n const minX = Math.min(b.slope.a.x, b.slope.b.x)\n const maxX = Math.max(b.slope.a.x, b.slope.b.x)\n if (point.x < minX || point.x > maxX) return false\n const t = (point.x - b.slope.a.x) / (b.slope.b.x - b.slope.a.x || 1)\n const ySlope = b.slope.a.y + (b.slope.b.y - b.slope.a.y) * t\n return point.y >= Math.min(ySlope, b.flat.a.y) && point.y <= Math.max(ySlope, b.flat.a.y)\n }\n}\n\n/** Disjoint channel: two sides of their own, the first two anchors and the last two, with a filled\n * body between them. */\nexport class DisjointChannel extends Drawing<ChannelProps> {\n readonly type = 'disjoint_channel'\n\n protected override defaultProps(): ChannelProps {\n return channelProps('#089981')\n }\n\n protected override upgradeProps(props: Partial<ChannelProps>): Partial<ChannelProps> {\n return upgradeChannel(props)\n }\n\n /** A format-2 channel set its words over its first side's start. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, textAtStart: true }\n }\n\n requiredAnchors(): number {\n return 4\n }\n\n protected boundaries(viewport: Viewport): { top: Segment; bottom: Segment } | null {\n const [p1, p2, p3, p4] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3 || !p4) return null\n const { extendLeft, extendRight } = this.props\n const line = (a: Point, b: Point): Segment => (extendLeft || extendRight ? extendSegment(a, b, viewport.width, viewport.height, extendLeft, extendRight) : { a, b })\n return { top: line(p1, p2), bottom: line(p3, p4) }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const b = this.boundaries(viewport)\n if (!b) return\n const [a1, a2, a3, a4] = this.anchors\n paintChannel(ctx, { style: this.style, props: this.props, format: (p) => this.formatPrice(p) }, [b.top, b.bottom], [\n [a1!.price, a2!.price],\n [a3!.price, a4!.price],\n ])\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const b = this.boundaries(viewport)\n if (!b) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n return distanceToSegment(point, b.top.a, b.top.b) <= tolerance || distanceToSegment(point, b.bottom.a, b.bottom.b) <= tolerance\n }\n}\n","import type { DrawingStyle, LineStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment, midpoint } from '../core/geometry'\nimport { applyStroke, strokeSegment, withAlpha } from '../render/canvas'\nimport { fibLevelColor, type FibLevel } from './fibonacci'\n\n/** One pair of fork lines set at ±value of the fork's half-width (1 = the tines through p2/p3), in\n * its own color, and its own width and style where it carries them. */\nexport type ForkLevel = FibLevel\n\nexport type ForkVariant = 'original' | 'schiff' | 'modified_schiff' | 'inside'\n\nexport type PitchforkProps = {\n /** Which fork construction the median uses, switchable in place. */\n variant: ForkVariant\n /** Extend all lines back past the fork's start as well as onward. */\n extendLines: boolean\n /** The median's own stroke. */\n medianColor: string\n medianWidth: number\n medianStyle: LineStyle\n levels: ForkLevel[]\n /** The bands between neighbouring line pairs, each in the color of the outer pair, at\n * `backgroundOpacity`. Switched off, the bands keep their opacity for when they return. */\n fillBackground: boolean\n backgroundOpacity: number\n /** The bands in the drawing's stroke color instead, the outermost at 9% and each one inward 3%\n * more. */\n shadedBands: boolean\n}\n\n/** The nine line pairs a pitchfork offers: the half and the tines shown, seven more to switch on. */\nconst FORK_LEVELS: readonly [number, string, boolean][] = [\n [0.25, '#ffb74d', false],\n [0.382, '#81c784', false],\n [0.5, '#089981', true],\n [0.618, '#089981', false],\n [0.75, '#00bcd4', false],\n [1, '#2962ff', true],\n [1.5, '#9c27b0', false],\n [1.75, '#e91e63', false],\n [2, '#f77c80', false],\n]\n\ninterface ForkGeometry {\n /** Where the median line begins (the fork's handle end). */\n origin: Point\n /** Midpoint of the p2→p3 segment, which every level line is placed from. */\n mid: Point\n /** Direction of all fork lines (origin → mid). */\n dir: Point\n /** Half-width vector (mid → p3); level k passes through mid ± k·halfWidth. */\n halfWidth: Point\n}\n\n/** A level's stroke: its own color, and its own width and style where it carries them. */\nconst levelStroke = (style: Readonly<DrawingStyle>, level: ForkLevel, color: string): DrawingStyle => ({\n ...style,\n lineColor: color,\n lineWidth: level.width ?? style.lineWidth,\n lineStyle: level.style ?? style.lineStyle,\n})\n\n/**\n * The pitchfork family. All variants share one parametric fork (a median through `mid(p2,p3)`\n * plus level lines offset by multiples of the half-width) and differ only in where the median\n * originates.\n */\nexport class Pitchfork extends Drawing<PitchforkProps> {\n readonly type: string = 'pitchfork'\n\n /** The construction seeded at creation; the prop switches it in place afterwards. */\n protected defaultVariant(): ForkVariant {\n return 'original'\n }\n\n protected override defaultProps(): PitchforkProps {\n return {\n variant: this.defaultVariant(),\n extendLines: false,\n medianColor: '#f23645',\n medianWidth: 2,\n medianStyle: 'solid',\n levels: FORK_LEVELS.map(([value, color, visible]) => ({ value, visible, color, width: 2, style: 'solid' })),\n fillBackground: true,\n backgroundOpacity: 0.2,\n shadedBands: false,\n }\n }\n\n /** A fork saved with its background switch as `background` reads it as `fillBackground`. */\n protected override upgradeProps(props: Partial<PitchforkProps>): Partial<PitchforkProps> {\n const saved = props as Partial<PitchforkProps> & { background?: unknown }\n if (!('background' in saved)) return props\n const { background, ...rest } = saved\n return 'fillBackground' in rest ? rest : { ...rest, fillBackground: background !== false }\n }\n\n /** A format-2 fork drew its median and its lines in its own stroke, a line in its own color where\n * it carried one, and its bands in that stroke's color shaded by depth. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n const { lineColor, lineWidth, lineStyle } = this._style\n const levels = this._props.levels.map((l): ForkLevel => ({ ...l, color: l.color ?? lineColor, width: lineWidth, style: lineStyle }))\n this._props = { ...this._props, medianColor: lineColor, medianWidth: lineWidth, medianStyle: lineStyle, levels, shadedBands: true }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected fork(viewport: Viewport): ForkGeometry | null {\n const [p1, p2, p3] = this.anchorPixels(viewport)\n if (!p1 || !p2 || !p3) return null\n const mid = midpoint(p2, p3)\n const variant = this.props.variant\n const origin =\n variant === 'schiff'\n ? midpoint(p1, p2)\n : variant === 'modified_schiff'\n ? { x: p1.x, y: (p1.y + p2.y) / 2 }\n : variant === 'inside'\n ? mid\n : p1\n // The inside fork has no handle: it emanates from the tine segment, aimed away from p1.\n const dir = variant === 'inside' ? { x: mid.x - p1.x, y: mid.y - p1.y } : { x: mid.x - origin.x, y: mid.y - origin.y }\n if (dir.x === 0 && dir.y === 0) return null\n return { origin, mid, dir, halfWidth: { x: p3.x - mid.x, y: p3.y - mid.y } }\n }\n\n /** A fork line through `at`, running along the fork direction to the pane edge(s). */\n protected lineThrough(fork: ForkGeometry, at: Point, viewport: Viewport): { a: Point; b: Point } {\n // Scale the direction so the far end always clears the pane regardless of zoom.\n const reach = (viewport.width + viewport.height) / Math.hypot(fork.dir.x, fork.dir.y)\n const b = { x: at.x + fork.dir.x * reach, y: at.y + fork.dir.y * reach }\n const a = this.props.extendLines ? { x: at.x - fork.dir.x * reach, y: at.y - fork.dir.y * reach } : at\n return { a, b }\n }\n\n protected levelPoint(fork: ForkGeometry, value: number): Point {\n return { x: fork.mid.x + fork.halfWidth.x * value, y: fork.mid.y + fork.halfWidth.y * value }\n }\n\n /** The visible line pairs, closest to the median first, each with its color. */\n protected shownLevels(): { level: ForkLevel; color: string }[] {\n return this.props.levels\n .map((level, i) => ({ level, color: fibLevelColor(level, i) }))\n .filter((e) => e.level.visible && e.level.value > 0)\n .sort((p, q) => p.level.value - q.level.value)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const fork = this.fork(viewport)\n if (!fork) return\n const shown = this.shownLevels()\n\n if (this.props.fillBackground && this.props.backgroundOpacity > 0) {\n // Fill between each pair of neighbouring lines on either side of the median, in the color of\n // the outer one.\n ctx.save()\n for (const sign of [1, -1]) {\n let inner = 0\n for (const [i, entry] of shown.entries()) {\n ctx.fillStyle = this.props.shadedBands ? withAlpha(this.style.lineColor, 0.06 + 0.03 * (shown.length - i)) : withAlpha(entry.color, this.props.backgroundOpacity)\n const lineA = this.lineThrough(fork, this.levelPoint(fork, inner * sign), viewport)\n const lineB = this.lineThrough(fork, this.levelPoint(fork, entry.level.value * sign), viewport)\n ctx.beginPath()\n ctx.moveTo(lineA.a.x, lineA.a.y)\n ctx.lineTo(lineA.b.x, lineA.b.y)\n ctx.lineTo(lineB.b.x, lineB.b.y)\n ctx.lineTo(lineB.a.x, lineB.a.y)\n ctx.closePath()\n ctx.fill()\n inner = entry.level.value\n }\n }\n ctx.restore()\n }\n\n // Level lines above and below, each pair in its own stroke.\n for (const entry of shown) {\n ctx.save()\n applyStroke(ctx, levelStroke(this.style, entry.level, entry.color))\n for (const sign of [1, -1]) {\n const line = this.lineThrough(fork, this.levelPoint(fork, entry.level.value * sign), viewport)\n strokeSegment(ctx, line.a, line.b)\n }\n ctx.restore()\n }\n // The median, in its own stroke: from the origin to mid, then onward along the fork.\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: this.props.medianColor, lineWidth: this.props.medianWidth, lineStyle: this.props.medianStyle })\n const median = this.lineThrough(fork, fork.mid, viewport)\n strokeSegment(ctx, this.props.extendLines ? median.a : fork.origin, median.b)\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const fork = this.fork(viewport)\n if (!fork) return false\n const median = this.lineThrough(fork, fork.mid, viewport)\n if (distanceToSegment(point, this.props.extendLines ? median.a : fork.origin, median.b) <= Math.max(6, this.props.medianWidth / 2 + 4)) return true\n for (const { level } of this.shownLevels()) {\n const tolerance = Math.max(6, (level.width ?? this.style.lineWidth) / 2 + 4)\n for (const sign of [1, -1]) {\n const line = this.lineThrough(fork, this.levelPoint(fork, level.value * sign), viewport)\n if (distanceToSegment(point, line.a, line.b) <= tolerance) return true\n }\n }\n return false\n }\n}\n\n/** Median origin at the full midpoint (time and price) of p1→p2. */\nexport class SchiffPitchfork extends Pitchfork {\n override readonly type = 'schiff_pitchfork'\n\n protected override defaultVariant(): ForkVariant {\n return 'schiff'\n }\n}\n\n/** Median origin shifted half the p1→p2 price distance, at p1's time. */\nexport class ModifiedSchiffPitchfork extends Pitchfork {\n override readonly type = 'schiff_pitchfork_modified'\n\n protected override defaultVariant(): ForkVariant {\n return 'modified_schiff'\n }\n}\n\n/** No handle: the fork emanates from the p2→p3 segment itself, aimed away from p1. */\nexport class InsidePitchfork extends Pitchfork {\n override readonly type = 'inside_pitchfork'\n\n protected override defaultVariant(): ForkVariant {\n return 'inside'\n }\n}\n","import type { Anchor, DrawingStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment, extendSegment } from '../core/geometry'\nimport { applyStroke, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\nimport { endSavedLook, savedLevels, type SavedLook } from '../core/savedLook'\nimport { boxDivisions, levelBox, paintBoxLabels, priceY, timeX, upgradeBoxLevels, type BoxLevelsProps, type LevelBox } from './boxLevels'\nimport { fibLevelColor, type FibLevel } from './fibonacci'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** A gann box: price divisions across the box and time divisions down it, each in its own color, the\n * bands between price divisions and between time divisions each switched and faded on its own, the\n * box's angles in a color of their own, and each division's labels. */\nexport type GannBoxProps = BoxLevelsProps & {\n fillPriceBackground: boolean\n priceBackgroundOpacity: number\n fillTimeBackground: boolean\n timeBackgroundOpacity: number\n angles: boolean\n anglesColor: string\n /** One fill over the whole box in this color, under its bands and divisions; null for none. */\n tint: string | null\n}\n\n/** The levels a format-2 gann box, square or fixed square save that names none divided by. */\nconst SAVED_BOX_LEVELS: readonly FibLevel[] = [0, 0.25, 0.382, 0.5, 0.618, 0.75, 1].map((value) => ({ value, visible: true }))\n\n/** Levels in the colors format 2 gave them: each shown level the palette's color for its place\n * among the shown ones. */\nfunction savedLevelColors(levels: readonly FibLevel[]): FibLevel[] {\n let shown = 0\n return levels.map((level, i) => ({ ...level, color: level.color ?? fibLevelColor(level, level.visible ? shown++ : i) }))\n}\n\n/** Box spanned by two corners with ratio lines dividing both axes. */\nexport class GannBox extends Drawing<GannBoxProps> {\n readonly type: string = 'gannbox'\n\n protected override defaultProps(): GannBoxProps {\n return {\n priceLevels: boxDivisions(),\n timeLevels: boxDivisions(),\n showLeftLabels: true,\n showRightLabels: true,\n showTopLabels: true,\n showBottomLabels: true,\n fillPriceBackground: true,\n priceBackgroundOpacity: 0.2,\n fillTimeBackground: true,\n timeBackgroundOpacity: 0.2,\n angles: false,\n anglesColor: '#9c9c9c',\n reverse: false,\n tint: null,\n }\n }\n\n protected override upgradeProps(props: Partial<GannBoxProps>): Partial<GannBoxProps> {\n const saved = upgradeBoxLevels(props) as Partial<GannBoxProps> & { background?: unknown; showLabels?: unknown }\n const out: Record<string, unknown> = {}\n const defaults = this.defaultProps()\n for (const key of Object.keys(defaults)) if (key in saved) out[key] = (saved as Record<string, unknown>)[key]\n // A box saved with one set of levels and one background divided both sides by those levels and\n // shaded the whole box: it reads them as its price and time divisions and both its bands.\n if (Array.isArray(saved.priceLevels) && !('timeLevels' in saved)) out.timeLevels = saved.priceLevels.map((l) => ({ ...l }))\n if (typeof saved.background === 'boolean' && !('fillPriceBackground' in saved)) out.fillPriceBackground = out.fillTimeBackground = saved.background\n if (typeof saved.showLabels === 'boolean' && !('showLeftLabels' in saved)) out.showLeftLabels = out.showRightLabels = out.showTopLabels = out.showBottomLabels = saved.showLabels\n return out as Partial<GannBoxProps>\n }\n\n /** A format-2 box counted its divisions from its first corner, divided both its sides by one set of\n * levels in the colors format 2 gave them, labelled them before its left side alone, and drew a\n * tint of its stroke's color at 5% over the box in place of bands. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n const levels = savedLevelColors(Array.isArray(saved.levels) ? savedLevels(saved) : SAVED_BOX_LEVELS)\n const labels = saved.showLabels !== false\n this._props = {\n ...this._props,\n priceLevels: levels,\n timeLevels: levels.map((l) => ({ ...l })),\n reverse: true,\n showLeftLabels: labels,\n showRightLabels: false,\n showTopLabels: false,\n showBottomLabels: false,\n fillPriceBackground: false,\n fillTimeBackground: false,\n tint: saved.background === false ? null : withAlpha(this._style.lineColor, 0.05),\n }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected box(viewport: Viewport): LevelBox | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n return levelBox(a, b, this.props.reverse)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const box = this.box(viewport)\n if (!box) return\n const { props } = this\n if (props.tint) {\n ctx.fillStyle = props.tint\n ctx.fillRect(box.left, box.top, box.right - box.left, box.bottom - box.top)\n }\n // The bands: between neighbouring price divisions across the box, and between neighbouring time\n // divisions down it, each band in the color of the division that closes it.\n const bands = (levels: FibLevel[], opacity: number, at: (v: number) => number, rect: (p: number, q: number) => [number, number, number, number]): void => {\n const shown = levels.map((level, i) => ({ level, color: fibLevelColor(level, i) })).filter((e) => e.level.visible).sort((p, q) => p.level.value - q.level.value)\n for (let i = 1; i < shown.length; i++) {\n ctx.fillStyle = withAlpha(shown[i]!.color, opacity)\n ctx.fillRect(...rect(at(shown[i - 1]!.level.value), at(shown[i]!.level.value)))\n }\n }\n if (props.fillPriceBackground && props.priceBackgroundOpacity > 0) bands(props.priceLevels, props.priceBackgroundOpacity, (v) => priceY(box, v), (p, q) => [box.left, Math.min(p, q), box.right - box.left, Math.abs(q - p)])\n if (props.fillTimeBackground && props.timeBackgroundOpacity > 0) bands(props.timeLevels, props.timeBackgroundOpacity, (v) => timeX(box, v), (p, q) => [Math.min(p, q), box.top, Math.abs(q - p), box.bottom - box.top])\n props.priceLevels.forEach((level, i) => {\n if (!level.visible) return\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: fibLevelColor(level, i) })\n strokeSegment(ctx, { x: box.left, y: priceY(box, level.value) }, { x: box.right, y: priceY(box, level.value) })\n ctx.restore()\n })\n props.timeLevels.forEach((level, i) => {\n if (!level.visible) return\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: fibLevelColor(level, i) })\n strokeSegment(ctx, { x: timeX(box, level.value), y: box.top }, { x: timeX(box, level.value), y: box.bottom })\n ctx.restore()\n })\n if (props.angles) {\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: props.anglesColor })\n strokeSegment(ctx, { x: box.left, y: box.top }, { x: box.right, y: box.bottom })\n strokeSegment(ctx, { x: box.left, y: box.bottom }, { x: box.right, y: box.top })\n ctx.restore()\n }\n paintBoxLabels(ctx, this.style, props, box, fibLevelColor)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const box = this.box(viewport)\n if (!box) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n const inX = point.x >= box.left - tolerance && point.x <= box.right + tolerance\n const inY = point.y >= box.top - tolerance && point.y <= box.bottom + tolerance\n if (!inX || !inY) return false\n if (this.props.priceLevels.some((l) => l.visible && Math.abs(point.y - priceY(box, l.value)) <= tolerance)) return true\n if (this.props.timeLevels.some((l) => l.visible && Math.abs(point.x - timeX(box, l.value)) <= tolerance)) return true\n if (!this.props.angles) return false\n return distanceToSegment(point, { x: box.left, y: box.top }, { x: box.right, y: box.bottom }) <= tolerance || distanceToSegment(point, { x: box.left, y: box.bottom }, { x: box.right, y: box.top }) <= tolerance\n }\n}\n\n/** A gann square's line: shown or not, in its color at its width. */\nexport type GannLine = { visible: boolean; color: string; width: number }\n\n/** A gann square's fan line or arc, at a ratio of the square's unit: `x` units along its time side\n * for `y` along its price side. */\nexport type GannRatioLine = GannLine & { x: number; y: number }\n\n/** A gann square's lines: a grid of six lines across it and down it at its fifths, fan lines from\n * its first corner at their ratios, arcs about that corner as long as their ratios, the bands\n * between neighbouring arcs, and which corner it counts from. */\nexport type GannSquareProps = {\n levels: GannLine[]\n fans: GannRatioLine[]\n arcs: GannRatioLine[]\n fillBackground: boolean\n backgroundOpacity: number\n /** Count from the second corner rather than the first. */\n reverse: boolean\n /** A format-2 square's box levels, labels and tint, painted as format 2 did until the square's\n * settings change. */\n savedLook: SavedLook\n}\n\n/** A gann square held to a price per bar: its price side spans `scaleRatio` for every bar its time\n * side spans, a ratio taken from the pane when it is first drawn so it opens square. Its price and\n * bar ranges and their ratio read under it, in the drawing's text size, weight and slant, while\n * `showLabels` is on. */\nexport type GannRatioSquareProps = GannSquareProps & {\n scaleRatio: number | null\n showLabels: boolean\n}\n\nconst line = (color: string, visible: boolean): GannLine => ({ visible, color, width: 2 })\nconst ratio = (x: number, y: number, color: string, visible: boolean): GannRatioLine => ({ x, y, visible, color, width: 2 })\n\n/** The six grid lines, from the first corner's edges to the far ones. */\nconst SQUARE_LEVELS = (): GannLine[] => ['#808080', '#ff9800', '#00bcd4', '#4caf50', '#089981', '#808080'].map((c) => line(c, true))\n\n/** The eleven fan lines, flattest first: 2x1, 1x1 and 1x2 shown. */\nconst SQUARE_FANS = (): GannRatioLine[] => [\n ratio(8, 1, '#b39ddb', false),\n ratio(5, 1, '#f23645', false),\n ratio(4, 1, '#808080', false),\n ratio(3, 1, '#ff9800', false),\n ratio(2, 1, '#00bcd4', true),\n ratio(1, 1, '#4caf50', true),\n ratio(1, 2, '#089981', true),\n ratio(1, 3, '#089981', false),\n ratio(1, 4, '#2962ff', false),\n ratio(1, 5, '#9575cd', false),\n ratio(1, 8, '#b39ddb', false),\n]\n\n/** The eleven arcs, nearest first, every one shown. */\nconst SQUARE_ARCS = (): GannRatioLine[] => [\n ratio(1, 0, '#ff9800', true),\n ratio(1, 1, '#ff9800', true),\n ratio(1.5, 0, '#ff9800', true),\n ratio(2, 0, '#00bcd4', true),\n ratio(2, 1, '#00bcd4', true),\n ratio(3, 0, '#4caf50', true),\n ratio(3, 1, '#4caf50', true),\n ratio(4, 0, '#089981', true),\n ratio(4, 1, '#089981', true),\n ratio(5, 0, '#2962ff', true),\n ratio(5, 1, '#2962ff', true),\n]\n\nconst SQUARE_PROPS = (): GannSquareProps => ({ levels: SQUARE_LEVELS(), fans: SQUARE_FANS(), arcs: SQUARE_ARCS(), fillBackground: true, backgroundOpacity: 0.2, reverse: false, savedLook: null })\n\n/** A gann ratio as its row and its label write it: so many units along the time side for so many\n * along the price side. */\nexport const gannRatioText = (r: { x: number; y: number }): string => `${r.x}x${r.y}`\n\n/** Whether a saved set of square lines has the shape a square reads: each a color and a width. */\nconst isSquareLines = (lines: unknown): boolean => Array.isArray(lines) && lines.every((l) => typeof l?.color === 'string' && typeof l?.width === 'number')\n\n/** The props a saved square keeps: the ones it reads in the shape it reads them, and its background\n * switch under its earlier name. */\nfunction squareProps<P extends GannSquareProps>(saved: Partial<P>, defaults: P): Partial<P> {\n const from = saved as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(defaults)) {\n if (!(key in from)) continue\n if ((key === 'levels' || key === 'fans' || key === 'arcs') && !isSquareLines(from[key])) continue\n out[key] = from[key]\n }\n if (typeof from.background === 'boolean' && !('fillBackground' in from)) out.fillBackground = from.background\n return out as Partial<P>\n}\n\n/** A format-2 box between two corners: a tint of the stroke's color at 5% over it where its\n * background showed, each shown level dividing both its sides in the color format 2 gave it, and\n * each level's ratio before its left side where its labels showed. */\nfunction paintSavedBox(ctx: CanvasRenderingContext2D, style: Readonly<DrawingStyle>, look: NonNullable<SavedLook>, a: Point, b: Point): void {\n const levels = savedLevels(look).filter((l) => l.visible)\n if (look.background !== false) {\n ctx.save()\n ctx.fillStyle = withAlpha(style.lineColor, 0.05)\n ctx.fillRect(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.abs(b.x - a.x), Math.abs(b.y - a.y))\n ctx.restore()\n }\n for (const [i, level] of levels.entries()) {\n const color = fibLevelColor(level, i)\n ctx.save()\n applyStroke(ctx, style)\n ctx.strokeStyle = color\n const y = a.y + (b.y - a.y) * level.value\n strokeSegment(ctx, { x: a.x, y }, { x: b.x, y })\n const x = a.x + (b.x - a.x) * level.value\n strokeSegment(ctx, { x, y: a.y }, { x, y: b.y })\n ctx.restore()\n if (look.showLabels !== false) paintLabel(ctx, String(level.value), { x: Math.min(a.x, b.x) - 6, y }, { ...style, textColor: color }, { align: 'right' })\n }\n}\n\n/** Whether a point is on a format-2 box's divisions. */\nfunction hitsSavedBox(point: Point, tolerance: number, look: NonNullable<SavedLook>, a: Point, b: Point): boolean {\n const inX = point.x >= Math.min(a.x, b.x) - tolerance && point.x <= Math.max(a.x, b.x) + tolerance\n const inY = point.y >= Math.min(a.y, b.y) - tolerance && point.y <= Math.max(a.y, b.y) + tolerance\n if (!inX || !inY) return false\n return savedLevels(look).some((l) => l.visible && (Math.abs(point.y - (a.y + (b.y - a.y) * l.value)) <= tolerance || Math.abs(point.x - (a.x + (b.x - a.x) * l.value)) <= tolerance))\n}\n\n/** A square's frame: its sides, the corner it counts from and the one across from it, and its unit,\n * a fifth of each side. */\ntype SquareFrame = { origin: Point; ux: number; uy: number; left: number; right: number; top: number; bottom: number }\n\n/** The square's arcs nearest first, each with its radius in units. */\nconst shownArcs = (arcs: readonly GannRatioLine[]): { arc: GannRatioLine; r: number }[] =>\n arcs\n .filter((a) => a.visible)\n .map((arc) => ({ arc, r: Math.hypot(arc.x, arc.y) }))\n .filter((a) => a.r > 0)\n .sort((p, q) => p.r - q.r)\n\n/** A gann square: a grid at fifths, fan lines and arcs from its first corner, all inside the square,\n * and the bands between its arcs. */\nexport abstract class GannSquareBase<P extends GannSquareProps> extends Drawing<P> {\n requiredAnchors(): number {\n return 2\n }\n\n /** A format-2 square was a box divided both ways by one set of levels, with a tint and its levels'\n * ratios before it. It paints so until its settings change. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n const look = {\n levels: Array.isArray(saved.levels) ? saved.levels : SAVED_BOX_LEVELS,\n showLabels: saved.showLabels !== false,\n background: saved.background !== false,\n }\n this._props = { ...this._props, savedLook: look }\n }\n\n override applyProps(patch: Partial<P>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n /** The box a saved look divides: the two corners, the fixed square's squared. */\n protected savedBox(viewport: Viewport): { a: Point; b: Point } | null {\n return this.corners(viewport)\n }\n\n /** What a saved look draws over its box beside its divisions. */\n protected paintSavedExtras(_ctx: CanvasRenderingContext2D, _a: Point, _b: Point): void {}\n\n /** The two corners the square stands between, on the pane. */\n protected corners(viewport: Viewport): { a: Point; b: Point } | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b || a.x === b.x || a.y === b.y) return null\n return { a, b }\n }\n\n protected frame(viewport: Viewport): SquareFrame | null {\n const c = this.corners(viewport)\n if (!c) return null\n const [origin, far] = this.props.reverse ? [c.b, c.a] : [c.a, c.b]\n return {\n origin,\n ux: (far.x - origin.x) / 5,\n uy: (far.y - origin.y) / 5,\n left: Math.min(c.a.x, c.b.x),\n right: Math.max(c.a.x, c.b.x),\n top: Math.min(c.a.y, c.b.y),\n bottom: Math.max(c.a.y, c.b.y),\n }\n }\n\n /** A point of the square: `x` units along its time side and `y` along its price side from the\n * corner it counts from. */\n protected at(f: SquareFrame, x: number, y: number): Point {\n return { x: f.origin.x + f.ux * x, y: f.origin.y + f.uy * y }\n }\n\n /** A fan line's end: where its ratio meets the square's far sides. */\n protected fanEnd(f: SquareFrame, fan: GannRatioLine): Point {\n const scale = 5 / Math.max(fan.x, fan.y)\n return this.at(f, fan.x * scale, fan.y * scale)\n }\n\n /** Trace an arc about the square's first corner: an ellipse through its ratio's length on both\n * sides, which the square's own edges cut to a quarter. */\n protected traceArc(ctx: CanvasRenderingContext2D, f: SquareFrame, r: number, back = false): void {\n ctx.ellipse(f.origin.x, f.origin.y, Math.abs(f.ux) * r, Math.abs(f.uy) * r, 0, back ? Math.PI * 2 : 0, back ? 0 : Math.PI * 2, back)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.props.savedLook) {\n const box = this.savedBox(viewport)\n if (!box) return\n paintSavedBox(ctx, this.style, this.props.savedLook, box.a, box.b)\n this.paintSavedExtras(ctx, box.a, box.b)\n return\n }\n const f = this.frame(viewport)\n if (!f) return\n const { props } = this\n ctx.save()\n ctx.beginPath()\n ctx.rect(f.left, f.top, f.right - f.left, f.bottom - f.top)\n ctx.clip()\n const arcs = shownArcs(props.arcs)\n if (props.fillBackground && props.backgroundOpacity > 0) {\n // Each band reaches from the arc inside it out to its own arc, in its own arc's color.\n arcs.forEach(({ arc, r }, i) => {\n ctx.fillStyle = withAlpha(arc.color, props.backgroundOpacity)\n ctx.beginPath()\n this.traceArc(ctx, f, r)\n if (i > 0) this.traceArc(ctx, f, arcs[i - 1]!.r, true)\n ctx.fill()\n })\n }\n for (const { arc, r } of arcs) {\n applyStroke(ctx, { ...this.style, lineColor: arc.color, lineWidth: arc.width, lineStyle: 'solid' })\n ctx.beginPath()\n this.traceArc(ctx, f, r)\n ctx.stroke()\n }\n props.levels.forEach((level, i) => {\n if (!level.visible) return\n applyStroke(ctx, { ...this.style, lineColor: level.color, lineWidth: level.width, lineStyle: 'solid' })\n const p = this.at(f, i, i)\n strokeSegment(ctx, { x: f.left, y: p.y }, { x: f.right, y: p.y })\n strokeSegment(ctx, { x: p.x, y: f.top }, { x: p.x, y: f.bottom })\n })\n for (const fan of props.fans) {\n if (!fan.visible || Math.max(fan.x, fan.y) <= 0) continue\n applyStroke(ctx, { ...this.style, lineColor: fan.color, lineWidth: fan.width, lineStyle: 'solid' })\n strokeSegment(ctx, f.origin, this.fanEnd(f, fan))\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n if (this.props.savedLook) {\n const box = this.savedBox(viewport)\n return !!box && (hitsSavedBox(point, tolerance, this.props.savedLook, box.a, box.b) || this.hitsSavedExtras(point, tolerance, box.a, box.b))\n }\n const f = this.frame(viewport)\n if (!f) return false\n if (point.x < f.left - tolerance || point.x > f.right + tolerance || point.y < f.top - tolerance || point.y > f.bottom + tolerance) return false\n for (const [i, level] of this.props.levels.entries()) {\n if (!level.visible) continue\n const p = this.at(f, i, i)\n if (Math.abs(point.y - p.y) <= tolerance || Math.abs(point.x - p.x) <= tolerance) return true\n }\n for (const fan of this.props.fans) {\n if (fan.visible && Math.max(fan.x, fan.y) > 0 && distanceToSegment(point, f.origin, this.fanEnd(f, fan)) <= tolerance) return true\n }\n // An arc is an ellipse about the first corner: a point is on it where its distance in units is\n // the arc's length.\n const ux = Math.abs(f.ux) || 1\n const uy = Math.abs(f.uy) || 1\n const units = Math.hypot((point.x - f.origin.x) / ux, (point.y - f.origin.y) / uy)\n return shownArcs(this.props.arcs).some(({ r }) => Math.abs(units - r) <= tolerance / Math.min(ux, uy))\n }\n\n /** Whether a point is on what a saved look draws beside its divisions. */\n protected hitsSavedExtras(_point: Point, _tolerance: number, _a: Point, _b: Point): boolean {\n return false\n }\n}\n\n/** Gann square: a square in price per bar, its second corner held at the ratio's price for the bars\n * between its corners, reading its ranges and ratio under it. */\nexport class GannSquare extends GannSquareBase<GannRatioSquareProps> {\n readonly type = 'gannbox_square'\n\n protected override defaultProps(): GannRatioSquareProps {\n return { ...SQUARE_PROPS(), scaleRatio: null, showLabels: true }\n }\n\n protected override upgradeProps(props: Partial<GannRatioSquareProps>): Partial<GannRatioSquareProps> {\n return squareProps(props, this.defaultProps())\n }\n\n override setAnchors(anchors: Anchor[]): void {\n super.setAnchors(anchors)\n this.holdRatio()\n }\n\n override updateAnchor(index: number, anchor: Anchor): void {\n super.updateAnchor(index, anchor)\n this.holdRatio()\n }\n\n override applyProps(patch: Partial<GannRatioSquareProps>): void {\n super.applyProps(patch)\n if ('scaleRatio' in patch) this.holdRatio()\n }\n\n /** A format-2 square crossed its box corner to corner. */\n protected override paintSavedExtras(ctx: CanvasRenderingContext2D, a: Point, b: Point): void {\n ctx.save()\n applyStroke(ctx, this.style)\n strokeSegment(ctx, a, b)\n strokeSegment(ctx, { x: a.x, y: b.y }, { x: b.x, y: a.y })\n ctx.restore()\n }\n\n protected override hitsSavedExtras(point: Point, tolerance: number, a: Point, b: Point): boolean {\n return distanceToSegment(point, a, b) <= tolerance || distanceToSegment(point, { x: a.x, y: b.y }, { x: b.x, y: a.y }) <= tolerance\n }\n\n /** The price per bar the pane shows a square at now: the price a run of bars as wide as the\n * square's time side spans when stood upright from its first corner. */\n private paneRatio(viewport: Viewport, a: Anchor, b: Anchor, bars: number): number | null {\n const pa = this.anchorToPixel(a, viewport)\n const pb = this.anchorToPixel(b, viewport)\n if (!pa || !pb) return null\n const up = viewport.priceAt(pa.y - Math.abs(pb.x - pa.x))\n return up === null ? null : Math.abs(up - a.price) / Math.abs(bars)\n }\n\n /** Hold the second corner on the ratio: at its own bar, as far above or below the first corner as\n * the ratio sets for the bars between them. A square first drawn before it has a ratio takes the\n * pane's, so it opens square. */\n private holdRatio(): void {\n // A format-2 square spans its corners freely while it paints as format 2 did.\n if (this.props.savedLook) return\n const viewport = this.getViewport()\n const [a, b] = this.anchors\n if (!viewport || !a || !b) return\n const bars = viewport.barsBetween(a.time, b.time)\n if (bars === null || bars === 0) return\n let perBar = this.props.scaleRatio\n if (perBar === null || !(perBar > 0)) {\n perBar = this.paneRatio(viewport, a, b, bars)\n if (perBar === null || !(perBar > 0)) return\n super.applyProps({ scaleRatio: perBar })\n }\n const price = a.price + (b.price < a.price ? -1 : 1) * perBar * Math.abs(bars)\n if (price !== b.price) super.updateAnchor(1, { ...b, price })\n }\n\n override paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n super.paint(ctx, viewport)\n if (!this.props.showLabels || this.props.savedLook) return\n const f = this.frame(viewport)\n const [a, b] = this.anchors\n const bars = a && b ? viewport.barsBetween(a.time, b.time) : null\n if (!f || !a || !b || bars === null || bars === 0) return\n const range = Math.abs(b.price - a.price)\n const perBar = Number((range / Math.abs(bars)).toFixed(7))\n const text = `${this.formatPrice(range)}, ${Math.round(Math.abs(bars))} bars, ${perBar}`\n const ink = this.props.levels[0]?.color ?? this.style.lineColor\n paintLabel(ctx, text, { x: (f.left + f.right) / 2, y: f.bottom + 4 }, { ...this.style, textColor: ink }, { align: 'center', baseline: 'top' })\n }\n}\n\n/** Gann square fixed: a square on the pane whatever its scale, the longer drag setting both sides. */\nexport class GannSquareFixed extends GannSquareBase<GannSquareProps> {\n readonly type = 'gannbox_fixed'\n\n protected override defaultProps(): GannSquareProps {\n return SQUARE_PROPS()\n }\n\n protected override upgradeProps(props: Partial<GannSquareProps>): Partial<GannSquareProps> {\n return squareProps(props, this.defaultProps())\n }\n\n protected override corners(viewport: Viewport): { a: Point; b: Point } | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n const size = Math.max(Math.abs(b.x - a.x), Math.abs(b.y - a.y))\n if (size === 0) return null\n return { a, b: { x: a.x + Math.sign(b.x - a.x || 1) * size, y: a.y + Math.sign(b.y - a.y || 1) * size } }\n }\n}\n\n/** A gann fan's settings: its rays at their price-to-time ratios, each in its own stroke, the bands\n * between neighbouring rays, and each ray's ratio read at its end. */\nexport type GannFanProps = {\n levels: FibLevel[]\n fillBackground: boolean\n backgroundOpacity: number\n showLabels: boolean\n}\n\n/** The nine fan ratios, price units per time unit, flattest first. */\nconst FAN_LEVELS = (): FibLevel[] =>\n (\n [\n [1 / 8, '#ff9800'],\n [1 / 4, '#089981'],\n [1 / 3, '#4caf50'],\n [1 / 2, '#089981'],\n [1, '#00bcd4'],\n [2, '#2962ff'],\n [3, '#9c27b0'],\n [4, '#e91e63'],\n [8, '#f23645'],\n ] as const\n ).map(([value, color]) => ({ value, visible: true, color, width: 2, style: 'solid' }))\n\n/** A fan ratio as its row and its label write it: 1/8 to 8/1. */\nexport const fanRatioText = (value: number): string => (value >= 1 ? `${Math.round(value)}/1` : `1/${Math.round(1 / value)}`)\n\n/** The 1/8 to 8/1 fan rays from an origin, scaled by the drag's price and time spans. */\nexport class GannFan extends Drawing<GannFanProps> {\n readonly type = 'gannbox_fan'\n\n protected override defaultProps(): GannFanProps {\n return { levels: FAN_LEVELS(), fillBackground: true, backgroundOpacity: 0.2, showLabels: true }\n }\n\n /** A fan saved with its background switch as `background` reads it as `fillBackground`. */\n protected override upgradeProps(props: Partial<GannFanProps>): Partial<GannFanProps> {\n const from = props as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(this.defaultProps())) if (key in from) out[key] = from[key]\n if (typeof from.background === 'boolean' && !('fillBackground' in from)) out.fillBackground = from.background\n return out as Partial<GannFanProps>\n }\n\n /** A format-2 fan drew no bands and its rays in the colors format 2 gave them. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, levels: savedLevelColors(this._props.levels), fillBackground: false }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected rays(viewport: Viewport): { level: FibLevel; color: string; a: Point; b: Point }[] {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2 || p1.x === p2.x || p1.y === p2.y) return []\n const dx = p2.x - p1.x\n const dy = p2.y - p1.y\n return this.props.levels\n .map((level, i) => ({ level, color: fibLevelColor(level, i) }))\n .filter((e) => e.level.visible && e.level.value > 0)\n .map((e) => ({ ...e, a: p1, b: extendSegment(p1, { x: p1.x + dx, y: p1.y + dy * e.level.value }, viewport.width, viewport.height, false, true).b }))\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const rays = this.rays(viewport)\n if (this.props.fillBackground && this.props.backgroundOpacity > 0) {\n // Each band reaches from the flatter ray beside it to its own, in its own ray's color.\n const ordered = [...rays].sort((p, q) => p.level.value - q.level.value)\n for (let i = 1; i < ordered.length; i++) {\n ctx.save()\n ctx.fillStyle = withAlpha(ordered[i]!.color, this.props.backgroundOpacity)\n ctx.beginPath()\n ctx.moveTo(ordered[i]!.a.x, ordered[i]!.a.y)\n ctx.lineTo(ordered[i - 1]!.b.x, ordered[i - 1]!.b.y)\n ctx.lineTo(ordered[i]!.b.x, ordered[i]!.b.y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n }\n for (const ray of rays) {\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: ray.color, lineWidth: ray.level.width ?? this.style.lineWidth, lineStyle: ray.level.style ?? this.style.lineStyle })\n strokeSegment(ctx, ray.a, ray.b)\n ctx.restore()\n if (this.props.showLabels) paintLabel(ctx, fanRatioText(ray.level.value), { x: ray.b.x - 8, y: ray.b.y }, { ...this.style, textColor: ray.color }, { align: 'right' })\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n return this.rays(viewport).some((ray) => distanceToSegment(point, ray.a, ray.b) <= hitTolerance(ray.level.width ?? this.style.lineWidth))\n }\n}\n","// The MONEY stand-in. A forecasting tool writes a position's P&L and the amount at its target or\n// stop; those are money in the account's currency, not prices on the symbol's grid, so they do\n// not go through the host's price-format port (a Treasury position would otherwise read its\n// P&L in thirty-seconds). Money is written at two decimals: a DECLARED policy, the same for every\n// magnitude and every symbol, never a rule read off the value.\n\n/** A money amount at the declared two decimals, with its sign. */\nexport function moneyText(value: number): string {\n return value.toFixed(2)\n}\n","import type { ControlPoint, DrawingStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { moneyText } from '../core/money'\nimport { distanceToSegment } from '../core/geometry'\nimport { applyStroke, fillPaint, fontOf, paintArrowHead, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\n\n/** The hues a position opens its two zones in, until the viewer says otherwise. */\nconst PROFIT = '#089981'\nconst LOSS = '#f23645'\n/** How solid a zone's wash opens. The bars have to stay readable through it. */\nconst ZONE_ALPHA = 0.2\n\n/** The stats a position can read, in the order its Stats list offers them: at the target its price,\n * percent and tick offsets, the account's amount and the profit; on the entry the open or closed\n * P&L, the quantity and the risk/reward ratio; at the stop the same five as at the target. */\nexport const POSITION_STATS = [\n 'tpPriceOffset',\n 'tpPercentOffset',\n 'tpTickOffset',\n 'tpAmount',\n 'tpPL',\n 'openClosePL',\n 'qty',\n 'riskRewardRatio',\n 'slPriceOffset',\n 'slPercentOffset',\n 'slTickOffset',\n 'slAmount',\n 'slPL',\n] as const\nexport type PositionStat = (typeof POSITION_STATS)[number]\n\n/** How a position writes its quantity: as it reads best, in whole lots, or to one to ten decimals. */\nexport const QTY_PRECISIONS = ['default', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] as const\nexport type QtyPrecision = (typeof QTY_PRECISIONS)[number]\n\nexport type PositionProps = {\n /** Account equity the risk figure is taken from. */\n accountSize: number\n /** Risk per trade, as a percent of the account or an amount in the symbol's currency (per\n * `riskDisplay`). */\n risk: number\n riskDisplay: 'percent' | 'money'\n /** Contract/lot granularity: quantity is expressed in lots of this size. */\n lotSize: number\n /** Caps the position at the account's buying power: qty ≤ account × leverage / entry. */\n leverage: number\n /** How the quantity is written. */\n qtyPrecision: QtyPrecision\n /** The reward zone's background: the band between entry and target, painted as given, opacity\n * and all. Its rule and its label take the same hue at full strength. */\n profitColor: string\n /** The risk zone's background, the same three places below the entry. */\n stopColor: string\n /** Each level's price beside the box. */\n showPrices: boolean\n /** The stats the tags read, in the Stats list's order. */\n stats: PositionStat[]\n /** Compact stats mode: the tags read their figures without their words. */\n compact: boolean\n /** The tags show at rest as well as while the position is hovered or selected. */\n alwaysShowStats: boolean\n}\n\n/** The stats a new position reads: all but the profit and loss at the target and the stop. */\nconst DEFAULT_STATS: readonly PositionStat[] = POSITION_STATS.filter((stat) => stat !== 'tpPL' && stat !== 'slPL')\n\n/** Everything the three tags read, derived once per paint. */\ntype PositionStats = {\n qty: number\n ratio: number\n tpOffset: number\n tpPercent: number\n slOffset: number\n slPercent: number\n amountAtTp: number\n amountAtSl: number\n /** Money PnL at the box's state (open tracks price, closed locks to the touched level). */\n pnl: number\n closed: boolean\n}\n\n/**\n * Trade plan visual: anchor 1 = entry (its time is the box's left edge), anchor 2 = target (its\n * time sets the right edge), anchor 3 = stop. The profit zone paints green with its target tag, the\n * risk zone red with its stop tag, and the entry line carries the P&L, the quantity and the\n * risk/reward ratio, each as the Stats list chooses. Quantity is the lesser of the risk budget over\n * the stop distance and the leveraged account's buying power.\n */\nexport class LongPosition extends Drawing<PositionProps> {\n readonly type: string = 'long_position'\n\n protected override defaultProps(): PositionProps {\n return {\n accountSize: 1000,\n risk: 25,\n riskDisplay: 'percent',\n lotSize: 1,\n leverage: 10000,\n qtyPrecision: 'default',\n profitColor: withAlpha(PROFIT, ZONE_ALPHA),\n stopColor: withAlpha(LOSS, ZONE_ALPHA),\n showPrices: true,\n stats: [...DEFAULT_STATS],\n compact: false,\n alwaysShowStats: false,\n }\n }\n\n /** A format-2 position showed its tags whether or not it was selected; compact, its target and\n * stop tags read their offsets alone; and a save naming no leverage carried none. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n const stats = saved.compact === true ? DEFAULT_STATS.filter((stat) => stat !== 'tpAmount' && stat !== 'slAmount') : [...DEFAULT_STATS]\n this._props = { ...this._props, stats, alwaysShowStats: true, ...('leverage' in saved ? {} : { leverage: 1 }) }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n protected isShort(): boolean {\n return false\n }\n\n protected zones(viewport: Viewport): {\n left: number\n right: number\n entryY: number\n targetY: number\n stopY: number\n } | null {\n const [entry, target, stop] = this.anchorPixels(viewport)\n if (!entry || !target || !stop) return null\n const left = Math.min(entry.x, target.x)\n const right = Math.max(entry.x, target.x)\n if (right - left < 2) return null\n return { left, right, entryY: entry.y, targetY: target.y, stopY: stop.y }\n }\n\n protected stats(): PositionStats | null {\n const [entry, target, stop] = this.anchors\n if (!entry || !target || !stop) return null\n const { accountSize, risk, riskDisplay, leverage } = this.props\n const lot = this.props.lotSize > 0 ? this.props.lotSize : 1\n const short = this.isShort()\n\n const tpOffset = Math.abs(target.price - entry.price)\n const slOffset = Math.abs(entry.price - stop.price)\n const riskSize = riskDisplay === 'percent' ? (accountSize * risk) / 100 : risk\n // Qty = min(QtyRisk, QtyLvg): the risk budget over the stop distance, capped by what the\n // leveraged account can carry at the entry price. Point value is 1 (prices are per unit).\n const qtyRisk = slOffset > 0 ? riskSize / slOffset / lot : 0\n const qtyLvg = entry.price > 0 ? (accountSize * Math.max(1, leverage)) / entry.price / lot : 0\n const qty = Math.max(0, Math.min(qtyRisk, qtyLvg))\n\n const amountAtTp = accountSize + tpOffset * qty * lot\n const amountAtSl = accountSize - slOffset * qty * lot\n const ratio = slOffset > 0 ? tpOffset / slOffset : 0\n\n // PnL over the box's span: closed at ±offset once the target/stop is touched by a bar inside\n // the box, else open against the latest close at (or after) the right edge.\n const sign = short ? -1 : 1\n const bars = this.bars()\n const from = Math.min(Number(entry.time), Number(target.time))\n const to = Math.max(Number(entry.time), Number(target.time))\n let pnl = 0\n let closed = false\n let lastClose: number | null = null\n for (const bar of bars) {\n const t = Number(bar.time)\n if (t < from) continue\n if (t > to) break\n lastClose = bar.close\n const hitTp = short ? bar.low <= target.price : bar.high >= target.price\n const hitSl = short ? bar.high >= stop.price : bar.low <= stop.price\n if (hitSl) {\n pnl = -slOffset * qty * lot\n closed = true\n break\n }\n if (hitTp) {\n pnl = tpOffset * qty * lot\n closed = true\n break\n }\n }\n if (!closed) {\n // The box may sit in the future (no bars inside): open PnL tracks the last known close.\n const reference = lastClose ?? (bars.length ? bars[bars.length - 1]!.close : null)\n pnl = reference == null ? 0 : sign * (reference - entry.price) * qty * lot\n }\n\n return {\n qty,\n ratio,\n tpOffset,\n tpPercent: entry.price !== 0 ? (tpOffset / entry.price) * 100 : 0,\n slOffset,\n slPercent: entry.price !== 0 ? (slOffset / entry.price) * 100 : 0,\n amountAtTp,\n amountAtSl,\n pnl,\n closed,\n }\n }\n\n /** The quantity as the position's precision writes it. */\n protected qtyText(qty: number): string {\n const precision = this.props.qtyPrecision\n if (precision === 'default') return qty >= 100 ? qty.toFixed(0) : qty.toFixed(2)\n return qty.toFixed(Number(precision))\n }\n\n /** A level's tag: its offset as a price, a percent and ticks, then its amount and its P&L, each as\n * the Stats list chooses, with their words unless the stats are compact. Ticks need the host's\n * tick; without one they are left out. */\n private levelTag(side: 'tp' | 'sl', offset: number, percent: number, amount: number, pl: number): string {\n const shown = (stat: string): boolean => (this.props.stats as readonly string[]).includes(stat)\n const compact = this.props.compact\n const tick = this.tickSize()\n const head: string[] = []\n if (shown(`${side}PriceOffset`)) head.push(this.formatPrice(offset))\n if (shown(`${side}PercentOffset`)) head.push(`(${percent.toFixed(2)}%)`)\n if (shown(`${side}TickOffset`) && tick && tick > 0) head.push(String(Math.round(offset / tick)))\n const parts: string[] = []\n if (head.length) parts.push(compact ? head.join(' ') : `${side === 'tp' ? 'Target' : 'Stop'}: ${head.join(' ')}`)\n if (shown(`${side}Amount`)) parts.push(compact ? moneyText(amount) : `Amount: ${moneyText(amount)}`)\n if (shown(`${side}PL`)) parts.push(compact ? moneyText(pl) : `P&L: ${moneyText(pl)}`)\n return parts.join(compact ? ' · ' : ', ')\n }\n\n /** The entry's tag: the open or closed P&L, the quantity and the risk/reward ratio, as chosen. */\n private entryTag(s: PositionStats): string {\n const shown = (stat: PositionStat): boolean => this.props.stats.includes(stat)\n const compact = this.props.compact\n const parts: string[] = []\n if (shown('openClosePL')) parts.push(compact ? moneyText(s.pnl) : `${s.closed ? 'Closed P&L' : 'Open P&L'}: ${moneyText(s.pnl)}`)\n if (shown('qty')) parts.push(compact ? this.qtyText(s.qty) : `Qty: ${this.qtyText(s.qty)}`)\n if (shown('riskRewardRatio')) parts.push(compact ? s.ratio.toFixed(2) : `Risk/Reward Ratio: ${s.ratio.toFixed(2)}`)\n return parts.join(compact ? ' · ' : ', ')\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const z = this.zones(viewport)\n if (!z) return\n const [entry, target, stop] = this.anchors\n ctx.save()\n const profitInk = withAlpha(this.props.profitColor, 1)\n const stopInk = withAlpha(this.props.stopColor, 1)\n ctx.fillStyle = this.props.profitColor\n ctx.fillRect(z.left, Math.min(z.entryY, z.targetY), z.right - z.left, Math.abs(z.targetY - z.entryY))\n ctx.fillStyle = this.props.stopColor\n ctx.fillRect(z.left, Math.min(z.entryY, z.stopY), z.right - z.left, Math.abs(z.stopY - z.entryY))\n ctx.restore()\n\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.strokeStyle = profitInk\n strokeSegment(ctx, { x: z.left, y: z.targetY }, { x: z.right, y: z.targetY })\n ctx.strokeStyle = stopInk\n strokeSegment(ctx, { x: z.left, y: z.stopY }, { x: z.right, y: z.stopY })\n ctx.strokeStyle = this.style.lineColor\n strokeSegment(ctx, { x: z.left, y: z.entryY }, { x: z.right, y: z.entryY })\n ctx.restore()\n\n const s = this.stats()\n if (s && (this.props.alwaysShowStats || this.state !== 'normal')) {\n // The P&L and the amounts at target and stop are MONEY, written by the money stand-in; the\n // level offsets are prices on the symbol's grid and go through the price port.\n const mid = (z.left + z.right) / 2\n const targetText = this.levelTag('tp', s.tpOffset, s.tpPercent, s.amountAtTp, s.tpOffset * s.qty * (this.props.lotSize > 0 ? this.props.lotSize : 1))\n const stopText = this.levelTag('sl', s.slOffset, s.slPercent, s.amountAtSl, -s.slOffset * s.qty * (this.props.lotSize > 0 ? this.props.lotSize : 1))\n const entryText = this.entryTag(s)\n // The three tags are written in the drawing's text colour, which is what the bar's text\n // control sets: the plan's words are the only text it has.\n if (targetText) paintLabel(ctx, targetText, { x: mid, y: z.targetY }, this.style, { align: 'center', background: profitInk })\n if (stopText) paintLabel(ctx, stopText, { x: mid, y: z.stopY }, this.style, { align: 'center', background: stopInk })\n if (entryText) paintLabel(ctx, entryText, { x: mid, y: z.entryY }, this.style, { align: 'center', background: '#585858' })\n }\n\n if (this.props.showPrices) {\n paintLabel(ctx, this.formatPrice(target!.price), { x: z.right + 6, y: z.targetY }, { ...this.style, textColor: profitInk })\n paintLabel(ctx, this.formatPrice(stop!.price), { x: z.right + 6, y: z.stopY }, { ...this.style, textColor: stopInk })\n // Each price beside the plan is written in its own level's ink, the entry's in the entry line's:\n // the text colour belongs to the tags alone.\n paintLabel(ctx, this.formatPrice(entry!.price), { x: z.right + 6, y: z.entryY }, { ...this.style, textColor: this.style.lineColor })\n }\n }\n\n /** The stop's handle stands on the box's far edge beside the target's, where the stop's level is\n * painted: the box's edges are the entry's time and the target's, and the stop's own time paints\n * nothing, so a handle at it would stay behind as the box's width changes. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n const points = super.getControlPoints(viewport)\n const edge = points.find((point) => point.index === 1)\n return edge ? points.map((point) => (point.index === 2 ? { ...point, x: edge.x } : point)) : points\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const z = this.zones(viewport)\n if (!z) return false\n const top = Math.min(z.entryY, z.targetY, z.stopY)\n const bottom = Math.max(z.entryY, z.targetY, z.stopY)\n return point.x >= z.left - 4 && point.x <= z.right + 4 && point.y >= top - 4 && point.y <= bottom + 4\n }\n}\n\n/** Identical structure to the long position; the PnL direction flips with the side. */\nexport class ShortPosition extends LongPosition {\n override readonly type = 'short_position'\n\n protected override isShort(): boolean {\n return true\n }\n}\n\n/** Bordered label pill (source/target/verdict boxes); returns its painted bounds. */\nfunction paintPill(\n ctx: CanvasRenderingContext2D,\n text: string,\n at: Point,\n style: DrawingStyle,\n colors: { text: string; back: string; border?: string },\n): { x: number; y: number; width: number; height: number } {\n ctx.save()\n ctx.font = fontOf(style)\n ctx.setLineDash([])\n const width = ctx.measureText(text).width + 12\n const height = style.fontSize + 10\n const box = { x: at.x - width / 2, y: at.y - height / 2, width, height }\n ctx.beginPath()\n ctx.roundRect(box.x, box.y, box.width, box.height, 4)\n ctx.fillStyle = colors.back\n ctx.fill()\n if (colors.border) {\n ctx.strokeStyle = colors.border\n ctx.lineWidth = 1\n ctx.stroke()\n }\n ctx.fillStyle = colors.text\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(text, at.x, at.y)\n ctx.restore()\n return box\n}\n\nexport type ForecastProps = {\n sourceTextColor: string\n sourceBackColor: string\n sourceBorderColor: string\n targetTextColor: string\n targetBackColor: string\n targetBorderColor: string\n successTextColor: string\n successBackColor: string\n failureTextColor: string\n failureBackColor: string\n}\n\n/**\n * Position forecast: entry (source) and exit (target) anchors set a projected move and its\n * duration. As bars arrive the idea resolves itself: Success when price touches the target before\n * the target time, Failure once that time passes untouched.\n */\nexport class Forecast extends Drawing<ForecastProps> {\n readonly type = 'forecast'\n\n protected override defaultProps(): ForecastProps {\n return {\n sourceTextColor: '#ffffff',\n sourceBackColor: 'rgba(41, 98, 255, 0.9)',\n sourceBorderColor: '#2962ff',\n targetTextColor: '#ffffff',\n targetBackColor: '#2962ff',\n targetBorderColor: '#2962ff',\n successTextColor: '#ffffff',\n successBackColor: '#4caf50',\n failureTextColor: '#ffffff',\n failureBackColor: LOSS,\n }\n }\n\n /** A format-2 forecast that named none of these colors drew its source tag blue, its target tag\n * and its success green. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n const earlier: Partial<ForecastProps> = { sourceBackColor: '#2962ff', targetBackColor: PROFIT, targetBorderColor: PROFIT, successBackColor: PROFIT }\n const missing = Object.fromEntries(Object.entries(earlier).filter(([key]) => !(key in saved)))\n this._props = { ...this._props, ...missing }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** Success once a bar inside the window touches the target; Failure when time runs out. */\n private verdict(): 'Success' | 'Failure' | null {\n const [a, b] = this.anchors\n if (!a || !b) return null\n const start = Math.min(Number(a.time), Number(b.time))\n const end = Math.max(Number(a.time), Number(b.time))\n const up = b.price >= a.price\n let latest = -Infinity\n for (const bar of this.bars()) {\n const t = Number(bar.time)\n latest = Math.max(latest, t)\n if (t <= start || t > end) continue\n if (up ? bar.high >= b.price : bar.low <= b.price) return 'Success'\n }\n return latest > end ? 'Failure' : null\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return\n const [a, b] = this.anchors\n applyStroke(ctx, this.style)\n strokeSegment(ctx, p1, p2)\n paintArrowHead(ctx, p1, p2, this.style)\n const p = this.props\n const up = b.price >= a.price\n paintPill(ctx, this.formatPrice(a.price), { x: p1.x, y: p1.y + (up ? 16 : -16) }, this.style, {\n text: p.sourceTextColor,\n back: p.sourceBackColor,\n border: p.sourceBorderColor,\n })\n paintPill(ctx, this.formatPrice(b.price), { x: p2.x, y: p2.y + (up ? -16 : 16) }, this.style, {\n text: p.targetTextColor,\n back: p.targetBackColor,\n border: p.targetBorderColor,\n })\n const verdict = this.verdict()\n if (verdict) {\n const win = verdict === 'Success'\n paintPill(ctx, verdict, { x: p2.x, y: p2.y + (up ? -40 : 40) }, this.style, {\n text: win ? p.successTextColor : p.failureTextColor,\n back: win ? p.successBackColor : p.failureBackColor,\n })\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const [p1, p2] = this.anchorPixels(viewport)\n if (!p1 || !p2) return false\n return distanceToSegment(point, p1, p2) <= Math.max(6, this.style.lineWidth / 2 + 4)\n }\n}\n\n/** A sector's two backgrounds, one for each half of the slice, and whether they fill. */\nexport type SectorProps = {\n /** The half of the slice toward its second point. */\n color1: string\n /** The half toward its third point. */\n color2: string\n fillBackground: boolean\n}\n\n/**\n * Sector: a wedge projecting price forward from an origin, a horizontal point in the future and a\n * third point at the estimated price. The arc between the two far points closes the slice, and the\n * ray through the arc's middle parts its two backgrounds.\n */\nexport class Sector extends Drawing<SectorProps> {\n readonly type = 'sector'\n\n protected override defaultProps(): SectorProps {\n return { color1: 'rgba(41, 98, 255, 0.2)', color2: 'rgba(156, 39, 176, 0.2)', fillBackground: true }\n }\n\n /** A format-2 sector filled its slice in its background, one color across both halves. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n const fill = fillPaint(this._style)\n this._props = fill ? { ...this._props, color1: fill, color2: fill, fillBackground: true } : { ...this._props, fillBackground: false }\n }\n\n requiredAnchors(): number {\n return 3\n }\n\n /** Arc samples from anchor 2 to anchor 3, radius blending between the two legs. */\n private arc(viewport: Viewport): { origin: Point; p2: Point; p3: Point; samples: Point[] } | null {\n const [origin, p2, p3] = this.anchorPixels(viewport)\n if (!origin || !p2 || !p3) return null\n const r2 = Math.hypot(p2.x - origin.x, p2.y - origin.y)\n const r3 = Math.hypot(p3.x - origin.x, p3.y - origin.y)\n const a2 = Math.atan2(p2.y - origin.y, p2.x - origin.x)\n const a3 = Math.atan2(p3.y - origin.y, p3.x - origin.x)\n let sweep = a3 - a2\n if (sweep > Math.PI) sweep -= Math.PI * 2\n if (sweep < -Math.PI) sweep += Math.PI * 2\n const steps = 32\n const samples: Point[] = []\n for (let i = 0; i <= steps; i++) {\n const t = i / steps\n const angle = a2 + sweep * t\n const radius = r2 + (r3 - r2) * t\n samples.push({ x: origin.x + Math.cos(angle) * radius, y: origin.y + Math.sin(angle) * radius })\n }\n return { origin, p2, p3, samples }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const arc = this.arc(viewport)\n if (!arc) return\n ctx.save()\n if (this.props.fillBackground !== false) {\n const middle = Math.floor(arc.samples.length / 2)\n const half = (from: number, to: number, color: string): void => {\n ctx.fillStyle = color\n ctx.beginPath()\n ctx.moveTo(arc.origin.x, arc.origin.y)\n for (let i = from; i <= to; i++) ctx.lineTo(arc.samples[i]!.x, arc.samples[i]!.y)\n ctx.closePath()\n ctx.fill()\n }\n // Halves of one color fill as one slice, with no seam between them.\n if (this.props.color1 === this.props.color2) half(0, arc.samples.length - 1, this.props.color1)\n else {\n half(0, middle, this.props.color1)\n half(middle, arc.samples.length - 1, this.props.color2)\n }\n }\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.moveTo(arc.origin.x, arc.origin.y)\n for (const s of arc.samples) ctx.lineTo(s.x, s.y)\n ctx.closePath()\n ctx.stroke()\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const arc = this.arc(viewport)\n if (!arc) return false\n const tolerance = Math.max(6, this.style.lineWidth / 2 + 4)\n if (distanceToSegment(point, arc.origin, arc.samples[0]) <= tolerance) return true\n if (distanceToSegment(point, arc.origin, arc.samples[arc.samples.length - 1]) <= tolerance) return true\n for (let i = 0; i < arc.samples.length - 1; i++) {\n if (distanceToSegment(point, arc.samples[i], arc.samples[i + 1]) <= tolerance) return true\n }\n return false\n }\n}\n","import type { ControlPoint, DrawingStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment } from '../core/geometry'\nimport { applyStroke, paintArrowHead, withAlpha } from '../render/canvas'\nimport type { LineEnd } from './lines'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** Earlier saved highlighters stored the shared 1–4 line width and rendered it eightfold. New\n * strokes store their actual pixel width, so the style value matches the toolbar label. */\nexport function highlighterStrokeWidth(lineWidth: number): number {\n return lineWidth <= 4 ? Math.max(lineWidth * 8, 12) : lineWidth\n}\n\n/** Polyline through every anchor — the shared body of the freehand/multi-point family. */\nabstract class StrokeDrawing<P extends Record<string, unknown> = Record<string, never>> extends Drawing<P> {\n requiredAnchors(): number {\n return 2\n }\n\n protected points(viewport: Viewport): Point[] {\n return this.anchorPixels(viewport).filter((p): p is Point => !!p)\n }\n\n protected tracePath(ctx: CanvasRenderingContext2D, points: Point[], smooth: boolean): void {\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n if (smooth && points.length > 2) {\n // Midpoint quadratic smoothing keeps a hand-drawn stroke from looking segmented.\n for (let i = 1; i < points.length - 1; i++) {\n const midX = (points[i].x + points[i + 1].x) / 2\n const midY = (points[i].y + points[i + 1].y) / 2\n ctx.quadraticCurveTo(points[i].x, points[i].y, midX, midY)\n }\n const last = points[points.length - 1]\n ctx.lineTo(last.x, last.y)\n } else {\n for (let i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y)\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const points = this.points(viewport)\n const tolerance = hitTolerance(this.strokeWidth())\n for (let i = 0; i < points.length - 1; i++) {\n if (distanceToSegment(point, points[i], points[i + 1]) <= tolerance) return true\n }\n return false\n }\n\n protected strokeWidth(): number {\n return this.style.lineWidth\n }\n}\n\n/** Sampled points shape a freehand stroke, but are not individually editable handles. The whole\n * stroke remains selectable and movable by grabbing its ink. */\nabstract class FreehandStroke<P extends Record<string, unknown> = Record<string, never>> extends StrokeDrawing<P> {\n override getControlPoints(_viewport: Viewport): ControlPoint[] {\n return []\n }\n}\n\n/** A stroke's two ends, each plain or an arrow. */\nexport type StrokeEndsProps = {\n leftEnd: LineEnd\n rightEnd: LineEnd\n}\n\n/** A brush's background switch, and its ends. */\nexport type BrushProps = StrokeEndsProps & {\n /** The area the stroke closes back to its start, filled in the drawing's fill. */\n fillBackground: boolean\n}\n\n/** Arrow heads at a stroke's ends, its first point the left end and its last the right. */\nfunction paintEnds(ctx: CanvasRenderingContext2D, points: Point[], ends: StrokeEndsProps, style: DrawingStyle): void {\n if (ends.leftEnd === 'arrow') paintArrowHead(ctx, points[1]!, points[0]!, style)\n if (ends.rightEnd === 'arrow') paintArrowHead(ctx, points[points.length - 2]!, points[points.length - 1]!, style)\n}\n\n/** Freehand stroke captured while the pointer drags. */\nexport class Brush extends FreehandStroke<BrushProps> {\n readonly type: string = 'brush'\n\n protected override defaultProps(): BrushProps {\n return { fillBackground: false, leftEnd: 'normal', rightEnd: 'normal' }\n }\n\n /** A format-2 brush filled its stroke's closed shape wherever its fill showed. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, fillBackground: this._style.fillOpacity > 0 }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.points(viewport)\n if (points.length < 2) return\n if (this.props.fillBackground && this.style.fillOpacity > 0) {\n ctx.save()\n ctx.fillStyle = withAlpha(this.style.fillColor, this.style.fillOpacity)\n this.tracePath(ctx, points, true)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n applyStroke(ctx, this.style)\n this.tracePath(ctx, points, true)\n ctx.stroke()\n paintEnds(ctx, points, this.props, this.style)\n }\n}\n\n/**\n * Brush variant: a wide stroke that reads as marker ink. Always solid — the translucency lives\n * in the color value itself (the default seeds ~35% alpha), so the opacity control is the whole\n * style surface.\n */\nexport class Highlighter extends FreehandStroke {\n override readonly type = 'highlighter'\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.points(viewport)\n if (points.length < 2) return\n ctx.save()\n ctx.setLineDash([])\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = highlighterStrokeWidth(this.style.lineWidth)\n this.tracePath(ctx, points, true)\n ctx.stroke()\n ctx.restore()\n }\n\n protected override strokeWidth(): number {\n return highlighterStrokeWidth(this.style.lineWidth)\n }\n}\n\n/** Click-placed polyline, an arrow at its last point unless its ends say otherwise. */\nexport class PathLine extends StrokeDrawing<StrokeEndsProps> {\n override readonly type = 'path'\n\n protected override defaultProps(): StrokeEndsProps {\n return { leftEnd: 'normal', rightEnd: 'arrow' }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.points(viewport)\n if (points.length < 2) return\n applyStroke(ctx, this.style)\n this.tracePath(ctx, points, false)\n ctx.stroke()\n paintEnds(ctx, points, this.props, this.style)\n }\n}\n\n/** A polygon's background switch: off, the polygon keeps its fill's color and opacity unpainted. */\nexport type PolylineProps = {\n fillBackground: boolean\n}\n\n/** Click-placed polygon; closes and fills once it has three points. */\nexport class Polyline extends StrokeDrawing<PolylineProps> {\n override readonly type = 'polyline'\n\n protected override defaultProps(): PolylineProps {\n return { fillBackground: true }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.points(viewport)\n if (points.length < 2) return\n applyStroke(ctx, this.style)\n this.tracePath(ctx, points, false)\n if (points.length > 2) {\n ctx.closePath()\n if (this.props.fillBackground !== false && this.style.fillOpacity > 0) {\n ctx.fillStyle = withAlpha(this.style.fillColor, this.style.fillOpacity)\n ctx.fill()\n }\n }\n ctx.stroke()\n }\n\n override testHit(point: Point, viewport: Viewport): boolean {\n if (super.testHit(point, viewport)) return true\n const points = this.points(viewport)\n if (points.length < 3) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n return distanceToSegment(point, points[points.length - 1], points[0]) <= tolerance\n }\n}\n","import type { ControlPoint, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { endSavedLook, type SavedLook } from '../core/savedLook'\nimport { layoutTextBlock, type TextEditFrame } from '../core/textEntry'\nimport { fillPaint, fontOf, lineMeasure, withAlpha, type HandleShape } from '../render/canvas'\nimport { paintTextEntry } from '../render/textEntry'\n\nexport type TableProps = {\n /** Row-major cell text. The grid's shape IS this array's shape. */\n cells: string[][]\n /** The first row banded as a header. */\n headerRow: boolean\n /** Where each cell's words stand across it. */\n textHAlign: 'left' | 'center' | 'right'\n /** Per-column widths in px; a column beyond the array is 120px wide. */\n colWidths: number[]\n /** Per-row heights in px; a row beyond the array, or of height 0, takes its words' height, and no\n * row stands shorter than its words. */\n rowHeights: number[]\n /** A format-2 table's look, its rows 26px tall around one line of words each and its border\n * rounded at 4, painted as format 2 did until the table's settings change. */\n savedLook: SavedLook\n}\n\n/** A cell of a table, by its row and column. */\nexport interface TableCell {\n row: number\n col: number\n}\n\n/** A table's columns' width where none is set, the bounds a resize holds a column and a row to,\n * how far a cell's words stand in from its grid line across and down, its lines' height to its\n * type, how much shorter a row of empty cells stands than a row of one line, the band a hovered\n * grid line wears on each side of its pixel, and how far in from a cell's grid lines the frame\n * round the cell being typed in stands. */\nconst CELL_WIDTH = 120\nconst MIN_COL = 28\nconst MAX_COL = 600\nconst MIN_ROW = 16\nconst MAX_ROW = 400\nconst CELL_INSET = 9\nconst CELL_PAD = 6.9\nconst LINE_HEIGHT = 1.3\nconst EMPTY_ROW_SHORTER = 1\nconst LINE_BAND = { half: 3, alpha: 0.2 }\nconst CELL_FRAME = 2\n\n/** A format-2 table's rows, and the room its words kept from a cell's side. */\nconst SAVED_ROW = 26\nconst SAVED_PAD = 8\n\n/** A cell's lines: its words split at their line breaks, none for an empty cell. */\nconst linesOf = (text: string): string[] => (text === '' ? [] : text.split('\\n'))\n\n/** A table's props with a column added: right of `after`, or at the right end where it is null. */\nexport function withColumn(props: Readonly<TableProps>, after: number | null): Pick<TableProps, 'cells' | 'colWidths'> {\n const cols = props.cells[0]?.length ?? 0\n const at = after === null ? cols : Math.min(cols, Math.max(0, after + 1))\n const colWidths = Array.from({ length: cols }, (_, c) => props.colWidths[c] ?? CELL_WIDTH)\n colWidths.splice(at, 0, CELL_WIDTH)\n return { cells: props.cells.map((row) => [...row.slice(0, at), '', ...row.slice(at)]), colWidths }\n}\n\n/** A table's props with a row added: below `after`, or at the bottom where it is null. */\nexport function withRow(props: Readonly<TableProps>, after: number | null): Pick<TableProps, 'cells' | 'rowHeights'> {\n const rows = props.cells.length\n const cols = props.cells[0]?.length ?? 0\n const at = after === null ? rows : Math.min(rows, Math.max(0, after + 1))\n const rowHeights = Array.from({ length: rows }, (_, r) => props.rowHeights[r] ?? 0)\n rowHeights.splice(at, 0, 0)\n const cells = props.cells.map((row) => [...row])\n cells.splice(at, 0, Array.from({ length: cols }, () => ''))\n return { cells, rowHeights }\n}\n\n/** A table's props without a row, or null where it is the table's last. */\nexport function withoutRow(props: Readonly<TableProps>, row: number): Pick<TableProps, 'cells' | 'rowHeights'> | null {\n if (props.cells.length <= 1 || row < 0 || row >= props.cells.length) return null\n return { cells: props.cells.filter((_, r) => r !== row), rowHeights: props.rowHeights.filter((_, r) => r !== row) }\n}\n\n/** A table's props without a column, or null where it is the table's last. */\nexport function withoutColumn(props: Readonly<TableProps>, col: number): Pick<TableProps, 'cells' | 'colWidths'> | null {\n const cols = props.cells[0]?.length ?? 0\n if (cols <= 1 || col < 0 || col >= cols) return null\n return { cells: props.cells.map((row) => row.filter((_, c) => c !== col)), colWidths: props.colWidths.filter((_, c) => c !== col) }\n}\n\n/** The cell after another in reading order, wrapping from the last to the first; backward, the one\n * before it. */\nexport function nextCell(props: Readonly<TableProps>, cell: TableCell, backward = false): TableCell {\n const rows = props.cells.length\n const cols = props.cells[0]?.length ?? 1\n const count = Math.max(1, rows * cols)\n const at = (cell.row * cols + cell.col + (backward ? count - 1 : 1)) % count\n return { row: Math.floor(at / cols), col: at % cols }\n}\n\n/**\n * Table: a grid of cells whose top-left stands on a chart point. Its columns are 120px wide unless\n * resized, and each row is as tall as its tallest cell's words, lines 1.3 times their size with\n * 6.9px above and below them, a row of empty cells a pixel shorter than one of a line; a row resized\n * taller keeps its height. The table is the drawing's fill, its grid one pixel lines in its stroke\n * color, and a cell's words stand 9px in from its grid line on the side they align to. Selected, it\n * shows a round handle on each corner, which scales the table, and a hovered grid line wears a band\n * 7px wide and resizes its column or row; a click on a cell of the selected table types into it,\n * framed 2px in from its grid lines.\n */\nexport class TableNote extends Drawing<TableProps> {\n readonly type = 'table'\n\n protected override defaultProps(): TableProps {\n return {\n cells: [\n ['', '', ''],\n ['', '', ''],\n ['', '', ''],\n ],\n headerRow: false,\n textHAlign: 'left',\n colWidths: [],\n rowHeights: [],\n savedLook: null,\n }\n }\n\n /** A format-2 table's columns stood 96px wide where it set no width, its rows 26px tall, its border\n * and grid took its stroke color at 45%, and a save naming no cells or header was two by two with\n * a header row; it paints so until its settings change. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n // A save naming no cells or header drew two by two with a header row.\n if (!('cells' in saved)) this._props = { ...this._props, cells: [['', ''], ['', '']] }\n if (!('headerRow' in saved)) this._props = { ...this._props, headerRow: true }\n const cols = this._props.cells[0]?.length ?? 0\n const colWidths = Array.from({ length: cols }, (_, c) => this._props.colWidths[c] ?? 96)\n this._props = { ...this._props, colWidths, savedLook: {} }\n this._style = { ...this._style, lineColor: withAlpha(this._style.lineColor, 0.45) }\n }\n\n override applyProps(patch: Partial<TableProps>): void {\n super.applyProps(endSavedLook(patch))\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n // ── The cell being typed in ─────────────────────────────────────────────────────────────────\n\n private _editingCell: TableCell | null = null\n\n /** The cell being typed in, or the one last typed in that an edit of the table's rows and\n * columns acts on (transient view state, never serialized); it wears a frame. */\n get editingCell(): TableCell | null {\n return this._editingCell\n }\n\n editCell(cell: TableCell | null): void {\n this._editingCell = cell\n this.requestUpdate()\n }\n\n /** The words a cell shows: the open edit's draft in the cell being typed in, its own elsewhere. */\n private wordsOf(row: number, col: number): string {\n const cell = this._editingCell\n const draft = this.textDraft\n if (draft && cell && cell.row === row && cell.col === col) return draft.value\n return this.props.cells[row]?.[col] ?? ''\n }\n\n /** The words a cell holds, committed, for an editor opened on it. */\n cellWords(cell: TableCell): string {\n return this.props.cells[cell.row]?.[cell.col] ?? ''\n }\n\n // ── Geometry ────────────────────────────────────────────────────────────────────────────────\n\n private lineHeight(): number {\n return Math.round(this.style.fontSize * LINE_HEIGHT * 10) / 10\n }\n\n private colWidth(i: number): number {\n if (this.props.savedLook) return Math.max(MIN_COL, this.props.colWidths[i] ?? CELL_WIDTH)\n return Math.min(MAX_COL, Math.max(MIN_COL, this.props.colWidths[i] ?? CELL_WIDTH))\n }\n\n /** How tall a row's words stand: its tallest cell's lines and the room above and below them. */\n private rowContent(r: number): number {\n const lh = this.lineHeight()\n const cols = this.props.cells[0]?.length ?? 0\n let lines = 0\n for (let c = 0; c < cols; c++) lines = Math.max(lines, linesOf(this.wordsOf(r, c)).length)\n return lines === 0 ? lh + CELL_PAD * 2 - EMPTY_ROW_SHORTER : lines * lh + CELL_PAD * 2\n }\n\n private rowHeight(r: number): number {\n if (this.props.savedLook) return Math.max(MIN_ROW, this.props.rowHeights[r] || SAVED_ROW)\n return Math.max(this.rowContent(r), this.props.rowHeights[r] ?? 0)\n }\n\n /** Left offsets per column boundary (0..cols) and top offsets per row boundary (0..rows). */\n private offsets(): { xs: number[]; ys: number[] } {\n const rows = this.props.cells.length\n const cols = this.props.cells[0]?.length ?? 0\n const xs = [0]\n for (let c = 0; c < cols; c++) xs.push(xs[c]! + this.colWidth(c))\n const ys = [0]\n for (let r = 0; r < rows; r++) ys.push(ys[r]! + this.rowHeight(r))\n return { xs, ys }\n }\n\n protected frame(viewport: Viewport): { x: number; y: number; width: number; height: number } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const { xs, ys } = this.offsets()\n if (xs.length < 2 || ys.length < 2) return null\n return { x: p.x, y: p.y, width: xs[xs.length - 1]!, height: ys[ys.length - 1]! }\n }\n\n /** The pixel columns of the table's vertical grid lines and the pixel rows of its horizontal\n * ones, outer edges included. */\n private gridPixels(viewport: Viewport): { xs: number[]; ys: number[] } | null {\n const f = this.frame(viewport)\n if (!f) return null\n const { xs, ys } = this.offsets()\n return { xs: xs.map((x) => Math.round(f.x + x)), ys: ys.map((y) => Math.round(f.y + y)) }\n }\n\n /** The cell under a pane point, with its rect: where a click on the selected table types. */\n cellAt(point: Point, viewport: Viewport): { row: number; col: number; rect: { x: number; y: number; width: number; height: number } } | null {\n const f = this.frame(viewport)\n if (!f) return null\n const { xs, ys } = this.offsets()\n const dx = point.x - f.x\n const dy = point.y - f.y\n if (dx < 0 || dy < 0 || dx > f.width || dy > f.height) return null\n let col = 0\n while (col < xs.length - 2 && dx >= xs[col + 1]!) col++\n let row = 0\n while (row < ys.length - 2 && dy >= ys[row + 1]!) row++\n return {\n row,\n col,\n rect: { x: f.x + xs[col]!, y: f.y + ys[row]!, width: xs[col + 1]! - xs[col]!, height: ys[row + 1]! - ys[row]! },\n }\n }\n\n /** Where a cell's words stand: their first line's box, its width across the cell, and the\n * height of a line. */\n private cellWordsPlace(cell: TableCell, viewport: Viewport): { x: number; y: number; width: number; lineHeight: number } | null {\n const f = this.frame(viewport)\n if (!f) return null\n const { xs, ys } = this.offsets()\n const left = xs[cell.col]\n const right = xs[cell.col + 1]\n const top = ys[cell.row]\n if (left === undefined || right === undefined || top === undefined) return null\n const lh = this.lineHeight()\n // The first line's middle stands on a whole pixel, as far down as the room and half a line and\n // a pixel more.\n const middle = Math.round(f.y + top + CELL_PAD + lh / 2 + 1)\n return { x: f.x + left + CELL_INSET, y: middle - lh / 2 - 1, width: right - left - CELL_INSET * 2, lineHeight: lh }\n }\n\n override textFrame(viewport: Viewport): TextEditFrame | null {\n const cell = this._editingCell\n if (!cell) return null\n const at = this.cellWordsPlace(cell, viewport)\n if (!at) return null\n const lines = Math.max(1, linesOf(this.wordsOf(cell.row, cell.col)).length)\n return { x: at.x, y: at.y, width: at.width, lines, lineHeight: at.lineHeight, font: fontOf(this.style), align: this.props.textHAlign ?? 'left', wrapWidth: null, angle: 0 }\n }\n\n // ── Painting ────────────────────────────────────────────────────────────────────────────────\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n if (this.props.savedLook) {\n this.paintSaved(ctx, viewport)\n return\n }\n const grid = this.gridPixels(viewport)\n if (!grid) return\n const rows = this.props.cells.length\n const cols = this.props.cells[0]?.length ?? 0\n const left = grid.xs[0]!\n const right = grid.xs[grid.xs.length - 1]!\n const top = grid.ys[0]!\n const bottom = grid.ys[grid.ys.length - 1]!\n ctx.save()\n ctx.setLineDash([])\n const base = fillPaint(this.style)\n if (base) {\n ctx.fillStyle = base\n ctx.fillRect(left, top, right - left + 1, bottom - top + 1)\n }\n if (this.props.headerRow) {\n ctx.fillStyle = withAlpha(this.style.lineColor, 0.16)\n ctx.fillRect(left, top, right - left + 1, grid.ys[1]! - top)\n }\n // The grid, every line on its pixel.\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.beginPath()\n for (const y of grid.ys) {\n ctx.moveTo(left, y + 0.5)\n ctx.lineTo(right + 1, y + 0.5)\n }\n for (const x of grid.xs) {\n ctx.moveTo(x + 0.5, top)\n ctx.lineTo(x + 0.5, bottom + 1)\n }\n ctx.stroke()\n // Each cell's words, clipped to the cell.\n const measure = lineMeasure(this.style)\n const align = this.props.textHAlign ?? 'left'\n const editing = this._editingCell\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const typing = !!editing && editing.row === r && editing.col === c && !!this.textDraft\n const words = this.wordsOf(r, c)\n if (!words && !typing) continue\n const at = this.cellWordsPlace({ row: r, col: c }, viewport)\n if (!at) continue\n ctx.save()\n ctx.beginPath()\n ctx.rect(grid.xs[c]! + 1, grid.ys[r]! + 1, grid.xs[c + 1]! - grid.xs[c]! - 1, grid.ys[r + 1]! - grid.ys[r]! - 1)\n ctx.clip()\n paintTextEntry(ctx, {\n x: at.x,\n y: at.y,\n width: at.width,\n lineHeight: at.lineHeight,\n font: fontOf(this.style),\n color: this.style.textColor,\n align,\n block: layoutTextBlock(words, measure),\n placeholder: null,\n draft: typing ? this.textDraft : null,\n measure,\n })\n ctx.restore()\n }\n }\n const inks = this.inks()\n // The hovered grid line's band, over the whole table.\n const line = this.state === 'selected' ? this.hoveredLine(viewport) : null\n if (line) {\n ctx.globalAlpha = LINE_BAND.alpha\n ctx.fillStyle = inks.accent\n if (line.across === 'column') ctx.fillRect(line.at - LINE_BAND.half, top, LINE_BAND.half * 2 + 1, bottom - top + 1)\n else ctx.fillRect(left, line.at - LINE_BAND.half, right - left + 1, LINE_BAND.half * 2 + 1)\n ctx.globalAlpha = 1\n }\n // The frame round the cell being typed in.\n if (editing && editing.row < rows && editing.col < cols) {\n const x0 = grid.xs[editing.col]!\n const y0 = grid.ys[editing.row]!\n ctx.strokeStyle = inks.accent\n ctx.lineWidth = CELL_FRAME\n ctx.strokeRect(x0 + CELL_FRAME, y0 + CELL_FRAME, grid.xs[editing.col + 1]! - x0 - CELL_FRAME - 1, grid.ys[editing.row + 1]! - y0 - CELL_FRAME - 1)\n }\n ctx.restore()\n }\n\n /** A format-2 table: a card rounded at 4 in its fill, its grid in its stroke, one line of words in\n * each cell. */\n private paintSaved(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const f = this.frame(viewport)\n if (!f) return\n const rows = this.props.cells.length\n const cols = this.props.cells[0]?.length ?? 0\n const { xs, ys } = this.offsets()\n ctx.save()\n ctx.setLineDash([])\n const base = fillPaint(this.style)\n if (base) {\n ctx.fillStyle = base\n ctx.beginPath()\n ctx.roundRect(f.x, f.y, f.width, f.height, 4)\n ctx.fill()\n }\n if (this.props.headerRow) {\n ctx.fillStyle = withAlpha(this.style.lineColor, 0.16)\n ctx.beginPath()\n ctx.roundRect(f.x, f.y, f.width, ys[1]!, 4)\n ctx.fill()\n }\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.roundRect(f.x, f.y, f.width, f.height, 4)\n ctx.stroke()\n ctx.beginPath()\n for (let r = 1; r < rows; r++) {\n ctx.moveTo(f.x, f.y + ys[r]!)\n ctx.lineTo(f.x + f.width, f.y + ys[r]!)\n }\n for (let c = 1; c < cols; c++) {\n ctx.moveTo(f.x + xs[c]!, f.y)\n ctx.lineTo(f.x + xs[c]!, f.y + f.height)\n }\n ctx.stroke()\n ctx.font = fontOf(this.style)\n ctx.textBaseline = 'middle'\n const align = this.props.textHAlign ?? 'left'\n ctx.textAlign = align\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const text = this.props.cells[r]![c]\n if (!text) continue\n ctx.save()\n ctx.beginPath()\n ctx.rect(f.x + xs[c]! + 1, f.y + ys[r]! + 1, xs[c + 1]! - xs[c]! - 2, ys[r + 1]! - ys[r]! - 2)\n ctx.clip()\n ctx.fillStyle = this.style.textColor\n const x = align === 'left' ? f.x + xs[c]! + SAVED_PAD : align === 'right' ? f.x + xs[c + 1]! - SAVED_PAD : f.x + (xs[c]! + xs[c + 1]!) / 2\n ctx.fillText(text, x, f.y + (ys[r]! + ys[r + 1]!) / 2)\n ctx.restore()\n }\n }\n ctx.restore()\n }\n\n // ── Handles, lines and the pointer ──────────────────────────────────────────────────────────\n\n /** No anchor handle: the corners' handles stand for the table. */\n override getControlPoints(viewport: Viewport): ControlPoint[] {\n return this.props.savedLook ? super.getControlPoints(viewport) : []\n }\n\n /** The four corners, each a round handle that scales the table. */\n override resizeHandles(viewport: Viewport): Point[] {\n const f = this.frame(viewport)\n if (!f) return []\n return [\n { x: f.x, y: f.y },\n { x: f.x + f.width, y: f.y },\n { x: f.x + f.width, y: f.y + f.height },\n { x: f.x, y: f.y + f.height },\n ]\n }\n\n override gripShape(): HandleShape | null {\n return this.props.savedLook ? null : 'circle'\n }\n\n /** Handle indices: 0-3 corners, then column dividers, row dividers, and the four outer edges\n * (left, right, top, bottom). */\n private edgeBase(): number {\n const rows = this.props.cells.length\n const cols = this.props.cells[0]?.length ?? 0\n return 4 + Math.max(0, cols - 1) + Math.max(0, rows - 1)\n }\n\n /**\n * The grid line under a point that resizes its column or row, grabbable anywhere along it (±4px):\n * an inner line, or the right or bottom edge. Returns the `resizeTo`-compatible handle index;\n * corners win first (the host checks grips before calling this).\n */\n dividerHandleIndex(point: Point, viewport: Viewport): number | null {\n const f = this.frame(viewport)\n if (!f) return null\n const { xs, ys } = this.offsets()\n const inY = point.y >= f.y - 4 && point.y <= f.y + f.height + 4\n const inX = point.x >= f.x - 4 && point.x <= f.x + f.width + 4\n if (inY) {\n for (let c = 1; c < xs.length - 1; c++) {\n if (Math.abs(point.x - (f.x + xs[c]!)) <= 4) return 4 + (c - 1)\n }\n }\n if (inX) {\n for (let r = 1; r < ys.length - 1; r++) {\n if (Math.abs(point.y - (f.y + ys[r]!)) <= 4) return 4 + (xs.length - 2) + (r - 1)\n }\n }\n const edge = this.edgeBase()\n if (inY && Math.abs(point.x - (f.x + f.width)) <= 4) return edge + 1\n if (inX && Math.abs(point.y - (f.y + f.height)) <= 4) return edge + 3\n return null\n }\n\n /** The grid line under the pointer that a drag would resize: the pixel it stands on, and whether\n * it runs down a column's side or across a row's. */\n private hoveredLine(viewport: Viewport): { across: 'column' | 'row'; at: number } | null {\n const p = this.pointer\n const grid = this.gridPixels(viewport)\n if (!p || !grid) return null\n if (this.resizeHandles(viewport).some((g) => Math.hypot(g.x - p.x, g.y - p.y) <= 9)) return null\n const index = this.dividerHandleIndex(p, viewport)\n if (index === null) return null\n const cols = this.props.cells[0]?.length ?? 0\n const edge = this.edgeBase()\n if (index === edge + 1) return { across: 'column', at: grid.xs[grid.xs.length - 1]! }\n if (index === edge + 3) return { across: 'row', at: grid.ys[grid.ys.length - 1]! }\n const divider = index - 4\n return divider < cols - 1 ? { across: 'column', at: grid.xs[divider + 1]! } : { across: 'row', at: grid.ys[divider - (cols - 1) + 1]! }\n }\n\n /** Over the selected table: resize cursors over the corners and the lines, and typing over a\n * cell. An unselected table takes the plain pointer. */\n protected override cursorAt(point: Point, viewport: Viewport): string | null {\n const f = this.frame(viewport)\n if (!f || this.state !== 'selected') return null\n const corners = this.resizeHandles(viewport)\n for (let i = 0; i < corners.length; i++) {\n if (Math.hypot(point.x - corners[i]!.x, point.y - corners[i]!.y) <= 9) return i % 2 === 0 ? 'nwse-resize' : 'nesw-resize'\n }\n const divider = this.dividerHandleIndex(point, viewport)\n if (divider !== null) {\n const cols = this.props.cells[0]?.length ?? 0\n const edge = this.edgeBase()\n if (divider >= edge) return divider - edge < 2 ? 'ew-resize' : 'ns-resize'\n return divider - 4 < cols - 1 ? 'ew-resize' : 'ns-resize'\n }\n return this.cellAt(point, viewport) ? 'text' : null\n }\n\n override resizeTo(handleIndex: number, point: Point, viewport: Viewport): void {\n const f = this.frame(viewport)\n if (!f) return\n const rows = this.props.cells.length\n const cols = this.props.cells[0]?.length ?? 0\n if (!rows || !cols) return\n\n if (handleIndex < 4) {\n // Corner drag: the opposite corner pins, every column scales with the width, and every row\n // with the height, no row shorter than its words.\n const pin = [\n { x: f.x + f.width, y: f.y + f.height },\n { x: f.x, y: f.y + f.height },\n { x: f.x, y: f.y },\n { x: f.x + f.width, y: f.y },\n ][handleIndex]!\n const newW = Math.max(cols * MIN_COL, Math.abs(point.x - pin.x))\n const newH = Math.max(rows * MIN_ROW, Math.abs(point.y - pin.y))\n const scaleX = newW / f.width\n const scaleY = newH / f.height\n const colWidths = Array.from({ length: cols }, (_, c) => Math.min(MAX_COL, Math.max(MIN_COL, this.colWidth(c) * scaleX)))\n const rowHeights = Array.from({ length: rows }, (_, r) => Math.min(MAX_ROW, Math.max(this.rowContent(r), this.rowHeight(r) * scaleY)))\n this.applyProps({ colWidths, rowHeights } as Partial<TableProps>)\n // Keep the pinned corner where it was: the anchor is the box's top-left.\n const { xs, ys } = this.offsets()\n const width = xs[xs.length - 1]!\n const height = ys[ys.length - 1]!\n const left = point.x < pin.x ? pin.x - width : pin.x\n const top = point.y < pin.y ? pin.y - height : pin.y\n const time = viewport.timeAt(left)\n const price = viewport.priceAt(top)\n if (time !== null && price !== null) this.updateAnchor(0, { time, price })\n return\n }\n\n const { xs, ys } = this.offsets()\n const edge = this.edgeBase()\n if (handleIndex >= edge) {\n const which = handleIndex - edge\n if (which === 1) {\n const colWidths = Array.from({ length: cols }, (_, c) => this.colWidth(c))\n colWidths[cols - 1] = Math.min(MAX_COL, Math.max(MIN_COL, point.x - (f.x + xs[cols - 1]!)))\n this.applyProps({ colWidths } as Partial<TableProps>)\n } else if (which === 3) {\n const rowHeights = Array.from({ length: rows }, (_, r) => this.props.rowHeights[r] ?? 0)\n rowHeights[rows - 1] = Math.min(MAX_ROW, Math.max(this.rowContent(rows - 1), point.y - (f.y + ys[rows - 1]!)))\n this.applyProps({ rowHeights } as Partial<TableProps>)\n }\n return\n }\n\n const divider = handleIndex - 4\n if (divider < cols - 1) {\n const colWidths = Array.from({ length: cols }, (_, c) => this.colWidth(c))\n colWidths[divider] = Math.min(MAX_COL, Math.max(MIN_COL, point.x - (f.x + xs[divider]!)))\n this.applyProps({ colWidths } as Partial<TableProps>)\n return\n }\n const rowIndex = divider - (cols - 1)\n if (rowIndex < rows - 1) {\n const rowHeights = Array.from({ length: rows }, (_, r) => this.props.rowHeights[r] ?? 0)\n rowHeights[rowIndex] = Math.min(MAX_ROW, Math.max(this.rowContent(rowIndex), point.y - (f.y + ys[rowIndex]!)))\n this.applyProps({ rowHeights } as Partial<TableProps>)\n }\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const f = this.frame(viewport)\n if (!f) return false\n return point.x >= f.x - 2 && point.x <= f.x + f.width + 2 && point.y >= f.y - 2 && point.y <= f.y + f.height + 2\n }\n}\n","import type { Anchor, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment } from '../core/geometry'\nimport { applyStroke, fontOf, paintLabel, withAlpha } from '../render/canvas'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** A pattern's pills: drawn at this radius, or growing with the letters' size where null. */\nexport type PillProps = {\n pillRadius: number | null\n}\n\n/** A shaded pattern's background switch: off, the shaded legs keep their fill's color and opacity\n * for when it is switched back on. */\nexport type PatternProps = PillProps & {\n fillBackground: boolean\n}\n\n/**\n * Shared body of the pattern/wave tools: a polyline through every anchor with a lettered (or\n * numbered) pill at each vertex, the letters in the drawing's label ink, size, weight and slant.\n * Subclasses supply the label sequence and any extra ink. A pattern is read by its letters, and its\n * pages offer no words of its own; a save that carries words draws them above the pattern.\n */\nexport abstract class LabeledPolyline<P extends PillProps = PillProps> extends Drawing<P> {\n protected abstract labels(): readonly string[]\n\n protected override defaultProps(): P {\n return { pillRadius: null } as P\n }\n\n /** A save's empty words are no words: a pattern carries words only where a save names some. */\n protected override upgradeProps(props: Partial<P>): Partial<P> {\n const saved = props as Partial<P> & { text?: unknown }\n if (!('text' in saved) || saved.text) return props\n const { text: _text, ...rest } = saved\n void _text\n return rest as Partial<P>\n }\n\n /** A format-2 pattern drew its pills at 9px whatever its letters' size. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, pillRadius: 9 }\n }\n\n protected points(viewport: Viewport): (Point | null)[] {\n return this.anchorPixels(viewport)\n }\n\n /** Whether the shaded legs paint: while the background is switched on and its fill shows. */\n protected shaded(): boolean {\n return (this.props as { fillBackground?: boolean }).fillBackground !== false && this.style.fillOpacity > 0\n }\n\n /** Whether the line through the vertices paints: a wave count can stand on its labels alone. */\n protected showsLine(): boolean {\n return true\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const points = this.points(viewport).filter((p): p is Point => !!p)\n if (points.length < 2) return\n if (this.showsLine()) {\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n for (let i = 1; i < points.length; i++) ctx.lineTo(points[i].x, points[i].y)\n ctx.stroke()\n }\n this.paintExtras(ctx, points, viewport)\n this.paintLabels(ctx, points)\n const text = (this.props as { text?: unknown }).text\n if (typeof text === 'string' && text) {\n // A point that repeats the one before it, as a completed six-point save's last does, adds no\n // weight to where the words stand.\n const distinct = points.filter((p, i) => i === 0 || p.x !== points[i - 1]!.x || p.y !== points[i - 1]!.y)\n paintLabel(ctx, text, this.textHintPlacement(distinct), this.style, { align: 'center' })\n }\n }\n\n /** The placement preview is the pattern itself: the zigzag grows labeled leg by leg. */\n override paintConstruction(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n this.paint(ctx, viewport)\n }\n\n protected paintExtras(_ctx: CanvasRenderingContext2D, _points: Point[], _viewport: Viewport): void {}\n\n /** Each vertex's letter in a pill that grows with the letters' size, standing off the line on the\n * side away from the leg that reaches it. */\n protected paintLabels(ctx: CanvasRenderingContext2D, points: Point[]): void {\n const labels = this.labels()\n const radius = this.props.pillRadius ?? Math.max(9, Math.round(this.style.fontSize * 0.75))\n ctx.save()\n ctx.setLineDash([])\n ctx.font = fontOf(this.style)\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n for (let i = 0; i < points.length && i < labels.length; i++) {\n if (!labels[i]) continue // an unlabeled vertex (a pattern's starting point)\n const p = points[i]\n // Place the pill away from the line: above when the vertex is a local high, below otherwise.\n const prev = points[i - 1] ?? points[i + 1]\n const dy = prev && prev.y > p.y ? -(radius + 5) : radius + 5\n const cy = p.y + dy\n ctx.fillStyle = withAlpha('#1b1f27', 0.95)\n ctx.beginPath()\n ctx.arc(p.x, cy, radius, 0, Math.PI * 2)\n ctx.fill()\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.stroke()\n // The letters take the text channel, so their color and type are set apart from the line.\n ctx.fillStyle = this.style.textColor\n ctx.fillText(labels[i], p.x, cy + 0.5)\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const points = this.points(viewport).filter((p): p is Point => !!p)\n const tolerance = hitTolerance(this.style.lineWidth)\n for (let i = 0; i < points.length - 1; i++) {\n if (distanceToSegment(point, points[i], points[i + 1]) <= tolerance) return true\n }\n return false\n }\n}\n\n/** Fill the triangle spanned by three points with the drawing's background channel. */\nfunction fillTriangle(\n ctx: CanvasRenderingContext2D,\n style: { fillColor: string; fillOpacity: number },\n a: Point,\n b: Point,\n c: Point,\n): void {\n ctx.save()\n ctx.fillStyle = withAlpha(style.fillColor, style.fillOpacity)\n ctx.beginPath()\n ctx.moveTo(a.x, a.y)\n ctx.lineTo(b.x, b.y)\n ctx.lineTo(c.x, c.y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n}\n\n/** Five-point harmonic (X A B C D) with the two classic triangles shaded. */\nexport class XabcdPattern extends LabeledPolyline<PatternProps> {\n readonly type: string = 'xabcd_pattern'\n\n protected override defaultProps(): PatternProps {\n return { pillRadius: null, fillBackground: true }\n }\n\n requiredAnchors(): number {\n return 5\n }\n\n protected labels(): readonly string[] {\n return ['X', 'A', 'B', 'C', 'D']\n }\n\n protected override paintExtras(ctx: CanvasRenderingContext2D, points: Point[]): void {\n if (!this.shaded()) return\n if (points.length >= 3) fillTriangle(ctx, this.style, points[0], points[1], points[2])\n if (points.length >= 5) fillTriangle(ctx, this.style, points[2], points[3], points[4])\n }\n}\n\n/** Cypher: same five-point construction, its own identity for defaults/recognition. */\nexport class CypherPattern extends XabcdPattern {\n override readonly type = 'cypher_pattern'\n}\n\n/**\n * Three drives: a start point, three with-trend drives (1, 2, 3) separated by two retracements (A,\n * C), and the reversal that completes the pattern. Symmetry of the drives and retracements is the\n * pattern's whole premise; the tool labels the swing points.\n */\nexport class ThreeDrivesPattern extends LabeledPolyline {\n readonly type = 'three_drives'\n\n requiredAnchors(): number {\n return 7\n }\n\n /** A three drives saved on six points, without the reversal, completes with its reversal at its\n * third drive, so it draws as it was saved until the reversal is dragged out. */\n protected override upgradeAnchors(anchors: Anchor[]): Anchor[] {\n if (anchors.length !== 6) return anchors\n return [...anchors, { ...anchors[5]! }]\n }\n\n protected labels(): readonly string[] {\n return ['', '1', 'A', '2', 'C', '3', '']\n }\n}\n\n/** Four-point AB=CD pattern with its two guide diagonals. */\nexport class AbcdPattern extends LabeledPolyline {\n readonly type = 'abcd_pattern'\n\n requiredAnchors(): number {\n return 4\n }\n\n protected labels(): readonly string[] {\n return ['A', 'B', 'C', 'D']\n }\n\n protected override paintExtras(ctx: CanvasRenderingContext2D, points: Point[]): void {\n if (points.length >= 4) {\n // The AC / BD guide diagonals, dashed.\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.setLineDash([4, 4])\n ctx.globalAlpha = 0.55\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n ctx.lineTo(points[2].x, points[2].y)\n ctx.moveTo(points[1].x, points[1].y)\n ctx.lineTo(points[3].x, points[3].y)\n ctx.stroke()\n ctx.restore()\n }\n }\n}\n\n/** Four-point triangle pattern: the zigzag plus its two converging boundary lines. */\nexport class TrianglePattern extends LabeledPolyline<PatternProps> {\n readonly type = 'triangle_pattern'\n\n protected override defaultProps(): PatternProps {\n return { pillRadius: null, fillBackground: true }\n }\n\n requiredAnchors(): number {\n return 4\n }\n\n protected labels(): readonly string[] {\n return ['A', 'B', 'C', 'D']\n }\n\n protected override paintExtras(ctx: CanvasRenderingContext2D, points: Point[]): void {\n if (points.length < 4) return\n // Boundaries connect the alternating swing points (A→C and B→D), extended to D's time.\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.globalAlpha = 0.7\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[0].y)\n ctx.lineTo(points[2].x, points[2].y)\n ctx.moveTo(points[1].x, points[1].y)\n ctx.lineTo(points[3].x, points[3].y)\n ctx.stroke()\n ctx.restore()\n if (this.shaded()) fillTriangle(ctx, this.style, points[0], points[1], points[2])\n }\n}\n\n/** Seven-point head & shoulders with the neckline and shaded shoulders/head. */\nexport class HeadAndShoulders extends LabeledPolyline<PatternProps> {\n readonly type = 'head_and_shoulders'\n\n protected override defaultProps(): PatternProps {\n return { pillRadius: null, fillBackground: true }\n }\n\n requiredAnchors(): number {\n return 7\n }\n\n protected labels(): readonly string[] {\n // Left shoulder, head, right shoulder over the classic seven pivots.\n return ['', 'LS', '', 'H', '', 'RS', '']\n }\n\n protected override paintExtras(ctx: CanvasRenderingContext2D, points: Point[]): void {\n if (points.length < 7) return\n // Neckline through the two troughs framing the head, extended across the pattern.\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.setLineDash([4, 4])\n ctx.beginPath()\n ctx.moveTo(points[0].x, points[2].y + (points[0].x - points[2].x) * ((points[4].y - points[2].y) / ((points[4].x - points[2].x) || 1)))\n ctx.lineTo(points[6].x, points[2].y + (points[6].x - points[2].x) * ((points[4].y - points[2].y) / ((points[4].x - points[2].x) || 1)))\n ctx.stroke()\n ctx.restore()\n if (!this.shaded()) return\n fillTriangle(ctx, this.style, points[0], points[1], points[2])\n fillTriangle(ctx, this.style, points[2], points[3], points[4])\n fillTriangle(ctx, this.style, points[4], points[5], points[6])\n }\n}\n","import type { Point } from '../core/types'\nimport { fontOf } from '../render/canvas'\nimport { LabeledPolyline, type PillProps } from './patterns'\n\n// The Elliott wave set: labeled zigzags whose vocabulary (numbers vs letters) IS the tool. The\n// degree of a count sets how its labels are written, and the color is the wave's and the labels'.\n\n/** The fifteen degrees of an Elliott wave count, largest first. */\nexport const ELLIOTT_DEGREES = [\n 'supermillennium',\n 'millennium',\n 'submillennium',\n 'grandSupercycle',\n 'supercycle',\n 'cycle',\n 'primary',\n 'intermediate',\n 'minor',\n 'minute',\n 'minuette',\n 'subminuette',\n 'micro',\n 'submicro',\n 'minuscule',\n] as const\n\nexport type ElliottDegree = (typeof ELLIOTT_DEGREES)[number]\n\n/** A wave count's settings: whether the wave line runs through its pivots, and its degree. */\nexport type ElliottProps = PillProps & {\n /** The wave line through the pivots; off, the count stands on its labels alone. */\n showWave: boolean\n /** The degree of the count, which sets how each label is written. */\n degree: ElliottDegree\n /** Each pivot's number or letter as written, in a pill as a pattern's letters stand, in place of\n * the degree's writing. */\n labelPills: boolean\n}\n\nconst UPPER_ROMAN: Record<string, string> = { '1': 'I', '2': 'II', '3': 'III', '4': 'IV', '5': 'V' }\nconst LOWER_ROMAN: Record<string, string> = { '1': 'i', '2': 'ii', '3': 'iii', '4': 'iv', '5': 'v' }\n\n/**\n * How a degree writes a label. The degrees stand in five threes, largest first: each three ringed,\n * in parentheses, then bare, the way the classic notation writes primary, intermediate and minor.\n * The threes write a wave's number and a corrective letter as: upper roman numerals and capitals\n * (supermillennium to submillennium), upper roman numerals and small letters (grand supercycle to\n * cycle), figures and capitals (primary to minor), lower roman numerals and small letters (minute to\n * subminuette), and figures and small letters (micro to minuscule).\n */\nexport function elliottLabel(base: string, degree: ElliottDegree): { text: string; ringed: boolean } {\n const index = Math.max(0, ELLIOTT_DEGREES.indexOf(degree))\n const three = Math.floor(index / 3)\n const place = index % 3\n let text = base\n if (/^[1-5]$/.test(base)) text = three <= 1 ? UPPER_ROMAN[base]! : three === 3 ? LOWER_ROMAN[base]! : base\n else if (/^[A-Z]$/.test(base)) text = three === 0 || three === 2 ? base : base.toLowerCase()\n return { text: place === 1 ? `(${text})` : text, ringed: place === 0 }\n}\n\n/** The shared body of the wave counts: the wave line where it is on, and each pivot's label in the\n * wave's color, written as the count's degree writes it, standing off the line on the side away\n * from the leg that reaches it. */\nabstract class ElliottWave extends LabeledPolyline<ElliottProps> {\n protected override defaultProps(): ElliottProps {\n return { pillRadius: null, showWave: true, degree: 'intermediate', labelPills: false }\n }\n\n /** A format-2 count drew its line and each pivot's number or letter in a pill. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n super.keepSavedLook(saved)\n this._props = { ...this._props, showWave: true, labelPills: true }\n }\n\n protected override showsLine(): boolean {\n return this.props.showWave !== false\n }\n\n protected override paintLabels(ctx: CanvasRenderingContext2D, points: Point[]): void {\n if (this.props.labelPills) {\n super.paintLabels(ctx, points)\n return\n }\n const labels = this.labels()\n ctx.save()\n ctx.setLineDash([])\n ctx.font = fontOf(this.style)\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillStyle = this.style.lineColor\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n const lift = this.style.fontSize\n for (let i = 0; i < points.length && i < labels.length; i++) {\n if (!labels[i]) continue\n const p = points[i]!\n const prev = points[i - 1] ?? points[i + 1]\n const y = p.y + (prev && prev.y > p.y ? -lift : lift)\n const { text, ringed } = elliottLabel(labels[i]!, this.props.degree)\n ctx.fillText(text, p.x, y)\n if (ringed) {\n ctx.beginPath()\n ctx.arc(p.x, y, Math.max(ctx.measureText(text).width / 2, this.style.fontSize / 2) + 3, 0, Math.PI * 2)\n ctx.stroke()\n }\n }\n ctx.restore()\n }\n}\n\n/** Impulse 12345: six pivots, the origin and waves 1 to 5. */\nexport class ElliottImpulse extends ElliottWave {\n readonly type: string = 'elliott_impulse_wave'\n\n requiredAnchors(): number {\n return 6\n }\n\n protected labels(): readonly string[] {\n return ['0', '1', '2', '3', '4', '5']\n }\n}\n\n/** Correction ABC: the origin and three corrective waves. */\nexport class ElliottCorrection extends ElliottWave {\n readonly type = 'elliott_correction'\n\n requiredAnchors(): number {\n return 4\n }\n\n protected labels(): readonly string[] {\n return ['0', 'A', 'B', 'C']\n }\n}\n\n/** Triangle ABCDE: the origin and five contracting waves. */\nexport class ElliottTriangle extends ElliottWave {\n readonly type = 'elliott_triangle_wave'\n\n requiredAnchors(): number {\n return 6\n }\n\n protected labels(): readonly string[] {\n return ['0', 'A', 'B', 'C', 'D', 'E']\n }\n}\n\n/** Double combo WXY. */\nexport class ElliottDoubleCombo extends ElliottWave {\n readonly type = 'elliott_double_combo'\n\n requiredAnchors(): number {\n return 4\n }\n\n protected labels(): readonly string[] {\n return ['0', 'W', 'X', 'Y']\n }\n}\n\n/** Triple combo WXYXZ. */\nexport class ElliottTripleCombo extends ElliottWave {\n readonly type = 'elliott_triple_combo'\n\n requiredAnchors(): number {\n return 6\n }\n\n protected labels(): readonly string[] {\n return ['0', 'W', 'X', 'Y', 'X', 'Z']\n }\n}\n","import type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { distanceToSegment } from '../core/geometry'\nimport { applyStroke, fillPaint, strokeSegment } from '../render/canvas'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** Vertical lines repeating rightward at the span between the two anchors. */\nexport class CyclicLines extends Drawing {\n readonly type = 'cyclic_lines'\n\n requiredAnchors(): number {\n return 2\n }\n\n protected xs(viewport: Viewport): number[] {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return []\n const step = b.x - a.x\n if (Math.abs(step) < 2) return []\n const out: number[] = []\n for (let x = a.x; x >= -step && x <= viewport.width + Math.abs(step); x += Math.abs(step)) {\n out.push(x)\n if (out.length > 200) break\n }\n return out.filter((x) => x >= 0 && x <= viewport.width)\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n applyStroke(ctx, this.style)\n for (const x of this.xs(viewport)) strokeSegment(ctx, { x, y: 0 }, { x, y: viewport.height })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const tolerance = hitTolerance(this.style.lineWidth)\n return this.xs(viewport).some((x) => Math.abs(point.x - x) <= tolerance)\n }\n}\n\n/** A time cycle's background switch: off, its humps keep their fill's color and opacity for when it\n * is switched back on. */\nexport type TimeCyclesProps = {\n fillBackground: boolean\n}\n\n/** Repeating semicircle arcs along the anchors' baseline, one hump per cycle. */\nexport class TimeCycles extends Drawing<TimeCyclesProps> {\n readonly type = 'time_cycles'\n\n protected override defaultProps(): TimeCyclesProps {\n return { fillBackground: true }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected geometry(viewport: Viewport): { y: number; startX: number; step: number } | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n const step = Math.abs(b.x - a.x)\n if (step < 4) return null\n return { y: a.y, startX: Math.min(a.x, b.x), step }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const geo = this.geometry(viewport)\n if (!geo) return\n const fill = this.props.fillBackground !== false ? fillPaint(this.style) : null\n if (fill) {\n ctx.save()\n ctx.fillStyle = fill\n ctx.setLineDash([])\n let filled = 0\n for (let x = geo.startX; x <= viewport.width && filled < 200; x += geo.step, filled++) {\n ctx.beginPath()\n ctx.arc(x + geo.step / 2, geo.y, geo.step / 2, 0, Math.PI, true)\n ctx.closePath()\n ctx.fill()\n }\n ctx.restore()\n }\n applyStroke(ctx, this.style)\n ctx.beginPath()\n let count = 0\n for (let x = geo.startX; x <= viewport.width && count < 200; x += geo.step, count++) {\n ctx.moveTo(x + geo.step, geo.y)\n ctx.arc(x + geo.step / 2, geo.y, geo.step / 2, 0, Math.PI, true)\n }\n ctx.stroke()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const geo = this.geometry(viewport)\n if (!geo) return false\n if (point.x < geo.startX) return false\n const radius = geo.step / 2\n const within = (point.x - geo.startX) % geo.step\n const cx = point.x - within + radius\n const distance = Math.hypot(point.x - cx, point.y - geo.y)\n return point.y <= geo.y + 2 && Math.abs(distance - radius) <= hitTolerance(this.style.lineWidth)\n }\n}\n\n/** Sine wave: the anchors set half a period and the amplitude. */\nexport class SineLine extends Drawing {\n readonly type = 'sine_line'\n\n requiredAnchors(): number {\n return 2\n }\n\n protected samples(viewport: Viewport): Point[] | null {\n const [a, b] = this.anchorPixels(viewport)\n if (!a || !b) return null\n const half = b.x - a.x\n if (Math.abs(half) < 2) return null\n const amplitude = b.y - a.y\n const period = Math.abs(half) * 2\n const out: Point[] = []\n for (let x = 0; x <= viewport.width; x += Math.max(2, period / 48)) {\n const phase = ((x - a.x) / half) * Math.PI * 0.5\n out.push({ x, y: a.y + Math.sin(phase) * amplitude })\n }\n return out\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const samples = this.samples(viewport)\n if (!samples || samples.length < 2) return\n applyStroke(ctx, this.style)\n ctx.beginPath()\n ctx.moveTo(samples[0].x, samples[0].y)\n for (let i = 1; i < samples.length; i++) ctx.lineTo(samples[i].x, samples[i].y)\n ctx.stroke()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const samples = this.samples(viewport)\n if (!samples) return false\n const tolerance = hitTolerance(this.style.lineWidth)\n for (let i = 0; i < samples.length - 1; i++) {\n if (distanceToSegment(point, samples[i], samples[i + 1]) <= tolerance) return true\n }\n return false\n }\n}\n","import type { LineStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { barPrice, barsInRange, linearRegression, type BarPriceSource, type SourceBar } from '../core/bars'\nimport { distanceToSegment, extendSegment } from '../core/geometry'\nimport { alphaOf, applyStroke, paintLabel, strokeSegment, withAlpha } from '../render/canvas'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** A regression line's stroke: shown or not, its color, width and style. */\ntype RegressionLine = { show: boolean; color: string; width: number; style: LineStyle }\n\n/** A regression trend's inputs and its lines' strokes. */\nexport type RegressionProps = {\n /** How many standard deviations the upper band stands from the line; the lower band's count is\n * signed, so a band below the line is a negative count. */\n upperDeviation: number\n lowerDeviation: number\n useUpper: boolean\n useLower: boolean\n /** The price of each bar the line is fitted through. */\n source: BarPriceSource\n /** The line through the bars and the two bands, each shown or not in a stroke of its own. */\n baseLine: boolean\n baseColor: string\n baseWidth: number\n baseStyle: LineStyle\n upLine: boolean\n upColor: string\n upWidth: number\n upStyle: LineStyle\n downLine: boolean\n downColor: string\n downWidth: number\n downStyle: LineStyle\n /** Run the line and the bands on past both ends, to the pane's edges. */\n extendLines: boolean\n /** Read the correlation of the bars with the line under its end. */\n showPearsons: boolean\n /** One body between the two bands in this color, drawn while both stand; null draws a body\n * between the line and each band in that band's color. */\n bodyColor: string | null\n}\n\nconst REGRESSION_PROPS: RegressionProps = {\n upperDeviation: 2,\n lowerDeviation: -2,\n useUpper: true,\n useLower: true,\n source: 'close',\n baseLine: true,\n baseColor: 'rgba(242, 54, 69, 0.3)',\n baseWidth: 1,\n baseStyle: 'dashed',\n upLine: true,\n upColor: 'rgba(41, 98, 255, 0.3)',\n upWidth: 2,\n upStyle: 'solid',\n downLine: true,\n downColor: 'rgba(41, 98, 255, 0.3)',\n downWidth: 2,\n downStyle: 'solid',\n extendLines: false,\n showPearsons: true,\n bodyColor: null,\n}\n\n/** The body between the line and each band, in the band's color at this share of its opacity. */\nconst BAND_BODY = 0.3\n\n/**\n * Regression trend: least-squares line over the chosen price of the bars between the two anchors,\n * with bands a set number of standard deviations from it. Recomputes live as bars arrive.\n */\nexport class RegressionTrend extends Drawing<RegressionProps> {\n readonly type = 'regression_trend'\n\n protected override defaultProps(): RegressionProps {\n return { ...REGRESSION_PROPS }\n }\n\n /** A trend saved before its lines had strokes of their own counted its lower deviation down from\n * the line. */\n protected override upgradeProps(props: Partial<RegressionProps>): Partial<RegressionProps> {\n if ('baseLine' in props || typeof props.lowerDeviation !== 'number') return props\n return { ...props, lowerDeviation: -props.lowerDeviation }\n }\n\n /** A format-2 trend drew its line in its own stroke and its bands in it at seven tenths, one body\n * between both bands in its color at 8%, and no correlation. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n const { lineColor, lineWidth, lineStyle } = this._style\n const band = withAlpha(lineColor, alphaOf(lineColor) * 0.7)\n this._props = {\n ...this._props,\n baseLine: true,\n baseColor: lineColor,\n baseWidth: lineWidth,\n baseStyle: lineStyle,\n upLine: true,\n upColor: band,\n upWidth: lineWidth,\n upStyle: lineStyle,\n downLine: true,\n downColor: band,\n downWidth: lineWidth,\n downStyle: lineStyle,\n showPearsons: false,\n bodyColor: withAlpha(lineColor, 0.08),\n }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** The fit over the bars between the anchors, and its correlation with them. */\n protected fit(): { range: SourceBar[]; slope: number; intercept: number; sigma: number; pearson: number } | null {\n const [a, b] = this.anchors\n if (!a || !b) return null\n const range = barsInRange(this.bars(), a.time, b.time)\n const fit = linearRegression(range, this.props.source)\n if (!fit) return null\n return { range, ...fit, pearson: pearsonOf(range, this.props.source) }\n }\n\n protected lines(viewport: Viewport): { base: [Point, Point]; upper?: [Point, Point]; lower?: [Point, Point]; pearson: number } | null {\n const fit = this.fit()\n if (!fit) return null\n const first = fit.range[0]!\n const last = fit.range[fit.range.length - 1]!\n const lineAt = (offset: number): [Point, Point] | null => {\n const y1 = viewport.yOf(fit.intercept + offset)\n const y2 = viewport.yOf(fit.intercept + fit.slope * (fit.range.length - 1) + offset)\n const x1 = viewport.xOf(first.time)\n const x2 = viewport.xOf(last.time)\n if (y1 === null || y2 === null || x1 === null || x2 === null) return null\n const a = { x: x1, y: y1 }\n const b = { x: x2, y: y2 }\n if (!this.props.extendLines) return [a, b]\n const run = extendSegment(a, b, viewport.width, viewport.height, true, true)\n return [run.a, run.b]\n }\n const base = lineAt(0)\n if (!base) return null\n return {\n base,\n upper: this.props.useUpper ? (lineAt(fit.sigma * this.props.upperDeviation) ?? undefined) : undefined,\n lower: this.props.useLower ? (lineAt(fit.sigma * this.props.lowerDeviation) ?? undefined) : undefined,\n pearson: fit.pearson,\n }\n }\n\n /** The strokes of the line and its two bands, as the props set them. */\n protected strokes(): { base: RegressionLine; up: RegressionLine; down: RegressionLine } {\n const p = this.props\n return {\n base: { show: p.baseLine, color: p.baseColor, width: p.baseWidth, style: p.baseStyle },\n up: { show: p.upLine, color: p.upColor, width: p.upWidth, style: p.upStyle },\n down: { show: p.downLine, color: p.downColor, width: p.downWidth, style: p.downStyle },\n }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const lines = this.lines(viewport)\n if (!lines) {\n this.paintUnavailable(ctx, viewport)\n return\n }\n const strokes = this.strokes()\n const body = (band: [Point, Point] | undefined, color: string): void => {\n if (!band) return\n ctx.save()\n ctx.fillStyle = withAlpha(color, alphaOf(color) * BAND_BODY)\n ctx.beginPath()\n ctx.moveTo(lines.base[0].x, lines.base[0].y)\n ctx.lineTo(lines.base[1].x, lines.base[1].y)\n ctx.lineTo(band[1].x, band[1].y)\n ctx.lineTo(band[0].x, band[0].y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n if (this.props.bodyColor === null) {\n body(lines.upper, strokes.up.color)\n body(lines.lower, strokes.down.color)\n } else if (lines.upper && lines.lower) {\n ctx.save()\n ctx.fillStyle = this.props.bodyColor\n ctx.beginPath()\n ctx.moveTo(lines.upper[0].x, lines.upper[0].y)\n ctx.lineTo(lines.upper[1].x, lines.upper[1].y)\n ctx.lineTo(lines.lower[1].x, lines.lower[1].y)\n ctx.lineTo(lines.lower[0].x, lines.lower[0].y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n const draw = (line: [Point, Point] | undefined, stroke: RegressionLine): void => {\n if (!line || !stroke.show) return\n ctx.save()\n applyStroke(ctx, { ...this.style, lineColor: stroke.color, lineWidth: stroke.width, lineStyle: stroke.style })\n strokeSegment(ctx, line[0], line[1])\n ctx.restore()\n }\n draw(lines.upper, strokes.up)\n draw(lines.lower, strokes.down)\n draw(lines.base, strokes.base)\n if (this.props.showPearsons && Number.isFinite(lines.pearson)) {\n // The correlation reads under the lowest line's end, in the base line's hue.\n const end = (lines.lower ?? lines.base)[1]\n paintLabel(ctx, lines.pearson.toFixed(4), { x: end.x, y: end.y + 4 }, { ...this.style, textColor: withAlpha(strokes.base.color, 1) }, { align: 'center', baseline: 'top' })\n }\n }\n\n protected paintUnavailable(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.setLineDash([4, 4])\n ctx.globalAlpha = 0.5\n strokeSegment(ctx, pa, pb)\n ctx.restore()\n paintLabel(ctx, 'no bar data in range', { x: (pa.x + pb.x) / 2, y: (pa.y + pb.y) / 2 - 12 }, this.style, {\n align: 'center',\n background: withAlpha('#1b1f27', 0.92),\n })\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const lines = this.lines(viewport)\n if (!lines) {\n const [pa, pb] = this.anchorPixels(viewport)\n return !!pa && !!pb && distanceToSegment(point, pa, pb) <= hitTolerance(this.style.lineWidth)\n }\n const strokes = this.strokes()\n const parts: [[Point, Point] | undefined, RegressionLine][] = [\n [lines.base, strokes.base],\n [lines.upper, strokes.up],\n [lines.lower, strokes.down],\n ]\n return parts.some(([line, stroke]) => !!line && stroke.show && distanceToSegment(point, line[0], line[1]) <= hitTolerance(stroke.width))\n }\n}\n\n/** The correlation of the bars' chosen price with their order, from -1 to 1. */\nfunction pearsonOf(bars: readonly SourceBar[], source: BarPriceSource): number {\n const n = bars.length\n if (n < 2) return Number.NaN\n let sumX = 0\n let sumY = 0\n for (let i = 0; i < n; i++) {\n sumX += i\n sumY += barPrice(bars[i]!, source)\n }\n const meanX = sumX / n\n const meanY = sumY / n\n let covariance = 0\n let varX = 0\n let varY = 0\n for (let i = 0; i < n; i++) {\n const dx = i - meanX\n const dy = barPrice(bars[i]!, source) - meanY\n covariance += dx * dy\n varX += dx * dx\n varY += dy * dy\n }\n return varX > 0 && varY > 0 ? covariance / Math.sqrt(varX * varY) : Number.NaN\n}\n\n/** A captured bar (relative form) inside a bars-pattern/ghost-feed payload. */\nexport type CapturedBar = {\n o: number\n h: number\n l: number\n c: number\n}\n\nexport type BarsPatternProps = {\n /** OHLC snapshot captured at placement — the pattern stays as drawn while it moves. */\n bars: CapturedBar[]\n /** Reflect the pattern vertically (price axis). */\n mirrored: boolean\n /** Reflect the pattern horizontally (time axis). */\n flipped: boolean\n /** `hl` paints each bar's high-low range and `oc` its open-close range; a price paints the\n * pattern as a line through it. */\n mode: BarsPatternMode\n /** Each bar as a candle instead, its wick from high to low and its body from open to close. A\n * mode chosen ends it. */\n candles: boolean\n}\n\n/** The ways a bars pattern paints its bars, in the order its Mode list offers them. */\nexport const BARS_PATTERN_MODES = ['hl', 'oc', 'close', 'open', 'high', 'low', 'hl2'] as const\nexport type BarsPatternMode = (typeof BARS_PATTERN_MODES)[number]\n\nexport type GhostFeedProps = {\n /** Average candle high-low span in price units; 0 = auto-seed from recent bars at placement. */\n averageHL: number\n /** Wobble amplitude as a percentage of the average span (0..100). */\n variance: number\n upColor: string\n downColor: string\n borderUpColor: string\n borderDownColor: string\n wickColor: string\n drawBorder: boolean\n drawWick: boolean\n /** 0..100; candles paint at (100 − transparency)% opacity. */\n transparency: number\n}\n\n/**\n * Shared base for tools that snapshot the OHLC run between their anchors at placement and\n * repaint it wherever the drawing is dragged (prices shift with the first anchor).\n */\nexport abstract class CapturedBarsDrawing<P extends { bars: CapturedBar[] } & Record<string, unknown>> extends Drawing<P> {\n requiredAnchors(): number {\n return 2\n }\n\n /** Captured at placement by the host: the OHLC run between the anchors. */\n capture(): void {\n const [a, b] = this.anchors\n if (!a || !b) return\n const range = barsInRange(this.bars(), a.time, b.time)\n if (!range.length) return\n this.applyProps({\n bars: range.map((bar) => ({ o: bar.open, h: bar.high, l: bar.low, c: bar.close })),\n } as unknown as Partial<P>)\n }\n\n protected frame(viewport: Viewport): { x1: number; x2: number; baseY: number; scale: number } | null {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb || this.props.bars.length === 0) return null\n // Price-to-pixel scale from the viewport at the first anchor's price.\n const yAtBase = viewport.yOf(this.anchors[0].price)\n const yAtBasePlus = viewport.yOf(this.anchors[0].price + 1)\n if (yAtBase === null || yAtBasePlus === null) return null\n const scale = yAtBasePlus - yAtBase // px per +1 price (negative in screen space)\n return { x1: Math.min(pa.x, pb.x), x2: Math.max(pa.x, pb.x), baseY: pa.y, scale }\n }\n\n protected paintPlaceholder(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return\n ctx.save()\n applyStroke(ctx, this.style)\n ctx.setLineDash([4, 4])\n ctx.globalAlpha = 0.5\n ctx.strokeRect(Math.min(pa.x, pb.x), Math.min(pa.y, pb.y), Math.abs(pb.x - pa.x), Math.max(12, Math.abs(pb.y - pa.y)))\n ctx.restore()\n }\n}\n\n/** Bars pattern: the captured run repainted as sticks (or a source line), in the stroke color. */\nexport class BarsPattern extends CapturedBarsDrawing<BarsPatternProps> {\n readonly type: string = 'bars_pattern'\n\n protected override defaultProps(): BarsPatternProps {\n return { bars: [], mirrored: false, flipped: false, mode: 'hl', candles: false }\n }\n\n /** A pattern saved painting candle sticks reads its bars' ranges as its mode, and paints its\n * candles. */\n protected override upgradeProps(props: Partial<BarsPatternProps>): Partial<BarsPatternProps> {\n return (props.mode as string | undefined) === 'bars' ? { ...props, mode: 'hl', candles: true } : props\n }\n\n /** A format-2 pattern that named no mode painted candles. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n if (!('mode' in saved)) this._props = { ...this._props, candles: true }\n }\n\n override applyProps(patch: Partial<BarsPatternProps>): void {\n super.applyProps('mode' in patch && !('candles' in patch) ? { ...patch, candles: false } : patch)\n }\n\n private priceOf(bar: CapturedBar): number {\n const { mode } = this.props\n if (mode === 'open') return bar.o\n if (mode === 'high') return bar.h\n if (mode === 'low') return bar.l\n if (mode === 'hl2') return (bar.h + bar.l) / 2\n return bar.c\n }\n\n /** Bars in paint order (flip reverses time) with the y mapper (mirror negates price offsets). */\n private sequence(f: { baseY: number; scale: number }): { seq: CapturedBar[]; yAt: (v: number) => number } {\n const seq = this.props.flipped ? [...this.props.bars].reverse() : this.props.bars\n const base = seq[0].c\n const sign = this.props.mirrored ? -1 : 1\n return { seq, yAt: (v: number) => f.baseY + (v - base) * f.scale * sign }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const f = this.frame(viewport)\n if (!f) {\n this.paintPlaceholder(ctx, viewport)\n return\n }\n const { seq, yAt } = this.sequence(f)\n const width = (f.x2 - f.x1) / seq.length\n\n // The whole style surface is the one color, its opacity riding in it, with no width or dash.\n if (this.props.mode !== 'hl' && this.props.mode !== 'oc' && !this.props.candles) {\n ctx.save()\n ctx.setLineDash([])\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 2\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n ctx.beginPath()\n for (let i = 0; i < seq.length; i++) {\n const x = f.x1 + width * (i + 0.5)\n const y = yAt(this.priceOf(seq[i]))\n if (i === 0) ctx.moveTo(x, y)\n else ctx.lineTo(x, y)\n }\n ctx.stroke()\n ctx.restore()\n return\n }\n\n const bodyW = Math.max(1.5, Math.min(9, width * 0.6))\n if (this.props.candles) {\n ctx.save()\n ctx.setLineDash([])\n ctx.strokeStyle = this.style.lineColor\n ctx.fillStyle = this.style.lineColor\n ctx.lineWidth = 1\n for (let i = 0; i < seq.length; i++) {\n const bar = seq[i]!\n const cx = f.x1 + width * (i + 0.5)\n const yO = yAt(bar.o)\n const yC = yAt(bar.c)\n ctx.beginPath()\n ctx.moveTo(cx, yAt(bar.h))\n ctx.lineTo(cx, yAt(bar.l))\n ctx.stroke()\n ctx.fillRect(cx - bodyW / 2, Math.min(yO, yC), bodyW, Math.max(1, Math.abs(yC - yO)))\n }\n ctx.restore()\n return\n }\n\n // Each bar its range as a bar: high to low, or open to close.\n const oc = this.props.mode === 'oc'\n ctx.save()\n ctx.fillStyle = this.style.lineColor\n for (let i = 0; i < seq.length; i++) {\n const bar = seq[i]!\n const cx = f.x1 + width * (i + 0.5)\n const y1 = yAt(oc ? bar.o : bar.h)\n const y2 = yAt(oc ? bar.c : bar.l)\n ctx.fillRect(cx - bodyW / 2, Math.min(y1, y2), bodyW, Math.max(1, Math.abs(y2 - y1)))\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const f = this.frame(viewport)\n if (!f) {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return false\n return point.x >= Math.min(pa.x, pb.x) && point.x <= Math.max(pa.x, pb.x) && Math.abs(point.y - pa.y) <= 24\n }\n const { seq, yAt } = this.sequence(f)\n let minY = Infinity\n let maxY = -Infinity\n for (const bar of seq) {\n minY = Math.min(minY, yAt(bar.h), yAt(bar.l))\n maxY = Math.max(maxY, yAt(bar.h), yAt(bar.l))\n }\n return point.x >= f.x1 - 4 && point.x <= f.x2 + 4 && point.y >= minY - 4 && point.y <= maxY + 4\n }\n}\n\n/**\n * Ghost feed: projected candles sketched from the first anchor toward the second — any\n * direction, including empty future space. One candle per bar slot; sizes come from the\n * average-span and variance inputs (auto-seeded from the trailing bars at placement); the\n * wobble is deterministic, so the same drawing always sketches the same candles.\n */\nexport class GhostFeed extends Drawing<GhostFeedProps> {\n readonly type = 'ghost_feed'\n\n protected override defaultProps(): GhostFeedProps {\n return {\n averageHL: 0,\n variance: 50,\n upColor: '#ACE5DC',\n downColor: '#FAA1A4',\n borderUpColor: '#089981',\n borderDownColor: '#F23645',\n wickColor: '#808080',\n drawBorder: true,\n drawWick: true,\n transparency: 50,\n }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n /** Placement hook: seed the average candle span from the trailing bars (only while auto). */\n capture(): void {\n if (this.props.averageHL > 0) return\n const recent = this.bars().slice(-20)\n if (!recent.length) return\n const avg = recent.reduce((sum, bar) => sum + Math.abs(bar.high - bar.low), 0) / recent.length\n if (avg > 0) this.applyProps({ averageHL: avg } as Partial<GhostFeedProps>)\n }\n\n /** Candle span in price units — the auto fallback keys off the anchor price. */\n private span(): number {\n if (this.props.averageHL > 0) return this.props.averageHL\n const price = Math.abs(this.anchors[0]?.price ?? 0)\n return price > 0 ? price * 0.005 : 1\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const [a, b] = this.anchors\n const [pa, pb] = this.anchorPixels(viewport)\n if (!a || !b || !pa || !pb) return\n const rawCount = viewport.barsBetween(a.time, b.time)\n const count = Math.max(1, Math.min(500, Math.round(Math.abs(rawCount ?? (pb.x - pa.x) / 8))))\n const width = (pb.x - pa.x) / count\n if (!Number.isFinite(width) || Math.abs(width) < 0.5) return\n const avg = this.span()\n const wobbleAmp = avg * (Math.max(0, this.props.variance) / 100)\n const alpha = Math.max(0, Math.min(1, 1 - this.props.transparency / 100))\n const drift = (b.price - a.price) / count\n const bodyW = Math.max(1.5, Math.min(9, Math.abs(width) * 0.6))\n let price = a.price\n ctx.save()\n ctx.setLineDash([])\n ctx.lineWidth = 1\n for (let i = 0; i < count; i++) {\n // Deterministic wobble seeded by the index (stable across repaints).\n const w1 = Math.sin(i * 2.399963)\n const w2 = Math.sin(i * 2.399963 + 1.7)\n const open = price\n const close = open + drift + w1 * wobbleAmp * 0.6\n const high = Math.max(open, close) + Math.abs(w2) * avg * 0.35\n const low = Math.min(open, close) - Math.abs(w1) * avg * 0.35\n const cx = pa.x + width * (i + 0.5)\n const ys = { o: viewport.yOf(open), h: viewport.yOf(high), l: viewport.yOf(low), c: viewport.yOf(close) }\n if (ys.o !== null && ys.h !== null && ys.l !== null && ys.c !== null) {\n const up = close >= open\n // The tool-wide opacity multiplies any alpha a color value carries of its own.\n const paint = (c: string) => withAlpha(c, alpha * alphaOf(c))\n if (this.props.drawWick) {\n ctx.strokeStyle = paint(this.props.wickColor)\n ctx.beginPath()\n ctx.moveTo(cx, ys.h)\n ctx.lineTo(cx, ys.l)\n ctx.stroke()\n }\n const top = Math.min(ys.o, ys.c)\n const bodyH = Math.max(1, Math.abs(ys.c - ys.o))\n ctx.fillStyle = paint(up ? this.props.upColor : this.props.downColor)\n ctx.fillRect(cx - bodyW / 2, top, bodyW, bodyH)\n if (this.props.drawBorder) {\n ctx.strokeStyle = paint(up ? this.props.borderUpColor : this.props.borderDownColor)\n ctx.strokeRect(cx - bodyW / 2, top, bodyW, bodyH)\n }\n }\n price = close\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return false\n const minX = Math.min(pa.x, pb.x)\n const maxX = Math.max(pa.x, pb.x)\n const minY = Math.min(pa.y, pb.y) - 20\n const maxY = Math.max(pa.y, pb.y) + 20\n return point.x >= minX && point.x <= maxX && point.y >= minY && point.y <= maxY\n }\n}\n","import type { Time } from 'lightweight-charts'\n\nimport type { ISeriesPrimitiveAxisView } from 'lightweight-charts'\nimport type { DrawingStyle, LineStyle, Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { barPrice, barsInRange, volumeProfile, volumeText } from '../core/bars'\nimport type { BarPriceSource, SourceBar, VolumeBin } from '../core/bars'\nimport { distanceToSegment } from '../core/geometry'\nimport { alphaOf, applyStroke, dashPattern, fillPaint, paintLabel, withAlpha } from '../render/canvas'\nimport { AxisLabel } from '../render/axis-view'\n\nfunction hitTolerance(lineWidth: number): number {\n return Math.max(6, lineWidth / 2 + 4)\n}\n\n/** Bars from the anchor's time to the newest bar. */\nfunction barsFrom(all: readonly SourceBar[], from: Time): SourceBar[] {\n const start = Number(from)\n if (!Number.isFinite(start)) return []\n return all.filter((bar) => Number(bar.time) >= start)\n}\n\n/** A VWAP band line's stroke: shown or not, its color, width and style. */\nexport type VwapLine = { visible: boolean; color: string; width: number; style: LineStyle }\n\n/** An anchored VWAP's inputs and its bands' strokes. */\nexport type AnchoredVwapProps = {\n /** The price of each bar the average weighs by its volume. */\n source: BarPriceSource\n /** How far a band stands off the average: in volume-weighted standard deviations, or in percents\n * of the average. */\n bandsMode: 'stdev' | 'percent'\n /** The three bands' multipliers, and which of the bands are calculated. */\n bandMultipliers: number[]\n bandsOn: boolean[]\n /** Each band's upper and lower line, the first band first. */\n upperBands: VwapLine[]\n lowerBands: VwapLine[]\n /** The first band's body, in the drawing's fill. */\n fillBackground: boolean\n /** The average's latest value read on the price scale. */\n showPriceLabel: boolean\n}\n\nconst vwapLine = (color: string): VwapLine => ({ visible: true, color, width: 1, style: 'solid' })\nconst BAND_COLORS = ['#4caf50', '#808000', '#00897b']\n\n/** The average and its bands at one bar. */\ntype VwapSample = { time: SourceBar['time']; vwap: number; upper: (number | null)[]; lower: (number | null)[] }\n\n/**\n * Anchored VWAP: the volume-weighted average of the chosen price of every bar since the anchor,\n * drawn as a line that extends live as bars arrive, with up to three bands standing off it by\n * standard deviations or percents.\n */\nexport class AnchoredVwap extends Drawing<AnchoredVwapProps> {\n readonly type = 'anchored_vwap'\n\n protected override defaultProps(): AnchoredVwapProps {\n return {\n source: 'hlc3',\n bandsMode: 'stdev',\n bandMultipliers: [1, 2, 3],\n bandsOn: [true, false, false],\n upperBands: BAND_COLORS.map(vwapLine),\n lowerBands: BAND_COLORS.map(vwapLine),\n fillBackground: true,\n showPriceLabel: false,\n }\n }\n\n /** A format-2 VWAP drew its average alone, with no bands. */\n protected override keepSavedLook(_saved: Readonly<Record<string, unknown>>): void {\n this._props = { ...this._props, bandsOn: this._props.bandsOn.map(() => false) }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n /** The average and its calculated bands, bar by bar from the anchor. */\n protected series(): VwapSample[] {\n const anchor = this.anchors[0]\n if (!anchor) return []\n const run = barsFrom(this.bars(), anchor.time)\n const p = this.props\n let sumPV = 0\n let sumPPV = 0\n let sumV = 0\n const out: VwapSample[] = []\n for (const bar of run) {\n const volume = bar.volume ?? 0\n const price = barPrice(bar, p.source)\n sumPV += price * volume\n sumPPV += price * price * volume\n sumV += volume\n if (sumV <= 0) continue\n const vwap = sumPV / sumV\n const deviation = Math.sqrt(Math.max(0, sumPPV / sumV - vwap * vwap))\n const offsets = p.bandMultipliers.map((k, i) => (p.bandsOn[i] ? (p.bandsMode === 'percent' ? (vwap * k) / 100 : deviation * k) : null))\n out.push({ time: bar.time, vwap, upper: offsets.map((o) => (o === null ? null : vwap + o)), lower: offsets.map((o) => (o === null ? null : vwap - o)) })\n }\n return out\n }\n\n /** A run of values along the samples, on the pane. */\n private points(samples: readonly VwapSample[], value: (s: VwapSample) => number | null, viewport: Viewport): Point[] {\n const out: Point[] = []\n for (const s of samples) {\n const v = value(s)\n if (v === null) continue\n const x = viewport.xOf(s.time)\n const y = viewport.yOf(v)\n if (x !== null && y !== null) out.push({ x, y })\n }\n return out\n }\n\n private readonly _axisViews = [\n new AxisLabel({\n coordinate: () => {\n const viewport = this.getViewport()\n const last = this.series().at(-1)\n return viewport && last ? viewport.yOf(last.vwap) : null\n },\n text: () => {\n const last = this.series().at(-1)\n return last ? this.formatPrice(last.vwap) : ''\n },\n color: () => withAlpha(this.style.lineColor, 1),\n visible: () => this.props.showPriceLabel && this.isVisibleNow(),\n }),\n ]\n\n protected override axisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._axisViews\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const samples = this.series()\n const anchor = this.anchors[0]\n const p = anchor ? this.anchorToPixel(anchor, viewport) : null\n if (p) {\n ctx.save()\n ctx.setLineDash([])\n ctx.fillStyle = this.style.lineColor\n ctx.beginPath()\n ctx.arc(p.x, p.y, 3.5, 0, Math.PI * 2)\n ctx.fill()\n ctx.restore()\n }\n const line = this.points(samples, (s) => s.vwap, viewport)\n if (line.length < 2) {\n if (p) {\n paintLabel(ctx, 'VWAP needs volume data', { x: p.x + 8, y: p.y - 12 }, this.style, {\n background: withAlpha('#1b1f27', 0.92),\n })\n }\n return\n }\n const props = this.props\n // The first band's body, between its upper and lower lines.\n const fill = props.fillBackground && props.bandsOn[0] ? fillPaint(this.style) : null\n if (fill) {\n const upper = this.points(samples, (s) => s.upper[0] ?? null, viewport)\n const lower = this.points(samples, (s) => s.lower[0] ?? null, viewport)\n if (upper.length > 1 && lower.length > 1) {\n ctx.save()\n ctx.fillStyle = fill\n ctx.beginPath()\n ctx.moveTo(upper[0]!.x, upper[0]!.y)\n for (const point of upper.slice(1)) ctx.lineTo(point.x, point.y)\n for (const point of [...lower].reverse()) ctx.lineTo(point.x, point.y)\n ctx.closePath()\n ctx.fill()\n ctx.restore()\n }\n }\n const stroke = (points: Point[], style: Readonly<DrawingStyle>): void => {\n if (points.length < 2) return\n ctx.save()\n applyStroke(ctx, style)\n ctx.beginPath()\n ctx.moveTo(points[0]!.x, points[0]!.y)\n for (const point of points.slice(1)) ctx.lineTo(point.x, point.y)\n ctx.stroke()\n ctx.restore()\n }\n for (let i = 0; i < props.bandMultipliers.length; i++) {\n for (const [bands, side] of [\n [props.upperBands, 'upper'],\n [props.lowerBands, 'lower'],\n ] as const) {\n const band = bands[i]\n if (!band?.visible || !props.bandsOn[i]) continue\n stroke(this.points(samples, (s) => s[side][i] ?? null, viewport), { ...this.style, lineColor: band.color, lineWidth: band.width, lineStyle: band.style })\n }\n }\n stroke(line, this.style)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const line = this.points(this.series(), (s) => s.vwap, viewport)\n if (line.length < 2) {\n const anchor = this.anchors[0]\n const p = anchor ? this.anchorToPixel(anchor, viewport) : null\n return !!p && Math.hypot(point.x - p.x, point.y - p.y) <= 10\n }\n const tolerance = hitTolerance(this.style.lineWidth)\n for (let i = 0; i < line.length - 1; i++) {\n if (distanceToSegment(point, line[i]!, line[i + 1]!) <= tolerance) return true\n }\n return false\n }\n}\n\n/**\n * Running POC/VAH/VAL per bar, computed incrementally over the range's fixed price extent in\n * one pass over the bars, O(rows) work per bar, so a 5k-bar range stays cheap. Sampled points\n * come back in price space; the caller maps them to pixels per paint.\n */\nfunction developingLevels(\n range: readonly SourceBar[],\n rows: number,\n vaShare: number,\n): { poc: { time: SourceBar['time']; price: number }[]; vah: { time: SourceBar['time']; price: number }[]; val: { time: SourceBar['time']; price: number }[] } | null {\n const withVolume = range.filter((b) => typeof b.volume === 'number' && b.volume > 0)\n if (withVolume.length < 2 || rows < 1) return null\n let min = Infinity\n let max = -Infinity\n for (const bar of withVolume) {\n min = Math.min(min, bar.low)\n max = Math.max(max, bar.high)\n }\n if (!(max > min)) return null\n const height = (max - min) / rows\n const bins = new Array<number>(rows).fill(0)\n const out = {\n poc: [] as { time: SourceBar['time']; price: number }[],\n vah: [] as { time: SourceBar['time']; price: number }[],\n val: [] as { time: SourceBar['time']; price: number }[],\n }\n let total = 0\n for (const bar of withVolume) {\n const lowBin = Math.max(0, Math.min(rows - 1, Math.floor((bar.low - min) / height)))\n const highBin = Math.max(0, Math.min(rows - 1, Math.floor((bar.high - min) / height)))\n const share = (bar.volume as number) / (highBin - lowBin + 1)\n for (let i = lowBin; i <= highBin; i++) bins[i] += share\n total += bar.volume as number\n let pocIndex = 0\n for (let i = 1; i < rows; i++) if (bins[i] > bins[pocIndex]) pocIndex = i\n out.poc.push({ time: bar.time, price: min + (pocIndex + 0.5) * height })\n if (vaShare > 0) {\n let low = pocIndex\n let high = pocIndex\n let covered = bins[pocIndex]\n while (covered < total * vaShare && (low > 0 || high < rows - 1)) {\n const below = low > 0 ? bins[low - 1] : -1\n const above = high < rows - 1 ? bins[high + 1] : -1\n if (above >= below) covered += bins[++high]\n else covered += bins[--low]\n }\n out.vah.push({ time: bar.time, price: min + (high + 1) * height })\n out.val.push({ time: bar.time, price: min + low * height })\n }\n }\n return out\n}\n\n/** A profile line's stroke: shown or not, its color, width and style. */\ntype ProfileLine = { visible: boolean; color: string; width: number; style: LineStyle }\n\nexport type ProfileProps = {\n /** 'number' sizes the histogram by total row count; 'ticks' by price ticks per row. */\n rowsLayout: 'number' | 'ticks'\n rowSize: number\n /** 'updown' splits each row by up/down bars, 'total' paints one bar, 'delta' their difference. */\n volume: 'updown' | 'total' | 'delta'\n /** Percentage of total volume the value area holds (0 holds none). */\n valueAreaVolume: number\n /** The histogram itself. */\n showProfile: boolean\n /** Each row's volume written beside it, in its own color. */\n showValues: boolean\n valuesColor: string\n /** Histogram width as a percentage of the range box. */\n widthPercent: number\n /** Which edge the histogram grows from. */\n placement: 'left' | 'right'\n /** The rows outside the value area, and inside it, as given, opacity and all. */\n upColor: string\n downColor: string\n valueAreaUpColor: string\n valueAreaDownColor: string\n /** The value area's high and low and the point of control, each across the range in a stroke of\n * its own. */\n vahVisible: boolean\n vahColor: string\n vahWidth: number\n vahStyle: LineStyle\n valVisible: boolean\n valColor: string\n valWidth: number\n valStyle: LineStyle\n pocVisible: boolean\n pocColor: string\n pocWidth: number\n pocStyle: LineStyle\n /** The running point of control and value area, walked bar by bar across the range, each in a\n * stroke of its own. */\n developingPoc: boolean\n developingPocColor: string\n developingPocWidth: number\n developingPocStyle: LineStyle\n developingVa: boolean\n developingVaColor: string\n developingVaWidth: number\n developingVaStyle: LineStyle\n /** The range box's background. */\n boxColor: string\n /** The point of control and the value area's shown bounds read on the price scale. */\n showLabelsOnPriceScale: boolean\n /** The range's edges, dashed in grey at half its opacity. */\n outline: boolean\n}\n\n/** The profile's levels: its rows, its point of control and its value area's bounds. */\ntype ProfileLevels = { bins: VolumeBin[]; pocIndex: number; low: number; high: number; vaShare: number }\n\n/** What a format-2 profile save that names none of these settings drew with. */\nconst SAVED_PROFILE: Partial<ProfileProps> & { extendRight: boolean } = {\n rowsLayout: 'number',\n rowSize: 24,\n volume: 'updown',\n valueAreaVolume: 70,\n upColor: '#089981',\n downColor: '#f23645',\n valueAreaUpColor: '#089981',\n valueAreaDownColor: '#f23645',\n widthPercent: 30,\n placement: 'left',\n pocVisible: true,\n pocColor: '#f23645',\n pocWidth: 2,\n pocStyle: 'solid',\n vahVisible: true,\n vahColor: '#787b86',\n vahWidth: 1,\n vahStyle: 'dashed',\n valVisible: true,\n valColor: '#787b86',\n valWidth: 1,\n valStyle: 'dashed',\n developingPoc: false,\n developingVa: false,\n extendRight: false,\n}\n\n/** Shared volume-by-price histogram body; subclasses define the bar range and the x-span. */\nabstract class VolumeProfileBase<P extends ProfileProps & Record<string, unknown>> extends Drawing<P> {\n protected abstract range(): SourceBar[]\n protected abstract span(viewport: Viewport): { x1: number; x2: number } | null\n\n protected rowCount(range: readonly SourceBar[]): number {\n const size = Math.max(1, this.props.rowSize)\n if (this.props.rowsLayout === 'ticks') {\n let min = Infinity\n let max = -Infinity\n for (const bar of range) {\n min = Math.min(min, bar.low)\n max = Math.max(max, bar.high)\n }\n if (!(max > min)) return 24\n // Tick rows need the symbol's tick; without one the profile keeps its default row count.\n const tick = this.tickSize()\n if (tick === null) return 24\n const rows = Math.ceil((max - min) / (tick * size))\n return Math.max(1, Math.min(400, rows))\n }\n return Math.max(1, Math.min(400, Math.round(size)))\n }\n\n /** The rows, the point of control, and the value area grown from it toward the heavier neighbour\n * until it holds its share of the volume: the trading-profile convention. */\n protected levels(range: readonly SourceBar[]): ProfileLevels | null {\n const bins = volumeProfile(range, this.rowCount(range))\n if (!bins) return null\n const pocIndex = bins.reduce((best, bin, i) => (bin.volume > bins[best]!.volume ? i : best), 0)\n const vaShare = Math.max(0, Math.min(100, this.props.valueAreaVolume)) / 100\n const total = bins.reduce((s, b) => s + b.volume, 0)\n let low = pocIndex\n let high = pocIndex\n let covered = bins[pocIndex]!.volume\n while (vaShare > 0 && covered < total * vaShare && (low > 0 || high < bins.length - 1)) {\n const below = low > 0 ? bins[low - 1]!.volume : -1\n const above = high < bins.length - 1 ? bins[high + 1]!.volume : -1\n if (above >= below) covered += bins[++high]!.volume\n else covered += bins[--low]!.volume\n }\n return { bins, pocIndex, low, high, vaShare }\n }\n\n /** The prices the point of control and the value area's bounds stand at. */\n protected levelPrices(): { poc: number; vah: number | null; val: number | null } | null {\n const l = this.levels(this.range())\n if (!l) return null\n const poc = l.bins[l.pocIndex]!\n return {\n poc: (poc.priceLow + poc.priceHigh) / 2,\n vah: l.vaShare > 0 ? l.bins[l.high]!.priceHigh : null,\n val: l.vaShare > 0 ? l.bins[l.low]!.priceLow : null,\n }\n }\n\n private readonly _axisViews = (['poc', 'vah', 'val'] as const).map(\n (key) =>\n new AxisLabel({\n coordinate: () => {\n const viewport = this.getViewport()\n const price = this.levelPrices()?.[key]\n return viewport && price !== null && price !== undefined ? viewport.yOf(price) : null\n },\n text: () => {\n const price = this.levelPrices()?.[key]\n return price === null || price === undefined ? '' : this.formatPrice(price)\n },\n color: () => withAlpha(this.props[`${key}Color`] as string, 1),\n visible: () => this.props.showLabelsOnPriceScale && this.props[`${key}Visible`] === true && this.isVisibleNow(),\n }),\n )\n\n protected override axisViews(): readonly ISeriesPrimitiveAxisView[] {\n return this._axisViews\n }\n\n /** A format-2 profile drew its rows outside the value area at 30% of their colors' opacity and\n * inside it at 80%, its levels at 90%, its developing lines in its levels' colors at 70%, 1px\n * and dotted, held its value area to 95%, outlined its range, filled no box and read nothing on\n * the price scale. */\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n const missing = Object.fromEntries(Object.entries(SAVED_PROFILE).filter(([key]) => !(key in saved) && key in this._props))\n const p = { ...this._props, ...missing }\n const at = (color: string, share: number): string => withAlpha(color, share * alphaOf(color))\n this._props = {\n ...p,\n upColor: at(p.upColor, 0.3),\n downColor: at(p.downColor, 0.3),\n valueAreaUpColor: at(p.valueAreaUpColor, 0.8),\n valueAreaDownColor: at(p.valueAreaDownColor, 0.8),\n pocColor: at(p.pocColor, 0.9),\n vahColor: at(p.vahColor, 0.9),\n valColor: at(p.valColor, 0.9),\n developingPocColor: at(p.pocColor, 0.7),\n developingPocWidth: 1,\n developingPocStyle: 'dotted',\n developingVaColor: at(p.vahColor, 0.7),\n developingVaWidth: 1,\n developingVaStyle: 'dotted',\n valueAreaVolume: Math.min(95, p.valueAreaVolume),\n boxColor: withAlpha(p.boxColor, 0),\n showLabelsOnPriceScale: false,\n outline: true,\n }\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const span = this.span(viewport)\n if (!span) return\n const range = this.range()\n const p = this.props\n // The range box's background, as given, opacity and all.\n if (alphaOf(p.boxColor) > 0) {\n ctx.save()\n ctx.fillStyle = p.boxColor\n ctx.fillRect(span.x1, 0, span.x2 - span.x1, viewport.height)\n ctx.restore()\n }\n if (p.outline) {\n ctx.save()\n ctx.strokeStyle = withAlpha('#787b86', 0.5)\n ctx.lineWidth = 1\n ctx.setLineDash([4, 4])\n ctx.strokeRect(span.x1, 0, span.x2 - span.x1, viewport.height)\n ctx.restore()\n }\n const l = this.levels(range)\n if (!l) {\n paintLabel(ctx, 'profile needs volume data', { x: (span.x1 + span.x2) / 2, y: 16 }, this.style, {\n align: 'center',\n background: withAlpha('#1b1f27', 0.92),\n })\n return\n }\n const { bins, pocIndex, low, high, vaShare } = l\n const maxVolume = Math.max(...bins.map((b) => b.volume))\n if (maxVolume <= 0) return\n const maxWidth = ((span.x2 - span.x1) * Math.max(5, Math.min(100, p.widthPercent))) / 100\n const fromRight = p.placement === 'right'\n\n ctx.save()\n ctx.setLineDash([])\n for (const [i, bin] of bins.entries()) {\n const y1 = viewport.yOf(bin.priceHigh)\n const y2 = viewport.yOf(bin.priceLow)\n if (y1 === null || y2 === null) continue\n const top = Math.min(y1, y2)\n const rowH = Math.max(1, Math.abs(y2 - y1) - 1)\n const inValueArea = vaShare > 0 && i >= low && i <= high\n const upPaint = inValueArea ? p.valueAreaUpColor : p.upColor\n const downPaint = inValueArea ? p.valueAreaDownColor : p.downColor\n // Rows grow from the chosen edge; a right placement mirrors every rect.\n const rect = (offset: number, w: number) => {\n if (fromRight) ctx.fillRect(span.x2 - offset - w, top, w, rowH)\n else ctx.fillRect(span.x1 + offset, top, w, rowH)\n }\n let width = 0\n if (p.showProfile) {\n if (p.volume === 'updown') {\n const upW = (bin.upVolume / maxVolume) * maxWidth\n const downW = (bin.downVolume / maxVolume) * maxWidth\n ctx.fillStyle = upPaint\n rect(0, upW)\n ctx.fillStyle = downPaint\n rect(upW, downW)\n width = upW + downW\n } else if (p.volume === 'delta') {\n const delta = bin.upVolume - bin.downVolume\n ctx.fillStyle = delta >= 0 ? upPaint : downPaint\n width = (Math.abs(delta) / maxVolume) * maxWidth\n rect(0, width)\n } else {\n ctx.fillStyle = upPaint\n width = (bin.volume / maxVolume) * maxWidth\n rect(0, width)\n }\n }\n if (p.showValues) {\n const value = p.volume === 'delta' ? bin.upVolume - bin.downVolume : bin.volume\n const at = { x: fromRight ? span.x2 - width - 4 : span.x1 + width + 4, y: top + rowH / 2 }\n paintLabel(ctx, volumeText(value), at, { ...this.style, textColor: p.valuesColor }, { align: fromRight ? 'right' : 'left' })\n }\n }\n // The point of control across the whole range, and the value area's bounds, each its own stroke.\n const level = (y: number | null, line: ProfileLine) => {\n if (y === null || !line.visible) return\n ctx.strokeStyle = line.color\n ctx.lineWidth = line.width\n ctx.setLineDash(dashPattern(line.style, line.width))\n ctx.beginPath()\n ctx.moveTo(span.x1, y)\n ctx.lineTo(span.x2, y)\n ctx.stroke()\n }\n const poc = bins[pocIndex]!\n level(viewport.yOf((poc.priceLow + poc.priceHigh) / 2), { visible: p.pocVisible, color: p.pocColor, width: p.pocWidth, style: p.pocStyle })\n if (vaShare > 0) {\n level(viewport.yOf(bins[high]!.priceHigh), { visible: p.vahVisible, color: p.vahColor, width: p.vahWidth, style: p.vahStyle })\n level(viewport.yOf(bins[low]!.priceLow), { visible: p.valVisible, color: p.valColor, width: p.valWidth, style: p.valStyle })\n }\n // The developing lines: the running point of control and value area walked bar by bar.\n if (p.developingPoc || p.developingVa) {\n const developing = developingLevels(range, this.rowCount(range), vaShare)\n if (developing) {\n const polyline = (points: { time: SourceBar['time']; price: number }[], line: ProfileLine) => {\n ctx.strokeStyle = line.color\n ctx.lineWidth = line.width\n ctx.setLineDash(dashPattern(line.style, line.width))\n ctx.beginPath()\n let started = false\n for (const point of points) {\n const x = viewport.xOf(point.time)\n const y = viewport.yOf(point.price)\n if (x === null || y === null) continue\n if (started) ctx.lineTo(x, y)\n else ctx.moveTo(x, y)\n started = true\n }\n if (started) ctx.stroke()\n }\n if (p.developingPoc) polyline(developing.poc, { visible: true, color: p.developingPocColor, width: p.developingPocWidth, style: p.developingPocStyle })\n if (p.developingVa) {\n const va = { visible: true, color: p.developingVaColor, width: p.developingVaWidth, style: p.developingVaStyle }\n polyline(developing.vah, va)\n polyline(developing.val, va)\n }\n }\n }\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const span = this.span(viewport)\n if (!span) return false\n return point.x >= span.x1 - 4 && point.x <= span.x2 + 4\n }\n}\n\nexport type FixedProfileProps = ProfileProps & {\n /** Keep building through every bar right of the range: new bars join the profile live. */\n extendRight: boolean\n}\n\n/** Volume-by-price histogram over the two anchors' time range, drawn inside the range box. */\nexport class FixedRangeVolumeProfile extends VolumeProfileBase<FixedProfileProps> {\n readonly type = 'fixed_range_volume_profile'\n\n protected override defaultProps(): FixedProfileProps {\n return {\n rowsLayout: 'number',\n rowSize: 200,\n volume: 'updown',\n valueAreaVolume: 100,\n showProfile: true,\n showValues: false,\n valuesColor: '#424242',\n widthPercent: 30,\n placement: 'left',\n upColor: 'rgba(41, 98, 255, 0)',\n downColor: 'rgba(251, 192, 45, 0)',\n valueAreaUpColor: 'rgba(149, 152, 161, 0.35)',\n valueAreaDownColor: 'rgba(149, 152, 161, 0.35)',\n vahVisible: false,\n vahColor: '#2962ff',\n vahWidth: 2,\n vahStyle: 'solid',\n valVisible: false,\n valColor: '#2962ff',\n valWidth: 2,\n valStyle: 'solid',\n pocVisible: true,\n pocColor: 'rgba(244, 67, 54, 0.35)',\n pocWidth: 1,\n pocStyle: 'solid',\n developingPoc: false,\n developingPocColor: '#f44336',\n developingPocWidth: 1,\n developingPocStyle: 'solid',\n developingVa: false,\n developingVaColor: '#2962ff',\n developingVaWidth: 1,\n developingVaStyle: 'solid',\n boxColor: 'rgba(55, 166, 239, 0)',\n showLabelsOnPriceScale: true,\n outline: false,\n extendRight: true,\n }\n }\n\n requiredAnchors(): number {\n return 2\n }\n\n protected range(): SourceBar[] {\n const [a, b] = this.anchors\n if (!a || !b) return []\n if (this.props.extendRight) {\n return barsFrom(this.bars(), Number(a.time) <= Number(b.time) ? a.time : b.time)\n }\n return barsInRange(this.bars(), a.time, b.time)\n }\n\n protected span(viewport: Viewport): { x1: number; x2: number } | null {\n const [pa, pb] = this.anchorPixels(viewport)\n if (!pa || !pb) return null\n const x1 = Math.min(pa.x, pb.x)\n return { x1, x2: this.props.extendRight ? viewport.width : Math.max(pa.x, pb.x) }\n }\n}\n\n/** Volume profile from the anchor's time to the newest bar. */\nexport class AnchoredVolumeProfile extends VolumeProfileBase<ProfileProps> {\n readonly type = 'anchored_volume_profile'\n\n protected override defaultProps(): ProfileProps {\n return {\n rowsLayout: 'number',\n rowSize: 24,\n volume: 'updown',\n valueAreaVolume: 70,\n showProfile: true,\n showValues: false,\n valuesColor: '#dbdbdb',\n widthPercent: 30,\n placement: 'right',\n upColor: 'rgba(38, 198, 218, 0.5)',\n downColor: 'rgba(236, 64, 122, 0.5)',\n valueAreaUpColor: 'rgba(38, 198, 218, 0.75)',\n valueAreaDownColor: 'rgba(236, 64, 122, 0.75)',\n vahVisible: false,\n vahColor: '#dbdbdb',\n vahWidth: 2,\n vahStyle: 'solid',\n valVisible: false,\n valColor: '#dbdbdb',\n valWidth: 2,\n valStyle: 'solid',\n pocVisible: true,\n pocColor: '#dbdbdb',\n pocWidth: 2,\n pocStyle: 'solid',\n developingPoc: false,\n developingPocColor: '#dbdbdb',\n developingPocWidth: 1,\n developingPocStyle: 'solid',\n developingVa: false,\n developingVaColor: '#00bcd4',\n developingVaWidth: 1,\n developingVaStyle: 'solid',\n boxColor: 'rgba(38, 198, 218, 0.05)',\n showLabelsOnPriceScale: true,\n outline: false,\n }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n protected range(): SourceBar[] {\n const anchor = this.anchors[0]\n if (!anchor) return []\n return barsFrom(this.bars(), anchor.time)\n }\n\n protected span(viewport: Viewport): { x1: number; x2: number } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const x = viewport.xOf(anchor.time)\n if (x === null) return null\n return { x1: x, x2: viewport.width }\n }\n}\n","import type { Point, Viewport } from '../core/types'\nimport { Drawing } from '../core/drawing'\nimport { cachedImageBitmap, primeImageBitmap } from '../render/imageCache'\nimport { glyphArtwork } from '../render/glyphArtwork'\n\nfunction inBox(p: Point, box: { x: number; y: number; width: number; height: number }, pad = 3): boolean {\n return (\n p.x >= box.x - pad && p.x <= box.x + box.width + pad && p.y >= box.y - pad && p.y <= box.y + box.height + pad\n )\n}\n\nexport type ImageProps = {\n /** Data-URL payload (kept small by the host's picker); empty = placeholder frame. */\n dataUrl: string\n width: number\n /** 0..1 paint opacity. */\n opacity: number\n}\n\n/** A viewer's image pinned to a chart point (anchor = top-left). */\nexport class ImageNote extends Drawing<ImageProps> {\n readonly type = 'image'\n\n private _bitmap: HTMLImageElement | null = null\n private _loadedFrom = ''\n\n protected override defaultProps(): ImageProps {\n return { dataUrl: '', width: 160, opacity: 1 }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n protected frame(viewport: Viewport): { x: number; y: number; width: number; height: number } | null {\n const anchor = this.anchors[0]\n if (!anchor) return null\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return null\n const width = Math.max(24, this.props.width)\n const ratio = this._bitmap && this._bitmap.naturalWidth > 0 ? this._bitmap.naturalHeight / this._bitmap.naturalWidth : 0.66\n return { x: p.x, y: p.y, width, height: width * ratio }\n }\n\n private ensureBitmap(): void {\n const source = this.props.dataUrl\n if (!source || source === this._loadedFrom || typeof Image === 'undefined') return\n // Whoever chose this picture already decoded this exact payload to preview it, so the bitmap is\n // usually sitting in the cache and the first frame can paint it. Decoding it a second time here\n // is what made a placed image arrive a beat after the click that placed it.\n const warm = cachedImageBitmap(source)\n if (warm) {\n this._loadedFrom = source\n this._bitmap = warm\n return\n }\n this._loadedFrom = source\n const image = new Image()\n image.onload = () => {\n primeImageBitmap(source, image) // so a second drawing on the same picture pays nothing\n this._bitmap = image\n this.requestUpdate()\n }\n image.src = source\n }\n\n /** Four corners, so any of them can be grabbed. */\n override resizeHandles(viewport: Viewport): Point[] {\n if (!this.props.dataUrl) return []\n const f = this.frame(viewport)\n if (!f) return []\n return [\n { x: f.x, y: f.y },\n { x: f.x + f.width, y: f.y },\n { x: f.x, y: f.y + f.height },\n { x: f.x + f.width, y: f.y + f.height },\n ]\n }\n\n /** A corner drag scales the picture about its anchor, which is the top-left. Only WIDTH is stored —\n * height follows the bitmap's own ratio, so an image cannot be dragged out of proportion into\n * something that just looks broken. */\n override resizeTo(handleIndex: number, point: Point, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const origin = this.anchorToPixel(anchor, viewport)\n if (!origin) return\n // Left-side handles are mirrored so dragging outward grows the image whichever corner is held.\n const dx = handleIndex === 0 || handleIndex === 2 ? origin.x - point.x : point.x - origin.x\n this.applyProps({ width: Math.max(24, Math.round(dx)) })\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n this.ensureBitmap()\n const f = this.frame(viewport)\n if (!f) return\n if (this._bitmap && this.props.dataUrl) {\n ctx.save()\n ctx.globalAlpha = Math.max(0, Math.min(1, this.props.opacity))\n ctx.drawImage(this._bitmap, f.x, f.y, f.width, f.height)\n ctx.restore()\n if (this.state === 'selected' || this.state === 'editing') {\n ctx.save()\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.setLineDash([])\n ctx.strokeRect(f.x, f.y, f.width, f.height)\n ctx.restore()\n }\n return\n }\n // Placeholder until an image is chosen in settings.\n ctx.save()\n ctx.setLineDash([4, 4])\n ctx.strokeStyle = this.style.lineColor\n ctx.lineWidth = 1\n ctx.strokeRect(f.x, f.y, f.width, f.height)\n ctx.setLineDash([])\n ctx.font = '11px ui-sans-serif, system-ui, sans-serif'\n ctx.fillStyle = this.style.lineColor\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText('image: pick in settings', f.x + f.width / 2, f.y + f.height / 2)\n ctx.restore()\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const f = this.frame(viewport)\n return !!f && inBox(point, f)\n }\n}\n\nexport type GlyphProps = {\n /** The rendered character(s) — an emoji, sticker glyph, or symbol. */\n glyph: string\n size: number\n}\n\n/** Shared body of the emoji/sticker/icon tools: one glyph rendered at a point. */\nexport class GlyphMark extends Drawing<GlyphProps> {\n readonly type: string = 'emoji'\n\n protected override defaultProps(): GlyphProps {\n return { glyph: '😀', size: 72 }\n }\n\n /** The size a format-2 save that names none drew its glyph at. */\n protected savedSize(): number {\n return 28\n }\n\n protected override keepSavedLook(saved: Readonly<Record<string, unknown>>): void {\n if (!('size' in saved)) this._props = { ...this._props, size: this.savedSize() }\n }\n\n requiredAnchors(): number {\n return 1\n }\n\n protected radius(): number {\n return Math.max(10, this.props.size) / 2 + 4\n }\n\n /** Icon marks tint with the stroke color; emoji/sticker marks carry their own artwork. */\n protected tintsWithStroke(): boolean {\n return false\n }\n\n private glyphImage(): HTMLImageElement | null {\n if (this.tintsWithStroke()) return null\n const url = this.glyphUrl(this.props.glyph)\n return url ? glyphArtwork(url, () => this.requestUpdate()) : null\n }\n\n paint(ctx: CanvasRenderingContext2D, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n const size = Math.max(10, this.props.size)\n const image = this.glyphImage()\n if (image) {\n ctx.drawImage(image, p.x - size / 2, p.y - size / 2, size, size)\n return\n }\n ctx.save()\n ctx.font = `${size}px ui-sans-serif, system-ui, sans-serif`\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n // Icons render in the drawing hue; emoji/stickers carry their own colors.\n ctx.fillStyle = this.style.lineColor\n ctx.fillText(this.props.glyph || '?', p.x, p.y)\n ctx.restore()\n }\n\n /** Scale grips at the glyph's bounding-box corners. */\n override resizeHandles(viewport: Viewport): Point[] {\n const anchor = this.anchors[0]\n if (!anchor) return []\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return []\n const r = this.radius()\n return [\n { x: p.x - r, y: p.y - r },\n { x: p.x + r, y: p.y - r },\n { x: p.x + r, y: p.y + r },\n { x: p.x - r, y: p.y + r },\n ]\n }\n\n override resizeTo(_handleIndex: number, point: Point, viewport: Viewport): void {\n const anchor = this.anchors[0]\n if (!anchor) return\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return\n const r = Math.max(Math.abs(point.x - p.x), Math.abs(point.y - p.y))\n this.applyProps({ size: Math.max(10, Math.min(160, Math.round((r - 4) * 2))) } as Partial<GlyphProps>)\n }\n\n testHit(point: Point, viewport: Viewport): boolean {\n const anchor = this.anchors[0]\n if (!anchor) return false\n const p = this.anchorToPixel(anchor, viewport)\n if (!p) return false\n const r = this.radius()\n return Math.abs(point.x - p.x) <= r && Math.abs(point.y - p.y) <= r\n }\n}\n\nexport class StickerMark extends GlyphMark {\n override readonly type = 'sticker'\n\n protected override defaultProps(): GlyphProps {\n return { glyph: '👍', size: 72 }\n }\n\n protected override savedSize(): number {\n return 44\n }\n}\n\nexport class IconMark extends GlyphMark {\n override readonly type = 'icon'\n\n protected override defaultProps(): GlyphProps {\n return { glyph: '★', size: 40 }\n }\n\n protected override savedSize(): number {\n return 24\n }\n\n protected override tintsWithStroke(): boolean {\n return true\n }\n}\n","import type { Anchor, DrawingOptions, DrawingStyle, SerializedDrawing, ToolCategory } from './core/types'\nimport { SERIAL_VERSION } from './core/types'\nimport type { AnyDrawing, Drawing } from './core/drawing'\n\nimport {\n Arrow,\n CrossLine,\n ExtendedLine,\n HorizontalLine,\n HorizontalRay,\n InfoLine,\n Ray,\n TrendAngle,\n TrendLine,\n VerticalLine,\n} from './tools/lines'\nimport {\n Arc,\n Circle,\n Curve,\n DoubleCurve,\n Ellipse,\n Rectangle,\n RotatedRectangle,\n Triangle,\n} from './tools/shapes'\nimport {\n ArrowMarkDown,\n ArrowMarkUp,\n Callout,\n Comment,\n FlagMark,\n Note,\n PriceLabel,\n TextLabel,\n} from './tools/annotations'\nimport { DatePriceRange, DateRange, Measure, PriceRange } from './tools/measurement'\nimport { DisjointChannel, FlatTopBottom, ParallelChannel } from './tools/channels'\nimport { InsidePitchfork, ModifiedSchiffPitchfork, Pitchfork, SchiffPitchfork } from './tools/pitchforks'\nimport {\n FibArcs,\n FibChannel,\n FibCircles,\n FibExtension,\n FibRetracement,\n FibSpeedFan,\n FibSpiral,\n FibTimeExtension,\n FibTimeZone,\n FibWedge,\n Pitchfan,\n} from './tools/fibonacci'\nimport { GannBox, GannFan, GannSquare, GannSquareFixed } from './tools/gann'\nimport { Forecast, LongPosition, Sector, ShortPosition } from './tools/forecasting'\nimport { Brush, Highlighter, PathLine, Polyline } from './tools/freehand'\nimport { ArrowMarker, Pin, PriceNote, Signpost } from './tools/annotations'\nimport { TableNote } from './tools/table'\nimport { AbcdPattern, CypherPattern, HeadAndShoulders, ThreeDrivesPattern, TrianglePattern, XabcdPattern } from './tools/patterns'\nimport {\n ElliottCorrection,\n ElliottDoubleCombo,\n ElliottImpulse,\n ElliottTriangle,\n ElliottTripleCombo,\n} from './tools/elliott'\nimport { CyclicLines, SineLine, TimeCycles } from './tools/cycles'\nimport { BarsPattern, GhostFeed, RegressionTrend } from './tools/bars'\nimport { AnchoredVolumeProfile, AnchoredVwap, FixedRangeVolumeProfile } from './tools/volume'\nimport { GlyphMark, IconMark, ImageNote, StickerMark } from './tools/content'\n\n/** How a tool that types its words on the chart answers the pointer and an empty draft. The\n * drawing paints the words as they are typed, with their caret, selection and placeholder, while\n * an invisible field laid over them takes the keys; Escape and a press elsewhere keep the words\n * exactly as typed. */\nexport interface InlineTextRules {\n /** A click on the drawing's words while it is selected types into them, the caret after the\n * last. */\n clickToType: boolean\n /** What becomes of a drawing left without words: `deselect` keeps it while it is selected and\n * removes it once it is not, `commit` removes it as the edit that left it empty ends, and `keep`\n * keeps it, its words being optional. */\n whenEmpty: 'deselect' | 'commit' | 'keep'\n}\n\nexport interface ToolDefinition {\n type: string\n name: string\n category: ToolCategory\n /** Anchor count that completes placement. */\n anchors: number\n /** Default style overrides for new drawings of this tool (e.g. a highlighter's fill). */\n style?: Partial<DrawingStyle>\n /** Tool renders the viewer's text — the host opens its text editor right after placement. */\n hasText?: boolean\n /** The tool types its words on the chart, under these rules. Absent, its words are typed in an\n * editor box of their own. */\n inlineText?: InlineTextRules\n /** A double-click on one of the tool's drawings opens its settings, never an editor of its\n * words. */\n settingsOnDoubleClick?: boolean\n /** While the tool is armed, the drawing a click would place follows the pointer. */\n previewed?: boolean\n /** How anchors are gathered: drag-captured stroke, or click-to-add points (double-click ends).\n * Omitted = the fixed `anchors` count. */\n placement?: 'freehand' | 'multipoint' | 'instant'\n /** Tool snapshots the bars between its anchors when placement completes (the host triggers\n * the drawing's `capture()`). */\n capturesBars?: boolean\n create(\n id: string,\n anchors?: Anchor[],\n style?: Partial<DrawingStyle>,\n options?: Partial<DrawingOptions>,\n props?: Record<string, unknown>,\n ): AnyDrawing\n}\n\ninterface ToolMeta {\n type: string\n name: string\n category: ToolCategory\n anchors: number\n style?: Partial<DrawingStyle>\n hasText?: boolean\n inlineText?: InlineTextRules\n settingsOnDoubleClick?: boolean\n previewed?: boolean\n placement?: 'freehand' | 'multipoint' | 'instant'\n capturesBars?: boolean\n}\n\n/** Bind a tool class to its metadata (typed props cast happens exactly once, here). */\nfunction tool<P extends Record<string, unknown>>(\n Ctor: new (\n id: string,\n anchors?: Anchor[],\n style?: Partial<DrawingStyle>,\n options?: Partial<DrawingOptions>,\n props?: Partial<P>,\n ) => Drawing<P>,\n meta: ToolMeta,\n): ToolDefinition {\n return {\n ...meta,\n create: (id, anchors, style, options, props) =>\n new Ctor(id, anchors, style, options, props as Partial<P> | undefined) as AnyDrawing,\n }\n}\n\n/** A line tool's factory look: a 2px stroke and its words in one blue, the words at 14px. */\nconst LINE_LOOK: Partial<DrawingStyle> = { lineColor: '#2962ff', lineWidth: 2, lineStyle: 'solid', textColor: '#2962ff', fontSize: 14 }\n\n/** A shape's factory look in one hue: a 2px border, a background of the same hue at a fifth, and\n * its words in the hue at 14px. */\nconst shapeLook = (hue: string): Partial<DrawingStyle> => ({ lineColor: hue, lineWidth: 2, lineStyle: 'solid', fillColor: hue, fillOpacity: 0.2, textColor: hue, fontSize: 14 })\n\n/** A pattern's factory look: a 2px border in its hue and its letters white at 12px, and where it\n * shades its legs, a background of the hue at fifteen percent. */\nconst patternLook = (hue: string, shaded: boolean): Partial<DrawingStyle> => ({\n lineColor: hue,\n lineWidth: 2,\n lineStyle: 'solid',\n textColor: '#ffffff',\n fontSize: 12,\n ...(shaded ? { fillColor: hue, fillOpacity: 0.15 } : {}),\n})\n\n/** A leveled fib's factory look: its levels drawn solid at 2px, their labels at 12px. */\nconst FIB_LOOK: Partial<DrawingStyle> = { lineWidth: 2, lineStyle: 'solid', fontSize: 12 }\n\n/** A channel's look: its sides, its body at a fifth and its words in its hue, the sides 2px and the\n * words 14px. */\nconst channelLook = (hue: string): Partial<DrawingStyle> => ({ lineColor: hue, lineWidth: 2, lineStyle: 'solid', fillColor: hue, fillOpacity: 0.2, textColor: hue, fontSize: 14 })\n\n/** A range meter's look: its arrows in their color at 2px over a blue span at fifteen percent, the\n * viewer's words blue at 12px. */\nconst meterLook = (line: string): Partial<DrawingStyle> => ({ lineColor: line, lineWidth: 2, lineStyle: 'solid', fillColor: '#2962ff', fillOpacity: 0.15, textColor: '#2962ff', fontSize: 12 })\n\n/** A wave count's look: its line and its labels in one color, the line 2px and solid. */\nconst waveLook = (color: string): Partial<DrawingStyle> => ({ lineColor: color, lineWidth: 2, lineStyle: 'solid' })\n\n/** Display order of categories in the drawing toolbar. */\nexport const TOOL_CATEGORIES: readonly ToolCategory[] = [\n 'lines',\n 'channels',\n 'pitchforks',\n 'fibonacci',\n 'gann',\n 'patterns',\n 'elliott',\n 'cycles',\n 'forecasting',\n 'volume',\n 'measurement',\n 'shapes',\n 'annotation',\n 'content',\n]\n\n/** A line types its words on the chart: a click on the invitation of a selected line, or on its\n * words, types them in place, and a line keeps its place without words. */\nconst LINE_WORDS = { inlineText: { clickToType: true, whenEmpty: 'keep' }, settingsOnDoubleClick: true } as const\n\nconst DEFINITIONS: ToolDefinition[] = [\n // Lines\n tool(TrendLine, { type: 'trend_line', name: 'Trend line', category: 'lines', anchors: 2, style: LINE_LOOK, ...LINE_WORDS }),\n tool(Ray, { type: 'ray', name: 'Ray', category: 'lines', anchors: 2, style: LINE_LOOK, ...LINE_WORDS }),\n tool(InfoLine, { type: 'info_line', name: 'Info line', category: 'lines', anchors: 2, style: LINE_LOOK, ...LINE_WORDS }),\n tool(ExtendedLine, { type: 'extended', name: 'Extended line', category: 'lines', anchors: 2, style: LINE_LOOK, ...LINE_WORDS }),\n tool(TrendAngle, { type: 'trend_angle', name: 'Trend angle', category: 'lines', anchors: 2, settingsOnDoubleClick: true, style: { ...LINE_LOOK, fontSize: 12 } }),\n tool(HorizontalLine, { type: 'horizontal_line', name: 'Horizontal line', category: 'lines', anchors: 1, style: { ...LINE_LOOK, fontSize: 12 }, ...LINE_WORDS }),\n tool(HorizontalRay, { type: 'horizontal_ray', name: 'Horizontal ray', category: 'lines', anchors: 1, settingsOnDoubleClick: true, style: { ...LINE_LOOK, fontSize: 12 } }),\n tool(VerticalLine, { type: 'vertical_line', name: 'Vertical line', category: 'lines', anchors: 1, style: LINE_LOOK, ...LINE_WORDS }),\n tool(CrossLine, { type: 'cross_line', name: 'Cross line', category: 'lines', anchors: 1, settingsOnDoubleClick: true, style: LINE_LOOK }),\n tool(Arrow, { type: 'arrow', name: 'Arrow', category: 'lines', anchors: 2, style: LINE_LOOK, ...LINE_WORDS }),\n\n // Shapes\n tool(Rectangle, { type: 'rectangle', name: 'Rectangle', category: 'shapes', anchors: 2, style: shapeLook('#9c27b0') }),\n tool(RotatedRectangle, { type: 'rotated_rectangle', name: 'Rotated rectangle', category: 'shapes', anchors: 3, style: shapeLook('#4caf50') }),\n tool(Ellipse, { type: 'ellipse', name: 'Ellipse', category: 'shapes', anchors: 3, style: shapeLook('#f23645') }),\n tool(Circle, { type: 'circle', name: 'Circle', category: 'shapes', anchors: 2, style: shapeLook('#ff9800') }),\n tool(Triangle, { type: 'triangle', name: 'Triangle', category: 'shapes', anchors: 3, style: shapeLook('#089981') }),\n tool(Arc, { type: 'arc', name: 'Arc', category: 'shapes', anchors: 3, style: shapeLook('#e91e63') }),\n tool(Curve, { type: 'curve', name: 'Curve', category: 'shapes', anchors: 3, style: shapeLook('#2962ff') }),\n tool(DoubleCurve, { type: 'double_curve', name: 'Double curve', category: 'shapes', anchors: 4, style: shapeLook('#673ab7') }),\n\n // Channels\n tool(RegressionTrend, { type: 'regression_trend', name: 'Regression trend', category: 'channels', anchors: 2, style: { lineWidth: 1, lineStyle: 'solid' } }),\n tool(ParallelChannel, { type: 'parallel_channel', name: 'Parallel channel', category: 'channels', anchors: 3, style: channelLook('#2962ff') }),\n tool(FlatTopBottom, { type: 'flat_top_bottom', name: 'Flat top/bottom', category: 'channels', anchors: 3, style: channelLook('#ff9800') }),\n tool(DisjointChannel, { type: 'disjoint_channel', name: 'Disjoint channel', category: 'channels', anchors: 4, style: channelLook('#089981') }),\n\n // Fibonacci\n tool(FibRetracement, { type: 'fib_retracement', name: 'Fib retracement', category: 'fibonacci', anchors: 2, style: FIB_LOOK }),\n tool(FibExtension, { type: 'fib_trend_ext', name: 'Trend-based fib extension', category: 'fibonacci', anchors: 3, style: FIB_LOOK }),\n tool(FibChannel, { type: 'fib_channel', name: 'Fib channel', category: 'fibonacci', anchors: 3, style: FIB_LOOK }),\n tool(FibTimeZone, { type: 'fib_timezone', name: 'Fib time zone', category: 'fibonacci', anchors: 2, style: FIB_LOOK }),\n tool(FibSpeedFan, { type: 'fib_speed_resist_fan', name: 'Fib speed resistance fan', category: 'fibonacci', anchors: 2, style: FIB_LOOK }),\n tool(FibTimeExtension, { type: 'fib_trend_time', name: 'Trend-based fib time', category: 'fibonacci', anchors: 3, style: FIB_LOOK }),\n tool(FibCircles, { type: 'fib_circles', name: 'Fib circles', category: 'fibonacci', anchors: 2, style: FIB_LOOK }),\n tool(FibSpiral, { type: 'fib_spiral', name: 'Fib spiral', category: 'fibonacci', anchors: 2, style: { lineColor: '#00bcd4', lineWidth: 2, lineStyle: 'solid' } }),\n tool(FibArcs, { type: 'fib_speed_resist_arcs', name: 'Fib speed resistance arcs', category: 'fibonacci', anchors: 2, style: FIB_LOOK }),\n tool(FibWedge, { type: 'fib_wedge', name: 'Fib wedge', category: 'fibonacci', anchors: 3, style: FIB_LOOK }),\n tool(Pitchfan, { type: 'pitchfan', name: 'Pitchfan', category: 'fibonacci', anchors: 3, style: FIB_LOOK }),\n\n // Pitchforks\n tool(Pitchfork, { type: 'pitchfork', name: 'Pitchfork', category: 'pitchforks', anchors: 3, style: FIB_LOOK }),\n tool(SchiffPitchfork, { type: 'schiff_pitchfork', name: 'Schiff pitchfork', category: 'pitchforks', anchors: 3, style: FIB_LOOK }),\n tool(ModifiedSchiffPitchfork, { type: 'schiff_pitchfork_modified', name: 'Modified Schiff pitchfork', category: 'pitchforks', anchors: 3, style: FIB_LOOK }),\n tool(InsidePitchfork, { type: 'inside_pitchfork', name: 'Inside pitchfork', category: 'pitchforks', anchors: 3, style: FIB_LOOK }),\n\n // Gann\n tool(GannBox, { type: 'gannbox', name: 'Gann box', category: 'gann', anchors: 2, style: { lineColor: 'rgba(21, 56, 153, 0.8)', lineWidth: 2, lineStyle: 'solid', fontSize: 12 } }),\n tool(GannSquare, { type: 'gannbox_square', name: 'Gann square', category: 'gann', anchors: 2, style: FIB_LOOK }),\n tool(GannSquareFixed, { type: 'gannbox_fixed', name: 'Gann square fixed', category: 'gann', anchors: 2 }),\n tool(GannFan, { type: 'gannbox_fan', name: 'Gann fan', category: 'gann', anchors: 2 }),\n\n // Patterns\n tool(XabcdPattern, { type: 'xabcd_pattern', name: 'XABCD pattern', category: 'patterns', anchors: 5, style: patternLook('#2962ff', true) }),\n tool(CypherPattern, { type: 'cypher_pattern', name: 'Cypher pattern', category: 'patterns', anchors: 5, style: patternLook('#2962ff', true) }),\n tool(AbcdPattern, { type: 'abcd_pattern', name: 'ABCD pattern', category: 'patterns', anchors: 4, style: patternLook('#089981', false) }),\n tool(ThreeDrivesPattern, { type: 'three_drives', name: 'Three drives pattern', category: 'patterns', anchors: 7, style: patternLook('#673ab7', false) }),\n tool(TrianglePattern, { type: 'triangle_pattern', name: 'Triangle pattern', category: 'patterns', anchors: 4, style: patternLook('#673ab7', true) }),\n tool(HeadAndShoulders, { type: 'head_and_shoulders', name: 'Head and shoulders', category: 'patterns', anchors: 7, style: patternLook('#089981', true) }),\n\n // Elliott waves\n tool(ElliottImpulse, { type: 'elliott_impulse_wave', name: 'Elliott impulse (12345)', category: 'elliott', anchors: 6, style: waveLook('#3d85c6') }),\n tool(ElliottCorrection, { type: 'elliott_correction', name: 'Elliott correction (ABC)', category: 'elliott', anchors: 4, style: waveLook('#3d85c6') }),\n tool(ElliottTriangle, { type: 'elliott_triangle_wave', name: 'Elliott triangle (ABCDE)', category: 'elliott', anchors: 6, style: waveLook('#ff9800') }),\n tool(ElliottDoubleCombo, { type: 'elliott_double_combo', name: 'Elliott double combo (WXY)', category: 'elliott', anchors: 4, style: waveLook('#6aa84f') }),\n tool(ElliottTripleCombo, { type: 'elliott_triple_combo', name: 'Elliott triple combo (WXYXZ)', category: 'elliott', anchors: 6, style: waveLook('#6aa84f') }),\n\n // Cycles\n tool(CyclicLines, { type: 'cyclic_lines', name: 'Cyclic lines', category: 'cycles', anchors: 2, style: { lineColor: '#80ccdb', lineWidth: 2, lineStyle: 'solid' } }),\n tool(TimeCycles, { type: 'time_cycles', name: 'Time cycles', category: 'cycles', anchors: 2, style: { lineColor: '#159980', lineWidth: 2, lineStyle: 'solid', fillColor: '#6aa84f', fillOpacity: 0.5 } }),\n tool(SineLine, { type: 'sine_line', name: 'Sine line', category: 'cycles', anchors: 2, style: { lineColor: '#159980', lineWidth: 2, lineStyle: 'solid' } }),\n\n // Forecasting & positions\n tool(LongPosition, { type: 'long_position', name: 'Long position', category: 'forecasting', anchors: 3, placement: 'instant', style: { lineColor: '#808080', lineWidth: 1, lineStyle: 'solid', textColor: '#ffffff', fontSize: 12 } }),\n tool(ShortPosition, { type: 'short_position', name: 'Short position', category: 'forecasting', anchors: 3, placement: 'instant', style: { lineColor: '#808080', lineWidth: 1, lineStyle: 'solid', textColor: '#ffffff', fontSize: 12 } }),\n tool(Forecast, { type: 'forecast', name: 'Position forecast', category: 'forecasting', anchors: 2, style: { lineColor: '#2962ff', lineWidth: 2, lineStyle: 'solid' } }),\n tool(Sector, { type: 'sector', name: 'Sector', category: 'forecasting', anchors: 3, style: { lineColor: '#9c9c9c', lineWidth: 2, lineStyle: 'solid' } }),\n tool(BarsPattern, { type: 'bars_pattern', name: 'Bars pattern', category: 'forecasting', anchors: 2, capturesBars: true, style: { lineColor: '#2962ff' } }),\n tool(GhostFeed, { type: 'ghost_feed', name: 'Ghost feed', category: 'forecasting', anchors: 2, capturesBars: true }),\n\n // Volume\n tool(AnchoredVwap, { type: 'anchored_vwap', name: 'Anchored VWAP', category: 'volume', anchors: 1, style: { lineColor: '#1e88e5', lineWidth: 1, lineStyle: 'solid', fillColor: '#4caf50', fillOpacity: 0.05 } }),\n tool(FixedRangeVolumeProfile, { type: 'fixed_range_volume_profile', name: 'Fixed range volume profile', category: 'volume', anchors: 2 }),\n tool(AnchoredVolumeProfile, { type: 'anchored_volume_profile', name: 'Anchored volume profile', category: 'volume', anchors: 1 }),\n\n // Content\n tool(ImageNote, { type: 'image', name: 'Image', category: 'content', anchors: 1 }),\n tool(GlyphMark, { type: 'emoji', name: 'Emoji', category: 'content', anchors: 1 }),\n tool(StickerMark, { type: 'sticker', name: 'Sticker', category: 'content', anchors: 1 }),\n tool(IconMark, { type: 'icon', name: 'Icon', category: 'content', anchors: 1, style: { lineColor: '#2962ff' } }),\n\n // Annotation\n tool(TextLabel, {\n type: 'text',\n name: 'Text',\n category: 'annotation',\n anchors: 1,\n hasText: true,\n inlineText: { clickToType: true, whenEmpty: 'deselect' },\n settingsOnDoubleClick: true,\n style: { textColor: '#2962ff', fontSize: 14, fillColor: '#2962ff', fillOpacity: 0.25, lineColor: '#707070' },\n }),\n tool(Note, {\n type: 'note',\n name: 'Note',\n category: 'annotation',\n anchors: 2,\n hasText: true,\n inlineText: { clickToType: true, whenEmpty: 'deselect' },\n settingsOnDoubleClick: true,\n style: { lineColor: '#dbdbdb', textColor: '#dbdbdb', fontSize: 14, fillColor: '#2e2e2e', fillOpacity: 1 },\n }),\n tool(Comment, {\n type: 'comment',\n name: 'Comment',\n category: 'annotation',\n anchors: 1,\n hasText: true,\n inlineText: { clickToType: true, whenEmpty: 'deselect' },\n settingsOnDoubleClick: true,\n style: { textColor: '#ffffff', fontSize: 16, fillColor: '#2962ff', fillOpacity: 1, lineColor: '#2962ff' },\n }),\n tool(Callout, {\n type: 'callout',\n name: 'Callout',\n category: 'annotation',\n anchors: 2,\n hasText: true,\n inlineText: { clickToType: true, whenEmpty: 'commit' },\n settingsOnDoubleClick: true,\n style: { textColor: '#ffffff', fontSize: 14, fillColor: '#0097a7', fillOpacity: 0.7, lineColor: '#0097a7', lineWidth: 2 },\n }),\n tool(PriceLabel, { type: 'price_label', name: 'Price label', category: 'annotation', anchors: 1, settingsOnDoubleClick: true, style: { textColor: '#ffffff', fontSize: 14, bold: true, fillColor: '#2962ff', fillOpacity: 1, lineColor: '#2962ff' } }),\n tool(ArrowMarkUp, { type: 'arrow_up', name: 'Arrow mark up', category: 'annotation', anchors: 1, settingsOnDoubleClick: true, style: { lineColor: '#089981', textColor: '#089981', fontSize: 14 } }),\n tool(ArrowMarkDown, { type: 'arrow_down', name: 'Arrow mark down', category: 'annotation', anchors: 1, settingsOnDoubleClick: true, style: { lineColor: '#cc2f3c', textColor: '#cc2f3c', fontSize: 14 } }),\n tool(ArrowMarker, { type: 'arrow_marker', name: 'Arrow marker', category: 'annotation', anchors: 2, settingsOnDoubleClick: true, style: { lineColor: '#1e53e5', textColor: '#1e53e5', fontSize: 16, bold: true } }),\n tool(FlagMark, { type: 'flag', name: 'Flag mark', category: 'annotation', anchors: 1, settingsOnDoubleClick: true, style: { lineColor: '#2962ff' } }),\n tool(PriceNote, { type: 'price_note', name: 'Price note', category: 'annotation', anchors: 2, settingsOnDoubleClick: true, style: { lineColor: '#2962ff', textColor: '#2962ff', fontSize: 14 } }),\n tool(Pin, {\n type: 'pin',\n name: 'Pin',\n category: 'annotation',\n anchors: 1,\n hasText: true,\n inlineText: { clickToType: true, whenEmpty: 'keep' },\n settingsOnDoubleClick: true,\n style: { lineColor: '#2962ff', textColor: '#dbdbdb', fontSize: 14, fillColor: '#2e2e2e', fillOpacity: 1 },\n }),\n tool(Signpost, {\n type: 'signpost',\n name: 'Signpost',\n category: 'annotation',\n anchors: 1,\n hasText: true,\n inlineText: { clickToType: true, whenEmpty: 'deselect' },\n settingsOnDoubleClick: true,\n previewed: true,\n style: { lineColor: '#2962ff', fontSize: 12 },\n }),\n tool(TableNote, { type: 'table', name: 'Table', category: 'annotation', anchors: 1, settingsOnDoubleClick: true, style: { fillColor: '#0f0f0f', fillOpacity: 1, lineColor: '#575757', textColor: '#dbdbdb', fontSize: 14 } }),\n\n // Brushes & multi-point shapes\n tool(Brush, { type: 'brush', name: 'Brush', category: 'shapes', anchors: 2, placement: 'freehand', style: { lineColor: '#00bcd4', lineWidth: 2, lineStyle: 'solid', fillColor: '#00bcd4', fillOpacity: 0.5 } }),\n tool(Highlighter, { type: 'highlighter', name: 'Highlighter', category: 'shapes', anchors: 2, placement: 'freehand', style: { lineColor: 'rgba(242, 54, 69, 0.2)', lineWidth: 20 } }),\n tool(PathLine, { type: 'path', name: 'Path', category: 'shapes', anchors: 2, placement: 'multipoint', style: { lineColor: '#2962ff', lineWidth: 2, lineStyle: 'solid' } }),\n tool(Polyline, { type: 'polyline', name: 'Polyline', category: 'shapes', anchors: 2, placement: 'multipoint', style: shapeLook('#00bcd4') }),\n\n // Measurement\n tool(PriceRange, { type: 'price_range', name: 'Price range', category: 'measurement', anchors: 2, style: meterLook('rgba(79, 87, 107, 1)') }),\n tool(DateRange, { type: 'date_range', name: 'Date range', category: 'measurement', anchors: 2, style: meterLook('#2962ff') }),\n tool(DatePriceRange, { type: 'date_and_price_range', name: 'Date and price range', category: 'measurement', anchors: 2, style: meterLook('#2962ff') }),\n tool(Measure, { type: 'measure', name: 'Measure', category: 'measurement', anchors: 2 }),\n]\n\n/**\n * The tool registry: type → metadata + factory. The toolbar lists it, placement creates through\n * it, and persistence restores through it.\n */\nexport class ToolRegistry {\n private readonly _tools = new Map<string, ToolDefinition>()\n\n constructor(definitions: readonly ToolDefinition[]) {\n for (const definition of definitions) this._tools.set(definition.type, definition)\n }\n\n register(definition: ToolDefinition): void {\n this._tools.set(definition.type, definition)\n }\n\n get(type: string): ToolDefinition | undefined {\n return this._tools.get(type)\n }\n\n has(type: string): boolean {\n return this._tools.has(type)\n }\n\n all(): ToolDefinition[] {\n return Array.from(this._tools.values())\n }\n\n byCategory(category: ToolCategory): ToolDefinition[] {\n return this.all().filter((t) => t.category === category)\n }\n\n /** New drawing with the tool's default style under the given overrides. */\n create(\n type: string,\n id: string,\n anchors: Anchor[],\n styleOverrides?: Partial<DrawingStyle>,\n ): AnyDrawing | null {\n const definition = this._tools.get(type)\n if (!definition) return null\n return definition.create(id, anchors, { ...definition.style, ...styleOverrides })\n }\n\n /** Whether `restore` rebuilds a serialized drawing: the registry holds its type, its anchors are a\n * list, and its options are not null, since a drawing reads its options as it is built and absent\n * options take the defaults. Nothing else in the state is refused: what an anchor, the style or\n * the props hold is the tool's to read. */\n readable(data: SerializedDrawing): boolean {\n return this._tools.has(data.type) && Array.isArray(data.anchors) && data.options !== null\n }\n\n /** Rebuild a drawing from its serialized form; null for a state that is not `readable`. A save in\n * an earlier format keeps the look it was saved with. */\n restore(data: SerializedDrawing): AnyDrawing | null {\n if (!this.readable(data)) return null\n try {\n const drawing = this._tools.get(data.type)!.create(data.id, data.anchors, data.style, data.options, data.props)\n if (!(data.v >= SERIAL_VERSION)) drawing.holdSavedLook(data)\n return drawing\n } catch {\n return null\n }\n }\n}\n\nexport const toolRegistry = new ToolRegistry(DEFINITIONS)\n","// The persisted drawings STORE codec: one JSON document per surface holding every symbol's\n// serialized drawings — `{ [symbol]: SerializedDrawing[] }`. This codec is the cross-surface\n// compatibility contract: every host that persists drawings through it, the widget among them,\n// reads a store any other wrote, so a saved store survives a move between hosts. Keep it boring\n// and total: parsing tolerates anything (malformed JSON, a\n// non-object root, a junk bucket → the empty store / a dropped bucket, never a throw), and\n// serializing drops empty buckets so a store never accumulates dead symbol keys.\nimport { toolRegistry } from './registry'\nimport type { SerializedDrawing } from './core/types'\nimport type { AnyDrawing } from './core/drawing'\n\n/** Parse a persisted store document. Total: malformed input is an EMPTY store, a non-array or\n * empty bucket is dropped — a corrupt corner of the document never takes the healthy rest down. */\nexport function parseDrawingsStore(raw: string | null | undefined): Record<string, SerializedDrawing[]> {\n try {\n const parsed: unknown = JSON.parse(raw ?? 'null')\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {}\n const out: Record<string, SerializedDrawing[]> = {}\n for (const [sym, bucket] of Object.entries(parsed as Record<string, unknown>)) {\n if (Array.isArray(bucket) && bucket.length > 0) out[sym] = bucket as SerializedDrawing[]\n }\n return out\n } catch {\n return {}\n }\n}\n\n/** Serialize a store document, dropping empty buckets. The inverse of {@link parseDrawingsStore}\n * for every well-formed store: parse(serialize(m)) deep-equals m minus empty buckets. */\nexport function serializeDrawingsStore(map: Record<string, readonly SerializedDrawing[]>): string {\n const out: Record<string, readonly SerializedDrawing[]> = {}\n for (const [sym, bucket] of Object.entries(map)) {\n if (Array.isArray(bucket) && bucket.length > 0) out[sym] = bucket\n }\n return JSON.stringify(out)\n}\n\n/** Rebuild live drawings from one symbol's serialized bucket through the tool registry. A row the\n * registry cannot restore (an unknown type, malformed anchors) is skipped, never a throw — the\n * rest of the bucket still loads. */\nexport function restoreDrawings(list: readonly SerializedDrawing[]): AnyDrawing[] {\n const out: AnyDrawing[] = []\n for (const d of list) {\n const obj = toolRegistry.restore(d)\n if (obj) out.push(obj)\n }\n return out\n}\n","// The public view of the drawing tool catalog.\n//\n// The internal seam registers its 89 tools in one mutable registry whose entries carry a factory\n// that builds a live drawing object. Neither the mutability nor the factory belongs on a public\n// surface: a consumer reads the catalog to build a picker and restores drawings through the codec,\n// and the drawing classes themselves are implementation. So this module publishes a READ-ONLY view\n// over the registry and a `DrawingTool` shape that stops at metadata.\n//\n// There is deliberately no host registration door. A host-authored tool would need the seam's\n// `Drawing` base class, which is not public, and host tool contribution belongs behind the\n// access-policy plane rather than a bare `register`. Publishing a door nobody can walk through is\n// the kind of dead API this sprint deletes.\nimport { toolRegistry, TOOL_CATEGORIES, type ToolCategory, type SerializedDrawing, type IDrawing, type Anchor, type DrawingStyle } from '../internal/drawings/index'\n\nexport { TOOL_CATEGORIES }\n\n/** How a tool gathers the anchors that complete a placement. Absent means the fixed `anchors`\n * count: the host collects exactly that many points. */\nexport type DrawingPlacement = 'freehand' | 'multipoint' | 'instant'\n\n/** One tool in the catalog, as a consumer reads it: identity, grouping, and the facts a picker or\n * a placement loop needs. The factory that builds the drawing stays inside the library. */\nexport interface DrawingTool {\n /** The stable id a serialized drawing carries and a preference is keyed by. */\n readonly type: string\n /** The English fallback name. Localized display goes through `toolName` on the root entrypoint. */\n readonly name: string\n readonly category: ToolCategory\n /** Anchor count that completes placement when `placement` is absent. */\n readonly anchors: number\n /** Style overrides every new drawing of this tool starts with. */\n readonly style?: Partial<DrawingStyle>\n /** The tool renders the viewer's text, so a host opens its text editor once placement completes. */\n readonly hasText?: boolean\n readonly placement?: DrawingPlacement\n /** The tool snapshots the bars between its anchors when placement completes. */\n readonly capturesBars?: boolean\n}\n\nconst readOnly = (definition: {\n type: string\n name: string\n category: ToolCategory\n anchors: number\n style?: Partial<DrawingStyle>\n hasText?: boolean\n placement?: DrawingPlacement\n capturesBars?: boolean\n}): DrawingTool => Object.freeze({ ...definition })\n\n/** The catalog: read access to the registered tools, plus the two constructors persistence needs.\n * Nothing here mutates the catalog. */\nexport interface DrawingToolCatalog {\n /** One tool by type, or undefined when nothing is registered under it. */\n get(type: string): DrawingTool | undefined\n has(type: string): boolean\n /** Every registered tool, in registration order. */\n all(): DrawingTool[]\n /** The tools of one category, in registration order. */\n byCategory(category: ToolCategory): DrawingTool[]\n /** A new drawing of `type` at `anchors`, under the tool's default style and the given overrides.\n * Null when the type is not registered. */\n create(type: string, id: string, anchors: Anchor[], style?: Partial<DrawingStyle>): IDrawing | null\n /** One serialized drawing rebuilt, or null for an unknown type or malformed data. */\n restore(data: SerializedDrawing): IDrawing | null\n}\n\nconst catalog: DrawingToolCatalog = {\n get(type) {\n const definition = toolRegistry.get(type)\n return definition ? readOnly(definition) : undefined\n },\n has(type) {\n return toolRegistry.has(type)\n },\n all() {\n return toolRegistry.all().map(readOnly)\n },\n byCategory(category) {\n return toolRegistry.byCategory(category).map(readOnly)\n },\n create(type, id, anchors, style) {\n return toolRegistry.create(type, id, anchors, style)\n },\n restore(data) {\n return toolRegistry.restore(data)\n },\n}\n\n/** The library's tool catalog. Frozen: the view itself cannot be extended with a registration door\n * at runtime either. */\nexport const drawingTools: DrawingToolCatalog = Object.freeze(catalog)\n","// The drawings STORE codec, as a consumer meets it.\n//\n// One JSON document per surface holding every symbol's serialized drawings. The codec is total in\n// both directions: parsing tolerates anything (malformed JSON, a non-object root, a junk bucket\n// reads as the empty store or a dropped bucket, never a throw) and serializing drops empty buckets\n// so a document never accumulates dead symbol keys. That is what lets a host hand the chart\n// whatever a backend returned without guarding it first.\n//\n// `restoreDrawings` is wrapped rather than re-exported so its result is typed as the public\n// `IDrawing`, not the library's internal drawing class.\nimport {\n parseDrawingsStore as parseStore,\n restoreDrawings as restoreAll,\n serializeDrawingsStore as serializeStore,\n type IDrawing,\n type SerializedDrawing,\n} from '../internal/drawings/index'\n\nexport { parseStore as parseDrawingsStore, serializeStore as serializeDrawingsStore }\n\n/** Rebuild live drawings from one symbol's serialized bucket. A row the catalog cannot restore (an\n * unknown type, malformed anchors) is skipped, never a throw, so the rest of the bucket loads. */\nexport function restoreDrawings(list: readonly SerializedDrawing[]): IDrawing[] {\n return restoreAll(list)\n}\n","// The magnet, as a POLICY over the seam's snap.\n//\n// `magnetSnap` answers one question — which OHLC value does this point pull to — and it is pure\n// geometry. The product decisions around it are separate and belong here: the toolbar's icon toggles\n// between off and weak rather than cycling three states, the menu's two rows are latching (picking\n// the mode that is already on releases the magnet, so there is no Off row to hunt for), and the\n// button's face says strong or plain magnet rather than on or off.\nimport type { MagnetMode } from '../internal/drawings/index'\nimport type { ChartMessageKey } from '../i18n/en'\n\nexport type { MagnetMode }\n\n/** The two modes the menu offers. Off is reached by toggling, never by picking. */\nexport const MAGNET_STRENGTHS: readonly Exclude<MagnetMode, 'off'>[] = ['weak', 'strong']\n\nexport const MAGNET_LABELS: Readonly<Record<Exclude<MagnetMode, 'off'>, ChartMessageKey>> = {\n weak: 'drawing.magnetWeak',\n strong: 'drawing.magnetStrong',\n}\n\n/** The toolbar button. It is a plain on/off switch over the LAST strength the viewer chose, so a\n * viewer who set strong gets strong back when they turn the magnet on again. */\nexport function toggleMagnet(mode: MagnetMode, lastStrength: Exclude<MagnetMode, 'off'> = 'weak'): MagnetMode {\n return mode === 'off' ? lastStrength : 'off'\n}\n\n/** A menu row. Picking the active strength releases the magnet; picking the other switches to it\n * without a trip through off. */\nexport function chooseMagnetStrength(mode: MagnetMode, strength: Exclude<MagnetMode, 'off'>): MagnetMode {\n return mode === strength ? 'off' : strength\n}\n\n/** Whether the magnet is pulling at all. */\nexport const magnetActive = (mode: MagnetMode): boolean => mode !== 'off'\n","// The drawing toolbar's STRUCTURE, with no view attached.\n//\n// The toolbar is one button per tool GROUP; each group opens a flyout whose sections gather the\n// related registry categories under a heading. Categories alone do not give that shape: the arrow\n// marks belong beside the arrow line rather than with the annotations, the brushes lead the shapes,\n// and the image sits under Content rather than with the glyph marks. Those moves\n// are the product's, so they live here as data rather than as conditions inside a component.\n//\n// Everything is catalog KEYS, never words: the toolbar is built once from the registry while the\n// headings it shows follow the interface language.\nimport type { ToolCategory } from '../internal/drawings/index'\nimport type { ChartMessageKey } from '../i18n/en'\nimport { drawingTools, type DrawingTool } from './tools'\n\n/** One heading inside a group's flyout and the tools under it. */\nexport interface DrawingToolbarSection {\n label: ChartMessageKey\n tools: DrawingTool[]\n}\n\n/** One toolbar button: its stable id, its heading, and the sections its flyout shows. */\nexport interface DrawingToolbarGroup {\n id: string\n label: ChartMessageKey\n sections: DrawingToolbarSection[]\n}\n\n/** The arrow marks ride with the plain arrow line in the shapes group's Arrows section. */\nexport const ARROW_TYPES: readonly string[] = ['arrow_marker', 'arrow', 'arrow_up', 'arrow_down']\n/** The brushes lead the shapes group rather than sitting among the geometric shapes. */\nexport const BRUSH_TYPES: readonly string[] = ['brush', 'highlighter']\n/** The glyph marks get a group of their own. */\nexport const GLYPH_TYPES: readonly string[] = ['emoji', 'sticker', 'icon']\n/** The image makes the Content section under Text and notes. */\nexport const CARD_TYPES: readonly string[] = ['image']\n\n/** A section built from whole categories, minus the types that moved elsewhere. */\ninterface CategorySection {\n label: ChartMessageKey\n category: ToolCategory\n exclude?: readonly string[]\n}\n\n/** A section built from an explicit list, in that order. */\ninterface TypeSection {\n label: ChartMessageKey\n types: readonly string[]\n}\n\ntype SectionPlan = CategorySection | TypeSection\n\ninterface GroupPlan {\n id: string\n label: ChartMessageKey\n sections: readonly SectionPlan[]\n}\n\n/** The toolbar's seven groups and their sections, in display order. This is the product decision the\n * registry cannot express: which categories share a button, and where the moved types land. */\nexport const DRAWING_TOOLBAR_PLAN: readonly GroupPlan[] = [\n {\n id: 'trend',\n label: 'drawing.groupTrend',\n sections: [\n { label: 'drawing.sectionLines', category: 'lines', exclude: ['arrow'] },\n { label: 'drawing.sectionChannels', category: 'channels' },\n { label: 'drawing.sectionPitchforks', category: 'pitchforks' },\n ],\n },\n {\n id: 'fib-gann',\n label: 'drawing.groupFibGann',\n sections: [\n { label: 'drawing.sectionFibonacci', category: 'fibonacci' },\n { label: 'drawing.sectionGann', category: 'gann' },\n ],\n },\n {\n id: 'patterns',\n label: 'drawing.groupPatterns',\n sections: [\n { label: 'drawing.sectionChartPatterns', category: 'patterns' },\n { label: 'drawing.sectionElliott', category: 'elliott' },\n { label: 'drawing.sectionCycles', category: 'cycles' },\n ],\n },\n {\n id: 'forecast',\n label: 'drawing.groupForecast',\n sections: [\n { label: 'drawing.sectionForecasting', category: 'forecasting' },\n { label: 'drawing.sectionVolumeBased', category: 'volume' },\n // Measure is a transient tool on the toolbar's action row, not a placeable drawing in a flyout.\n { label: 'drawing.sectionMeasures', category: 'measurement', exclude: ['measure'] },\n ],\n },\n {\n id: 'shapes',\n label: 'drawing.shapes',\n sections: [\n { label: 'drawing.sectionBrushes', types: BRUSH_TYPES },\n { label: 'drawing.sectionArrows', types: ARROW_TYPES },\n { label: 'drawing.shapes', category: 'shapes', exclude: BRUSH_TYPES },\n ],\n },\n {\n id: 'annotation',\n label: 'drawing.textNotes',\n sections: [\n { label: 'drawing.textNotes', category: 'annotation', exclude: ARROW_TYPES },\n { label: 'drawing.sectionContent', types: CARD_TYPES },\n ],\n },\n {\n id: 'glyphs',\n label: 'drawing.groupGlyphs',\n sections: [{ label: 'drawing.sectionGlyphs', types: GLYPH_TYPES }],\n },\n]\n\nconst isTypeSection = (section: SectionPlan): section is TypeSection => 'types' in section\n\n/** Build the toolbar from the tool catalog. An empty section and a group left with none are dropped,\n * so a catalog trimmed by configuration never shows a button that opens on nothing. */\nexport function buildDrawingToolbarGroups(catalog = drawingTools): DrawingToolbarGroup[] {\n const toolsOf = (section: SectionPlan): DrawingTool[] =>\n isTypeSection(section)\n ? section.types.map((type) => catalog.get(type)).filter((tool): tool is DrawingTool => !!tool)\n : catalog.byCategory(section.category).filter((tool) => !(section.exclude ?? []).includes(tool.type))\n\n return DRAWING_TOOLBAR_PLAN.map((group) => ({\n id: group.id,\n label: group.label,\n sections: group.sections.map((section) => ({ label: section.label, tools: toolsOf(section) })).filter((section) => section.tools.length > 0),\n })).filter((group) => group.sections.length > 0)\n}\n\n/** Which group holds a tool, or null when no group shows it. The toolbar highlights that button while\n * the tool is armed. */\nexport function groupOfTool(groups: readonly DrawingToolbarGroup[], type: string | null): string | null {\n if (!type) return null\n return groups.find((group) => group.sections.some((section) => section.tools.some((tool) => tool.type === type)))?.id ?? null\n}\n\n/** Each toolbar button wears its last-picked tool's glyph, so the toolbar keeps that face across\n * reloads. This resolves the face: the remembered tool when the group still shows it, else the\n * group's first tool, else null for a group whose tools carry no glyph. */\nexport function drawingToolbarFaceOf(group: DrawingToolbarGroup, lastTools: Readonly<Record<string, string>>): string | null {\n const remembered = lastTools[group.id]\n if (remembered && group.sections.some((section) => section.tools.some((tool) => tool.type === remembered))) return remembered\n return group.sections[0]?.tools[0]?.type ?? null\n}\n\n/** Remember the tool a group was last used to arm. Returns a NEW record, so a caller stores the\n * result rather than mutating what it was handed. A tool no group shows changes nothing. */\nexport function rememberDrawingToolbarTool(\n groups: readonly DrawingToolbarGroup[],\n lastTools: Readonly<Record<string, string>>,\n type: string,\n): Record<string, string> {\n const group = groupOfTool(groups, type)\n if (!group) return { ...lastTools }\n return { ...lastTools, [group]: type }\n}\n","// The toolbar's eye: ONE switch with a chosen subject, not a row of toggles.\n//\n// The menu picks which layer the eye blanks, the eye blanks it, and the eye keeps wearing that\n// layer's mark until the subject changes. Exactly one subject is ever blanked, so choosing a new\n// one restores the last, and `all` is a subject like the others rather than an extra switch.\n//\n// The chart's own layers are drawings and indicators. Positions, working orders, executions and\n// any other overlay are not the chart's to know: an extension that draws one CONTRIBUTES it as a\n// layer, and it then lists between the chart's own and `all`, which blanks it with them.\nimport type { ChartMessageKey } from '../i18n/en'\n\n/** The layers the eye itself owns, and `all`. */\nexport type BuiltInHideMode = 'drawings' | 'indicators' | 'all'\n\n/** A subject of the eye: one of its own, or the id of a contributed layer. */\nexport type HideMode = string\n\n/** The chart's own layers, ahead of any contributed one. */\nexport const CHART_HIDE_LAYERS: readonly BuiltInHideMode[] = ['drawings', 'indicators']\n\n/** Menu order: the chart's layers, then the contributed ones in contribution order, then all. */\nexport function hideOrder(contributed: readonly string[] = []): readonly HideMode[] {\n return [...CHART_HIDE_LAYERS, ...contributed, 'all']\n}\n\n/** What the eye is pointed at, and whether it is blanking. */\nexport interface HideState {\n mode: HideMode\n on: boolean\n}\n\n/** The eye's resting state: pointed at drawings, blanking nothing. */\nexport const DEFAULT_HIDE_STATE: HideState = { mode: 'drawings', on: false }\n\n/** Each built-in subject's wording in both states. The eye keeps its subject's mark whether or not\n * the layer is blanked, so the toolbar never stops naming what the button acts on. A contributed\n * layer carries its own wording. */\nexport const HIDE_LABELS: Readonly<Record<BuiltInHideMode, { hide: ChartMessageKey; show: ChartMessageKey }>> = {\n drawings: { hide: 'drawing.hideDrawings', show: 'drawing.showDrawings' },\n indicators: { hide: 'drawing.hideIndicators', show: 'drawing.showIndicators' },\n all: { hide: 'drawing.hideAll', show: 'drawing.showAll' },\n}\n\nexport function isBuiltInHideMode(mode: HideMode): mode is BuiltInHideMode {\n return mode === 'drawings' || mode === 'indicators' || mode === 'all'\n}\n\n/** Whether a state blanks one concrete layer. `all` covers every concrete layer; asking whether\n * `all` itself is blanked is asking about the subject, which is `state.mode`. */\nexport function blanks(state: HideState, layer: HideMode): boolean {\n return state.on && (state.mode === layer || state.mode === 'all')\n}\n\n/** The eye itself: blank or restore the current subject. */\nexport function toggleHide(state: HideState): HideState {\n return { mode: state.mode, on: !state.on }\n}\n\n/** The menu picking a subject. Picking the subject that is currently blanked releases it; picking\n * any other subject points the eye there AND blanks it, which is what makes the pick a single\n * gesture rather than a pick followed by a click on the eye. */\nexport function chooseHideMode(state: HideState, mode: HideMode): HideState {\n const active = state.on && state.mode === mode\n return { mode, on: !active }\n}\n\n/** Whether the menu marks a row: only when it is BOTH the chosen subject and currently blanked, so\n * the menu reads as \"this is what the eye is doing\" rather than three separate states. */\nexport function hideRowActive(state: HideState, mode: HideMode): boolean {\n return state.on && state.mode === mode\n}\n","// What the pointer is doing on the chart: the cursor glyph, the two TRANSIENT tools, and whether\n// arming a tool survives the drawing it just made.\n//\n// Measure and Zoom arm from the toolbar exactly like a drawing tool, but nothing they place is kept:\n// the readout lives until the next gesture and the zoom box disappears into the range it set. They\n// are therefore not drawings with a \"temporary\" flag; they are pointer modes with a shape, which is\n// why they are modelled here and not in the tool catalog.\nimport type { ChartMessageKey } from '../i18n/en'\n\n/** The pointer's own glyph over the chart. */\nexport type CursorMode = 'cross' | 'dot' | 'arrow'\n\nexport const CURSOR_MODES: readonly CursorMode[] = ['cross', 'dot', 'arrow']\n\nexport const CURSOR_LABELS: Readonly<Record<CursorMode, ChartMessageKey>> = {\n cross: 'drawing.cursorCross',\n dot: 'drawing.cursorDot',\n arrow: 'drawing.cursorArrow',\n}\n\n/** The armed pointer tools that place nothing permanent. The eraser removes on click and stays\n * armed; measure and zoom draw a two-anchor shape that is discarded once it has done its work. */\nexport type TransientTool = 'eraser' | 'measure' | 'zoom'\n\nexport const TRANSIENT_TOOLS: readonly TransientTool[] = ['eraser', 'measure', 'zoom']\n\nexport const TRANSIENT_LABELS: Readonly<Record<TransientTool, ChartMessageKey>> = {\n eraser: 'drawing.cursorEraser',\n measure: 'drawing.measure',\n zoom: 'drawing.zoomIn',\n}\n\n/** Whether an armed tool id is a transient rather than a catalog tool. `null` (nothing armed) is\n * not a transient. */\nexport function isTransientTool(tool: string | null): tool is TransientTool {\n return tool !== null && (TRANSIENT_TOOLS as readonly string[]).includes(tool)\n}\n\n/** Whether a lingering measure readout or zoom box survives the gesture starting now. It survives\n * only while the same transient stays armed, which is what lets a second measure replace the\n * first without the readout flickering away in between. */\nexport function transientSurvives(tool: string | null): boolean {\n return tool === 'measure' || tool === 'zoom'\n}\n\n/** What stays armed after a placement completes. Freehand tools keep drawing successive strokes;\n * other permanent tools follow Stay in drawing mode. Transients keep their own pointer mode. */\nexport function toolAfterPlacement(tool: string | null, stayInDrawingMode: boolean): string | null {\n if (isTransientTool(tool) || tool === 'brush' || tool === 'highlighter') return tool\n return stayInDrawingMode ? tool : null\n}\n\n/** Which toolbar buttons look armed. The cursor button is the resting state, and it also owns the\n * eraser, so it reads as armed while the eraser is. */\nexport function cursorButtonArmed(tool: string | null): boolean {\n return tool === null || tool === 'eraser'\n}\n","// What a lock refuses, and what the remove menu takes.\n//\n// Two locks act at once and they are not the same thing. The toolbar's LOCK ALL is a mode that\n// suspends the chart: it refuses every edit, the deliberate Delete and Clone included, without\n// changing any drawing. A DRAWING's own lock is a viewer pinning one object down: it refuses a\n// move, a resize, a text edit, the eraser and a modifier-drag duplicate, and lets Delete and Clone\n// act, because a viewer who names a locked drawing and asks for either has asked for exactly that.\n// One predicate holds that matrix, so no surface has to remember which lock answers which edit.\n//\n// The matrix is the library's own and stays inside it. Nothing on the public subpath names it: a\n// host locks and unlocks through the drawing commands and reads what they answer, so the policy\n// can be sharpened here without a consumer having reproduced it.\n//\n// The remove menu is here for the same reason: its counts are a lock question. A sweep spares\n// locked drawings unless the standing preference says otherwise, so what the menu offers to take\n// and what it says it will take are one calculation.\nimport type { ChartMessageKey } from '../i18n/en'\n\n/** Every edit a lock is asked about. `place` and `paste` bring a new drawing and so have no target\n * of their own; the rest act on one.\n *\n * `delete` and `clone` are the DELIBERATE actions a viewer names from the toolbar, the menu or a\n * key. `erase` and `cloneDrag` are the gestures that would do the same thing by accident: the\n * eraser sweeping over a drawing, and a modifier-drag pulling a copy out of it. They are separate\n * edits because a lock answers them differently. */\ntype DrawingEdit = 'select' | 'move' | 'resize' | 'delete' | 'editText' | 'clone' | 'erase' | 'cloneDrag' | 'place' | 'paste'\n\n/** What a drawing's OWN lock refuses: everything that would change the object where it stands, or\n * take it away under a gesture aimed at the chart rather than at it.\n *\n * Selecting is deliberately absent, because a locked drawing stays reachable so it can be\n * inspected, restyled and unlocked, which is the only way back. So are `delete` and `clone`: a\n * viewer who selects a locked drawing and presses Delete, or picks Clone from its menu, has named\n * that one object and asked for exactly this. Refusing there leaves a button that says it acted\n * and did not. */\nconst LOCKED_REFUSES: readonly DrawingEdit[] = ['move', 'resize', 'editText', 'erase', 'cloneDrag']\n\n/** The one lock question every surface asks.\n *\n * Two locks act at once. `allLocked` is the toolbar's mode and it suspends editing across the whole\n * chart, new drawings included, without changing any drawing's own flag. A drawing's `locked`\n * refuses only the edits that would change it. `target` is null for an edit that has no drawing\n * yet. */\nexport function editRefused(edit: DrawingEdit, target: { locked: boolean } | null, allLocked: boolean): boolean {\n if (allLocked) return true\n return !!target && target.locked && LOCKED_REFUSES.includes(edit)\n}\n\n/** Live tally the remove menu counts from. */\nexport interface DrawingCounts {\n total: number\n locked: number\n}\n\n/** How many drawings a sweep would actually take. A locked drawing survives unless the standing\n * \"always remove locked\" preference is on, and the menu's row shows THIS number rather than the\n * total, so the count and the outcome cannot disagree. */\nexport function removableDrawings(counts: DrawingCounts, includeLocked: boolean): number {\n return includeLocked ? counts.total : counts.total - counts.locked\n}\n\n/** One row the remove menu offers. Rows whose count is zero are never built, so the menu never\n * offers a no-op, and the combined row appears only when both kinds are present. */\nexport interface RemoveRow {\n id: 'drawings' | 'indicators' | 'both'\n /** The carrier message; its slots are filled with counted phrases by the surface that renders it. */\n label: ChartMessageKey\n drawings: number\n indicators: number\n}\n\n/** The remove menu's rows for the current tallies. An empty array means there is nothing to take,\n * and the surface says so rather than showing a menu of dead rows. */\nexport function removeRows(counts: DrawingCounts, indicators: number, includeLocked: boolean): RemoveRow[] {\n const drawings = removableDrawings(counts, includeLocked)\n const rows: RemoveRow[] = []\n if (drawings > 0) rows.push({ id: 'drawings', label: 'drawing.removeItems', drawings, indicators: 0 })\n if (indicators > 0) rows.push({ id: 'indicators', label: 'drawing.removeItems', drawings: 0, indicators })\n if (drawings > 0 && indicators > 0) rows.push({ id: 'both', label: 'drawing.removeBoth', drawings, indicators })\n return rows\n}\n","// Favorite drawing tools: the starred list, and the floating bar it fills.\n//\n// The list is ORDERED and the order is the viewer's: a tool joins at the end and keeps its place,\n// because a bar that re-sorts itself is a bar whose buttons move under the pointer. The bar's own\n// visibility and dragged position travel with the list, since all three are the same preference\n// from a viewer's point of view: where my favorites are.\n//\n// The cap exists so the bar cannot grow past the chart it floats over. Starring past the cap is\n// refused rather than silently dropping the oldest: a star that appears to do nothing is a bug\n// report, and a star that quietly evicts another is worse.\n\n/** The most tools the bar holds. */\nexport const MAX_FAVORITE_TOOLS = 24\n\n/** Where the bar sits inside the chart, in CSS pixels from the chart's top left. Null means the\n * bar has never been dragged and takes its default corner. */\nexport interface FavoritesPosition {\n x: number\n y: number\n}\n\n/** The whole favorites preference: what is starred, whether the bar shows, and where it sits. */\nexport interface FavoritesState {\n tools: readonly string[]\n visible: boolean\n position: FavoritesPosition | null\n}\n\nexport const DEFAULT_FAVORITES: FavoritesState = { tools: [], visible: true, position: null }\n\n/** Where favorites live. The chart holds no storage of its own, so a host implements this over\n * whatever it already uses for viewer state, and every surface that stars a tool goes through it.\n * `subscribe` is what keeps the toolbar's stars and the floating bar showing the same list without\n * either one owning the other. */\nexport interface FavoritesPort {\n read(): FavoritesState\n write(state: FavoritesState): void\n /** Hear every change, including one made by another surface. Returns its own unsubscribe. */\n subscribe(listener: () => void): () => void\n}\n\nexport const isFavorite = (state: FavoritesState, type: string): boolean => state.tools.includes(type)\n\n/** Star or unstar a tool. Returns a NEW state; unstarring always succeeds, and starring past the\n * cap returns the state unchanged so the caller can say why nothing happened. */\nexport function toggleFavorite(state: FavoritesState, type: string): FavoritesState {\n if (isFavorite(state, type)) return { ...state, tools: state.tools.filter((t) => t !== type) }\n if (state.tools.length >= MAX_FAVORITE_TOOLS) return state\n return { ...state, tools: [...state.tools, type] }\n}\n\n/** Whether the bar has anything to show. An empty list hides the bar even when it is switched on,\n * because an empty floating strip over a chart is a smudge, not a control. */\nexport const favoritesBarShown = (state: FavoritesState): boolean => state.visible && state.tools.length > 0\n\n/** Drop starred tools the catalog no longer registers, so a list saved against an older\n * configuration does not leave dead buttons on the bar. */\nexport function pruneFavorites(state: FavoritesState, known: (type: string) => boolean): FavoritesState {\n const tools = state.tools.filter(known)\n return tools.length === state.tools.length ? state : { ...state, tools }\n}\n\n/** Keep a dragged bar inside the chart. A chart that shrinks below the bar's last position would\n * otherwise strand it off the edge with no way to drag it back. */\nexport function clampFavoritesPosition(\n position: FavoritesPosition,\n bar: { width: number; height: number },\n chart: { width: number; height: number },\n): FavoritesPosition {\n return {\n x: Math.min(Math.max(0, position.x), Math.max(0, chart.width - bar.width)),\n y: Math.min(Math.max(0, position.y), Math.max(0, chart.height - bar.height)),\n }\n}\n","// Two edit workflows whose rules are decisions rather than geometry: copying a drawing, and\n// typing into one.\n//\n// CLONE AND PASTE both land a copy BESIDE its source rather than under it, because a copy that\n// lands exactly on the original is invisible and the viewer drags what they think is the copy while\n// the original sits underneath. The offset is stated once here, in pixels, and converted to the\n// chart's own time by the caller that has a viewport.\n//\n// TEXT is the workflow where an empty commit means two different things. On a drawing the viewer\n// just placed, empty means \"I changed my mind\" and the placement is undone: there is no such thing\n// as a blank note nobody asked for. On a drawing that already carries text, empty means \"clear it\",\n// and the drawing stays. Getting that backwards leaves a chart littered with empty labels or eats\n// a note somebody meant to blank.\n\n/** How far right a clone or a paste lands from its source, in CSS pixels. */\nexport const CLONE_OFFSET_PX = 24\n\n/** What a text edit is attached to: one drawing, optionally one cell of a table. */\nexport interface TextEditTarget {\n id: string\n /** Set for a table cell; absent when the edit is the drawing's own text. */\n cell?: { row: number; col: number }\n /** The edit opened as part of placing this drawing, rather than on an existing one. */\n fresh: boolean\n}\n\n/** What committing a text edit does. */\nexport type TextCommit =\n | { kind: 'apply'; text: string }\n | { kind: 'apply-cell'; row: number; col: number; text: string }\n /** A fresh placement committed empty: undo the placement, and write no history entry. */\n | { kind: 'discard' }\n\n/** Resolve a commit. Whitespace is trimmed first, so a note of nothing but spaces is a blank one. */\nexport function commitText(target: TextEditTarget, value: string): TextCommit {\n const text = value.trim()\n if (target.cell) return { kind: 'apply-cell', row: target.cell.row, col: target.cell.col, text }\n if (!text && target.fresh) return { kind: 'discard' }\n return { kind: 'apply', text }\n}\n\n/** What cancelling does. A fresh placement is removed, because cancelling the text of a drawing\n * that only exists to carry text cancels the drawing. An existing one keeps what it had. */\nexport function cancelText(target: TextEditTarget): { kind: 'remove' } | { kind: 'keep' } {\n return target.fresh ? { kind: 'remove' } : { kind: 'keep' }\n}\n\n/** Whether placing this tool opens the text editor straight away. */\nexport const opensTextEditor = (tool: { hasText?: boolean } | undefined): boolean => !!tool?.hasText\n","// The theme system's own color arithmetic. Quick Charts adds no dependency for this: parsing a CSS\n// color, compositing a translucent value over its backdrop, and computing a WCAG contrast ratio are\n// the three operations the schema's validation and contrast gates need, and each is a few lines of\n// arithmetic defined by a public specification.\n//\n// The parser accepts the two notations a palette or a host override is written in: hex (`#rgb`,\n// `#rgba`, `#rrggbb`, `#rrggbbaa`) and the `rgb()`/`rgba()` functions in either the comma or the\n// space-with-slash form. It rejects everything else, including named colors and `currentColor`,\n// because a role's value has to be measurable for the contrast gate to mean anything.\n\n/** A parsed color in sRGB. Channels are 0-255 integers; `a` is 0-1. */\nexport interface Rgba {\n r: number\n g: number\n b: number\n a: number\n}\n\nconst HEX = /^#([0-9a-f]{3,8})$/i\nconst FUNCTIONAL = /^rgba?\\(([^)]*)\\)$/i\n\n/** One `rgb()` argument: a 0-255 number, or a percentage of 255. Alpha percentages are handled by\n * the caller, which divides by 100 rather than by 255. */\nfunction channel(token: string): number | null {\n const pct = token.endsWith('%')\n const n = Number(pct ? token.slice(0, -1) : token)\n if (!Number.isFinite(n)) return null\n return pct ? (n / 100) * 255 : n\n}\n\n/** Parse a CSS color string into sRGB channels, or null when the notation is not one a palette may\n * use. A parse failure is a diagnostic, never a throw: an invalid host override is reported and\n * the built-in value is kept. */\nexport function parseCssColor(input: string): Rgba | null {\n const value = input.trim()\n\n const hex = HEX.exec(value)\n if (hex) {\n const digits = hex[1]!\n const expand = (s: string): number => parseInt(s.length === 1 ? s + s : s, 16)\n if (digits.length === 3 || digits.length === 4) {\n const [r, g, b, a] = [digits[0]!, digits[1]!, digits[2]!, digits[3]]\n return { r: expand(r), g: expand(g), b: expand(b), a: a === undefined ? 1 : expand(a) / 255 }\n }\n if (digits.length === 6 || digits.length === 8) {\n const pair = (i: number): number => parseInt(digits.slice(i, i + 2), 16)\n return { r: pair(0), g: pair(2), b: pair(4), a: digits.length === 8 ? pair(6) / 255 : 1 }\n }\n return null\n }\n\n const fn = FUNCTIONAL.exec(value)\n if (!fn) return null\n const body = fn[1]!.trim()\n const [colorPart, alphaPart] = body.includes('/') ? body.split('/') : [body, undefined]\n const parts = colorPart!.trim().split(/[\\s,]+/).filter(Boolean)\n const explicitAlpha = alphaPart?.trim() ?? (parts.length === 4 ? parts[3] : undefined)\n if (parts.length !== 3 && parts.length !== 4) return null\n const rgb = [parts[0]!, parts[1]!, parts[2]!].map(channel)\n if (rgb.some((c) => c === null)) return null\n let a = 1\n if (explicitAlpha !== undefined) {\n const raw = explicitAlpha.endsWith('%') ? Number(explicitAlpha.slice(0, -1)) / 100 : Number(explicitAlpha)\n if (!Number.isFinite(raw)) return null\n a = raw\n }\n const clamp = (n: number, hi: number): number => Math.min(hi, Math.max(0, n))\n return { r: clamp(Math.round(rgb[0]!), 255), g: clamp(Math.round(rgb[1]!), 255), b: clamp(Math.round(rgb[2]!), 255), a: clamp(a, 1) }\n}\n\n/** Flatten a translucent color onto an opaque backdrop, the way a browser composites it. Contrast\n * is only defined between opaque colors, so every ratio starts here. */\nexport function compositeOver(front: Rgba, back: Rgba): Rgba {\n if (front.a >= 1) return { ...front, a: 1 }\n const mix = (f: number, b: number): number => Math.round(f * front.a + b * (1 - front.a))\n return { r: mix(front.r, back.r), g: mix(front.g, back.g), b: mix(front.b, back.b), a: 1 }\n}\n\n/** WCAG 2.2 relative luminance of an opaque sRGB color (WCAG 2.2, relative luminance definition). */\nexport function relativeLuminance(c: Rgba): number {\n const linear = (v: number): number => {\n const s = v / 255\n return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4\n }\n return 0.2126 * linear(c.r) + 0.7152 * linear(c.g) + 0.0722 * linear(c.b)\n}\n\nconst WHITE: Rgba = { r: 255, g: 255, b: 255, a: 1 }\n\n/** The WCAG 2.2 contrast ratio between a foreground and a backdrop, 1 to 21. Contrast is defined on\n * opaque colors, so a translucent backdrop is flattened first, onto `beneath` (the opaque surface\n * it is drawn on) when one is given and onto white otherwise, and the foreground is then composited\n * onto that. */\nexport function contrastRatio(foreground: Rgba, background: Rgba, beneath?: Rgba): number {\n const back = compositeOver(background, beneath ? compositeOver(beneath, WHITE) : WHITE)\n const front = compositeOver(foreground, back)\n const [hi, lo] = [relativeLuminance(front), relativeLuminance(back)].sort((a, b) => b - a) as [number, number]\n return (hi + 0.05) / (lo + 0.05)\n}\n\n/** The contrast ratio between two color strings, or null when any of them is unparseable. `beneath`\n * is the opaque surface a translucent `background` is drawn on. */\nexport function contrastOf(foreground: string, background: string, beneath?: string): number | null {\n const f = parseCssColor(foreground)\n const b = parseCssColor(background)\n const under = beneath === undefined ? undefined : parseCssColor(beneath)\n if (!f || !b || under === null) return null\n return contrastRatio(f, b, under)\n}\n","// The color arithmetic behind every palette and custom editor in the chart: hex and HSV both ways,\n// a typed hex read as a color, the opaque base of a value that carries alpha, and the swatch grid.\n// The grid's ten hues and ten greys are stated as values, because a palette is a chosen set of\n// colors rather than a formula: deriving the hues from angles would move eight of the ten off their\n// pinned values. The six ramps under the hues are stated row by row for the same reason.\n//\n// These are the only literal colors outside `theme/palettes.ts` and the documented series\n// defaults, and they belong here rather than in a theme role: they are the set the chart OFFERS a\n// viewer to choose from, the same in light and dark, and a pick becomes a drawing or indicator\n// property rather than anything a mode re-resolves. `theme/literals.test.ts` names this file as\n// that exemption and pins its count.\nimport { parseCssColor } from '../../../theme/color'\n\nexport interface Hsv {\n /** 0..360 */\n h: number\n /** 0..1 */\n s: number\n /** 0..1 */\n v: number\n}\n\nconst to2 = (n: number): string => Math.round(Math.max(0, Math.min(255, n))).toString(16).padStart(2, '0')\n\n/** `#rrggbb` from channels. */\nexport const rgbToHex = (r: number, g: number, b: number): string => `#${to2(r)}${to2(g)}${to2(b)}`\n\n/** Whether a string is a six-digit hex color, with or without its hash. */\nexport const isHex = (s: string): boolean => /^#?[0-9a-f]{6}$/i.test(s)\n\n/** The `#rrggbb` a typed hex names: three or six hex digits, with or without the hash, a three-digit\n * value standing for each digit doubled. Anything else names no color, and answers null. */\nexport function hexFromText(text: string): string | null {\n const digits = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(text.trim())?.[1]?.toLowerCase()\n if (!digits) return null\n return `#${digits.length === 3 ? [...digits].map((d) => d + d).join('') : digits}`\n}\n\n/** `#rrggbb` to HSV. */\nexport function hexToHsv(hex: string): Hsv {\n const n = parseInt(hex.replace('#', ''), 16)\n const r = ((n >> 16) & 255) / 255\n const g = ((n >> 8) & 255) / 255\n const b = (n & 255) / 255\n const max = Math.max(r, g, b)\n const min = Math.min(r, g, b)\n const d = max - min\n let h = 0\n if (d !== 0) {\n if (max === r) h = ((g - b) / d) % 6\n else if (max === g) h = (b - r) / d + 2\n else h = (r - g) / d + 4\n h *= 60\n if (h < 0) h += 360\n }\n return { h, s: max === 0 ? 0 : d / max, v: max }\n}\n\n/** HSV to `#rrggbb`. */\nexport function hsvToHex(h: number, s: number, v: number): string {\n const c = v * s\n const x = c * (1 - Math.abs(((h / 60) % 2) - 1))\n const m = v - c\n const [r1, g1, b1] = h < 60 ? [c, x, 0] : h < 120 ? [x, c, 0] : h < 180 ? [0, c, x] : h < 240 ? [0, x, c] : h < 300 ? [x, 0, c] : [c, 0, x]\n return rgbToHex((r1 + m) * 255, (g1 + m) * 255, (b1 + m) * 255)\n}\n\n/** The opaque `#rrggbb` of a hex, rgb or rgba value: what a swatch highlight compares against and\n * what the opacity track fades into. A value in a notation the palette does not read passes\n * through untouched, so an unsupported declaration is never rewritten as opaque black. */\nexport function hexOf(color: string): string {\n const value = color.trim()\n const parsed = parseCssColor(value)\n if (parsed) return rgbToHex(parsed.r, parsed.g, parsed.b)\n return value.toLowerCase()\n}\n\n/** The color and alpha of a value the control can edit, or null when the notation is not one it\n * reads. A null keeps the declaration intact until a valid edit replaces it. */\nexport function readColor(color: string | undefined): { hex: string; alpha: number } | null {\n if (!color) return null\n const parsed = parseCssColor(color.trim())\n if (!parsed) return null\n return { hex: rgbToHex(parsed.r, parsed.g, parsed.b), alpha: parsed.a }\n}\n\n/** The grey ramp of the first row, white to black. */\nexport const GREY_RAMP: readonly string[] = ['#ffffff', '#dbdbdb', '#b8b8b8', '#9c9c9c', '#808080', '#636363', '#4a4a4a', '#2e2e2e', '#0f0f0f', '#000000']\n\n/** The ten base hues, the row every ramp below is a lighter or darker reading of. */\nexport const HUE_BASES: readonly string[] = ['#f23645', '#ff9800', '#ffeb3b', '#4caf50', '#089981', '#00bcd4', '#2962ff', '#673ab7', '#9c27b0', '#e91e63']\n\n/** The six ramps under the bases, light to dark. Each is a CHOSEN row rather than a mix of the\n * base above it: a ramp computed by moving every hue the same distance toward white or black\n * goes muddy in the greens and neons in the yellows, so each step is stated as the value it is. */\nexport const HUE_RAMPS: readonly (readonly string[])[] = [\n ['#fccbcd', '#ffe0b2', '#fff9c4', '#c8e6c9', '#ace5dc', '#b2ebf2', '#bbd9fb', '#d1c4e9', '#e1bee7', '#f8bbd0'],\n ['#faa1a4', '#ffcc80', '#fff59d', '#a5d6a7', '#70ccbd', '#80deea', '#90bff9', '#b39ddb', '#ce93d8', '#f48fb1'],\n ['#f77c80', '#ffb74d', '#fff176', '#81c784', '#42bda8', '#4dd0e1', '#5b9cf6', '#9575cd', '#ba68c8', '#f06292'],\n ['#f7525f', '#ffa726', '#ffee58', '#66bb6a', '#22ab94', '#26c6da', '#3179f5', '#7e57c2', '#ab47bc', '#ec407a'],\n ['#b22833', '#f57c00', '#fbc02d', '#388e3c', '#056656', '#0097a7', '#1848cc', '#512da8', '#7b1fa2', '#c2185b'],\n ['#801922', '#e65100', '#f57f17', '#1b5e20', '#00332a', '#006064', '#0c3299', '#311b92', '#4a148c', '#880e4f'],\n]\n\n/** The default the custom editor opens on when the current value is not a color it can read. */\nexport const CUSTOM_COLOR_FALLBACK = '#4c98fb'\n\n/** The palette as the panel lays it out: the greys and the bases stand together as what a viewer\n * reaches for first, and the ramps stand as their own block under a gap. Ten columns throughout,\n * every cell a `#rrggbb`. */\nexport const SWATCH_BLOCKS: readonly (readonly (readonly string[])[])[] = [[GREY_RAMP, HUE_BASES], HUE_RAMPS]\n","// The two DOM questions every surface asks: what in here can take the keyboard, and which way does\n// this element read. Both the chrome and the drawing surfaces need them, and an answer that differs\n// between the two would put a dialog's focus trap and a menu's out of step.\n\n/** Everything inside `root` a hand or the keyboard can reach: not disabled, not taken out of the\n * tab order, not hidden from sight or from a reader, and not inside a hidden group. */\nexport function focusables(root: HTMLElement): HTMLElement[] {\n const nodes = root.querySelectorAll<HTMLElement>('button, [href], input, select, textarea, [tabindex]')\n return [...nodes].filter((n) => !n.hasAttribute('disabled') && n.tabIndex >= 0 && !hiddenWithin(n, root) && n.getAttribute('aria-hidden') !== 'true')\n}\n\n/** Whether the element, or a group between it and `root`, is hidden. */\nfunction hiddenWithin(node: HTMLElement, root: HTMLElement): boolean {\n for (let el: HTMLElement | null = node; el && el !== root; el = el.parentElement) if (el.hidden) return true\n return false\n}\n\n/** Which way the element reads, by the nearest declared direction and the computed one after it.\n * A document without a layout engine answers left to right rather than throwing. */\nexport function isRtl(node: Element): boolean {\n const dir = node.closest<HTMLElement>('[dir]')?.getAttribute('dir') ?? (typeof getComputedStyle === 'function' ? getComputedStyle(node).direction : 'ltr')\n return dir === 'rtl'\n}\n","// Who owns Escape when overlays nest. A menu, a dialog, a drawing popover and the color panel a\n// row expands each bind Escape on the document in the capture phase, so without an order the\n// outermost surface would win and a nested panel could never be dismissed on its own. Every\n// surface that closes on Escape registers here on open and releases on close; only the surface at\n// the top of the stack, the innermost one open, acts on the press. The stack is module state with\n// no public API: it is the package's own overlay contract, not a host capability.\n\nconst stack: object[] = []\n\n/** Register a surface as an Escape owner. Returns the release, which its close runs. */\nexport function pushEscapeOwner(): { token: object; release(): void } {\n const token = {}\n stack.push(token)\n return {\n token,\n release() {\n const at = stack.indexOf(token)\n if (at >= 0) stack.splice(at, 1)\n },\n }\n}\n\n/** Whether this token is the innermost open surface, and therefore the one Escape belongs to. */\nexport function ownsEscape(token: object): boolean {\n return stack.length === 0 || stack[stack.length - 1] === token\n}\n","// The small DOM vocabulary the drawing surfaces share: building elements, keeping presses out of\n// the gesture layers, roving keyboard focus over a row of controls, a menu's own keyboard, a\n// dialog's focus trap and restoration, and placing a floating panel inside the chart root.\n//\n// Nothing here is a component. Each helper does one thing to real elements, so every surface stays\n// readable as the DOM it builds.\n\nimport { focusables, isRtl } from '../controls/dom'\nimport { ownsEscape, pushEscapeOwner } from '../controls/escape'\n\ntype Child = Node | string | null | undefined | false\n\n/** Build an element with attributes and children in one call. `class` is the class list, `text`\n * is the text content, `on` binds listeners, and any other key is an attribute. */\nexport function el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n props: Record<string, string | number | boolean | undefined | Record<string, EventListener>> = {},\n ...children: Child[]\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag)\n for (const [key, value] of Object.entries(props)) {\n if (value === undefined || value === false) continue\n if (typeof value === 'object') {\n if (key === 'on') for (const [type, listener] of Object.entries(value)) node.addEventListener(type, listener)\n } else if (key === 'class') node.className = String(value)\n else if (key === 'text') node.textContent = String(value)\n else if (key === 'html') node.innerHTML = String(value)\n else node.setAttribute(key, value === true ? '' : String(value))\n }\n for (const child of children) {\n if (child === null || child === undefined || child === false) continue\n node.append(child)\n }\n return node\n}\n\n/** A button of the chart's own chrome: never a form submitter, always named. */\nexport function button(props: { class?: string; label: string; title?: string; icon?: Element | null; text?: string; onClick?: (event: MouseEvent) => void; pressed?: boolean; disabled?: boolean }): HTMLButtonElement {\n const b = el('button', {\n type: 'button',\n class: props.class ?? 'qc-button',\n 'aria-label': props.label,\n title: props.title ?? props.label,\n ...(props.text !== undefined ? { text: props.text } : {}),\n ...(props.pressed !== undefined ? { 'aria-pressed': String(props.pressed) } : {}),\n })\n if (props.icon) b.append(props.icon)\n if (props.disabled) b.disabled = true\n if (props.onClick) b.addEventListener('click', props.onClick)\n return b\n}\n\n/** Keep a surface's presses to itself. The chrome layer is inert and each control opts back in, but\n * the drag layers under it bind capture-phase handlers on the gesture box: a surface that lives in\n * the chrome subtree is safe, and this stops the bubble so a press on a panel never reaches a\n * chart handler either. */\nexport function ownPointer(node: HTMLElement): void {\n for (const type of ['pointerdown', 'pointerup', 'pointermove', 'wheel', 'mousedown', 'dblclick'] as const) {\n node.addEventListener(type, (e) => e.stopPropagation())\n }\n}\n\n/** Where a floating bar is PAINTED, given where the viewer left it and the box it floats in now.\n * The remembered position is the viewer's and is never rewritten: a panel that opens beside the\n * chart pushes the bar in, and one that closes lets it back to where it was put. A box with no\n * measured size yet, as before first layout, leaves the position as it was remembered. */\nexport function paintedPosition(position: { x: number; y: number }, bar: HTMLElement, host: HTMLElement): { x: number; y: number } {\n const box = host.getBoundingClientRect()\n if (!(box.width > 0 && box.height > 0)) return position\n return {\n x: Math.min(Math.max(0, position.x), Math.max(0, box.width - bar.offsetWidth)),\n y: Math.min(Math.max(0, position.y), Math.max(0, box.height - bar.offsetHeight)),\n }\n}\n\n/** Re-place a floating bar whenever the box it floats in changes size. Returns the stop. */\nexport function followHostSize(host: HTMLElement, place: () => void): () => void {\n if (typeof ResizeObserver === 'undefined') return () => undefined\n const observer = new ResizeObserver(() => place())\n observer.observe(host)\n return () => observer.disconnect()\n}\n\n/** Follow a pointer until it is released, then stop.\n *\n * The listeners take the CAPTURE phase, and that is the whole point: these floating surfaces call\n * {@link ownPointer} so a press on a control never reaches the chart underneath, which means a\n * move or a release over the surface is stopped on its way out and a bubble listener never hears\n * it. Capture runs before the event reaches the surface at all, so a drag always hears its own\n * end. A cancelled press ends it as a release does, and so does the window losing focus, since a\n * release that lands while another window has the focus never reaches this one. The stop returned\n * ends the drag without reporting a release, for an owner that leaves mid-drag. */\nexport function dragUntilRelease(onMove: (event: PointerEvent) => void, onRelease: () => void): () => void {\n const types = ['pointermove', 'pointerup', 'pointercancel'] as const\n const stop = (): void => {\n for (const type of types) window.removeEventListener(type, handlers[type], true)\n window.removeEventListener('blur', end)\n }\n const end = (): void => {\n stop()\n onRelease()\n }\n const handlers = { pointermove: onMove, pointerup: end, pointercancel: end }\n for (const type of types) window.addEventListener(type, handlers[type], true)\n window.addEventListener('blur', end)\n return stop\n}\n\n/** The elements inside a root that take focus in tab order. */\n/** Roving focus over a set of controls: one tab stop, arrows move between them, Home and End\n * jump. The set is read at every press, so controls that come and go are always current. */\nexport function rovingFocus(root: HTMLElement, items: () => HTMLElement[], orientation: 'horizontal' | 'vertical' | 'both' = 'both'): () => void {\n const sync = (active: HTMLElement | null): void => {\n const list = items()\n for (const item of list) item.tabIndex = item === active ? 0 : -1\n if (!active && list[0]) list[0].tabIndex = 0\n }\n const onKey = (e: KeyboardEvent): void => {\n const list = items()\n if (list.length === 0) return\n const at = list.indexOf(document.activeElement as HTMLElement)\n const next = orientation !== 'vertical' && (e.key === 'ArrowRight' || (orientation === 'horizontal' && e.key === 'ArrowDown'))\n const prev = orientation !== 'vertical' && (e.key === 'ArrowLeft' || (orientation === 'horizontal' && e.key === 'ArrowUp'))\n const down = orientation !== 'horizontal' && e.key === 'ArrowDown'\n const up = orientation !== 'horizontal' && e.key === 'ArrowUp'\n let target: HTMLElement | undefined\n if (next || down) target = list[(at + 1 + list.length) % list.length]\n else if (prev || up) target = list[(at - 1 + list.length) % list.length]\n else if (e.key === 'Home') target = list[0]\n else if (e.key === 'End') target = list[list.length - 1]\n if (!target) return\n e.preventDefault()\n sync(target)\n target.focus()\n }\n const onFocus = (e: FocusEvent): void => {\n const target = e.target as HTMLElement\n if (items().includes(target)) sync(target)\n }\n root.addEventListener('keydown', onKey)\n root.addEventListener('focusin', onFocus)\n sync(null)\n return () => {\n root.removeEventListener('keydown', onKey)\n root.removeEventListener('focusin', onFocus)\n }\n}\n\n/** Trap Tab inside a dialog and restore focus to the opener when it closes. */\nexport function trapFocus(root: HTMLElement): () => void {\n const opener = document.activeElement as HTMLElement | null\n const onKey = (e: KeyboardEvent): void => {\n if (e.key !== 'Tab') return\n const list = focusables(root)\n if (list.length === 0) {\n e.preventDefault()\n return\n }\n const first = list[0]!\n const last = list[list.length - 1]!\n const active = document.activeElement\n if (e.shiftKey && (active === first || !root.contains(active))) {\n e.preventDefault()\n last.focus()\n } else if (!e.shiftKey && (active === last || !root.contains(active))) {\n e.preventDefault()\n first.focus()\n }\n }\n root.addEventListener('keydown', onKey)\n return () => {\n root.removeEventListener('keydown', onKey)\n if (opener && opener.isConnected) opener.focus({ preventScroll: true })\n }\n}\n\n/** Close a floating panel on a press outside it (and outside the control that opened it), or on\n * Escape. Bound on the document in the capture phase, so a press the chart swallows still counts.\n * Escape belongs to the innermost surface open, so a panel raised over this one dismisses first. */\nexport function dismissOnOutside(panel: HTMLElement, anchor: HTMLElement | null, close: () => void, inside?: (target: Node) => boolean): () => void {\n const escape = pushEscapeOwner()\n const onDown = (e: Event): void => {\n const target = e.target as Node\n if (panel.contains(target) || (anchor && anchor.contains(target)) || inside?.(target)) return\n close()\n }\n const onKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && ownsEscape(escape.token)) {\n e.stopPropagation()\n close()\n }\n }\n document.addEventListener('pointerdown', onDown, true)\n document.addEventListener('keydown', onKey, true)\n return () => {\n escape.release()\n document.removeEventListener('pointerdown', onDown, true)\n document.removeEventListener('keydown', onKey, true)\n }\n}\n\n/** Whether the chart reads right to left, from the root's own direction. */\nexport type PanelPlacement = 'side' | 'sidecar' | 'below' | 'below-end' | 'above'\n\n/** Place a floating panel inside the chart's chrome box beside its anchor: to the inline end of\n * the anchor for `side`, below it for `below` (its inline-end edges level for `below-end`), above\n * it with its inline-start edges level for `above`,\n * clamped so the panel stays within the box and flipping to the other side when there is no\n * room. A `sidecar` is a submenu: level with its row and flush to the row's outer edge, with no\n * offset at all, so a pointer travelling from the row into the panel crosses nothing that would\n * close it. Sizes are measured after the panel is in the DOM; the position is the one inline\n * write, because a position is calculated geometry. A panel's height is held to the room from its\n * top to the box's end, so a panel that fits keeps its whole height and only one taller than the\n * room scrolls. */\nexport function placePanel(panel: HTMLElement, anchor: HTMLElement, box: HTMLElement, mode: PanelPlacement, gap = 2): void {\n // The widget's layer on the document body has no box of its own: what stands in it is placed at\n // viewport coordinates and kept within the viewport.\n const b = box.classList.contains('qc-layer')\n ? { left: 0, top: 0, width: document.documentElement.clientWidth, height: document.documentElement.clientHeight }\n : box.getBoundingClientRect()\n const a = anchor.getBoundingClientRect()\n const w = panel.offsetWidth\n const h = panel.offsetHeight\n const rtl = isRtl(box)\n let left: number\n let top: number\n if (mode === 'sidecar') {\n // The list the row belongs to pads its rows, so the row's own edge sits inside the list's. A\n // panel placed on the row's edge would stand that padding over the list it came from.\n const list = (anchor.closest('[role=\"menu\"]') ?? anchor).getBoundingClientRect()\n left = rtl ? list.left - b.left - w : list.right - b.left\n if (rtl ? left < 0 : left + w > b.width) left = rtl ? list.right - b.left : list.left - b.left - w\n top = a.top - b.top\n } else if (mode === 'side') {\n // A side panel opens a pixel clear of its trigger: the gap is the trigger's own edge, not space\n // the pointer has to travel, and the panel's padding carries the rest.\n left = rtl ? a.left - b.left - w - 1 : a.right - b.left + 1\n if (left + w > b.width) left = a.left - b.left - w - 1\n if (left < 0) left = Math.max(0, rtl ? a.right - b.left : 0)\n // Lifted by the panel's OWN top padding, so its first row lands level with the trigger instead\n // of a padding's worth below it.\n const lift = Number.parseFloat(getComputedStyle(panel).paddingTop) || 0\n top = a.top - b.top - lift\n if (top + h > b.height) top = Math.max(0, b.height - h)\n } else if (mode === 'above') {\n left = rtl ? a.right - b.left - w : a.left - b.left\n top = a.top - b.top - h - gap\n if (top < 0) top = a.bottom - b.top + gap\n } else {\n const end = (mode === 'below-end') !== rtl\n left = end ? a.right - b.left - w : a.left - b.left\n left = Math.max(0, Math.min(left, b.width - w))\n top = a.bottom - b.top + gap\n if (top + h > b.height) top = Math.max(0, a.top - b.top - h - gap)\n }\n // The anchor may sit just outside an explicitly selected host (an external drawing toolbar beside\n // its widget). Clamp the result to that host without changing which chart owns the action.\n left = Math.max(0, Math.min(left, b.width - w))\n top = Math.max(0, Math.min(top, b.height - h))\n panel.style.left = `${Math.round(left)}px`\n panel.style.top = `${Math.round(top)}px`\n panel.style.maxHeight = `${Math.max(120, b.height - top)}px`\n}\n\n/** A menu's own keyboard: arrows move over its rows, Home and End jump, Escape is the caller's.\n * Rows are read at every press, so a rebuilt menu needs no rebinding. */\nexport function menuKeys(menu: HTMLElement, rows: () => HTMLElement[]): () => void {\n return rovingFocus(menu, rows, 'vertical')\n}\n\n/** The first row of a menu takes focus when it opens, so the keyboard lands on the choices. */\nexport function focusFirst(root: HTMLElement): void {\n focusables(root)[0]?.focus({ preventScroll: true })\n}\n","// The one color control the chart offers, wherever a color is chosen: the drawing settings bar and\n// the settings dialog's color popover, the chart settings menu, and the indicator plot, level and\n// fill editors. It replaces the native color input, which opened the operating system's own dialog:\n// a different window on every machine, unstyleable, and jarring over a dark chart.\n//\n// The control owns transient interaction state only. It reports a typed edit and is updated and\n// destroyed explicitly by its consumer, which owns persistence, previews, commits and\n// cancellation: the drawing surfaces apply at once, the indicator dialog collects for Apply. A\n// value update repaints in place, so neither a new value nor a theme change remounts an open\n// panel, and a drag on the custom editor's area or strip reports nothing until the color is added,\n// so one drag is one edit rather than one per pointer move.\nimport { button, dragUntilRelease, el, focusFirst } from '../../drawings/dom'\nimport { isRtl } from '../dom'\nimport type { ChartTranslate } from '../../../i18n'\nimport type { ColorMemory } from './memory'\nimport { CUSTOM_COLOR_FALLBACK, GREY_RAMP, hexFromText, hexOf, hexToHsv, hsvToHex, readColor, SWATCH_BLOCKS, type Hsv } from './palette'\n\nconst clamp01 = (n: number): number => Math.min(1, Math.max(0, n))\n\n/** How many mixed colors the palette keeps, newest first: three rows of the grid less the cell the\n * plus stands in. A viewer reaching past thirty is reaching for the mixer, not for a memory. */\nexport const RECENT_COLOR_LIMIT = 29\n\n/** The grid's width in cells, the same for every row the palette lays out. */\nconst COLUMNS = 10\n\n/** The opacity knob's width: it travels the track less its own width, so it never pokes past an end. */\nconst KNOB = 12\n\nexport interface ControlHandle<E extends HTMLElement = HTMLElement> {\n element: E\n destroy(): void\n}\n\nexport interface CustomColorHandle extends ControlHandle {\n /** Repaint from a value the consumer now holds, without rebuilding the editor. */\n update(value: string): void\n}\n\nexport interface OpacityHandle extends ControlHandle {\n /** Repaint from the color and the opacity the consumer now holds. */\n update(color: string, value: number): void\n}\n\nconst percentOf = (value: number): number => Math.round(clamp01(value) * 100)\n\n/** The keys that step a slider, by how far each moves it along its axis. */\nconst STEPS: Readonly<Record<string, number>> = { ArrowRight: 1, ArrowUp: 1, ArrowLeft: -1, ArrowDown: -1, PageUp: 10, PageDown: -10 }\n\n/** The opacity control: a track that fades from nothing into the color over a checked ground, a knob\n * riding it, and beside it the same value as a percent the viewer may type over. Both report the\n * fraction, so which one a hand reaches for is the only difference between them.\n *\n * The track is a slider of its own rather than a native range, so the knob travels exactly the\n * track's width less its own. A press anywhere on the track takes the knob there and follows the\n * pointer until it is released; the arrows step a percent, Page Up and Page Down ten, and Home and\n * End reach the ends. The figure takes digits alone and holds a hundred at most as it is typed, the\n * up and down arrows step it (ten with Shift), and Enter or leaving it puts back the value it\n * stands for. */\nexport function createOpacitySlider(t: ChartTranslate, color: string, value: number, onChange: (v: number) => void): OpacityHandle {\n let percent = percentOf(value)\n let ink = hexOf(color)\n const knob = el('span', { class: 'qc-drawing-opacity-knob' })\n const track = el(\n 'div',\n { class: 'qc-drawing-opacity', role: 'slider', tabindex: '0', 'aria-label': t('drawing.opacity'), 'aria-valuemin': '0', 'aria-valuemax': '100' },\n el('span', { class: 'qc-drawing-opacity-fade' }),\n el('span', { class: 'qc-drawing-opacity-travel' }, knob),\n )\n const figure = el('input', { class: 'qc-drawing-opacity-readout', 'aria-label': t('drawing.opacity'), inputmode: 'numeric', spellcheck: 'false', autocomplete: 'off', maxlength: '3' }) as HTMLInputElement\n\n const paint = (): void => {\n track.style.setProperty('--qcd-swatch', ink)\n knob.style.setProperty('inset-inline-start', `${percent}%`)\n track.setAttribute('aria-valuenow', String(percent))\n track.setAttribute('aria-valuetext', `${percent}%`)\n if (document.activeElement !== figure) figure.value = String(percent)\n }\n const set = (next: number): void => {\n const p = Math.round(Math.min(100, Math.max(0, next)))\n if (p === percent) return\n percent = p\n paint()\n onChange(p / 100)\n }\n\n /** The percent under the pointer: where the knob's middle would stand. */\n const under = (event: PointerEvent): number => {\n const r = track.getBoundingClientRect()\n const along = isRtl(track) ? r.right - event.clientX : event.clientX - r.left\n return ((along - KNOB / 2) / Math.max(1, r.width - KNOB)) * 100\n }\n /** The drag in flight, stopped without a release when the slider goes mid-drag. */\n let stopDrag: (() => void) | null = null\n track.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) return\n event.preventDefault()\n track.focus({ preventScroll: true })\n stopDrag?.()\n track.dataset.qcDragging = 'true'\n set(under(event))\n stopDrag = dragUntilRelease(\n (move) => set(under(move)),\n () => {\n stopDrag = null\n delete track.dataset.qcDragging\n },\n )\n })\n track.addEventListener('keydown', (event) => {\n const step = STEPS[event.key]\n // The knob moves the way the arrow points, so a right-to-left track takes the sideways arrows\n // the other way round.\n if (step !== undefined) set(percent + ((event.key === 'ArrowLeft' || event.key === 'ArrowRight') && isRtl(track) ? -step : step))\n else if (event.key === 'Home') set(0)\n else if (event.key === 'End') set(100)\n else return\n event.preventDefault()\n })\n\n figure.addEventListener('input', () => {\n const digits = figure.value.replace(/\\D/g, '')\n // An emptied field reports nothing until there is a number to report.\n if (digits === '') {\n figure.value = ''\n return\n }\n const typed = Math.min(100, Number(digits))\n figure.value = String(typed)\n set(typed)\n })\n figure.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n figure.value = String(percent)\n return\n }\n const step = event.key === 'ArrowUp' ? 1 : event.key === 'ArrowDown' ? -1 : 0\n if (!step) return\n event.preventDefault()\n set(percent + step * (event.shiftKey ? 10 : 1))\n figure.value = String(percent)\n })\n figure.addEventListener('blur', () => {\n figure.value = String(percent)\n })\n\n const element = el(\n 'div',\n { class: 'qc-drawing-opacity-row' },\n track,\n el('span', { class: 'qc-drawing-opacity-field' }, figure, el('span', { class: 'qc-drawing-opacity-unit', 'aria-hidden': 'true', text: '%' })),\n )\n paint()\n return {\n element,\n update(nextColor, nextValue) {\n ink = hexOf(nextColor)\n // A drag in flight owns the knob; what it reported comes back as this same value.\n if (track.dataset.qcDragging !== 'true') percent = percentOf(nextValue)\n paint()\n },\n destroy() {\n stopDrag?.()\n element.remove()\n },\n }\n}\n\n/** The custom color editor behind the palette's plus: the color it holds in a well, that color's hex\n * in a field the viewer may type over, and Add, on one row; under them a saturation and brightness\n * area beside a hue strip.\n *\n * The field reads three or six hex digits, with or without the hash, and repaints the area and the\n * strip from a value it can read as it is typed. Asked to add anything else, it refuses it in the\n * field's invalid state until the text names a color again. A press on the area or the strip takes\n * its knob there and follows the pointer until it is released, and the arrows step either from the\n * keyboard (Shift steps further). Nothing is reported until Add, or Enter, adds the color. */\nexport function createCustomColorPicker(t: ChartTranslate, initial: string, onAdd: (hex: string) => void): CustomColorHandle {\n const startOf = (value: string): string => readColor(value)?.hex ?? CUSTOM_COLOR_FALLBACK\n let hsv: Hsv = hexToHsv(startOf(initial))\n const held = (): string => hsvToHex(hsv.h, hsv.s, hsv.v)\n\n const well = el('span', { class: 'qc-drawing-custom-swatch' })\n const field = el('input', { class: 'qc-drawing-hex', 'aria-label': t('drawing.hexColor'), spellcheck: 'false', autocomplete: 'off', maxlength: '7' }) as HTMLInputElement\n const add = button({ class: 'qc-button qc-button--primary qc-drawing-add', label: t('drawing.add'), text: t('drawing.add'), onClick: () => commit() })\n const areaKnob = el('span', { class: 'qc-drawing-sv-dot' })\n const area = el('div', { class: 'qc-drawing-sv', role: 'slider', tabindex: '0', 'aria-label': t('drawing.saturationValue') }, areaKnob)\n const stripKnob = el('span', { class: 'qc-drawing-hue-dot' })\n const stripTravel = el('span', { class: 'qc-drawing-hue-travel' }, stripKnob)\n const strip = el('div', { class: 'qc-drawing-hue', role: 'slider', tabindex: '0', 'aria-label': t('drawing.hue'), 'aria-valuemin': '0', 'aria-valuemax': '360', 'aria-orientation': 'vertical' }, stripTravel)\n\n /** Repaint from the color held. A paint that follows typing leaves the field as typed, so a\n * three-digit hex is never spelled out under the viewer's hands. */\n const paint = (typed = false): void => {\n const hex = held()\n well.style.setProperty('--qcd-swatch', hex)\n area.style.setProperty('--qcd-hue', hsvToHex(hsv.h, 1, 1))\n areaKnob.style.setProperty('inset-inline-start', `${hsv.s * 100}%`)\n areaKnob.style.top = `${(1 - hsv.v) * 100}%`\n stripKnob.style.top = `${(hsv.h / 360) * 100}%`\n area.setAttribute('aria-valuetext', hex)\n strip.setAttribute('aria-valuenow', String(Math.round(hsv.h)))\n if (typed) return\n field.value = hex.slice(1)\n field.removeAttribute('aria-invalid')\n }\n const commit = (): void => {\n const hex = hexFromText(field.value)\n if (!hex) {\n field.setAttribute('aria-invalid', 'true')\n field.focus({ preventScroll: true })\n return\n }\n onAdd(hex)\n }\n field.addEventListener('input', () => {\n const hex = hexFromText(field.value)\n if (!hex) return\n field.removeAttribute('aria-invalid')\n hsv = hexToHsv(hex)\n paint(true)\n })\n field.addEventListener('keydown', (event) => {\n if (event.key !== 'Enter') return\n event.preventDefault()\n commit()\n })\n\n /** The drag in flight, stopped without a release when the editor goes mid-drag. */\n let stopDrag: (() => void) | null = null\n /** A press on a slider takes its knob to the pointer and follows it until the release. `frame` is\n * the box the knob travels, which for the strip is its track inside the ends. */\n const follow = (target: HTMLElement, frame: HTMLElement, onPos: (x: number, y: number) => void): void => {\n target.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) return\n event.preventDefault()\n target.focus({ preventScroll: true })\n const at = (e: PointerEvent): void => {\n const r = frame.getBoundingClientRect()\n const x = clamp01((e.clientX - r.left) / (r.width || 1))\n onPos(isRtl(target) ? 1 - x : x, clamp01((e.clientY - r.top) / (r.height || 1)))\n paint()\n }\n stopDrag?.()\n target.dataset.qcDragging = 'true'\n at(event)\n stopDrag = dragUntilRelease(at, () => {\n stopDrag = null\n delete target.dataset.qcDragging\n })\n })\n }\n follow(area, area, (x, y) => {\n hsv = { ...hsv, s: x, v: 1 - y }\n })\n follow(strip, stripTravel, (_x, y) => {\n hsv = { ...hsv, h: y * 360 }\n })\n\n // The area moves saturation sideways and brightness up and down; Home is white and End is black.\n // The strip's arrows move the hue up and down its range, Home and End reach its ends.\n area.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n commit()\n return\n }\n const size = event.shiftKey ? 0.1 : 0.02\n const across = isRtl(area) ? -size : size\n if (event.key === 'ArrowRight') hsv = { ...hsv, s: clamp01(hsv.s + across) }\n else if (event.key === 'ArrowLeft') hsv = { ...hsv, s: clamp01(hsv.s - across) }\n else if (event.key === 'ArrowUp') hsv = { ...hsv, v: clamp01(hsv.v + size) }\n else if (event.key === 'ArrowDown') hsv = { ...hsv, v: clamp01(hsv.v - size) }\n else if (event.key === 'Home') hsv = { ...hsv, s: 0, v: 1 }\n else if (event.key === 'End') hsv = { ...hsv, s: 1, v: 0 }\n else return\n event.preventDefault()\n paint()\n })\n strip.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n commit()\n return\n }\n const size = event.shiftKey ? 20 : 2\n const move = (h: number): void => {\n hsv = { ...hsv, h: Math.min(360, Math.max(0, h)) }\n }\n if (event.key === 'ArrowRight' || event.key === 'ArrowUp') move(hsv.h + size)\n else if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') move(hsv.h - size)\n else if (event.key === 'Home') move(0)\n else if (event.key === 'End') move(360)\n else return\n event.preventDefault()\n paint()\n })\n paint()\n\n const element = el(\n 'div',\n { class: 'qc-drawing-custom' },\n el('div', { class: 'qc-drawing-custom-row' }, well, el('span', { class: 'qc-drawing-hex-wrap' }, el('span', { class: 'qc-drawing-hex-mark', 'aria-hidden': 'true', text: '#' }), field), add),\n el('div', { class: 'qc-drawing-custom-tracks' }, area, strip),\n )\n return {\n element,\n update(value) {\n // A repaint while the field has the keyboard would overwrite what is being typed.\n if (document.activeElement === field) return\n hsv = hexToHsv(startOf(value))\n paint()\n },\n destroy() {\n stopDrag?.()\n element.remove()\n },\n }\n}\n\nexport interface PaletteOptions {\n value: string\n onPick(color: string): void\n /** The colors this viewer has mixed, newest first, and how a new one joins them. The control reads\n * and writes through this rather than holding a store: what a chart remembers is the chart's to\n * keep. Absent, the palette offers no mixed colors and the mixer still applies. */\n recents?: ColorMemory | null\n /** 0..1 opacity; omit to leave the opacity out. A value whose notation carries no alpha the\n * control reads has no opacity, and its declaration stands until a valid edit. */\n opacity?: number\n onOpacity?(value: number): void\n /** Told when the palette turns over to the custom editor and back, for a surface that stands rows\n * of its own beside it and stands them down while the editor shows. */\n onMixing?(mixing: boolean): void\n}\n\nexport interface PaletteHandle extends ControlHandle {\n /** The value, and the opacity where the consumer supplies one, without a rebuild. */\n update(value: string, opacity?: number): void\n}\n\n/** The palette: the offered colors on a ten-wide grid (the greys and the ten hues, then six ramps of\n * them), a rule, the colors this viewer mixed with the plus after them, and the opacity beneath.\n *\n * The grid is one stop for the keyboard: the arrows move along a row and between rows, Home and\n * End reach its first and last cells, and Enter or Space picks. The chosen color is ringed, and a\n * pick moves the ring at once. The plus turns the palette over to the custom editor at the same\n * anchor, and adding a color there brings the palette back with the color remembered and chosen. */\nexport function createColorPalette(t: ChartTranslate, options: PaletteOptions): PaletteHandle {\n let value = options.value\n const memory = options.recents ?? null\n const grid = el('div', { class: 'qc-drawing-swatches', role: 'group', 'aria-label': t('drawing.pickColor') })\n const swatch = (c: string): HTMLButtonElement => {\n const b = el('button', { type: 'button', class: 'qc-drawing-swatch', 'aria-label': t('drawing.colorSwatch', { hex: c }) }) as HTMLButtonElement\n b.addEventListener('click', () => pick(c))\n b.style.setProperty('--qcd-swatch', c)\n b.dataset.qcColor = c\n // The palest cell of all would otherwise have no edge against a light panel.\n if (c === GREY_RAMP[0]) b.dataset.qcPale = 'true'\n return b\n }\n /** A block of cells, ten to a row. A trailing control is laid out as one more cell, so it takes the\n * next free place in the last row rather than standing on a row of its own. */\n const blockOf = (cells: readonly HTMLElement[], className = 'qc-drawing-swatch-block'): HTMLElement => {\n const block = el('div', { class: className })\n for (let i = 0; i < cells.length; i += COLUMNS) block.appendChild(el('div', { class: 'qc-drawing-swatch-row' }, ...cells.slice(i, i + COLUMNS)))\n return block\n }\n for (const rows of SWATCH_BLOCKS) grid.appendChild(blockOf(rows.flat().map(swatch)))\n grid.appendChild(el('div', { class: 'qc-drawing-separator', role: 'presentation' }))\n\n // The plus stands after the mixed colors, in the next free cell: it is one more place a viewer's\n // colors come from, not a control parked under them.\n const plus = button({ class: 'qc-drawing-swatch-plus', label: t('drawing.addCustomColor'), onClick: () => openMixer() })\n let mixed: readonly string[] | null = null\n let mixedBlock = blockOf([plus], 'qc-drawing-swatch-block qc-drawing-swatch-block--mixed')\n grid.appendChild(mixedBlock)\n /** Lay out the mixed colors again when the list has moved, and only then: a block rebuilt under a\n * focused cell would drop the keyboard. */\n const paintMixed = (): void => {\n const list = (memory?.list() ?? []).slice(0, RECENT_COLOR_LIMIT)\n if (mixed && list.length === mixed.length && list.every((c, i) => c === mixed![i])) return\n mixed = list\n const next = blockOf([...list.map(swatch), plus], 'qc-drawing-swatch-block qc-drawing-swatch-block--mixed')\n mixedBlock.replaceWith(next)\n mixedBlock = next\n }\n\n const cells = (): HTMLElement[] => [...grid.querySelectorAll<HTMLElement>('.qc-drawing-swatch, .qc-drawing-swatch-plus')]\n /** The grid's one tab stop: the chosen cell, or the first. */\n const markChosen = (): void => {\n const base = hexOf(value)\n let stop: HTMLElement | null = null\n for (const cell of cells()) {\n const chosen = cell.dataset.qcColor === base\n if (chosen) {\n cell.dataset.qcActive = 'true'\n stop ??= cell\n } else delete cell.dataset.qcActive\n if (cell.dataset.qcColor) cell.setAttribute('aria-pressed', String(chosen))\n }\n const focused = cells().find((cell) => cell === document.activeElement)\n rove(focused ?? stop ?? cells()[0] ?? null)\n }\n const rove = (to: HTMLElement | null): void => {\n for (const cell of cells()) cell.tabIndex = cell === to ? 0 : -1\n }\n const pick = (c: string): void => {\n value = c\n markChosen()\n options.onPick(c)\n }\n grid.addEventListener('focusin', (event) => {\n const cell = event.target as HTMLElement\n if (cells().includes(cell)) rove(cell)\n })\n grid.addEventListener('keydown', (event) => {\n const list = cells()\n const at = list.indexOf(document.activeElement as HTMLElement)\n if (at < 0) return\n const rtl = isRtl(grid)\n let to = at\n if (event.key === 'ArrowRight') to = at + (rtl ? -1 : 1)\n else if (event.key === 'ArrowLeft') to = at + (rtl ? 1 : -1)\n else if (event.key === 'ArrowDown') to = at + COLUMNS < list.length ? at + COLUMNS : Math.floor(at / COLUMNS) < Math.floor((list.length - 1) / COLUMNS) ? list.length - 1 : at\n else if (event.key === 'ArrowUp') to = at - COLUMNS >= 0 ? at - COLUMNS : at\n else if (event.key === 'Home') to = 0\n else if (event.key === 'End') to = list.length - 1\n else return\n event.preventDefault()\n const target = list[Math.min(list.length - 1, Math.max(0, to))]!\n rove(target)\n target.focus({ preventScroll: true })\n })\n\n const element = el('div', { class: 'qc-drawing-palette' }, grid)\n\n let opacity: OpacityHandle | null = null\n let opacityBlock: HTMLElement | null = null\n if (options.opacity !== undefined && options.onOpacity) {\n opacity = createOpacitySlider(t, hexOf(value), options.opacity, options.onOpacity)\n opacityBlock = el('div', { class: 'qc-drawing-palette-opacity' }, el('div', { class: 'qc-drawing-section-title', text: t('drawing.opacity') }), opacity.element)\n element.appendChild(opacityBlock)\n }\n\n // The mixer TURNS THE PALETTE OVER rather than growing it: the grid and the opacity stand down,\n // the editor takes their place at the same anchor, and adding a color brings them back with the\n // new one remembered and chosen.\n let mixer: CustomColorHandle | null = null\n const closeMixer = (): void => {\n if (!mixer) return\n mixer.destroy()\n mixer = null\n grid.hidden = false\n if (opacityBlock) opacityBlock.hidden = false\n options.onMixing?.(false)\n }\n const openMixer = (): void => {\n if (mixer) return\n mixer = createCustomColorPicker(t, value, (hex) => {\n memory?.add(hex)\n closeMixer()\n paintMixed()\n pick(hex)\n ;(mixedBlock.querySelector<HTMLElement>(`[data-qc-color=\"${hex}\"]`) ?? grid.querySelector<HTMLElement>('[data-qc-active=\"true\"]') ?? plus).focus({ preventScroll: true })\n })\n grid.hidden = true\n if (opacityBlock) opacityBlock.hidden = true\n element.appendChild(mixer.element)\n options.onMixing?.(true)\n focusFirst(mixer.element)\n }\n\n paintMixed()\n markChosen()\n return {\n element,\n update(next, nextOpacity) {\n value = next\n paintMixed()\n markChosen()\n mixer?.update(next)\n if (opacity && nextOpacity !== undefined) opacity.update(hexOf(next), nextOpacity)\n },\n destroy() {\n closeMixer()\n opacity?.destroy()\n element.remove()\n },\n }\n}\n\n/** How a consumer mounts the panel the control opens: it places `content` against `anchor`, calls\n * `onClosed` whenever the panel goes for any reason, and returns its own close. The control never\n * mounts an overlay itself, so overlay lifetime stays with the surface that owns it. */\nexport type OpenColorPanel = (anchor: HTMLElement, content: HTMLElement, onClosed: () => void) => () => void\n\nexport interface ColorControlOptions {\n label: string\n value: string\n onPick(color: string): void\n opacity?: number\n onOpacity?(value: number): void\n disabled?: boolean\n /** Close the panel as soon as a swatch is picked. */\n closeOnPick?: boolean\n /** The colors this viewer mixed, offered beside the palette's own. */\n recents?: ColorMemory | null\n openPanel: OpenColorPanel\n}\n\nexport interface ColorControlHandle extends ControlHandle<HTMLButtonElement> {\n update(value: string, opacity?: number): void\n}\n\n/** The color field: a well showing the value over a checkerboard, which opens the palette. */\nexport function createColorControl(t: ChartTranslate, options: ColorControlOptions): ColorControlHandle {\n let value = options.value\n let opacity = options.opacity\n const fill = el('span', { class: 'qc-drawing-well-fill' })\n const well = el('span', { class: 'qc-drawing-well' }, fill)\n const face = (): void => {\n fill.style.setProperty('--qcd-swatch', value)\n fill.style.opacity = String(opacity ?? 1)\n }\n face()\n const element = button({ class: 'qc-field qc-drawing-swatch-button', label: options.label, disabled: options.disabled })\n element.setAttribute('aria-haspopup', 'dialog')\n element.setAttribute('aria-expanded', 'false')\n element.appendChild(well)\n\n let palette: PaletteHandle | null = null\n let close: (() => void) | null = null\n element.addEventListener('click', () => {\n if (close) {\n close()\n return\n }\n const panel = el('div', { class: 'qc-drawing-swatch-panel' })\n palette = createColorPalette(t, {\n value,\n onPick: (c) => {\n options.onPick(c)\n if (options.closeOnPick) close?.()\n },\n recents: options.recents ?? null,\n ...(opacity !== undefined && options.onOpacity ? { opacity, onOpacity: options.onOpacity } : {}),\n })\n panel.appendChild(palette.element)\n close = options.openPanel(element, panel, () => {\n palette?.destroy()\n palette = null\n close = null\n })\n focusFirst(panel)\n })\n\n return {\n element,\n update(next, nextOpacity) {\n value = next\n if (nextOpacity !== undefined) opacity = nextOpacity\n face()\n palette?.update(next, nextOpacity)\n },\n destroy() {\n close?.()\n element.remove()\n },\n }\n}\n","// Every standing choice the drawing workflow remembers, as ONE record.\n//\n// These were seven separate browser keys, each read and written where it happened to be needed,\n// which is why a host had no way to move them anywhere else. They are one preference record now,\n// persisted through the chart's `ChartStorage` port by the widget, so a host that keeps viewer\n// state on a server keeps these there too and a second device opens the chart set up the same way.\n//\n// This is flat viewer state, not an entity: no identity, no revision, no conflict. That is exactly\n// the line `ChartStorage` draws against the revisioned resource contract next door, where saved\n// charts, layouts, drawings and templates live.\nimport type { CursorMode } from './cursorModel'\nimport { CURSOR_MODES } from './cursorModel'\nimport type { MagnetMode } from './magnetModel'\nimport type { FavoritesPosition, FavoritesState } from './favoritesModel'\nimport { DEFAULT_FAVORITES, MAX_FAVORITE_TOOLS } from './favoritesModel'\nimport { RECENT_COLOR_LIMIT } from '../ui/controls/color'\n\n/** The most recent glyph picks the record keeps. */\nconst RECENT_GLYPHS_MAX = 12\n\nexport interface DrawingPreferences {\n /** The pointer's glyph over the chart. */\n cursor: CursorMode\n /** Off, or the strength the magnet pulls with. */\n magnet: MagnetMode\n /** The last strength chosen, so switching the magnet back on restores it rather than falling\n * back to weak. */\n magnetStrength: Exclude<MagnetMode, 'off'>\n /** A placed tool stays armed for the next drawing. */\n stayInDrawingMode: boolean\n /** A sweep takes locked drawings too. */\n removeLocked: boolean\n /** A NEW drawing is replicated to every pane charting the same symbol. */\n syncAcrossPanes: boolean\n /** Each toolbar group's last-picked tool, so the button keeps that face. Keyed by group id. */\n drawingToolbarTools: Readonly<Record<string, string>>\n favorites: FavoritesState\n /** Where the selected drawing's settings bar was dragged to; null takes its default place. */\n settingsBarPosition: FavoritesPosition | null\n /** The glyph picker's most recent picks, newest first. */\n recentGlyphs: readonly string[]\n /** The colours this viewer mixed in the picker, newest first. */\n recentColors: readonly string[]\n}\n\nexport const DEFAULT_DRAWING_PREFERENCES: DrawingPreferences = {\n cursor: 'cross',\n magnet: 'off',\n magnetStrength: 'weak',\n stayInDrawingMode: false,\n removeLocked: false,\n syncAcrossPanes: true,\n drawingToolbarTools: {},\n favorites: DEFAULT_FAVORITES,\n settingsBarPosition: null,\n recentGlyphs: [],\n recentColors: [],\n}\n\nconst positionOf = (value: unknown): FavoritesPosition | null => {\n const p = value as { x?: unknown; y?: unknown } | null | undefined\n return p && typeof p.x === 'number' && typeof p.y === 'number' ? { x: p.x, y: p.y } : null\n}\n\nconst oneOf = <T extends string>(value: unknown, allowed: readonly T[], fallback: T): T =>\n typeof value === 'string' && (allowed as readonly string[]).includes(value) ? (value as T) : fallback\n\nconst bool = (value: unknown, fallback: boolean): boolean => (typeof value === 'boolean' ? value : fallback)\n\nconst stringRecord = (value: unknown): Record<string, string> => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {}\n const out: Record<string, string> = {}\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) if (typeof entry === 'string') out[key] = entry\n return out\n}\n\nconst favoritesOf = (value: unknown): FavoritesState => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return DEFAULT_FAVORITES\n const raw = value as { tools?: unknown; visible?: unknown; position?: unknown }\n const tools = Array.isArray(raw.tools) ? raw.tools.filter((t): t is string => typeof t === 'string').slice(0, MAX_FAVORITE_TOOLS) : []\n const p = raw.position as { x?: unknown; y?: unknown } | null | undefined\n const position = p && typeof p.x === 'number' && typeof p.y === 'number' ? { x: p.x, y: p.y } : null\n return { tools, visible: bool(raw.visible, DEFAULT_FAVORITES.visible), position }\n}\n\n/** Read a stored record. TOTAL: anything unreadable, and any field that is missing or not what it\n * claims, falls back to its default rather than throwing. A preference document is the one piece\n * of state a chart must never fail to open on. */\nexport function parseDrawingPreferences(raw: string | null | undefined): DrawingPreferences {\n let parsed: unknown = null\n try {\n parsed = JSON.parse(raw ?? 'null')\n } catch {\n parsed = null\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return DEFAULT_DRAWING_PREFERENCES\n const value = parsed as Record<string, unknown>\n return {\n cursor: oneOf(value.cursor, CURSOR_MODES, DEFAULT_DRAWING_PREFERENCES.cursor),\n magnet: oneOf(value.magnet, ['off', 'weak', 'strong'] as const, DEFAULT_DRAWING_PREFERENCES.magnet),\n magnetStrength: oneOf(value.magnetStrength, ['weak', 'strong'] as const, DEFAULT_DRAWING_PREFERENCES.magnetStrength),\n stayInDrawingMode: bool(value.stayInDrawingMode, DEFAULT_DRAWING_PREFERENCES.stayInDrawingMode),\n removeLocked: bool(value.removeLocked, DEFAULT_DRAWING_PREFERENCES.removeLocked),\n syncAcrossPanes: bool(value.syncAcrossPanes, DEFAULT_DRAWING_PREFERENCES.syncAcrossPanes),\n drawingToolbarTools: stringRecord(value.drawingToolbarTools),\n favorites: favoritesOf(value.favorites),\n settingsBarPosition: positionOf(value.settingsBarPosition),\n recentGlyphs: Array.isArray(value.recentGlyphs) ? value.recentGlyphs.filter((g): g is string => typeof g === 'string').slice(0, RECENT_GLYPHS_MAX) : [],\n recentColors: Array.isArray(value.recentColors) ? value.recentColors.filter((c): c is string => typeof c === 'string' && /^#[0-9a-f]{6}$/i.test(c)).slice(0, RECENT_COLOR_LIMIT) : [],\n }\n}\n\n/** Write a preference document. */\nexport function serializeDrawingPreferences(preferences: DrawingPreferences): string {\n return JSON.stringify(preferences)\n}\n\n/** The `ChartStorage` key the widget persists the record under, in the widget's own namespace\n * beside its symbol, timeframe and scale keys. */\nexport const DRAWING_PREFERENCES_KEY = 'quickcharts.drawingPrefs.v1'\n","// A tool's saved setup, in two kinds that look alike and behave nothing alike.\n//\n// DEFAULTS — the style and props every NEW drawing of a tool starts with. There is no save\n// control: the last edit to any drawing of that type becomes the default, silently,\n// and editing a default never touches drawings already on a chart. One per tool.\n// TEMPLATES — named snapshots a viewer applies on demand. Several per tool, each with a name the\n// viewer typed.\n//\n// Both ride the revisioned resource contract's `templates('drawing')` store rather than a store of\n// their own, so a host that keeps saved charts on a server keeps these there too, and two tabs\n// editing the same template get a typed conflict instead of a silent overwrite. A drawing template\n// carries its `tool`, which is what makes \"the templates for a trend line\" a filter rather than a\n// separate collection: a trend-line template is meaningless on a rectangle.\nimport type { DrawingStyle } from '../internal/drawings/index'\nimport type { ResourceRef, ResourceStore, TemplateBody, TemplateMeta, WriteOutcome } from '../resources'\n\n/** A saved tool setup: style and props partials layered over the tool's factory defaults. */\nexport interface ToolPreset {\n style?: Partial<DrawingStyle>\n props?: Record<string, unknown>\n}\n\n/** A named preset, as the picker lists it. */\nexport interface ToolTemplate extends ToolPreset {\n ref: ResourceRef\n name: string\n tool: string\n}\n\n/** The reserved template name that holds a tool's silent last-used DEFAULT. It is not shown in the\n * template list and cannot be typed: a name a viewer could collide with would let them overwrite\n * their defaults by saving a template. */\nexport const DEFAULT_PRESET_NAME = ''\n\nconst encode = (preset: ToolPreset): string => JSON.stringify(preset)\n\n/** Total: a body that will not parse reads as an empty preset, so one corrupt row never takes the\n * picker down with it. */\nexport function decodePreset(content: string): ToolPreset {\n try {\n const parsed: unknown = JSON.parse(content)\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {}\n const raw = parsed as { style?: unknown; props?: unknown }\n const preset: ToolPreset = {}\n if (raw.style && typeof raw.style === 'object' && !Array.isArray(raw.style)) preset.style = raw.style as Partial<DrawingStyle>\n if (raw.props && typeof raw.props === 'object' && !Array.isArray(raw.props)) preset.props = raw.props as Record<string, unknown>\n return preset\n } catch {\n return {}\n }\n}\n\n/** Whether a listing row is a tool's silent default rather than a named template. */\nconst isDefaultRow = (row: TemplateMeta): boolean => row.name === DEFAULT_PRESET_NAME\n\n/** How many template bodies `listAll` reads at a time. */\nconst BODY_READS = 6\n\n/** The drawing-template workflow over one `templates('drawing')` store. Every call takes the\n * caller's `AbortSignal`, so a closed dialog or a fast retype abandons in flight and a late answer\n * never lands. */\nexport class DrawingTemplates {\n constructor(private readonly store: ResourceStore<TemplateMeta, TemplateBody>) {}\n\n /** The named templates for one tool, in the store's order. The tool's silent default is not\n * among them. */\n async list(tool: string, signal?: AbortSignal): Promise<TemplateMeta[]> {\n const rows = await this.store.list(signal)\n return rows.filter((row) => row.tool === tool && !isDefaultRow(row))\n }\n\n /** Every row of the family, defaults included, each with its preset. A host that has to answer\n * synchronously (a placement path, a render) reads this once into a cache of its own rather\n * fetched: one read per saved setup, once, against a family a viewer keeps in the dozens. The\n * reads run together, `BODY_READS` at a time, and the answer keeps the store's order. */\n async listAll(signal?: AbortSignal): Promise<ToolTemplate[]> {\n const rows = await this.store.list(signal)\n const found: (Awaited<ReturnType<ResourceStore<TemplateMeta, TemplateBody>['load']>> | undefined)[] = new Array(rows.length)\n let next = 0\n const reader = async (): Promise<void> => {\n while (next < rows.length) {\n const at = next++\n found[at] = await this.store.load(rows[at]!.id, signal)\n }\n }\n await Promise.all(Array.from({ length: Math.min(BODY_READS, rows.length) }, reader))\n const out: ToolTemplate[] = []\n for (const one of found) {\n if (one) out.push({ ...decodePreset(one.body.content), ref: one.ref, name: one.body.name, tool: one.body.tool ?? '' })\n }\n return out\n }\n\n /** One template's preset. Null when the id is gone, which is what a picker shows after another\n * tab deleted it. */\n async load(id: string, signal?: AbortSignal): Promise<{ ref: ResourceRef; template: ToolTemplate } | null> {\n const found = await this.store.load(id, signal)\n if (!found) return null\n const preset = decodePreset(found.body.content)\n return { ref: found.ref, template: { ...preset, ref: found.ref, name: found.body.name, tool: found.body.tool ?? '' } }\n }\n\n /** Save a NAMED template. Saving over a name the tool already has REPLACES that row at the\n * revision the caller read, so two tabs saving the same name conflict rather than one silently\n * winning. A name the tool does not have creates a row. */\n async save(tool: string, name: string, preset: ToolPreset, signal?: AbortSignal): Promise<WriteOutcome<TemplateMeta>> {\n const body: TemplateBody = { name, tool, content: encode(preset) }\n const rows = await this.store.list(signal)\n const existing = rows.find((row) => row.tool === tool && row.name === name)\n if (!existing) return this.store.create(body, signal)\n const found = await this.store.load(existing.id, signal)\n if (!found) return this.store.create(body, signal)\n return this.store.update(found.ref, body, signal)\n }\n\n async remove(ref: ResourceRef, signal?: AbortSignal): Promise<WriteOutcome<void>> {\n return this.store.remove(ref, signal)\n }\n\n /** A tool's silent last-used default, or an empty preset when it has none. */\n async defaultFor(tool: string, signal?: AbortSignal): Promise<ToolPreset> {\n const rows = await this.store.list(signal)\n const row = rows.find((r) => r.tool === tool && isDefaultRow(r))\n if (!row) return {}\n const found = await this.store.load(row.id, signal)\n return found ? decodePreset(found.body.content) : {}\n }\n\n /** Remember a tool's default. This runs after an ordinary style edit, so a CONFLICT here is not\n * worth surfacing: another surface already wrote a newer default and the viewer's next edit\n * writes again. It is returned rather than swallowed so a caller may still look. */\n async rememberDefault(tool: string, preset: ToolPreset, signal?: AbortSignal): Promise<WriteOutcome<TemplateMeta>> {\n return this.save(tool, DEFAULT_PRESET_NAME, preset, signal)\n }\n\n /** Forget a tool's default, so new drawings of it start from the factory style again. */\n async clearDefault(tool: string, signal?: AbortSignal): Promise<WriteOutcome<void> | null> {\n const rows = await this.store.list(signal)\n const row = rows.find((r) => r.tool === tool && isDefaultRow(r))\n if (!row) return null\n const found = await this.store.load(row.id, signal)\n if (!found) return null\n return this.store.remove(found.ref, signal)\n }\n}\n","// Host image intake and an optional replacement for the chart's bundled emoji artwork.\nimport type { ChartMessageKey } from '../i18n/en'\n\n/** What the intake accepts. Stated here because it is a product rule, not a host preference: a\n * drawing is persisted with its picture inline, so an unbounded image is an unbounded saved chart. */\nexport const IMAGE_MAX_BYTES = 2 * 1024 * 1024\n/** Longest edge, in pixels. A larger picture is downscaled rather than refused. */\nexport const IMAGE_MAX_EDGE = 2000\n/** The pictures the intake takes: a JPG, a PNG or a WEBP. A WEBP is stored re-encoded, as a PNG or a\n * JPEG, so a saved chart opens in every browser. */\nexport const IMAGE_TYPES: readonly string[] = ['image/jpeg', 'image/png', 'image/webp']\n/** The `accept` attribute for a file input, kept beside the types it mirrors. */\nexport const IMAGE_ACCEPT = 'image/jpeg,image/png,image/webp'\n\n/** Why an intake failed. A CODE, not a sentence: the host renders it through the catalog, so the\n * reason reaches a viewer in their own language and no English lives in the port. */\nexport type ImageIntakeError = 'wrong-type' | 'too-large' | 'unreadable' | 'undecodable'\n\n/** The catalog message each code says. `too-large` carries the picked file's size in its slot. */\nexport const IMAGE_ERROR_MESSAGES: Readonly<Record<ImageIntakeError, ChartMessageKey>> = {\n 'wrong-type': 'drawing.imageErrorType',\n 'too-large': 'drawing.imageErrorSize',\n unreadable: 'drawing.imageErrorRead',\n undecodable: 'drawing.imageErrorDecode',\n}\n\n/** A picture that is ready to store on a drawing. */\nexport interface ImageAsset {\n /** A PNG or JPEG data URL sized within the caps, whatever the picked file was. */\n dataUrl: string\n width: number\n height: number\n /** The picture was larger than the edge cap and had to be resampled. */\n downscaled: boolean\n}\n\nexport type ImageIntakeResult = { ok: true; asset: ImageAsset } | { ok: false; error: ImageIntakeError; bytes?: number }\n\n/** What the host supplies so the image and glyph tools can draw. */\nexport interface DrawingAssetPort {\n /** Validate a picked file and turn it into a payload within the caps, or say why it cannot be\n * used. The host owns the decode and the resample; `checkImageFile` and `fitScale` below are the\n * library's rules it applies. The stored `dataUrl` is always a PNG or a JPEG, whatever the picked\n * file was, so a saved chart opens everywhere: a WEBP is decoded and re-encoded on a canvas, as a\n * PNG where it has transparency and a JPEG otherwise. */\n intakeImage(file: File): Promise<ImageIntakeResult>\n /** Optional replacement for the bundled Twemoji artwork. Artwork for one emoji or sticker glyph, as a URL the canvas can draw, or null to fall back to\n * drawing the glyph as text. Icon marks always stay text: their ink is tinted by the stroke\n * color, which artwork cannot carry. */\n glyphSource?(glyph: string): string | null\n}\n\n/** Type and size gate, pure so it needs no DOM and no real file. */\nexport function checkImageFile(file: { type: string; size: number }): { error: ImageIntakeError; bytes?: number } | null {\n if (!IMAGE_TYPES.includes(file.type)) return { error: 'wrong-type' }\n if (file.size > IMAGE_MAX_BYTES) return { error: 'too-large', bytes: file.size }\n return null\n}\n\n/** The scale that brings a picture inside the edge cap. 1 when it already fits, so a small picture\n * is never resampled and never loses a pixel it did not have to. */\nexport function fitScale(width: number, height: number, maxEdge = IMAGE_MAX_EDGE): number {\n const longest = Math.max(width, height)\n return longest > maxEdge ? maxEdge / longest : 1\n}\n\n/** The pixel size a picture is resampled to. */\nexport function fittedSize(width: number, height: number, maxEdge = IMAGE_MAX_EDGE): { width: number; height: number } {\n const scale = fitScale(width, height, maxEdge)\n return { width: Math.max(1, Math.round(width * scale)), height: Math.max(1, Math.round(height * scale)) }\n}\n","// Per-tool SETTINGS CAPABILITY sets: one place to answer \"does this tool have a fill?\", \"does it\n// have a stroke at all?\", and \"which of its props deserve a control?\".\n//\n// These are facts about what a tool paints, so they belong beside the tools rather than inside the\n// surface that renders their controls. A settings dialog and a floating bar reading the same sets\n// cannot disagree about whether a tool has a background, and a tool that gains a fill gains its\n// control everywhere at once.\n\n/** Tools whose paint has a fillable region — they get the Background color/opacity controls. */\nexport const FILLABLE: ReadonlySet<string> = new Set([\n 'rectangle',\n 'rotated_rectangle',\n 'ellipse',\n 'circle',\n 'triangle',\n 'polyline',\n 'parallel_channel',\n 'flat_top_bottom',\n 'disjoint_channel',\n 'price_range',\n 'date_range',\n 'date_and_price_range',\n 'xabcd_pattern',\n 'cypher_pattern',\n 'triangle_pattern',\n 'head_and_shoulders',\n 'time_cycles',\n 'comment',\n 'callout',\n 'price_label',\n 'table',\n 'arc',\n 'brush',\n 'curve',\n 'double_curve',\n])\n\n/** No stroke channel at all: the glyph and image marks, the ghost feed and the volume profiles,\n * which carry their own colors, the positions, and the text tool, whose ink is its words. No\n * color, width or line style control. */\nexport const NO_STROKE: ReadonlySet<string> = new Set([\n 'emoji',\n 'sticker',\n 'image',\n 'ghost_feed',\n 'fixed_range_volume_profile',\n 'anchored_volume_profile',\n 'text',\n 'long_position',\n 'short_position',\n])\n\n/** Stroke color applies but width/line-style don't (sized by their own geometry or fixed ink,\n * or the color paints a border whose thickness is fixed). */\nexport const NO_LINE_DECOR: ReadonlySet<string> = new Set([\n 'arrow_marker',\n 'bars_pattern',\n 'icon',\n 'arrow_up',\n 'arrow_down',\n 'price_label',\n 'comment',\n 'note',\n 'table',\n 'signpost',\n])\n\n/** Tools with no Style tab: the text tools whose words are the whole drawing, the words' look, their\n * background and their border on their Text tab, and the emoji and the sticker, whose only setting\n * is their visibility. */\nexport const NO_STYLE_TAB: ReadonlySet<string> = new Set(['text', 'comment', 'callout', 'emoji', 'sticker'])\n\n/** Tools that write words of their own and carry none of the viewer's: a plan's target, P&L and\n * stop tags. Their bar offers the text colour, because those words take it, and nothing that\n * belongs to a free label: no font size, and no invitation on the canvas to add text. */\nexport const OWN_WORDS_TOOLS: ReadonlySet<string> = new Set(['long_position', 'short_position'])\n\n/** Tools whose floating bar carries a font-size control (their ink is type, not lines). */\nexport const FONT_TOOLS: ReadonlySet<string> = new Set(['text', 'note', 'comment', 'callout', 'table', 'price_label', 'signpost'])\n\n/** The chart patterns, whose letters stand in pills: their Style page carries a Label row for the\n * letters' color, size, weight and slant. */\nexport const LABELED_PATTERNS: ReadonlySet<string> = new Set(['xabcd_pattern', 'cypher_pattern', 'abcd_pattern', 'triangle_pattern', 'head_and_shoulders', 'three_drives'])\n\nconst SAVED_LOOK = ['savedLook'] as const\nconst FIB_LABELS = ['bandsByPane', 'wordsInLabels', 'labelsAtStart'] as const\nconst FORK = ['shadedBands'] as const\nconst CHANNEL = ['textAtStart'] as const\nconst PATTERN = ['pillRadius'] as const\nconst WAVE = ['pillRadius', 'labelPills'] as const\nconst PROFILE = ['outline'] as const\nconst METER = ['labelTextStyle'] as const\n\n/** The props that keep a version 2 save's look as it was saved, where its tool's pages offer no\n * control for it. They are the drawing's own: its tool's remembered default and the templates\n * saved from it leave them out. */\nexport const SAVED_LOOK_PROPS: Record<string, readonly string[]> = {\n regression_trend: ['bodyColor'],\n parallel_channel: CHANNEL,\n flat_top_bottom: CHANNEL,\n disjoint_channel: CHANNEL,\n fib_retracement: FIB_LABELS,\n fib_trend_ext: FIB_LABELS,\n fib_channel: FIB_LABELS,\n fib_circles: ['roundPercents'],\n fib_speed_resist_fan: SAVED_LOOK,\n pitchfan: SAVED_LOOK,\n pitchfork: FORK,\n schiff_pitchfork: FORK,\n schiff_pitchfork_modified: FORK,\n inside_pitchfork: FORK,\n gannbox: ['tint'],\n gannbox_square: SAVED_LOOK,\n gannbox_fixed: SAVED_LOOK,\n xabcd_pattern: PATTERN,\n cypher_pattern: PATTERN,\n abcd_pattern: PATTERN,\n triangle_pattern: PATTERN,\n head_and_shoulders: PATTERN,\n three_drives: PATTERN,\n elliott_impulse_wave: WAVE,\n elliott_correction: WAVE,\n elliott_triangle_wave: WAVE,\n elliott_double_combo: WAVE,\n elliott_triple_combo: WAVE,\n bars_pattern: ['candles'],\n fixed_range_volume_profile: PROFILE,\n anchored_volume_profile: PROFILE,\n trend_line: SAVED_LOOK,\n ray: SAVED_LOOK,\n info_line: SAVED_LOOK,\n extended: SAVED_LOOK,\n trend_angle: SAVED_LOOK,\n arrow: SAVED_LOOK,\n callout: ['borderWidth', ...SAVED_LOOK],\n price_label: SAVED_LOOK,\n pin: SAVED_LOOK,\n flag: SAVED_LOOK,\n arrow_up: SAVED_LOOK,\n arrow_down: SAVED_LOOK,\n arrow_marker: SAVED_LOOK,\n table: SAVED_LOOK,\n text: SAVED_LOOK,\n comment: SAVED_LOOK,\n note: SAVED_LOOK,\n price_note: SAVED_LOOK,\n signpost: SAVED_LOOK,\n price_range: METER,\n date_range: METER,\n date_and_price_range: ['extendLeft', 'extendRight', ...METER],\n}\n\n/** Prop keys a tool carries that its pages do not set: a trend angle's shared line keys and stats,\n * which it draws only as a save carries them; a table's cells and header band, which stand on the\n * chart and in a save; and the props that keep a version 2 save's look as it was saved. */\nexport const INERT_PROPS: Record<string, readonly string[]> = {\n ...SAVED_LOOK_PROPS,\n trend_angle: ['text', 'leftEnd', 'rightEnd', 'showDateTimeRange', 'showDistance', 'showAngle', ...SAVED_LOOK],\n table: ['cells', 'headerRow', ...SAVED_LOOK],\n}\n\n/** Tools whose points are drawn from their shape rather than typed: a turned box, an arc, an\n * ellipse, a polygon of any count of points, a fib wedge, a flat top/bottom, a disjoint channel, a\n * sector, a bars pattern, a position, an anchored VWAP, a text, a table, the strokes, the glyphs\n * and an image have no Coordinates tab: a position's points are its entry, target and stop prices\n * on its Inputs page. */\nexport const NO_COORDINATES_TAB: ReadonlySet<string> = new Set(['rotated_rectangle', 'arc', 'polyline', 'ellipse', 'fib_wedge', 'flat_top_bottom', 'disjoint_channel', 'sector', 'bars_pattern', 'long_position', 'short_position', 'anchored_vwap', 'text', 'table', 'brush', 'highlighter', 'path', 'emoji', 'sticker', 'icon', 'image'])\n\n/** Tools that span every bar at one price: the Coordinates tab hides the bar field. */\nexport const PRICE_ONLY_COORDS: ReadonlySet<string> = new Set(['horizontal_line'])\n\n/** Tools whose anchors are time-only — the Coordinates tab hides the price field. */\nexport const BAR_ONLY_COORDS: ReadonlySet<string> = new Set([\n 'vertical_line',\n 'regression_trend',\n 'fixed_range_volume_profile',\n 'anchored_volume_profile',\n])\n\n/** Width applies but the stroke is always solid — no line-style control (marker ink). */\n/** A colour a tool paints that is none of the three every drawing may have. A plan paints two\n * zones, and a reader tells them apart by what the glyph says as much as by where it sits, so a\n * channel names its own mark. The pick writes the tool's own PROP, not the shared style. */\nexport interface ToolColorChannel {\n /** The prop the pick writes. */\n prop: string\n /** The mark the button wears, from the settings bar's own glyph set. */\n icon: 'pencil16' | 'bucket' | 'textTee'\n /** The catalog key naming it. */\n label: string\n}\n\n/** The extra colours a tool offers, in the order its bar shows them. A tool absent here offers\n * only the stroke, fill and text every drawing may carry. */\nexport const TOOL_COLOR_CHANNELS: Record<string, readonly ToolColorChannel[]> = {\n long_position: [\n { prop: 'profitColor', icon: 'bucket', label: 'drawing.profitColor' },\n { prop: 'stopColor', icon: 'bucket', label: 'drawing.stopColor' },\n ],\n short_position: [\n { prop: 'profitColor', icon: 'bucket', label: 'drawing.profitColor' },\n { prop: 'stopColor', icon: 'bucket', label: 'drawing.stopColor' },\n ],\n}\n\nexport const NO_DASH: ReadonlySet<string> = new Set(['highlighter', 'brush', 'price_range', 'date_range', 'date_and_price_range', 'callout'])\n\n/** Prop keys that belong on a separate Inputs tab: what a drawing computes with, kept apart from\n * how it looks.\n * A tool listed here gets the Inputs tab; unlisted props stay on Style. */\nexport const INPUT_PROPS: Record<string, readonly string[]> = {\n fixed_range_volume_profile: ['rowsLayout', 'rowSize', 'volume', 'valueAreaVolume', 'extendRight'],\n anchored_volume_profile: ['rowsLayout', 'rowSize', 'volume', 'valueAreaVolume'],\n ghost_feed: ['averageHL', 'variance'],\n long_position: ['accountSize', 'risk', 'riskDisplay', 'lotSize', 'leverage', 'qtyPrecision'],\n short_position: ['accountSize', 'risk', 'riskDisplay', 'lotSize', 'leverage', 'qtyPrecision'],\n regression_trend: ['upperDeviation', 'lowerDeviation', 'useUpper', 'useLower', 'source'],\n anchored_vwap: ['source', 'bandsMode', 'bandMultipliers', 'bandsOn'],\n}\n"],"mappings":";AAsBO,IAAM,qBAA0C;AAAA,EACrD,OAAO;AAAA,EACP,SAAS,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG;AAAA,EACrC,SAAS,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG;AAAA,EACrC,OAAO,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG;AAAA,EACnC,MAAM,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,IAAI;AAAA,EACnC,OAAO,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG;AAAA,EACnC,QAAQ,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG;AACtC;AAOA,IAAM,gBAAgB,CAAC,WAAW,WAAW,SAAS,QAAQ,SAAS,QAAQ;AAC/E,IAAM,aAA6D;AAAA,EACjE,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AACV;AAQO,SAAS,iBAAiB,MAAwB,KAA4C;AACnG,QAAM,MAA2B;AAAA,IAC/B,OAAO;AAAA,IACP,SAAS,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG;AAAA,IACrC,SAAS,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG;AAAA,IACrC,OAAO,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG;AAAA,IACnC,MAAM,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,IAAI;AAAA,IACnC,OAAO,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG;AAAA,IACnC,QAAQ,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG;AAAA,EACtC;AACA,MAAI,SAAS,SAAS,CAAC,IAAK,QAAO;AACnC,QAAM,QAA2B,CAAC,SAAS,GAAG,aAAa;AAC3D,QAAM,KAAK,MAAM,QAAQ,IAAI,MAAM;AACnC,QAAM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,KAAK,CAAC;AAC5C,QAAM,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC;AAC5C,QAAM,MAAM;AAGZ,MAAI,QAAQ,IAAI,WAAW,WAAW,SAAS;AAC/C,aAAW,UAAU,eAAe;AAClC,UAAM,IAAI,MAAM,QAAQ,MAAM;AAC9B,QAAI,MAAM,IAAI;AACZ,UAAI,MAAM,IACR,SAAS,sBACL,EAAE,IAAI,MAAM,MAAM,IAAI,IAAI,WAAW,MAAM,EAAE,IAC7C,SAAS,sBACP,EAAE,IAAI,MAAM,MAAM,GAAG,IAAI,GAAG,IAC5B,EAAE,IAAI,MAAM,MAAM,IAAI,IAAI,GAAG;AAAA,IACvC,WAAW,IAAI,IAAI;AACjB,UAAI,MAAM,IAAI,EAAE,IAAI,SAAS,qBAAqB,MAAM,GAAG,IAAI,WAAW,MAAM,EAAE;AAAA,IACpF,OAAO;AACL,UAAI,MAAM,IAAI,EAAE,IAAI,SAAS,qBAAqB,MAAM,GAAG,IAAI,WAAW,MAAM,EAAE;AAAA,IACpF;AAAA,EACF;AACA,SAAO;AACT;AASO,SAAS,sBAAsB,IAA8B;AAClE,QAAM,QAAQ,0BAA0B,KAAK,GAAG,KAAK,EAAE,YAAY,CAAC;AACpE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,QAAQ,OAAO,MAAM,CAAC,CAAC;AAC3B,QAAM,OAAO,MAAM,CAAC;AACpB,MAAI,SAAS,IAAK,QAAO,EAAE,QAAQ,SAAS,MAAM;AAClD,MAAI,SAAS,KAAK;AAChB,QAAI,QAAQ,GAAI,QAAO,EAAE,QAAQ,WAAW,MAAM;AAClD,aAAS;AACT,WAAO,QAAQ,KAAK,EAAE,QAAQ,WAAW,MAAM,IAAI,EAAE,QAAQ,SAAS,OAAO,QAAQ,GAAG;AAAA,EAC1F;AACA,MAAI,SAAS,KAAK;AAChB,WAAO,QAAQ,KAAK,EAAE,QAAQ,WAAW,MAAM,IAAI,EAAE,QAAQ,SAAS,OAAO,QAAQ,GAAG;AAAA,EAC1F;AACA,MAAI,SAAS,IAAK,QAAO,EAAE,QAAQ,SAAS,MAAM;AAClD,MAAI,SAAS,IAAK,QAAO,EAAE,QAAQ,QAAQ,MAAM;AACjD,MAAI,SAAS,IAAK,QAAO,EAAE,QAAQ,SAAS,MAAM;AAClD,SAAO,EAAE,QAAQ,UAAU,MAAM;AACnC;AAGO,SAAS,oBAAoB,SAA6D;AAC/F,SAAO;AAAA,IACL,OAAO,SAAS,SAAS,mBAAmB;AAAA,IAC5C,SAAS,EAAE,GAAG,mBAAmB,SAAS,GAAG,SAAS,QAAQ;AAAA,IAC9D,SAAS,EAAE,GAAG,mBAAmB,SAAS,GAAG,SAAS,QAAQ;AAAA,IAC9D,OAAO,EAAE,GAAG,mBAAmB,OAAO,GAAG,SAAS,MAAM;AAAA,IACxD,MAAM,EAAE,GAAG,mBAAmB,MAAM,GAAG,SAAS,KAAK;AAAA,IACrD,OAAO,EAAE,GAAG,mBAAmB,OAAO,GAAG,SAAS,MAAM;AAAA,IACxD,QAAQ,EAAE,GAAG,mBAAmB,QAAQ,GAAG,SAAS,OAAO;AAAA,EAC7D;AACF;AAGO,SAAS,UAAU,YAAiC,SAAoC;AAC7F,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,QAAQ,WAAW,QAAS,QAAO,WAAW;AAClD,QAAM,QAAQ,WAAW,QAAQ,MAAM;AACvC,SAAO,MAAM,MAAM,QAAQ,SAAS,MAAM,QAAQ,QAAQ,SAAS,MAAM;AAC3E;;;ACrFO,IAAM,gBAA8B;AAAA,EACzC,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,aAAa;AAAA,EACb,WAAW;AAAA,EACX,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AACV;AAaO,IAAM,kBAAkC;AAAA,EAC7C,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AACd;AAGO,IAAM,iBAAiB;;;ACvE9B,SAAS,sBAAsB;;;ACkDxB,SAAS,gBAAgB,MAAc,SAAmC,YAA2B,MAAiB;AAC3H,QAAM,QAAoB,CAAC;AAC3B,MAAI,OAAO;AACX,aAAW,aAAa,KAAK,MAAM,IAAI,GAAG;AACxC,QAAI,cAAc,QAAQ,EAAE,YAAY,GAAI,OAAM,KAAK,KAAK,MAAM,MAAM,OAAO,UAAU,QAAQ,OAAO,CAAC;AAAA,QACpG,eAAc,MAAM,MAAM,OAAO,UAAU,QAAQ,SAAS,WAAW,KAAK;AACjF,YAAQ,UAAU,SAAS;AAAA,EAC7B;AACA,SAAO,EAAE,OAAO,OAAO,MAAM,OAAO,CAAC,QAAQ,MAAM,KAAK,IAAI,QAAQ,EAAE,KAAK,GAAG,CAAC,EAAE;AACnF;AAEA,SAAS,KAAK,MAAc,OAAe,KAAa,SAA6C;AACnG,QAAM,QAAQ,KAAK,MAAM,OAAO,GAAG;AACnC,SAAO,EAAE,MAAM,OAAO,OAAO,KAAK,OAAO,QAAQ,KAAK,EAAE;AAC1D;AAEA,SAAS,cAAc,MAAc,OAAe,KAAa,SAAmC,OAAe,KAAuB;AACxI,MAAI,YAAY;AAChB,MAAI,UAAU;AACd,MAAI,KAAK;AACT,SAAO,MAAM,KAAK;AAChB,UAAM,QAAQ,KAAK,QAAQ,KAAK,EAAE;AAClC,UAAM,UAAU,UAAU,MAAM,QAAQ,MAAM,MAAM;AACpD,QAAI,QAAQ,KAAK,MAAM,WAAW,OAAO,CAAC,KAAK,OAAO;AACpD,gBAAU;AAAA,IACZ,OAAO;AACL,UAAI,UAAU,WAAW;AACvB,YAAI,KAAK,KAAK,MAAM,WAAW,SAAS,OAAO,CAAC;AAChD,oBAAY;AAAA,MACd;AAEA,aAAO,UAAU,YAAY,KAAK,QAAQ,KAAK,MAAM,WAAW,OAAO,CAAC,IAAI,OAAO;AACjF,YAAI,MAAM,UAAU;AACpB,eAAO,MAAM,YAAY,KAAK,QAAQ,KAAK,MAAM,WAAW,GAAG,CAAC,IAAI,MAAO;AAC3E,YAAI,KAAK,KAAK,MAAM,WAAW,KAAK,OAAO,CAAC;AAC5C,oBAAY;AAAA,MACd;AACA,gBAAU;AAAA,IACZ;AACA,SAAK,UAAU;AAAA,EACjB;AACA,MAAI,KAAK,KAAK,MAAM,WAAW,SAAS,OAAO,CAAC;AAClD;AAIO,SAAS,OAAO,OAAkB,QAAwB;AAC/D,WAAS,IAAI,GAAG,IAAI,MAAM,MAAM,QAAQ,KAAK;AAC3C,UAAM,IAAI,MAAM,MAAM,CAAC;AACvB,QAAI,UAAU,EAAE,IAAK,QAAO;AAC5B,UAAM,OAAO,MAAM,MAAM,IAAI,CAAC;AAC9B,QAAI,QAAQ,SAAS,KAAK,MAAO,QAAO;AAAA,EAC1C;AACA,SAAO,KAAK,IAAI,GAAG,MAAM,MAAM,SAAS,CAAC;AAC3C;AAGO,SAAS,WAAW,OAAkB,QAAgB,SAAgE;AAC3H,QAAM,QAAQ,OAAO,OAAO,MAAM;AAClC,QAAM,IAAI,MAAM,MAAM,KAAK;AAC3B,MAAI,CAAC,EAAG,QAAO,EAAE,MAAM,GAAG,GAAG,EAAE;AAC/B,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,EAAE,GAAG,IAAI,EAAE,KAAK;AAC5D,SAAO,EAAE,MAAM,OAAO,GAAG,WAAW,IAAI,IAAI,QAAQ,EAAE,KAAK,MAAM,GAAG,MAAM,CAAC,EAAE;AAC/E;AAIO,SAAS,SAAS,OAAkB,OAAe,KAAa,SAA+E;AACpJ,QAAM,OAAO,KAAK,IAAI,OAAO,GAAG;AAChC,QAAM,KAAK,KAAK,IAAI,OAAO,GAAG;AAC9B,MAAI,SAAS,GAAI,QAAO,CAAC;AACzB,QAAM,QAAoD,CAAC;AAC3D,QAAM,MAAM,QAAQ,CAAC,GAAG,MAAM;AAC5B,QAAI,KAAK,EAAE,SAAS,OAAO,EAAE,IAAK;AAClC,QAAI,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAO;AACvC,UAAM,IAAI,KAAK,IAAI,MAAM,EAAE,KAAK,IAAI,EAAE;AACtC,UAAM,IAAI,KAAK,IAAI,IAAI,EAAE,GAAG,IAAI,EAAE;AAClC,UAAM,KAAK,EAAE,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,QAAQ,EAAE,KAAK,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,MAAM,IAAI,IAAI,QAAQ,EAAE,KAAK,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;AAAA,EACtH,CAAC;AACD,SAAO;AACT;AAGO,SAAS,SAAS,OAAkB,OAAe,OAAoC,QAAQ,MAAM,OAAe;AACzH,QAAM,IAAI,MAAM,MAAM,KAAK;AAC3B,MAAI,CAAC,KAAK,UAAU,OAAQ,QAAO;AACnC,SAAO,UAAU,YAAY,QAAQ,EAAE,SAAS,IAAI,QAAQ,EAAE;AAChE;;;AC9FO,IAAM,cAA6B;AAAA,EACxC,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EAEpB,aAAa;AAAA,EACb,eAAe;AAAA,EACf,kBAAkB;AAAA,EAElB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,4BAA4B;AAAA,EAC5B,0BAA0B;AAAA,EAC1B,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,uBAAuB;AAAA,EAEvB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EAEtB,kBAAkB;AAAA,EAClB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,sBAAsB;AAAA,EACtB,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EAEtB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EAEtB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EAEnB,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EAExB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EAExB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAE1B,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EAEpB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,2BAA2B;AAAA,EAC3B,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,qBAAqB;AACvB;AAGO,IAAM,aAA4B;AAAA,EACvC,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EAEpB,aAAa;AAAA,EACb,eAAe;AAAA,EACf,kBAAkB;AAAA,EAElB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,kCAAkC;AAAA,EAClC,4BAA4B;AAAA,EAC5B,0BAA0B;AAAA,EAC1B,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,uBAAuB;AAAA,EAEvB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EAEtB,kBAAkB;AAAA,EAClB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,sBAAsB;AAAA,EACtB,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EAEtB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EAEtB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EAEnB,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EAExB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EAExB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAE1B,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EAEpB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,2BAA2B;AAAA,EAC3B,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,qBAAqB;AACvB;AAGO,IAAM,kBAA8D,OAAO,OAAO;AAAA,EACvF,OAAO;AAAA,EACP,MAAM;AACR,CAAC;AAgCM,IAAM,uBAAqD,OAAO,OAAO;AAAA,EAC9E,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,eAAe;AAAA,EACf,aAAa;AAAA,EACb,cAAc;AAAA,EACd,KAAK;AAAA,EACL,KAAK;AAAA,EACL,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,YAAY;AACd,CAAC;AAKM,IAAM,WAAW;AACjB,IAAM,aAAa;;;AC9UnB,SAAS,cAAc,OAAwI;AACpK,SAAO,EAAE,YAAY,MAAM,kBAAkB,GAAG,cAAc,MAAM,gBAAgB,GAAG,MAAM,MAAM,cAAc,GAAG,MAAM,MAAM,mBAAmB,GAAG,QAAQ,MAAM,cAAc,EAAE;AACtL;AAGO,IAAM,eAA4B,cAAc,WAAW;;;ACtB3D,SAAS,YAAY,OAAkB,OAAyB;AACrE,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO,CAAC,KAAK,IAAI,GAAG,QAAQ,CAAC,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC;AAAA,IACxD,KAAK;AACH,aAAO,CAAC,KAAK,IAAI,GAAG,KAAK,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC;AAAA,IACpD;AACE,aAAO,CAAC;AAAA,EACZ;AACF;AAGO,SAAS,YAAY,KAA+B,OAA2B;AACpF,MAAI,cAAc,MAAM;AACxB,MAAI,YAAY,MAAM;AACtB,MAAI,YAAY,YAAY,MAAM,WAAW,MAAM,SAAS,CAAC;AAC7D,MAAI,UAAU;AACd,MAAI,WAAW;AACjB;AAGO,SAAS,cAAc,KAA+B,GAAU,GAAgB;AACrF,MAAI,UAAU;AACd,MAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,MAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,MAAI,OAAO;AACb;AAIO,IAAM,sBAAsB,WAAW,iBAAiB;AAGxD,SAAS,OAAO,OAA6B;AAClD,QAAM,SAAS,MAAM,OAAO,SAAS;AACrC,QAAM,QAAQ,MAAM,SAAS,YAAY;AACzC,SAAO,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,QAAQ,MAAM,mBAAmB;AACpE;AAWO,SAAS,WACd,KACA,MACA,IACA,OACA,OAAqB,CAAC,GACmC;AACzD,QAAM,EAAE,QAAQ,QAAQ,WAAW,UAAU,YAAY,UAAU,EAAE,IAAI;AACzE,MAAI,KAAK;AACT,MAAI,OAAO,OAAO,KAAK;AACvB,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,QAAM,UAAU,IAAI,YAAY,IAAI;AACpC,QAAM,QAAQ,QAAQ;AACtB,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,OAAO,UAAU,UAAU,GAAG,IAAI,QAAQ,UAAU,WAAW,GAAG,IAAI,QAAQ,IAAI,GAAG;AAC3F,QAAM,MAAM,aAAa,WAAW,GAAG,IAAI,SAAS,aAAa,QAAQ,GAAG,IAAI,GAAG,IAAI,SAAS;AAChG,MAAI,YAAY;AACd,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,UAAU,OAAO,SAAS,MAAM,SAAS,QAAQ,UAAU,GAAG,SAAS,UAAU,GAAG,CAAC;AACzF,QAAI,KAAK;AAAA,EACX;AACA,MAAI,YAAY,MAAM;AACtB,MAAI,YAAY,CAAC,CAAC;AAClB,MAAI,SAAS,MAAM,GAAG,GAAG,GAAG,CAAC;AAC7B,MAAI,QAAQ;AACZ,SAAO,EAAE,GAAG,OAAO,SAAS,GAAG,MAAM,SAAS,OAAO,QAAQ,UAAU,GAAG,QAAQ,SAAS,UAAU,EAAE;AACzG;AAGO,SAAS,eACd,KACA,MACA,KACA,OACM;AACN,QAAM,QAAQ,KAAK,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,CAAC;AACvD,QAAM,OAAO,IAAI,MAAM,YAAY;AACnC,MAAI,KAAK;AACT,MAAI,YAAY,MAAM;AACtB,MAAI,YAAY,CAAC,CAAC;AAClB,MAAI,UAAU;AACd,MAAI,OAAO,IAAI,GAAG,IAAI,CAAC;AACvB,MAAI,OAAO,IAAI,IAAI,OAAO,KAAK,IAAI,QAAQ,KAAK,KAAK,CAAC,GAAG,IAAI,IAAI,OAAO,KAAK,IAAI,QAAQ,KAAK,KAAK,CAAC,CAAC;AACrG,MAAI,OAAO,IAAI,IAAI,OAAO,KAAK,IAAI,QAAQ,KAAK,KAAK,CAAC,GAAG,IAAI,IAAI,OAAO,KAAK,IAAI,QAAQ,KAAK,KAAK,CAAC,CAAC;AACrG,MAAI,UAAU;AACd,MAAI,KAAK;AACT,MAAI,QAAQ;AACd;AAEA,IAAI,WAA4C;AAGzC,SAAS,YAAY,OAA+C;AACzE,MAAI,CAAC,YAAY,OAAO,aAAa,aAAa;AAChD,eAAW,SAAS,cAAc,QAAQ,EAAE,WAAW,IAAI;AAAA,EAC7D;AACA,QAAM,IAAI;AACV,MAAI,CAAC,EAAG,QAAO,CAACA,UAASA,MAAK,SAAS,MAAM,WAAW;AACxD,QAAM,OAAO,OAAO,KAAK;AAEzB,SAAO,CAACA,UAAS;AACf,QAAI,EAAE,SAAS,KAAM,GAAE,OAAO;AAC9B,WAAO,EAAE,YAAYA,KAAI,EAAE;AAAA,EAC7B;AACF;AAGO,SAAS,iBACd,MACA,OACuD;AACvD,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,aAAa,KAAK,MAAM,MAAM,WAAW,IAAI;AACnD,QAAM,UAAU,YAAY,KAAK;AACjC,MAAI,QAAQ;AACZ,aAAWA,SAAQ,MAAO,SAAQ,KAAK,IAAI,OAAO,QAAQA,KAAI,CAAC;AAC/D,SAAO,EAAE,OAAO,QAAQ,MAAM,SAAS,YAAY,WAAW;AAChE;AAIO,SAAS,SAAS,MAAc,OAAqB,OAAuB;AACjF,MAAI,EAAE,QAAQ,GAAI,QAAO;AACzB,QAAM,UAAU,YAAY,KAAK;AACjC,QAAM,QAAkB,CAAC;AACzB,aAAW,aAAa,KAAK,MAAM,IAAI,GAAG;AACxC,QAAIA,QAAO;AACX,eAAW,QAAQ,UAAU,MAAM,GAAG,GAAG;AACvC,YAAM,SAASA,QAAO,GAAGA,KAAI,IAAI,IAAI,KAAK;AAC1C,UAAI,QAAQ,MAAM,KAAK,OAAO;AAC5B,QAAAA,QAAO;AACP;AAAA,MACF;AACA,UAAIA,MAAM,OAAM,KAAKA,KAAI;AACzB,UAAI,OAAO;AACX,aAAO,KAAK,SAAS,KAAK,QAAQ,IAAI,IAAI,OAAO;AAC/C,YAAI,MAAM,KAAK,SAAS;AACxB,eAAO,MAAM,KAAK,QAAQ,KAAK,MAAM,GAAG,GAAG,CAAC,IAAI,MAAO;AACvD,cAAM,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC;AAC7B,eAAO,KAAK,MAAM,GAAG;AAAA,MACvB;AACA,MAAAA,QAAO;AAAA,IACT;AACA,UAAM,KAAKA,KAAI;AAAA,EACjB;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAIO,SAAS,MAAM,OAAuB;AAC3C,QAAM,IAAI,UAAU,OAAO,CAAC,EAAE,MAAM,4CAA4C;AAChF,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM;AAC9C,UAAM,IAAI,OAAO,CAAC,IAAI;AACtB,WAAO,KAAK,UAAU,IAAI,UAAU,IAAI,SAAS,UAAU;AAAA,EAC7D,CAAC;AACD,SAAO,SAAS,IAAI,SAAS,IAAI,SAAS,IAAI,QAAQ,YAAY;AACpE;AAYO,SAAS,eACd,KACA,MACA,SACA,OACA,OAAyB,CAAC,GAC+B;AACzD,QAAM,EAAE,YAAY,aAAa,UAAU,GAAG,QAAQ,OAAO,IAAI;AACjE,QAAM,EAAE,OAAO,QAAQ,WAAW,IAAI,iBAAiB,MAAM,KAAK;AAClE,QAAMC,OAAM;AAAA,IACV,GAAG,QAAQ;AAAA,IACX,GAAG,QAAQ;AAAA,IACX,OAAO,QAAQ,UAAU;AAAA,IACzB,QAAQ,SAAS,UAAU;AAAA,EAC7B;AACA,MAAI,KAAK;AACT,MAAI,YAAY,CAAC,CAAC;AAClB,MAAI,cAAc,aAAa;AAC7B,QAAI,UAAU;AACd,QAAI,UAAUA,KAAI,GAAGA,KAAI,GAAGA,KAAI,OAAOA,KAAI,QAAQ,CAAC;AACpD,QAAI,YAAY;AACd,UAAI,YAAY;AAChB,UAAI,KAAK;AAAA,IACX;AACA,QAAI,aAAa;AACf,UAAI,cAAc;AAClB,UAAI,YAAY,KAAK,eAAe;AACpC,UAAI,OAAO;AAAA,IACb;AAAA,EACF;AACA,MAAI,OAAO,OAAO,KAAK;AACvB,MAAI,YAAY,MAAM;AACtB,MAAI,eAAe;AACnB,MAAI,YAAY;AAChB,QAAM,QAAQ,UAAU,WAAWA,KAAI,IAAIA,KAAI,QAAQ,IAAIA,KAAI,IAAI;AACnE,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,QAAI,SAAS,MAAM,CAAC,GAAG,OAAOA,KAAI,IAAI,UAAU,IAAI,UAAU;AAAA,EAChE;AACA,MAAI,QAAQ;AACZ,SAAOA;AACT;AAOO,SAAS,aAAa,QAA0B,SAAuB,OAA8B;AAC1G,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,OAAsB;AAC1B,MAAI,QAAQ;AACZ,SAAO,QAAQ,CAAC,GAAG,MAAM;AACvB,UAAM,IAAI,KAAK,MAAM,EAAE,IAAI,QAAQ,GAAG,EAAE,IAAI,QAAQ,CAAC;AACrD,QAAI,KAAK,OAAO;AACd,cAAQ;AACR,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAKA,IAAM,cAAc,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,KAAK,OAAO,GAAG,OAAO,IAAI;AAOrE,SAAS,aACd,KACA,QACA,MACA,QAAqB,UACrB,UAAyB,MACzB,OAA4B,YACtB;AACN,MAAI,KAAK;AACT,MAAI,YAAY,CAAC,CAAC;AAClB,SAAO,QAAQ,CAAC,GAAG,MAAM;AACvB,UAAM,IAAI,KAAK,MAAM,EAAE,CAAC,IAAI;AAC5B,UAAM,IAAI,KAAK,MAAM,EAAE,CAAC,IAAI;AAC5B,QAAI,MAAM,WAAW,UAAU,WAAW,SAAS,YAAY;AAC7D,UAAI,cAAc,YAAY;AAC9B,UAAI,cAAc,KAAK;AACvB,UAAI,YAAY,YAAY;AAC5B,UAAI,UAAU;AACd,UAAI,UAAU,SAAU,KAAI,UAAU,IAAI,YAAY,MAAM,IAAI,YAAY,MAAM,YAAY,OAAO,GAAG,YAAY,OAAO,GAAG,YAAY,MAAM;AAAA,UAC3I,KAAI,IAAI,GAAG,GAAG,YAAY,QAAQ,GAAG,KAAK,KAAK,CAAC;AACrD,UAAI,OAAO;AACX,UAAI,cAAc;AAAA,IACpB;AACA,UAAM,OAAO,SAAS;AACtB,QAAI,YAAY,KAAK;AACrB,QAAI,cAAc,KAAK;AACvB,QAAI,UAAU;AACd,QAAI,UAAU,UAAU;AACtB,YAAM,OAAO,OAAO,IAAI;AACxB,UAAI,YAAY,OAAO,IAAI;AAC3B,UAAI,UAAU,IAAI,MAAM,IAAI,MAAM,OAAO,GAAG,OAAO,GAAG,GAAG;AAAA,IAC3D,WAAW,UAAU,SAAS;AAC5B,UAAI,YAAY;AAChB,UAAI,IAAI,GAAG,GAAG,KAAK,GAAG,KAAK,KAAK,CAAC;AAAA,IACnC,OAAO;AACL,UAAI,YAAY,OAAO,IAAI;AAC3B,UAAI,IAAI,GAAG,GAAG,OAAO,IAAI,KAAK,GAAG,KAAK,KAAK,CAAC;AAAA,IAC9C;AACA,QAAI,KAAK;AACT,QAAI,OAAO;AAAA,EACb,CAAC;AACD,MAAI,QAAQ;AACd;AAGO,SAAS,iBACd,KACA,QACA,QACM;AACN,MAAI,KAAK;AACT,MAAI,YAAY,CAAC,CAAC;AAClB,MAAI,YAAY;AAChB,aAAW,KAAK,QAAQ;AACtB,QAAI,YAAY;AAChB,QAAI,cAAc;AAClB,QAAI,UAAU;AACd,QAAI,KAAK,EAAE,IAAI,KAAK,EAAE,IAAI,KAAK,GAAG,CAAC;AACnC,QAAI,KAAK;AACT,QAAI,OAAO;AAAA,EACb;AACA,MAAI,QAAQ;AACd;AAGO,SAAS,UAAU,OAAoC;AAC5D,MAAI,MAAM,eAAe,EAAG,QAAO;AACnC,SAAO,UAAU,MAAM,WAAW,MAAM,WAAW;AACrD;AAGO,SAAS,QAAQ,OAAuB;AAC7C,QAAM,IAAI,MAAM,KAAK,EAAE,MAAM,8CAA8C;AAC3E,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,IAAI,OAAO,EAAE,CAAC,CAAC;AACrB,SAAO,OAAO,SAAS,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI;AAC5D;AAGO,SAAS,UAAU,OAAe,OAAuB;AAC9D,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACxC,QAAM,MAAM,MAAM,KAAK,EAAE,MAAM,+BAA+B;AAC9D,MAAI,KAAK;AACP,UAAM,IAAI,IAAI,CAAC;AACf,UAAM,OAAO,EAAE,WAAW,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI;AACvE,UAAM,IAAI,SAAS,MAAM,EAAE;AAC3B,WAAO,QAAS,KAAK,KAAM,GAAG,KAAM,KAAK,IAAK,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AAAA,EACrE;AACA,QAAM,MAAM,MAAM,KAAK,EAAE,MAAM,qBAAqB;AACpD,MAAI,KAAK;AACP,UAAM,QAAQ,IAAI,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACnD,WAAO,QAAQ,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,KAAK,CAAC;AAAA,EACzD;AACA,SAAO;AACT;;;ACvVA,IAAM,eAAe;AACrB,IAAM,aAAa;AAMZ,IAAM,kBAAN,MAA4E;AAAA,EAChE;AAAA,EAEjB,YAAYC,UAAqB;AAC/B,SAAK,WAAWA;AAAA,EAClB;AAAA,EAEA,SAAkC;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,WAAmC;AACjC,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,QAAuC;AAC1C,UAAMA,WAAU,KAAK;AACrB,QAAI,CAACA,SAAQ,aAAa,EAAG;AAC7B,UAAM,WAAWA,SAAQ,YAAY;AACrC,QAAI,CAAC,SAAU;AAEf,WAAO,wBAAwB,CAAC,EAAE,SAAS,IAAI,MAAM;AACnD,UAAI,KAAK;AACT,UAAI;AACF,YAAIA,SAAQ,QAAQ,GAAG;AACrB,UAAAA,SAAQ,MAAM,KAAK,QAAQ;AAAA,QAC7B,OAAO;AACL,UAAAA,SAAQ,kBAAkB,KAAK,QAAQ;AAAA,QACzC;AACA,cAAM,QAAQA,SAAQ;AACtB,cAAM,OAAOA,SAAQ,KAAK;AAC1B,cAAM,aAAa,EAAE,MAAM,KAAK,YAAY,QAAQ,KAAK,aAAa;AACtE,YAAI,UAAU,cAAc,UAAU,WAAW;AAE/C,cAAIA,SAAQ,QAAQ,EAAG,CAAAA,SAAQ,cAAc,KAAK,QAAQ;AAC1D,gBAAM,SAASA,SAAQ,iBAAiB,QAAQ;AAChD,cAAI,OAAO,SAAS,EAAG,cAAa,KAAK,QAAQ,YAAYA,SAAQ,YAAY,GAAG,aAAa,QAAQA,SAAQ,SAAS,YAAY,CAAC;AACvI,gBAAM,QAAQA,SAAQ,cAAc,QAAQ;AAC5C,gBAAM,YAAYA,SAAQ,UAAU;AACpC,cAAI,MAAM,SAAS,KAAK,UAAW,cAAa,KAAK,OAAO,YAAY,WAAW,aAAa,OAAOA,SAAQ,SAAS,UAAU,CAAC;AAAA,mBAC1H,MAAM,SAAS,EAAG,kBAAiB,KAAK,OAAOA,SAAQ,MAAM,SAAS;AAAA,QACjF,WAAWA,SAAQ,WAAWA,SAAQ,eAAe,KAAKA,SAAQ,QAAQ,GAAG;AAE3E,gBAAM,SAASA,SAAQ,iBAAiB,QAAQ;AAChD,cAAI,OAAO,SAAS,EAAG,cAAa,KAAK,QAAQ,YAAYA,SAAQ,YAAY,GAAG,MAAM,MAAM;AAAA,QAClG;AAAA,MACF,UAAE;AACA,YAAI,QAAQ;AAAA,MACd;AAAA,IACF,CAAC;AAED,IAAAA,SAAQ,cAAc,QAAQ;AAAA,EAChC;AACF;;;ACtDO,IAAM,YAAN,MAAoD;AAAA,EACxC;AAAA,EAEjB,YAAY,QAAyB;AACnC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,aAAqB;AACnB,WAAO,KAAK,QAAQ,WAAW,KAAK;AAAA,EACtC;AAAA,EAEA,OAAe;AACb,WAAO,KAAK,QAAQ,KAAK;AAAA,EAC3B;AAAA,EAEA,YAAoB;AAClB,WAAO,KAAK,QAAQ,YAAY,KAAK;AAAA,EACvC;AAAA,EAEA,YAAoB;AAClB,WAAO,KAAK,QAAQ,MAAM;AAAA,EAC5B;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK,QAAQ,QAAQ,KAAK,KAAK,QAAQ,WAAW,MAAM;AAAA,EACjE;AACF;AAcO,IAAM,eAAN,MAAyE;AAAA,EAC7D;AAAA,EACA;AAAA,EAEjB,YAAY,QAAwB,MAAwB;AAC1D,SAAK,UAAU;AACf,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,SAAkC;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,WAAmC;AACjC,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,QAAuC;AAC1C,UAAM,OAAO,KAAK,QAAQ,KAAK;AAC/B,QAAI,CAAC,QAAQ,KAAK,YAAY,WAAW,EAAG;AAC5C,WAAO,wBAAwB,CAAC,EAAE,SAAS,KAAK,UAAU,MAAM;AAC9D,oBAAc,KAAK,KAAK,OAAO,KAAK,aAAa,KAAK,OAAO,SAAS;AAAA,IACxE,CAAC;AAAA,EACH;AACF;AAGO,SAAS,cAAc,KAA+B,MAAwB,aAAgC,OAAe,MAA+C;AACjL,QAAM,MAAM,KAAK,IAAI,GAAG,WAAW;AACnC,QAAM,OAAO,KAAK,IAAI,GAAG,WAAW;AACpC,MAAI,KAAK;AACT,MAAI,YAAY;AAChB,MAAI,SAAS,SAAS;AACpB,UAAM,MAAM,KAAK,MAAM,GAAG,IAAI;AAC9B,UAAM,SAAS,KAAK,MAAM,IAAI,IAAI;AAClC,QAAI,SAAS,IAAK,KAAI,SAAS,GAAG,KAAK,KAAK,OAAO,SAAS,GAAG;AAAA,QAC1D,KAAI,SAAS,GAAG,KAAK,MAAM,IAAI,IAAI,GAAG,KAAK,OAAO,CAAC;AAAA,EAC1D,OAAO;AACL,UAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,QAAI,SAAS,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,IAAI,IAAI,GAAG,KAAK,MAAM;AAAA,EACxE;AACA,MAAI,QAAQ;AACd;;;ACpFO,IAAM,UAAU;AAAA;AAAA;AAAA,EAGrB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,gCAAgC;AAAA,EAChC,0BAA0B;AAAA,EAC1B,yBAAyB;AAAA,EACzB,8BAA8B;AAAA,EAC9B,8BAA8B;AAAA,EAC9B,2BAA2B;AAAA,EAC3B,0BAA0B;AAAA,EAC1B,yBAAyB;AAAA,EACzB,0BAA0B;AAAA,EAC1B,yBAAyB;AAAA;AAAA,EAGzB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA;AAAA,EAGxB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,6BAA6B;AAAA,EAC7B,mBAAmB;AAAA,EACnB,qBAAqB;AAAA;AAAA;AAAA,EAIrB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA,EAC1B,mBAAmB;AAAA,EACnB,mBAAmB;AAAA;AAAA,EAGnB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA;AAAA;AAAA,EAIvB,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,yBAAyB,EAAE,KAAK,mBAAmB,OAAO,mBAAmB;AAAA,EAC7E,2BAA2B,EAAE,KAAK,qBAAqB,OAAO,qBAAqB;AAAA,EACnF,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,2BAA2B;AAAA,EAC3B,8BAA8B;AAAA;AAAA,EAG9B,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,gCAAgC;AAAA;AAAA,EAGhC,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,4BAA4B;AAAA,EAC5B,0BAA0B;AAAA,EAC1B,gCAAgC;AAAA,EAChC,+BAA+B;AAAA,EAC/B,kBAAkB;AAAA,EAClB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,2BAA2B;AAAA,EAC3B,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,kCAAkC;AAAA,EAClC,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,gCAAgC;AAAA,EAChC,+BAA+B;AAAA,EAC/B,kCAAkC;AAAA,EAClC,iCAAiC;AAAA,EACjC,2BAA2B;AAAA,EAC3B,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,gBAAgB;AAAA,EAChB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,8BAA8B;AAAA,EAC9B,8BAA8B;AAAA,EAC9B,0BAA0B;AAAA,EAC1B,kBAAkB;AAAA;AAAA,EAGlB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,+BAA+B;AAAA,EAC/B,8BAA8B;AAAA;AAAA,EAG9B,yBAAyB;AAAA,EACzB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,0BAA0B;AAAA,EAC1B,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,yBAAyB;AAAA,EACzB,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,iBAAiB;AAAA;AAAA,EAGjB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA;AAAA,EAGrB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,iCAAiC;AAAA,EACjC,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,yBAAyB;AAAA,EACzB,yBAAyB;AAAA,EACzB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,gBAAgB;AAAA,EAChB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,qBAAqB;AAAA,EACrB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,4BAA4B;AAAA,EAC5B,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,wBAAwB;AAAA,EACxB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,6BAA6B;AAAA,EAC7B,6BAA6B;AAAA,EAC7B,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,4BAA4B;AAAA;AAAA,EAG5B,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA;AAAA;AAAA,EAIpB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,2BAA2B;AAAA,EAC3B,4BAA4B;AAAA,EAC5B,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,6BAA6B;AAAA,EAC7B,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,4BAA4B;AAAA,EAC5B,kBAAkB;AAAA,EAClB,4BAA4B;AAAA,EAC5B,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,yBAAyB;AAAA,EACzB,0BAA0B;AAAA,EAC1B,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,iCAAiC;AAAA,EACjC,4BAA4B;AAAA,EAC5B,+BAA+B;AAAA,EAC/B,iCAAiC;AAAA,EACjC,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,8BAA8B;AAAA,EAC9B,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA,EAC1B,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,gBAAgB;AAAA,EAChB,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,6BAA6B;AAAA,EAC7B,+BAA+B;AAAA,EAC/B,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB,oBAAoB;AAAA,EACpB,2BAA2B;AAAA,EAC3B,mBAAmB;AAAA,EACnB,+BAA+B;AAAA,EAC/B,6BAA6B;AAAA,EAC7B,+BAA+B;AAAA,EAC/B,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB,oBAAoB;AAAA,EACpB,8BAA8B;AAAA,EAC9B,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,wBAAwB;AAAA,EACxB,8BAA8B;AAAA,EAC9B,yBAAyB;AAAA,EACzB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,4BAA4B;AAAA,EAC5B,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,6BAA6B;AAAA,EAC7B,uBAAuB;AAAA,EACvB,6BAA6B;AAAA,EAC7B,2BAA2B;AAAA,EAC3B,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA,EAC1B,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA;AAAA,EAGlB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA;AAAA;AAAA,EAItB,0BAA0B;AAAA,EAC1B,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA;AAAA,EAGxB,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,yBAAyB;AAAA;AAAA,EAGzB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,+BAA+B;AAAA;AAAA,EAG/B,uBAAuB;AAAA,EACvB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,eAAe;AAAA;AAAA,EAGf,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,0BAA0B;AAAA,EAC1B,wBAAwB;AAAA,EACxB,4BAA4B;AAAA,EAC5B,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,8BAA8B;AAAA,EAC9B,gCAAgC;AAAA,EAChC,gCAAgC;AAAA,EAChC,8BAA8B;AAAA,EAC9B,+BAA+B;AAAA,EAC/B,+BAA+B;AAAA;AAAA,EAG/B,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA,EAC1B,4BAA4B;AAC9B;;;ACvfO,SAAS,YAAY,QAAwC;AAClE,MAAI;AACF,UAAM,QAAQ,OAAO,QAAQ,EAAE,UAAU;AACzC,WAAO,OAAO,UAAU,KAAK,KAAK,SAAS,IAAI,QAAQ;AAAA,EACzD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,UAAU,OAAkB,OAAeC,MAA0B;AACnF,MAAI,SAAS,EAAG,QAAO;AACvB,MAAI;AACF,UAAM,QAAQ,MAAM,MAAM;AAC1B,UAAM,OAAO,MAAM,KAAK,GAAG,eAAe,GAAG,sBAAsB;AACnE,QAAI,QAAQ,KAAK,SAAS,EAAG,QAAO,KAAK,MAAMA,KAAI,sBAAsB,EAAE;AAC3E,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,SAAS,IAAI,MAAM,QAAQ,IAAK,QAAO,MAAM,CAAC,EAAG,UAAU;AAC/E,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,IAAM,gBAAgB,CAAC,OAAkB,QAAgCA,SAC9E,UAAU,OAAO,YAAY,MAAM,GAAGA,IAAG;;;ARI3C,SAAS,iBAAiB,OAAgD;AACxE,SAAO,EAAE,GAAG,iBAAiB,GAAG,OAAO,YAAY,oBAAoB,MAAM,UAAU,EAAE;AAC3F;AAQO,SAAS,WAAW,OAAkB,QAAiD;AAC5F,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM,UAAU,EAAE,MAAM;AAChC,aAAS,MAAM,SAAS,YAAY,MAAM,CAAC,EAAE;AAAA,EAC/C,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,SAAS,KAAK,UAAU,EAAG,QAAO;AACtC,QAAM,KAAK,MAAM,UAAU;AAgB3B,QAAM,OAAO,OAAO,KAAK;AACzB,QAAM,YAAY,KAAK,SAAS;AAChC,QAAM,UAAU,CAAC,MAA6B;AAC5C,UAAM,IAAI,KAAK,CAAC,GAAG;AACnB,WAAO,OAAO,MAAM,WAAW,IAAI;AAAA,EACrC;AACA,QAAM,YAAY,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI;AACjD,QAAM,WAAW,KAAK,SAAS,IAAI,QAAQ,SAAS,IAAI;AAGxD,QAAM,WAAW,QAAQ,YAAY,CAAC;AACtC,QAAM,YAAY,aAAa,QAAQ,aAAa,QAAQ,WAAW,WAAW,WAAW,WAAW;AACxG,QAAM,aAAa,QAAQ,CAAC;AAC5B,QAAM,WAAW,cAAc,QAAQ,eAAe,QAAQ,aAAa,YAAY,aAAa,YAAY;AAEhH,QAAM,gBAAgB,CAAC,SAA8B;AAGnD,UAAM,IAAI,GAAG,iBAAiB,IAAI;AAClC,QAAI,MAAM,MAAM;AACd,YAAM,UAAU,GAAG,oBAAoB,CAAC;AACxC,UAAI,YAAY,KAAM,QAAO;AAAA,IAC/B;AACA,QAAI,OAAO,SAAS,YAAY,cAAc,QAAQ,aAAa,KAAM,QAAO;AAChF,QAAI,QAAQ,SAAU,QAAO,cAAc,OAAO,YAAY,aAAa,OAAO,YAAY;AAC9F,QAAI,QAAQ,UAAW,QAAO,aAAa,OAAO,KAAK,OAAO,aAAa;AAK3E,QAAI,KAAK;AACT,QAAI,KAAK;AACT,WAAO,KAAK,KAAK,GAAG;AAClB,YAAM,MAAO,KAAK,MAAO;AACzB,YAAM,KAAK,QAAQ,GAAG;AACtB,UAAI,OAAO,KAAM,QAAO;AACxB,UAAI,MAAM,KAAM,MAAK;AAAA,UAChB,MAAK;AAAA,IACZ;AACA,UAAM,MAAM,QAAQ,EAAE;AACtB,UAAM,MAAM,QAAQ,EAAE;AACtB,QAAI,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,IAAK,QAAO;AACvD,WAAO,MAAM,OAAO,QAAQ,MAAM;AAAA,EACpC;AAMA,QAAM,qBAAqB,CAAC,YAAiC;AAC3D,QAAI,cAAc,QAAQ,aAAa,KAAM,QAAO;AACpD,QAAI,WAAW,UAAW,QAAO,cAAc,OAAQ,WAAsB,YAAY,UAAU,aAAa;AAChH,QAAI,WAAW,EAAG,QAAO,aAAa,OAAQ,YAAuB,YAAY,UAAU;AAC3F,UAAM,IAAI,KAAK,MAAM,OAAO;AAC5B,UAAM,MAAM,QAAQ,CAAC;AACrB,UAAM,MAAM,QAAQ,IAAI,CAAC;AACzB,QAAI,QAAQ,QAAQ,QAAQ,KAAM,QAAO;AACzC,WAAQ,OAAO,UAAU,MAAM,MAAM;AAAA,EACvC;AAIA,MAAI,aAAiD,MAAM;AAC3D,MAAI,KAAK,SAAS,GAAG;AACnB,UAAM,KAAK,GAAG,oBAAoB,CAAiD;AACnF,UAAM,aAAa,GAAG,QAAQ,EAAE;AAChC,QAAI,OAAO,QAAQ,aAAa,EAAG,cAAa,CAAC,YAAY,KAAK,UAAU;AAAA,EAC9E;AAGA,MAAI,WAAW;AACf,MAAI;AACF,eAAW,OAAO,WAAW,EAAE,QAAQ,EAAE,SAAS,eAAe;AAAA,EACnE,QAAQ;AACN,eAAW;AAAA,EACb;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,CAAC,SAAS;AACb,YAAM,SAAS,GAAG,iBAAiB,IAAI;AACvC,UAAI,WAAW,KAAM,QAAO;AAC5B,YAAM,UAAU,cAAc,IAAI;AAClC,UAAI,YAAY,KAAM,QAAO;AAC7B,aAAO,WAAW,OAAO;AAAA,IAC3B;AAAA,IACA,KAAK,CAAC,UAAU,OAAO,kBAAkB,KAAK;AAAA,IAC9C,QAAQ,CAAC,MAAM;AACb,YAAM,SAAS,GAAG,iBAAiB,CAAC;AACpC,UAAI,WAAW,KAAM,QAAO;AAC5B,YAAM,UAAU,GAAG,oBAAoB,CAAC;AACxC,UAAI,YAAY,KAAM,QAAO;AAC7B,aAAO,mBAAmB,OAAO;AAAA,IACnC;AAAA,IACA,SAAS,CAAC,MAAM,OAAO,kBAAkB,CAAC;AAAA,IAC1C,aAAa,CAAC,GAAG,MAAM;AACrB,YAAM,KAAK,cAAc,CAAC;AAC1B,YAAM,KAAK,cAAc,CAAC;AAC1B,UAAI,OAAO,QAAQ,OAAO,KAAM,QAAO;AACvC,aAAO,KAAK;AAAA,IACd;AAAA,IACA,WAAW;AAAA,IACX,eAAe;AAAA,EACjB;AACF;AAmBA,IAAM,wBAAyC,CAAC,UAAU,MAAM,QAAQ,CAAC;AAGzE,SAAS,UAAU,MAAoB;AACrC,QAAM,IAAI,OAAO,IAAI;AACrB,MAAI,CAAC,OAAO,SAAS,CAAC,EAAG,QAAO,OAAO,IAAI;AAC3C,QAAM,IAAI,IAAI,KAAK,IAAI,GAAI;AAC3B,QAAM,MAAM,CAAC,MAAc,OAAO,CAAC,EAAE,SAAS,GAAG,GAAG;AACpD,SAAO,GAAG,EAAE,eAAe,CAAC,IAAI,IAAI,EAAE,YAAY,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,WAAW,CAAC,CAAC,IAAI,IAAI,EAAE,YAAY,CAAC,CAAC,IAAI,IAAI,EAAE,cAAc,CAAC,CAAC;AACnI;AAYO,IAAe,UAAf,MAEP;AAAA,EACW;AAAA;AAAA;AAAA,EAGT;AAAA,EAGU;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAuB;AAAA,EACzB,oBAAsC;AAAA,EACtC,gBAAgB;AAAA,EAChB,aAA+B;AAAA,EAE/B,SAA2B;AAAA,EAC3B,UAAyC;AAAA,EACzC,iBAAsC;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YACE,IACA,UAAoB,CAAC,GACrB,QAA+B,CAAC,GAChC,UAAmC,CAAC,GACpC,QAAoB,CAAC,GACrB;AACA,SAAK,KAAK;AACV,SAAK,WAAW,KAAK,eAAe,QAAQ,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;AAClE,SAAK,SAAS,EAAE,GAAG,eAAe,GAAG,MAAM;AAC3C,SAAK,WAAW,iBAAiB,OAAO;AACxC,SAAK,SAAS,EAAE,GAAG,KAAK,aAAa,GAAG,GAAG,KAAK,aAAa,KAAK,EAAE;AACpE,SAAK,aAAa,CAAC,IAAI,gBAAgB,IAAI,CAAC;AAC5C,SAAK,cAAc,CAAC,IAAI,aAAa,EAAE,MAAM,MAAM,KAAK,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC;AACrF,SAAK,aAAa,CAAC,IAAI,aAAa,EAAE,MAAM,MAAM,KAAK,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC;AAAA,EACpF;AAAA;AAAA,EAGU,eAAkB;AAC1B,WAAO,CAAC;AAAA,EACV;AAAA;AAAA;AAAA;AAAA,EAKU,aAAa,OAA+B;AACpD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKU,eAAe,SAA6B;AACpD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,OAAmE;AAC7E,WAAO,EAAE,GAAG,KAAK,aAAa,EAAE,GAAG,MAAM,CAAe,EAAE;AAAA,EAC5D;AAAA;AAAA;AAAA,EAIA,cAAc,OAAgC;AAC5C,SAAK,cAAe,MAAM,SAAS,CAAC,CAAuC;AAC3E,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKU,cAAc,QAAiD;AAAA,EAAC;AAAA;AAAA,EAI1E,SAAS,QAA6C;AACpD,SAAK,SAAS,OAAO;AACrB,SAAK,UAAU,OAAO;AACtB,SAAK,iBAAiB,OAAO;AAAA,EAC/B;AAAA,EAEA,WAAiB;AACf,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,YAA2C;AACzC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,iBAAsD;AACpD,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EAEA,gBAAqD;AACnD,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA;AAAA,EAGU,YAAiD;AACzD,WAAO,CAAC;AAAA,EACV;AAAA;AAAA,EAGU,YAAiD;AACzD,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,qBAAoD;AAClD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,oBAAmD;AACjD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA,EAIU,YAAiF;AACzF,WAAO,EAAE,QAAQ,MAAM,OAAO,KAAK;AAAA,EACrC;AAAA;AAAA;AAAA,EAIQ,SAAS,MAAyE;AACxF,QAAK,KAAK,WAAW,cAAc,KAAK,WAAW,aAAc,CAAC,KAAK,aAAa,EAAG,QAAO;AAC9F,UAAM,WAAW,KAAK,YAAY;AAClC,QAAI,CAAC,SAAU,QAAO;AACtB,UAAM,QAAQ,KAAK,UAAU;AAC7B,UAAM,MAAM,SAAS,WAAW,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,MAAM,SAAS,IAAI,CAAC,CAAC,KAAK,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,SAAS,IAAI,CAAC,CAAC;AAChI,UAAM,cAAc,IAAI,OAAO,CAAC,MAAmB,MAAM,QAAQ,OAAO,SAAS,CAAC,CAAC;AACnF,WAAO,YAAY,SAAS,IAAI,EAAE,aAAa,OAAO,UAAU,KAAK,KAAK,EAAE,QAAQ,IAAI,EAAE,IAAI;AAAA,EAChG;AAAA;AAAA;AAAA,EAIU,WAAW,MAAgC;AACnD,QAAI,SAAS,OAAW,QAAO;AAC/B,QAAI;AACF,YAAM,YAAY,KAAK,QAAQ,QAAQ,EAAE,cAAc;AACvD,UAAI,UAAW,QAAO,UAAU,IAAI;AAAA,IACtC,QAAQ;AAAA,IAER;AACA,WAAO,UAAU,IAAI;AAAA,EACvB;AAAA,EAEA,QAAQ,GAAW,GAAwC;AACzD,QAAI,CAAC,KAAK,aAAa,EAAG,QAAO;AACjC,UAAM,WAAW,KAAK,YAAY;AAClC,QAAI,CAAC,SAAU,QAAO;AACtB,QAAI,CAAC,KAAK,QAAQ,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAG,QAAO;AAC9C,WAAO;AAAA,MACL,aAAa,KAAK,SAAS,SAAS,YAAa,KAAK,SAAS,EAAE,GAAG,EAAE,GAAG,QAAQ,KAAK;AAAA,MACtF,YAAY,KAAK;AAAA,MACjB,QAAQ;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,UAAU,OAAc,UAAmC;AACzD,WAAO,KAAK,SAAS,OAAO,QAAQ;AAAA,EACtC;AAAA;AAAA,EAGU,SAAS,QAAe,WAAoC;AACpE,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,IAAI,UAA6B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,QAAgC;AAClC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,UAAoC;AACtC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,QAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,QAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,MAAM,OAAqB;AAC7B,SAAK,SAAS,KAAK;AAAA,EACrB;AAAA,EAEA,WAAW,SAAyB;AAClC,SAAK,WAAW,QAAQ,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAC7C,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,aAAa,OAAe,QAAsB;AAChD,QAAI,QAAQ,KAAK,SAAS,KAAK,SAAS,OAAQ;AAChD,SAAK,SAAS,KAAK,IAAI,EAAE,GAAG,OAAO;AACnC,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,aAAa,QAAsB;AACjC,SAAK,SAAS,KAAK,EAAE,GAAG,OAAO,CAAC;AAChC,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,aAAa,OAAqB;AAChC,QAAI,QAAQ,KAAK,SAAS,KAAK,SAAS,OAAQ;AAChD,SAAK,SAAS,OAAO,OAAO,CAAC;AAC7B,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,YAAY,OAAoC;AAC9C,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,MAAM;AACzC,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,cAAc,OAAsC;AAClD,SAAK,WAAW;AAAA,MACd,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,MACH,YAAY,MAAM,aAAa,oBAAoB,MAAM,UAAU,IAAI,KAAK,SAAS;AAAA,IACvF;AACA,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,oBAAoB,SAAiC;AACnD,SAAK,oBAAoB;AACzB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,gBAAgB,QAAuB;AACrC,SAAK,gBAAgB;AACrB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,aAAa,QAAgC;AAC3C,SAAK,aAAa;AAClB,SAAK,cAAc;AAAA,EACrB;AAAA,EAEU,OAA6B;AACrC,WAAO,KAAK,aAAa,KAAK,CAAC;AAAA,EACjC;AAAA,EAEQ,YAA2B;AAAA;AAAA;AAAA,EAInC,YAAY,MAA2B;AACrC,SAAK,YAAY,QAAQ,OAAO,IAAI,OAAO;AAC3C,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,cAA6B;AAC3B,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEQ,gBAA+B;AAAA;AAAA,EAGvC,gBAAgB,MAA2B;AACzC,SAAK,gBAAgB,QAAQ,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI;AACzD,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,kBAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEU,WAA0B;AAClC,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,eAAuC;AAAA;AAAA,EAG/C,kBAAkB,QAAsC;AACtD,SAAK,eAAe;AACpB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGU,YAAY,OAAuB;AAC3C,YAAQ,KAAK,gBAAgB,uBAAuB,KAAK;AAAA,EAC3D;AAAA,EAEQ,eAAuC;AAAA;AAAA;AAAA,EAI/C,eAAe,QAAsC;AACnD,SAAK,eAAe;AACpB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGU,SAAS,OAA8B;AAC/C,WAAO,KAAK,eAAe,KAAK,aAAa,KAAK,IAAI;AAAA,EACxD;AAAA,EAEA,eAAwB;AACtB,WAAO,CAAC,KAAK,iBAAiB,KAAK,SAAS,WAAW,UAAU,KAAK,SAAS,YAAY,KAAK,iBAAiB;AAAA,EACnH;AAAA,EAEA,WAAW,OAAyB;AAClC,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,MAAM;AACzC,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,SAAS,OAA2B;AAClC,QAAI,KAAK,WAAW,MAAO;AAC3B,SAAK,SAAS;AACd,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,gBAAsB;AACpB,SAAK,iBAAiB;AAAA,EACxB;AAAA;AAAA,EAIA,cAA+B;AAC7B,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,QAAS,QAAO;AAC1C,WAAO,WAAW,KAAK,QAAQ,KAAK,OAAO;AAAA,EAC7C;AAAA,EAEA,cAAc,QAAgB,UAAkC;AAC9D,UAAM,IAAI,SAAS,IAAI,OAAO,IAAI;AAClC,UAAM,IAAI,SAAS,IAAI,OAAO,KAAK;AACnC,QAAI,MAAM,QAAQ,MAAM,KAAM,QAAO;AACrC,WAAO,EAAE,GAAG,EAAE;AAAA,EAChB;AAAA;AAAA,EAGU,aAAa,UAAsC;AAC3D,WAAO,KAAK,SAAS,IAAI,CAAC,MAAM,KAAK,cAAc,GAAG,QAAQ,CAAC;AAAA,EACjE;AAAA,EAEA,iBAAiB,UAAoC;AACnD,UAAM,SAAyB,CAAC;AAChC,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;AAC7C,YAAM,IAAI,KAAK,cAAc,KAAK,SAAS,CAAC,GAAG,QAAQ;AACvD,UAAI,EAAG,QAAO,KAAK,EAAE,OAAO,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,UAAmB;AACjB,WACE,KAAK,SAAS,UAAU,KAAK,gBAAgB,KAC7C,KAAK,SAAS,MAAM,CAAC,MAAM,OAAO,SAAS,EAAE,KAAK,CAAC;AAAA,EAEvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,kBAAkB,KAA+B,UAA0B;AACzE,UAAM,SAAS,KAAK,aAAa,QAAQ,EAAE,OAAO,CAAC,MAAkB,CAAC,CAAC,CAAC;AACxE,QAAI,OAAO,SAAS,EAAG;AACvB,QAAI,KAAK;AACT,QAAI,cAAc,KAAK,OAAO;AAC9B,QAAI,YAAY,KAAK,IAAI,GAAG,KAAK,OAAO,YAAY,GAAG;AACvD,QAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AACtB,QAAI,UAAU;AACd,QAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,KAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AAC3E,QAAI,OAAO;AACX,QAAI,QAAQ;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,WAA8B;AAC1C,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,SAAS,cAAsB,QAAe,WAA2B;AAAA,EAAC;AAAA,EAElE,YAA+B;AAAA;AAAA;AAAA,EAI7B,aAAa,QAAiC;AACtD,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA,EAGA,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYJ,kBAAkB,QAA0D;AACpF,WAAO;AAAA,MACL,GAAG,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,GAAG,CAAC,IAAI,OAAO;AAAA,MACpD,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE;AAAA,MACxD,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,cAAc,KAA+B,UAA0B;AACrE,SAAK,YAAY;AACjB,QAAI,KAAK,YAAa;AAGtB,QAAI,EAAE,UAAW,KAAK,aAAa,GAAgC;AACnE,UAAM,OAAQ,KAAK,OAAmC;AACtD,QAAI,OAAO,SAAS,YAAY,SAAS,GAAI;AAC7C,UAAM,SAAS,KAAK,aAAa,QAAQ,EAAE,OAAO,CAAC,MAAkB,CAAC,CAAC,CAAC;AACxE,QAAI,OAAO,WAAW,EAAG;AACzB,UAAM,EAAE,GAAG,IAAI,GAAG,IAAI,MAAM,IAAI,KAAK,kBAAkB,MAAM;AAC7D,UAAM,QAAQ;AACd,QAAI,KAAK;AACT,QAAI,UAAU,IAAI,EAAE;AACpB,QAAI,OAAO,KAAK;AAChB,QAAI,OAAO;AACX,QAAI,YAAY;AAChB,QAAI,eAAe;AACnB,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,YAAY;AAChB,QAAI,SAAS,OAAO,GAAG,CAAC;AACxB,UAAM,QAAQ,IAAI,YAAY,KAAK,EAAE;AACrC,QAAI,QAAQ;AACZ,SAAK,YAAY;AAAA,MACf,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ;AAAA,MACA,OAAO,QAAQ,IAAI;AAAA,MACnB,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,YAAY,OAAuB;AACjC,UAAM,IAAI,KAAK;AACf,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,KAAK,MAAM,IAAI,EAAE;AACvB,UAAM,KAAK,MAAM,IAAI,EAAE;AACvB,UAAM,MAAM,KAAK,IAAI,CAAC,EAAE,KAAK;AAC7B,UAAM,MAAM,KAAK,IAAI,CAAC,EAAE,KAAK;AAC7B,UAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,UAAM,KAAK,KAAK,MAAM,KAAK;AAC3B,WAAO,KAAK,IAAI,EAAE,KAAK,EAAE,SAAS,KAAK,IAAI,EAAE,KAAK,EAAE;AAAA,EACtD;AAAA,EAEA,iBAAiE;AAC/D,UAAM,IAAI,KAAK;AACf,WAAO,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,EAAE,IAAI,OAAO,EAAE,MAAM,IAAI;AAAA,EACpD;AAAA;AAAA,EAIQ,aAA+B;AAAA,EAC/B,eAA+D;AAAA,EAC/D,gBAA+B;AAAA,EAC/B,eAAsC;AAAA;AAAA;AAAA;AAAA,EAK9C,IAAI,YAA8B;AAChC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA,EAIA,aAAa,OAAyB,SAAuD;AAC3F,SAAK,aAAa;AAClB,QAAI,QAAS,MAAK,eAAe;AACjC,QAAI,CAAC,OAAO;AACV,WAAK,eAAe;AACpB,WAAK,gBAAgB;AAAA,IACvB;AACA,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA,EAIA,UAAU,WAA2C;AACnD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,cAAc,UAA0B;AACtC,QAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,WAAY;AAC5C,UAAM,QAAQ,KAAK,UAAU,QAAQ;AACrC,UAAM,MAAM,KAAK,UAAU,KAAK;AAChC,QAAI,QAAQ,KAAK,cAAe;AAChC,SAAK,gBAAgB;AACrB,SAAK,aAAa,KAAK;AAAA,EACzB;AAAA;AAAA,EAGA,mBAAmB,QAAqC;AACtD,SAAK,eAAe;AACpB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGU,kBAA0B;AAClC,WAAO,KAAK,eAAe,KAAK,QAAa,iBAAiB;AAAA,EAChE;AAAA,EAEQ,QAAoC;AAAA;AAAA,EAG5C,QAAQ,QAA0C;AAChD,SAAK,QAAQ;AACb,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,OAAoB;AAClB,WAAO,KAAK,QAAQ,KAAK;AAAA,EAC3B;AAAA;AAAA,EAGA,cAA2B;AACzB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,YAAgC;AAC9B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,iBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEQ,WAAW;AAAA,EACX,WAAyB;AAAA;AAAA,EAGjC,IAAI,UAAmB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAW,IAAmB;AAC5B,QAAI,KAAK,aAAa,GAAI;AAC1B,SAAK,WAAW;AAChB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA,EAIA,IAAI,UAAwB;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAW,OAA2B;AACpC,UAAM,MAAM,KAAK;AACjB,QAAI,QAAQ,SAAU,OAAO,SAAS,IAAI,MAAM,MAAM,KAAK,IAAI,MAAM,MAAM,EAAI;AAC/E,SAAK,WAAW,QAAQ,EAAE,GAAG,MAAM,GAAG,GAAG,MAAM,EAAE,IAAI;AACrD,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA,EAIA,eAAe,QAAe,WAAsC;AAClE,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,QAAQ,OAAc,UAA6B;AACjD,WAAO,KAAK,QAAQ,OAAO,QAAQ;AAAA,EACrC;AAAA;AAAA,EAGA,aAAa,OAAe,QAAsB;AAChD,SAAK,aAAa,OAAO,MAAM;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKU,WAAW,SAAmC,YAA2B,MAA2D;AAC5I,UAAM,MAAO,KAAK,OAAmC;AACrD,UAAM,YAAY,OAAO,QAAQ,WAAW,MAAM;AAClD,UAAM,QAAQ,KAAK,YAAY,SAAS;AACxC,WAAO;AAAA,MACL,OAAO,gBAAgB,OAAO,SAAS,SAAS;AAAA,MAChD,aAAa,UAAU,MAAM,cAAc,KAAK,gBAAgB,KAAK,gBAAgB,GAAG,OAAO,IAAI;AAAA,IACrG;AAAA,EACF;AAAA;AAAA,EAMA,SAA4B;AAC1B,UAAM,QAAQ,KAAK;AACnB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,IAAI,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,MACX,SAAS,KAAK,SAAS,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAAA,MAC5C,OAAO,EAAE,GAAG,KAAK,OAAO;AAAA,MACxB,SAAS,EAAE,GAAG,KAAK,SAAS;AAAA,MAC5B,GAAI,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,CAAC;AAAA,MAC/D,GAAI,KAAK,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;AAAA,IAC1D;AAAA,EACF;AAAA,EAEA,SAAS,MAA+B;AACtC,SAAK,WAAW,KAAK,eAAe,KAAK,QAAQ,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;AACvE,SAAK,SAAS,EAAE,GAAG,eAAe,GAAG,KAAK,MAAM;AAChD,SAAK,WAAW,iBAAiB,KAAK,OAAO;AAC7C,SAAK,SAAS,EAAE,GAAG,KAAK,aAAa,GAAG,GAAG,KAAK,aAAc,KAAK,SAAS,CAAC,CAAgB,EAAE;AAC/F,SAAK,QAAQ,KAAK;AAClB,QAAI,EAAE,KAAK,KAAK,gBAAiB,MAAK,cAAe,KAAK,SAAS,CAAC,CAAuC;AAC3G,SAAK,cAAc;AAAA,EACrB;AACF;;;ASh1BO,IAAM,iBAAN,MAAqB;AAAA,EACT,YAAY,oBAAI,IAAwB;AAAA,EACjD,SAAmB,CAAC;AAAA;AAAA,EACpB,cAA6B;AAAA,EAC7B,SAA2B;AAAA,EAC3B,UAAyC;AAAA,EACzC,oBAAsC;AAAA,EACtC,aAAa;AAAA,EACb,aAA+B;AAAA,EAC/B,YAA2B;AAAA,EAC3B,gBAA+B;AAAA,EAC/B,eAAuC;AAAA,EACvC,eAAuC;AAAA,EACvC,eAAsC;AAAA,EACtC,QAAoC;AAAA,EAC3B,aAAa,oBAAI,IAAiD;AAAA;AAAA,EAGnF,aAAa,QAAgC;AAC3C,SAAK,aAAa;AAClB,eAAWC,YAAW,KAAK,UAAU,OAAO,EAAG,CAAAA,SAAQ,aAAa,MAAM;AAAA,EAC5E;AAAA;AAAA,EAGA,YAAY,MAA2B;AACrC,SAAK,YAAY;AACjB,eAAWA,YAAW,KAAK,UAAU,OAAO,EAAG,CAAAA,SAAQ,YAAY,IAAI;AAAA,EACzE;AAAA;AAAA,EAGA,gBAAgB,MAA2B;AACzC,SAAK,gBAAgB;AACrB,eAAWA,YAAW,KAAK,UAAU,OAAO,EAAG,CAAAA,SAAQ,gBAAgB,IAAI;AAAA,EAC7E;AAAA;AAAA;AAAA,EAIA,kBAAkB,QAAsC;AACtD,SAAK,eAAe;AACpB,eAAWA,YAAW,KAAK,UAAU,OAAO,EAAG,CAAAA,SAAQ,kBAAkB,MAAM;AAAA,EACjF;AAAA;AAAA;AAAA,EAIA,eAAe,QAAsC;AACnD,SAAK,eAAe;AACpB,eAAWA,YAAW,KAAK,UAAU,OAAO,EAAG,CAAAA,SAAQ,eAAe,MAAM;AAAA,EAC9E;AAAA;AAAA;AAAA,EAIA,mBAAmB,QAAqC;AACtD,SAAK,eAAe;AACpB,eAAWA,YAAW,KAAK,UAAU,OAAO,EAAG,CAAAA,SAAQ,mBAAmB,MAAM;AAAA,EAClF;AAAA;AAAA;AAAA,EAIA,QAAQ,QAA0C;AAChD,SAAK,QAAQ;AACb,eAAWA,YAAW,KAAK,UAAU,OAAO,EAAG,CAAAA,SAAQ,QAAQ,MAAM;AAAA,EACvE;AAAA;AAAA,EAGA,oBAAoB,SAAiC;AACnD,SAAK,oBAAoB;AACzB,eAAWA,YAAW,KAAK,UAAU,OAAO,EAAG,CAAAA,SAAQ,oBAAoB,OAAO;AAAA,EACpF;AAAA;AAAA,EAGA,aAAa,QAAuB;AAClC,SAAK,aAAa;AAClB,eAAWA,YAAW,KAAK,UAAU,OAAO,EAAG,CAAAA,SAAQ,gBAAgB,MAAM;AAAA,EAC/E;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAAO,OAAkB,QAAsC;AAC7D,QAAI,KAAK,OAAQ,MAAK,OAAO;AAC7B,SAAK,SAAS;AACd,SAAK,UAAU;AACf,eAAW,MAAM,KAAK,QAAQ;AAC5B,YAAMA,WAAU,KAAK,UAAU,IAAI,EAAE;AACrC,UAAIA,SAAS,QAAO,gBAAgBA,QAAO;AAAA,IAC7C;AAAA,EACF;AAAA,EAEA,SAAe;AACb,QAAI,KAAK,SAAS;AAChB,iBAAWA,YAAW,KAAK,UAAU,OAAO,GAAG;AAC7C,YAAI;AACF,eAAK,QAAQ,gBAAgBA,QAAO;AAAA,QACtC,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AACA,SAAK,SAAS;AACd,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,aAAsB;AACpB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA;AAAA,EAIA,IAAIA,UAAyB;AAC3B,QAAI,KAAK,UAAU,IAAIA,SAAQ,EAAE,EAAG;AAGpC,UAAM,WAAWA;AACjB,aAAS,oBAAoB,KAAK,iBAAiB;AACnD,aAAS,gBAAgB,KAAK,UAAU;AACxC,aAAS,aAAa,KAAK,UAAU;AACrC,aAAS,YAAY,KAAK,SAAS;AACnC,aAAS,gBAAgB,KAAK,aAAa;AAC3C,aAAS,kBAAkB,KAAK,YAAY;AAC5C,aAAS,eAAe,KAAK,YAAY;AACzC,QAAI,KAAK,aAAc,UAAS,mBAAmB,KAAK,YAAY;AACpE,QAAI,KAAK,MAAO,UAAS,QAAQ,KAAK,KAAK;AAC3C,SAAK,UAAU,IAAI,SAAS,IAAI,QAAQ;AACxC,SAAK,OAAO,KAAK,SAAS,EAAE;AAC5B,SAAK,SAAS,gBAAgB,QAAQ;AACtC,SAAK,KAAK,iBAAiB,EAAE,WAAW,SAAS,IAAI,SAAS,SAAS,CAAC;AAAA,EAC1E;AAAA,EAEA,OAAO,IAAkB;AACvB,UAAMA,WAAU,KAAK,UAAU,IAAI,EAAE;AACrC,QAAI,CAACA,SAAS;AACd,QAAI,KAAK,gBAAgB,GAAI,MAAK,SAAS;AAC3C,QAAI,KAAK,SAAS;AAChB,UAAI;AACF,aAAK,QAAQ,gBAAgBA,QAAO;AAAA,MACtC,QAAQ;AAAA,MAER;AAAA,IACF;AACA,SAAK,UAAU,OAAO,EAAE;AACxB,SAAK,SAAS,KAAK,OAAO,OAAO,CAAC,MAAM,MAAM,EAAE;AAChD,SAAK,KAAK,mBAAmB,EAAE,WAAW,GAAG,CAAC;AAAA,EAChD;AAAA,EAEA,IAAI,IAAkC;AACpC,WAAO,KAAK,UAAU,IAAI,EAAE;AAAA,EAC9B;AAAA;AAAA,EAGA,MAAkB;AAChB,WAAO,KAAK,OACT,IAAI,CAAC,OAAO,KAAK,UAAU,IAAI,EAAE,CAAC,EAClC,OAAO,CAAC,MAAuB,CAAC,CAAC,CAAC;AAAA,EACvC;AAAA,EAEA,QAAc;AACZ,SAAK,SAAS;AACd,QAAI,KAAK,SAAS;AAChB,iBAAWA,YAAW,KAAK,UAAU,OAAO,GAAG;AAC7C,YAAI;AACF,eAAK,QAAQ,gBAAgBA,QAAO;AAAA,QACtC,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AACA,SAAK,UAAU,MAAM;AACrB,SAAK,SAAS,CAAC;AACf,SAAK,KAAK,mBAAmB,CAAC,CAAC;AAAA,EACjC;AAAA;AAAA,EAIA,OAAO,IAAkB;AACvB,UAAMA,WAAU,KAAK,UAAU,IAAI,EAAE;AACrC,QAAI,CAACA,YAAW,KAAK,gBAAgB,GAAI;AACzC,QAAI,KAAK,YAAa,MAAK,UAAU,IAAI,KAAK,WAAW,GAAG,SAAS,QAAQ;AAC7E,IAAAA,SAAQ,SAAS,UAAU;AAC3B,SAAK,cAAc;AACnB,SAAK,KAAK,oBAAoB,EAAE,WAAW,IAAI,SAAAA,SAAQ,CAAC;AAAA,EAC1D;AAAA,EAEA,WAAiB;AACf,QAAI,CAAC,KAAK,YAAa;AACvB,UAAM,KAAK,KAAK;AAChB,SAAK,UAAU,IAAI,EAAE,GAAG,SAAS,QAAQ;AACzC,SAAK,cAAc;AACnB,SAAK,KAAK,sBAAsB,EAAE,WAAW,GAAG,CAAC;AAAA,EACnD;AAAA,EAEA,WAA4B;AAC1B,WAAQ,KAAK,eAAe,KAAK,UAAU,IAAI,KAAK,WAAW,KAAM;AAAA,EACvE;AAAA;AAAA;AAAA,EAKA,aAAa,IAAkB;AAC7B,UAAMA,WAAU,KAAK,UAAU,IAAI,EAAE;AACrC,QAAI,CAACA,SAAS;AACd,UAAM,MAAM,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,MAAM,CAAC;AAClE,IAAAA,SAAQ,cAAc,EAAE,QAAQ,MAAM,EAAE,CAAC;AACzC,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,WAAW,IAAkB;AAC3B,UAAMA,WAAU,KAAK,UAAU,IAAI,EAAE;AACrC,QAAI,CAACA,SAAS;AACd,UAAM,SAAS,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,MAAM,CAAC;AACrE,IAAAA,SAAQ,cAAc,EAAE,QAAQ,SAAS,EAAE,CAAC;AAC5C,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,IAAkB;AAC7B,SAAK,UAAU,IAAI,CAAE;AAAA,EACvB;AAAA;AAAA,EAGA,aAAa,IAAkB;AAC7B,SAAK,UAAU,IAAI,EAAE;AAAA,EACvB;AAAA,EAEQ,UAAU,IAAY,KAAmB;AAC/C,UAAM,SAAS,KAAK,YAAY;AAChC,UAAM,KAAK,OAAO,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AAC9C,QAAI,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK,OAAO,OAAO,OAAQ;AACzD,UAAM,QAAQ,OAAO,KAAK,GAAG;AAC7B,WAAO,KAAK,GAAG,IAAI,OAAO,EAAE;AAC5B,WAAO,EAAE,IAAI;AACb,WAAO,QAAQ,CAAC,GAAG,MAAM;AACvB,UAAI,EAAE,QAAQ,WAAW,EAAG,GAAE,cAAc,EAAE,QAAQ,EAAE,CAAC;AAAA,IAC3D,CAAC;AACD,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA,EAIA,cAAc,IAAmD;AAC/D,UAAM,SAAS,KAAK,YAAY;AAChC,UAAM,KAAK,OAAO,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AAC9C,WAAO,EAAE,SAAS,KAAK,KAAK,OAAO,OAAO,SAAS,GAAG,QAAQ,MAAM,EAAE;AAAA,EACxE;AAAA;AAAA,EAGQ,cAA4B;AAClC,WAAO,KAAK,OACT,IAAI,CAAC,QAAQ,KAAK,UAAU,IAAI,GAAG,CAAC,EACpC,OAAO,CAAC,MAAuB,CAAC,CAAC,CAAC,EAClC,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,SAAS,EAAE,QAAQ,MAAM;AAAA,EACvD;AAAA;AAAA;AAAA,EAIQ,UAAgB;AACtB,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,SAAS,KAAK,YAAY;AAChC,eAAWA,YAAW,QAAQ;AAC5B,UAAI;AACF,aAAK,QAAQ,gBAAgBA,QAAO;AACpC,aAAK,QAAQ,gBAAgBA,QAAO;AAAA,MACtC,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,cAA+B;AAC7B,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,QAAS,QAAO;AAC1C,WAAO,WAAW,KAAK,QAAQ,KAAK,OAAO;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ,OAA+B;AACrC,UAAM,WAAW,KAAK,YAAY;AAClC,QAAI,CAAC,SAAU,QAAO;AACtB,UAAM,MAAM,KAAK,SAAS;AAC1B,QAAI,OAAO,IAAI,aAAa,KAAK,IAAI,QAAQ,OAAO,QAAQ,EAAG,QAAO;AACtE,UAAM,YAAY,CAAC,GAAG,KAAK,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,KAAK,UAAU,IAAI,EAAE,CAAC;AAC/E,cAAU,KAAK,CAAC,GAAG,OAAO,GAAG,QAAQ,UAAU,MAAM,GAAG,QAAQ,UAAU,EAAE;AAC5E,eAAWA,YAAW,WAAW;AAC/B,UAAI,CAACA,YAAW,CAACA,SAAQ,aAAa,EAAG;AACzC,UAAIA,SAAQ,QAAQ,OAAO,QAAQ,EAAG,QAAOA;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,SAA8B;AAC5B,WAAO,KAAK,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,EACzC;AAAA;AAAA,EAIA,GAAG,OAAyB,UAA4C;AACtE,QAAI,MAAM,KAAK,WAAW,IAAI,KAAK;AACnC,QAAI,CAAC,KAAK;AACR,YAAM,oBAAI,IAAI;AACd,WAAK,WAAW,IAAI,OAAO,GAAG;AAAA,IAChC;AACA,QAAI,IAAI,QAAQ;AAChB,WAAO,MAAM;AACX,UAAI,OAAO,QAAQ;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,KAAK,MAAwB,MAAwC;AAC3E,UAAM,YAAY,KAAK,WAAW,IAAI,IAAI;AAC1C,QAAI,CAAC,UAAW;AAChB,UAAM,QAAsB,EAAE,MAAM,GAAG,KAAK;AAC5C,eAAW,YAAY,UAAW,UAAS,KAAK;AAAA,EAClD;AACF;;;AC3VA,SAAS,yBAAyB;AAQlC,IAAM,cAAc;AAcb,SAAS,UACd,KACA,UACA,UACA,MACe;AACf,MAAI,OAAsB;AAC1B,MAAI,eAAe;AACnB,aAAW,SAAS,CAAC,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,GAAG;AAC5D,UAAM,IAAI,SAAS,KAAK;AACxB,QAAI,MAAM,KAAM;AAChB,UAAM,WAAW,KAAK,IAAI,IAAI,QAAQ;AACtC,QAAI,WAAW,cAAc;AAC3B,qBAAe;AACf,aAAO;AAAA,IACT;AAAA,EACF;AACA,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,SAAS,UAAU,eAAe,YAAa,QAAO;AAC1D,SAAO;AACT;AAOO,SAAS,WACd,OACA,QACA,OACA,MACe;AACf,MAAI,SAAS,MAAO,QAAO;AAC3B,MAAI,MAAsB;AAC1B,MAAI;AACF,UAAM,UAAU,MAAM,UAAU,EAAE,oBAAoB,MAAM,CAAC;AAC7D,QAAI,YAAY,KAAM,QAAO;AAC7B,UAAM,OAAO,OAAO,YAAY,KAAK,MAAM,OAAO,GAAG,kBAAkB,WAAW;AAClF,QAAI,CAAC,QAAQ,EAAE,UAAU,MAAO,QAAO;AACvC,UAAM;AAAA,EACR,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,UAAU,KAAK,MAAM,GAAG,CAAC,MAAM,OAAO,kBAAkB,CAAC,GAAG,IAAI;AAC9E,MAAI,UAAU,KAAM,QAAO;AAC3B,SAAO,EAAE,MAAM,IAAI,MAAM,MAAM;AACjC;;;AClEO,SAAS,kBAAkB,GAAU,GAAU,GAAkB;AACtE,QAAM,KAAK,EAAE,IAAI,EAAE;AACnB,QAAM,KAAK,EAAE,IAAI,EAAE;AACnB,QAAM,WAAW,KAAK,KAAK,KAAK;AAChC,MAAI,aAAa,EAAG,QAAO,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC1D,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,MAAM,QAAQ,CAAC;AACnF,SAAO,KAAK,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE,KAAK,EAAE,IAAI,IAAI,GAAG;AAC9D;AAWO,SAAS,SAAS,GAAU,GAAiB;AAClD,SAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE;AAClD;AAGO,SAAS,QAAQ,GAAU,GAAkB;AAClD,SAAO,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACxC;AAGO,SAAS,iBAAiB,GAAU,GAAkB;AAC3D,MAAI,QAAQ,QAAQ,GAAG,CAAC;AACxB,MAAI,QAAQ,KAAK,KAAK,EAAG,UAAS,KAAK;AACvC,MAAI,QAAQ,CAAC,KAAK,KAAK,EAAG,UAAS,KAAK;AACxC,SAAO;AACT;AAOO,SAAS,cACd,GACA,GACA,OACA,QACA,MACA,OACwB;AACxB,QAAM,KAAK,EAAE,IAAI,EAAE;AACnB,QAAM,KAAK,EAAE,IAAI,EAAE;AACnB,MAAI,OAAO,KAAK,OAAO,EAAG,QAAO,EAAE,GAAG,EAAE;AAIxC,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,OAAO,GAAG;AACZ,UAAM,MAAM,IAAI,EAAE,KAAK;AACvB,UAAM,MAAM,QAAQ,EAAE,KAAK;AAC3B,WAAO,KAAK,IAAI,IAAI,EAAE;AACtB,WAAO,KAAK,IAAI,IAAI,EAAE;AAAA,EACxB,OAAO;AACL,QAAI,EAAE,IAAI,KAAK,EAAE,IAAI,MAAO,QAAO,EAAE,GAAG,EAAE;AAAA,EAC5C;AACA,MAAI,OAAO,GAAG;AACZ,UAAM,MAAM,IAAI,EAAE,KAAK;AACvB,UAAM,MAAM,SAAS,EAAE,KAAK;AAC5B,WAAO,KAAK,IAAI,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;AACtC,WAAO,KAAK,IAAI,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;AAAA,EACxC,WAAW,EAAE,IAAI,KAAK,EAAE,IAAI,QAAQ;AAClC,WAAO,EAAE,GAAG,EAAE;AAAA,EAChB;AACA,MAAI,OAAO,KAAM,QAAO,EAAE,GAAG,EAAE;AAE/B,QAAM,KAAK,OAAO,KAAK,IAAI,GAAG,IAAI,IAAI;AACtC,QAAM,KAAK,QAAQ,KAAK,IAAI,GAAG,IAAI,IAAI;AACvC,SAAO;AAAA,IACL,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,IAAI,KAAK,GAAG;AAAA,IACxC,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,IAAI,KAAK,GAAG;AAAA,EAC1C;AACF;;;ACxEA,IAAM,QAAQ,oBAAI,IAA8B;AAIhD,IAAM,cAAc;AAEb,SAAS,iBAAiB,KAAa,OAA+B;AAC3E,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,IAAI,GAAG,EAAG,OAAM,OAAO,GAAG;AACpC,QAAM,IAAI,KAAK,KAAK;AACpB,SAAO,MAAM,OAAO,aAAa;AAC/B,UAAM,SAAS,MAAM,KAAK,EAAE,KAAK;AACjC,QAAI,OAAO,KAAM;AACjB,UAAM,OAAO,OAAO,KAAK;AAAA,EAC3B;AACF;AAGO,SAAS,kBAAkB,KAAsC;AACtE,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,MAAM,MAAM,IAAI,GAAG;AACzB,MAAI,CAAC,IAAK,QAAO;AAEjB,SAAO,IAAI,YAAY,IAAI,eAAe,IAAI,MAAM;AACtD;;;ACxBO,SAAS,aAAgD,OAA+B;AAC7F,SAAO,eAAe,SAAS,OAAO,KAAK,KAAK,EAAE,WAAW,IAAI,QAAQ,EAAE,GAAG,OAAO,WAAW,KAAK;AACvG;AAIO,SAAS,YAAY,MAA8B,MAAM,UAAgF;AAC9I,QAAM,SAAS,KAAK,GAAG;AACvB,MAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC;AACpC,SAAO,OACJ,OAAO,CAAC,MAAoC,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,OAAQ,EAA8B,UAAU,QAAQ,EACpI,IAAI,CAAC,OAAO;AAAA,IACX,OAAO,EAAE;AAAA,IACT,SAAS,EAAE,YAAY;AAAA,IACvB,GAAI,OAAO,EAAE,UAAU,WAAW,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAAA,IACxD,GAAI,OAAO,EAAE,SAAS,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAAA,EACvD,EAAE;AACN;;;ACXO,IAAM,cAAc,CAAC,aAA6B,WAAW,IAAI;AAIxE,IAAM,WAAW,CAAC,aAA6B,WAAW,IAAI;AAC9D,IAAM,UAAU,CAAC,aAA6B,WAAW,IAAI;AAGtD,SAAS,QAAQ,OAAmB,OAAe,QAAuB;AAC/E,QAAM,MAAM,KAAK,IAAI,MAAM,KAAK;AAChC,QAAM,MAAM,KAAK,IAAI,MAAM,KAAK;AAChC,SAAO,EAAE,GAAG,MAAM,IAAI,QAAQ,MAAM,SAAS,KAAK,GAAG,MAAM,IAAI,QAAQ,MAAM,SAAS,IAAI;AAC5F;AAiBO,SAAS,gBAAgB,KAA+B,OAAe,OAAmB,OAAqB,SAAqD;AACzK,QAAM,OAAO,MAAM;AACnB,QAAM,OAAO,SAAS,IAAI;AAC1B,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,QAAQ,OAAO,MAAM,QAAQ,KAAK;AACxC,QAAM,OAAO,MAAM,UAAU,SAAS,IAAI,MAAM,UAAU,UAAU,CAAC,QAAQ,CAAC,QAAQ;AACtF,QAAM,MAAM,UAAU,MAAM,WAAW,GAAG;AAC1C,MAAI,KAAK;AACT,MAAI,YAAY,CAAC,CAAC;AAClB,MAAI,UAAU,MAAM,GAAG,MAAM,CAAC;AAC9B,MAAI,MAAM,MAAO,KAAI,OAAO,MAAM,KAAK;AACvC,MAAI,OAAO,OAAO,KAAK;AACvB,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,SAAS,OAAO,OAAO,OAAO,KAAK,CAAC;AAExC,MAAI,KAAK,OAAO,OAAO;AACvB,MAAI,KAAK;AACT,MAAI,CAAC,MAAM,OAAO;AAChB,SAAK,KAAK,MAAM,MAAM,IAAI,KAAK,GAAG,IAAI,MAAM,MAAM;AAClD,SAAK,KAAK,MAAM,MAAM,IAAI,CAAC,IAAI,MAAM,MAAM;AAAA,EAC7C;AACA,MAAI,cAAc;AAClB,MAAI,YAAY;AAChB,MAAI,UAAU;AACd,MAAI,WAAW;AACf,MAAI,UAAU;AACd,MAAI,OAAO,KAAK,OAAO,GAAG,EAAE;AAC5B,MAAI,OAAO,KAAK,OAAO,GAAG,EAAE;AAC5B,MAAI,OAAO,IAAI,KAAK,OAAO,CAAC;AAC5B,MAAI,OAAO,IAAI,KAAK,OAAO,CAAC;AAC5B,MAAI,OAAO;AACX,MAAI,QAAQ;AACZ,QAAM,SAAS,QAAQ,OAAO,OAAO,QAAQ,GAAG,CAAC;AACjD,SAAO,EAAE,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,OAAO,MAAM,OAAO,OAAO,QAAQ,IAAI,GAAG,OAAO,OAAO,IAAI,EAAE;AACrG;AAGO,SAAS,SAAS,OAAc,GAA8B;AACnE,QAAM,KAAK,MAAM,IAAI,EAAE;AACvB,QAAM,KAAK,MAAM,IAAI,EAAE;AACvB,QAAM,MAAM,KAAK,IAAI,CAAC,EAAE,KAAK;AAC7B,QAAM,MAAM,KAAK,IAAI,CAAC,EAAE,KAAK;AAC7B,SAAO,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,KAAK,EAAE,SAAS,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,KAAK,EAAE;AACxF;;;ACrFO,IAAM,eAAe;AACrB,IAAM,YAAY;AACzB,IAAM,WAAW;AAEV,IAAM,kBAAkB;AAI/B,IAAM,QAAQ;AACd,IAAM,MAAM;AACZ,IAAM,SAAS;AACf,IAAM,UAAU;AAChB,IAAM,UAAU;AAcT,SAAS,WAAW,IAAW,MAA2B,SAA6C;AAC5G,QAAM,SAAS,KAAK,OAAO,CAAC,GAAG,MAAM,KAAK,IAAI,GAAG,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC;AACpE,SAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,OAAO,KAAK,MAAM,UAAU,SAAS,OAAO,GAAG,QAAQ,QAAQ,IAAI,KAAK,SAAS,IAAI;AAClH;AAGO,SAAS,cAAc,KAA+BC,MAAe,MAA2B,MAAoB;AACzH,MAAI,KAAK;AACT,MAAI,YAAY,CAAC,CAAC;AAClB,MAAI,YAAY;AAChB,MAAI,UAAU;AACd,MAAI,UAAUA,KAAI,GAAGA,KAAI,GAAGA,KAAI,OAAOA,KAAI,QAAQ,CAAC;AACpD,MAAI,KAAK;AACT,MAAI,OAAO;AACX,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,OAAK,QAAQ,CAAC,KAAK,MAAM;AACvB,UAAM,SAASA,KAAI,IAAI,QAAQ,MAAM,IAAI,IAAI;AAC7C,cAAU,KAAK,IAAI,MAAMA,KAAI,IAAI,QAAQ,MAAM;AAC/C,QAAI,YAAY;AAChB,QAAI,SAAS,IAAI,MAAMA,KAAI,IAAI,SAAS,MAAM;AAAA,EAChD,CAAC;AACD,MAAI,QAAQ;AACd;AAIA,SAAS,UAAU,KAA+B,MAAwB,IAAY,IAAkB;AACtG,MAAI,cAAc;AAClB,MAAI,YAAY;AAChB,MAAI,UAAU;AACd,MAAI,WAAW;AACf,MAAI,UAAU;AACd,MAAI,SAAS,SAAS;AACpB,eAAW,MAAM,CAAC,MAAM,GAAG,GAAG;AAC5B,UAAI,OAAO,KAAK,GAAG,KAAK,EAAE;AAC1B,UAAI,OAAO,KAAK,GAAG,KAAK,EAAE;AAAA,IAC5B;AACA,QAAI,OAAO,KAAK,KAAK,KAAK,CAAC;AAC3B,QAAI,OAAO,KAAK,KAAK,KAAK,CAAC;AAC3B,eAAW,KAAK,CAAC,IAAI,CAAC,GAAG;AACvB,UAAI,OAAO,KAAK,GAAG,KAAK,IAAI,CAAC;AAC7B,UAAI,OAAO,KAAK,KAAK,KAAK,IAAI,GAAG;AACjC,UAAI,OAAO,KAAK,GAAG,KAAK,IAAI,CAAC;AAAA,IAC/B;AAAA,EACF,WAAW,SAAS,QAAQ;AAC1B,eAAW,KAAK,CAAC,MAAM,GAAG,GAAG;AAC3B,UAAI,KAAK,KAAK,GAAG,KAAK,KAAK,GAAG,CAAC;AAC/B,UAAI,OAAO,KAAK,IAAI,GAAG,KAAK,CAAC;AAC7B,UAAI,OAAO,KAAK,IAAI,GAAG,KAAK,CAAC;AAC7B,UAAI,OAAO,KAAK,IAAI,GAAG,KAAK,CAAC;AAC7B,UAAI,OAAO,KAAK,IAAI,GAAG,KAAK,CAAC;AAAA,IAC/B;AACA,QAAI,OAAO,KAAK,KAAK,KAAK,GAAG;AAC7B,QAAI,OAAO,KAAK,KAAK,KAAK,GAAG;AAC7B,eAAW,KAAK,CAAC,IAAI,CAAC,GAAG;AACvB,UAAI,OAAO,KAAK,GAAG,KAAK,CAAC;AACzB,UAAI,OAAO,KAAK,IAAI,KAAK,KAAK,GAAG;AACjC,UAAI,OAAO,KAAK,GAAG,KAAK,CAAC;AAAA,IAC3B;AAAA,EACF,OAAO;AACL,UAAM,SAAS,EAAE,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI;AAC1C,UAAM,MAAO,OAAO,KAAK,KAAM;AAC/B,QAAI,OAAO,KAAK,GAAG,OAAO,CAAC;AAC3B,QAAI,OAAO,KAAK,GAAG,OAAO,CAAC;AAC3B,QAAI,OAAO,OAAO,GAAG,OAAO,CAAC;AAC7B,QAAI,OAAO,OAAO,IAAI,OAAO,KAAK,IAAI,GAAG,GAAG,OAAO,IAAI,OAAO,KAAK,IAAI,GAAG,CAAC;AAC3E,QAAI,OAAO,OAAO,IAAI,GAAG,OAAO,CAAC;AACjC,QAAI,IAAI,OAAO,GAAG,OAAO,GAAG,GAAG,GAAG,CAAC,KAAK,IAAI;AAAA,EAC9C;AACA,MAAI,OAAO;AACb;;;AC/FO,IAAM,iBAAiB;AAGvB,IAAM,cAAc;AAwBpB,IAAM,aAAa,CAAC,eAA+B,aAAa,IAAI;AAI3E,IAAM,cAAc,CAAC,MAAc,eAA+B,KAAK,IAAI,YAAY,OAAO,oBAAoB,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,UAAU;AAOzI,SAAS,eAAe,KAA+B,GAAyB;AACrF,QAAM,QAAQ,EAAE;AAChB,QAAM,QAAQ,EAAE,cAAc,EAAE,YAAY,QAAQ,EAAE;AACtD,QAAM,UAAU,CAAC,MAAsB,EAAE,IAAI,IAAI,EAAE;AACnD,QAAM,OAAO,CAAC,OAAkB,MAAsB,EAAE,IAAI,SAAS,OAAO,GAAG,EAAE,OAAO,EAAE,KAAK;AAC/F,MAAI,KAAK;AACT,MAAI,YAAY,CAAC,CAAC;AAElB,MAAI,YAAY;AAChB,MAAI,SAAS,MAAM,mBAAmB,MAAM,gBAAgB,CAAC,EAAE,aAAa;AAC1E,QAAI,YAAY;AAChB,eAAW,QAAQ,SAAS,EAAE,OAAO,MAAM,gBAAgB,MAAM,cAAc,EAAE,OAAO,GAAG;AACzF,YAAM,OAAO,KAAK,MAAM,KAAK,EAAE,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE;AAC1D,YAAM,KAAK,KAAK,KAAK,KAAK,EAAE,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE;AACvD,UAAI,KAAK,KAAM,KAAI,SAAS,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,UAAU;AAAA,IAC/E;AAAA,EACF;AACA,MAAI,OAAO,EAAE;AACb,MAAI,YAAY,EAAE;AAClB,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,QAAM,QAAQ,IAAI;AAClB,MAAI,EAAE,YAAa,KAAI,cAAc,QAAQ,EAAE,YAAY;AAC3D,QAAM,MAAM,QAAQ,CAAC,GAAG,MAAM;AAC5B,QAAI,EAAE,SAAS,GAAI;AACnB,QAAI,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,QAAQ,CAAC,IAAI,WAAW,EAAE,UAAU,CAAC;AAAA,EAC5E,CAAC;AACD,MAAI,cAAc;AAClB,MAAI,OAAO,eAAe,CAAC,EAAE,aAAa;AACxC,eAAW,QAAQ,SAAS,EAAE,OAAO,MAAM,YAAY,OAAO,MAAM,YAAY,KAAK,EAAE,OAAO,GAAG;AAC/F,YAAM,OAAO,KAAK,MAAM,KAAK,EAAE,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE;AAC1D,YAAM,KAAK,KAAK,KAAK,KAAK,EAAE,OAAO,KAAK,IAAI,IAAI,KAAK,EAAE;AACvD,UAAI,KAAK,KAAM,KAAI,SAAS,MAAM,QAAQ,KAAK,IAAI,IAAI,EAAE,aAAa,GAAG,KAAK,MAAM,CAAC;AAAA,IACvF;AAAA,EACF;AACA,MAAI,OAAO,SAAS,MAAM,mBAAmB,MAAM,cAAc;AAC/D,UAAM,KAAK,WAAW,EAAE,OAAO,MAAM,cAAc,EAAE,OAAO;AAC5D,UAAM,OAAO,YAAY,EAAE,MAAM,EAAE,UAAU;AAC7C,QAAI,SAAS,KAAK,MAAM,KAAK,EAAE,OAAO,GAAG,IAAI,IAAI,GAAG,CAAC,IAAI,cAAc,GAAG,QAAQ,GAAG,IAAI,IAAI,KAAK,OAAO,EAAE,aAAa,QAAQ,CAAC,GAAG,aAAa,IAAI;AAAA,EACvJ;AACA,MAAI,QAAQ;AACd;AAIO,SAAS,gBAAgB,KAA+BC,MAA8D,OAAe,OAAqB;AAC/J,MAAI,KAAK;AACT,MAAI,YAAY,CAAC,CAAC;AAClB,MAAI,cAAc,IAAI,cAAc;AACpC,MAAI,cAAc;AAClB,MAAI,YAAY;AAChB,MAAI,WAAWA,KAAI,IAAI,GAAGA,KAAI,IAAI,GAAGA,KAAI,QAAQ,GAAGA,KAAI,SAAS,CAAC;AAClE,MAAI,QAAQ;AACd;;;ACxCA,IAAM,aAA6B;AAAA,EACjC,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,SAAS;AAAA,EACT,UAAU;AAAA,EACV,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,WAAW;AACb;AAIA,IAAM,SAAmF;AAAA,EACvF,KAAK,EAAE,GAAG,IAAI,UAAU,SAAS;AAAA,EACjC,QAAQ,EAAE,GAAG,GAAG,UAAU,SAAS;AAAA,EACnC,QAAQ,EAAE,GAAG,GAAG,UAAU,MAAM;AAClC;AAGA,IAAM,oBAAoB;AAG1B,IAAM,kBAAkB;AAExB,SAAS,aAAa,WAA2B;AAC/C,SAAO,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACtC;AAIA,SAAS,MAAM,GAAW,OAAuB;AAC/C,SAAO,KAAK,MAAM,CAAC,KAAK,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,MAAM;AAC9D;AAIA,SAAS,SAAS,KAA+B,MAAa,KAAY,WAAyB;AACjG,QAAM,SAAS,KAAK,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,CAAC;AACxD,MAAI,EAAE,SAAS,GAAI;AACnB,QAAM,MAAM,IAAI,IAAI,KAAK,KAAK;AAC9B,QAAM,MAAM,IAAI,IAAI,KAAK,KAAK;AAC9B,QAAM,OAAO,IAAI,MAAM;AACvB,MAAI,OAAO,IAAI,IAAI,OAAO,KAAK,OAAO,IAAI,IAAI,IAAI,OAAO,KAAK,OAAO,EAAE;AACvE,MAAI,OAAO,IAAI,GAAG,IAAI,CAAC;AACvB,MAAI,OAAO,IAAI,IAAI,OAAO,KAAK,OAAO,IAAI,IAAI,IAAI,OAAO,KAAK,OAAO,EAAE;AACzE;AAGA,SAAS,QAAQ,GAAmB;AAClC,QAAM,SAAS,OAAO,KAAK,IAAI,CAAC,CAAC,EAAE,QAAQ,yBAAyB,GAAG;AACvE,SAAO,IAAI,IAAI,IAAI,MAAM,KAAK;AAChC;AAGA,SAAS,SAAS,SAAyB;AACzC,QAAM,IAAI,KAAK,MAAM,UAAU,KAAK;AACpC,QAAM,IAAI,KAAK,MAAO,UAAU,QAAS,IAAI;AAC7C,QAAM,IAAI,KAAK,MAAO,UAAU,OAAQ,EAAE;AAC1C,SAAO,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;AAC7D;AAaA,SAAS,SAAS,OAAmB,OAAkB,YAAoB,QAA8B;AACvG,QAAM,QAAQ,KAAK,IAAI,GAAG,MAAM,MAAM,MAAM;AAC5C,QAAM,QAAQ,MAAM;AACpB,QAAM,OAAO,MAAM,UAAU,SAAS,IAAI,MAAM,UAAU,UAAU,CAAC,QAAQ,CAAC,QAAQ;AACtF,QAAM,QAAQ,CAAC,aAAa,IAAI;AAChC,QAAM,MAAM,WAAW,QAAQ,SAAS,QAAQ,KAAK,aAAa,WAAW,WAAW,QAAQ,SAAU,QAAQ,KAAK,aAAc;AACrI,SAAO,EAAE,MAAM,KAAK,OAAO,MAAM;AACnC;AAQA,IAAe,YAAf,cAAuF,QAAW;AAAA;AAAA,EAQtF,UAAmB;AAC3B,WAAO;AAAA,EACT;AAAA,EAEU,aAAkE;AAC1E,WAAO,KAAK,WAAW,YAAY,KAAK,KAAK,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA,EAIU,WAAW,KAA+B,UAA0B;AAC5E,UAAM,QAAQ,KAAK;AACnB,QAAI,CAAC,SAAS,KAAK,MAAM,SAAS,GAAI;AACtC,UAAM,QAAQ,KAAK,WAAW,QAAQ;AACtC,QAAI,CAAC,MAAO;AACZ,UAAM,EAAE,OAAO,YAAY,IAAI,KAAK,WAAW;AAC/C,UAAM,QAAQ,QAAS,eAAe,QAAS;AAC/C,UAAMC,OAAM,SAAS,OAAO,OAAO,KAAK,MAAM,UAAU,KAAK,YAAY,CAAC;AAC1E,QAAI,KAAK;AACT,QAAI,UAAU,MAAM,GAAG,MAAM,CAAC;AAC9B,QAAI,MAAM,MAAO,KAAI,OAAO,MAAM,KAAK;AACvC,mBAAe,KAAK;AAAA,MAClB,GAAGA,KAAI;AAAA,MACP,GAAGA,KAAI;AAAA,MACP,OAAOA,KAAI;AAAA,MACX,YAAY,KAAK,MAAM;AAAA,MACvB,MAAM,OAAO,KAAK,KAAK;AAAA,MACvB,OAAO,KAAK,MAAM;AAAA,MAClB,OAAO,MAAM;AAAA,MACb;AAAA,MACA,aAAa,SAAS,cAAc,EAAE,OAAO,aAAa,OAAO,IAAI,IAAI;AAAA,MACzE;AAAA,MACA,SAAS,YAAY,KAAK,KAAK;AAAA,IACjC,CAAC;AACD,QAAI,QAAQ;AAAA,EACd;AAAA,EAES,UAAU,UAA0C;AAC3D,UAAM,QAAQ,KAAK,WAAW,QAAQ;AACtC,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,EAAE,OAAO,YAAY,IAAI,KAAK,WAAW;AAC/C,UAAM,QAAQ,eAAe;AAC7B,UAAMA,OAAM,SAAS,OAAO,OAAO,KAAK,MAAM,UAAU,KAAK,YAAY,CAAC;AAC1E,UAAM,KAAK,QAAQ,OAAOA,KAAI,MAAMA,KAAI,GAAG;AAC3C,WAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,OAAOA,KAAI,OAAO,OAAOA,KAAI,OAAO,YAAY,KAAK,MAAM,UAAU,MAAM,OAAO,KAAK,KAAK,GAAG,OAAO,MAAM,OAAO,WAAW,MAAM,OAAO,MAAM,MAAM;AAAA,EACpL;AAAA;AAAA,EAGU,YAAY,UAA6C;AACjE,QAAI,KAAK,MAAM,SAAS,MAAM,CAAC,KAAK,UAAW,QAAO;AACtD,UAAM,QAAQ,KAAK,WAAW,QAAQ;AACtC,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,EAAE,OAAO,YAAY,IAAI,KAAK,WAAW;AAC/C,UAAM,QAAQ,KAAK,aAAa,cAAc,cAAc;AAC5D,UAAM,aAAa,KAAK,MAAM;AAC9B,UAAMA,OAAM,SAAS,OAAO,OAAO,YAAY,KAAK,YAAY,CAAC;AACjE,UAAM,SAAS,QAAQ,OAAOA,KAAI,OAAOA,KAAI,QAAQ,GAAGA,KAAI,MAAOA,KAAI,QAAQ,aAAc,CAAC;AAC9F,WAAO,EAAE,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,OAAO,MAAM,OAAO,OAAOA,KAAI,QAAQ,IAAI,GAAG,OAAQA,KAAI,QAAQ,aAAc,IAAI,EAAE;AAAA,EAC7H;AAAA,EAES,QAAQ,OAAc,UAA6B;AAC1D,UAAM,SAAS,KAAK,YAAY,QAAQ;AACxC,WAAO,CAAC,CAAC,UAAU,SAAS,OAAO,MAAM;AAAA,EAC3C;AAAA;AAAA,EAGS,cAAc,KAA+B,UAA0B;AAC9E,SAAK,aAAa,IAAI;AACtB,QAAI,KAAK,UAAU,cAAc,KAAK,eAAe,KAAK,MAAM,SAAS,MAAM,CAAC,KAAK,QAAQ,EAAG;AAChG,UAAM,QAAQ,KAAK,WAAW,QAAQ;AACtC,QAAI,CAAC,MAAO;AACZ,SAAK,aAAa,gBAAgB,KAAK,KAAK,gBAAgB,GAAG,OAAO,KAAK,OAAO,YAAY,KAAK,KAAK,CAAC,CAAC;AAAA,EAC5G;AAAA;AAAA;AAAA,EAImB,SAAS,OAAc,UAAmC;AAC3E,UAAM,SAAS,KAAK,aAAa,OAAO,QAAQ;AAChD,QAAI,OAAQ,QAAO;AACnB,QAAI,KAAK,UAAU,eAAe,KAAK,QAAQ,OAAO,QAAQ,KAAK,KAAK,YAAY,KAAK,GAAI,QAAO;AACpG,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,aAAa,OAAc,UAAmC;AACtE,UAAM,OAAO,KAAK,iBAAiB,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,IAAI,MAAM,GAAG,EAAE,IAAI,MAAM,CAAC,KAAK,GAAG;AACxG,WAAO,OAAO,KAAK,iBAAiB,IAAI;AAAA,EAC1C;AAAA,EAEU,mBAA2B;AACnC,WAAO;AAAA,EACT;AAAA;AAAA,EAGS,iBAA0B;AACjC,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,SAAS,OAAc,UAA6B;AAC5D,QAAI,KAAK,QAAQ,OAAO,QAAQ,EAAG,QAAO;AAC1C,WAAO,KAAK,UAAU,cAAc,KAAK,YAAY,KAAK;AAAA,EAC5D;AACF;AAGA,IAAM,aAAa,CAACC,UAA2C,YAAiC,MAAoB,UAClH,IAAI,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,EACA,OAAO,MAAMA,SAAQ,KAAK,EAAE;AAAA,EAC5B,WAAW,MAAM;AAAA,EACjB,SAAS;AACX,CAAC;AAMI,IAAM,YAAN,cAAwB,UAA0B;AAAA,EAC9C,OAAe;AAAA,EAEP,cAAmD,CAAC,GAAG,CAAC,EAAE;AAAA,IAAI,CAAC,MAC9E;AAAA,MACE;AAAA,MACA,MAAM;AACJ,cAAM,WAAW,KAAK,YAAY;AAClC,cAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,eAAO,YAAY,SAAS,SAAS,IAAI,OAAO,KAAK,IAAI;AAAA,MAC3D;AAAA,MACA,MAAM,KAAK,YAAY,KAAK,QAAQ,CAAC,GAAG,SAAS,CAAC;AAAA,MAClD,MAAM,KAAK,UAAU,KAAK,CAAC,CAAC,KAAK,QAAQ,CAAC;AAAA,IAC5C;AAAA,EACF;AAAA,EAEiB,aAAkD,CAAC,GAAG,CAAC,EAAE;AAAA,IAAI,CAAC,MAC7E;AAAA,MACE;AAAA,MACA,MAAM;AACJ,cAAM,WAAW,KAAK,YAAY;AAClC,cAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,eAAO,YAAY,SAAS,SAAS,IAAI,OAAO,IAAI,IAAI;AAAA,MAC1D;AAAA,MACA,MAAM,KAAK,WAAW,KAAK,QAAQ,CAAC,GAAG,IAAI;AAAA,MAC3C,MAAM,KAAK,UAAU,KAAK,CAAC,CAAC,KAAK,QAAQ,CAAC;AAAA,IAC5C;AAAA,EACF;AAAA,EAEmB,eAA+B;AAChD,WAAO,EAAE,GAAG,WAAW;AAAA,EACzB;AAAA,EAES,WAAW,OAAsC;AACxD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,YAAqB;AAC7B,YAAQ,KAAK,UAAU,cAAc,KAAK,UAAU,cAAc,KAAK,aAAa;AAAA,EACtF;AAAA,EAEmB,YAAiD;AAClE,WAAO,KAAK;AAAA,EACd;AAAA,EAEmB,YAAiD;AAClE,WAAO,KAAK;AAAA,EACd;AAAA,EAEmB,YAAiF;AAClG,WAAO,EAAE,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;AAAA,EAC5F;AAAA;AAAA,EAGS,iBAAiB,UAAoC;AAC5D,UAAM,SAAS,MAAM,iBAAiB,QAAQ;AAC9C,WAAO,KAAK,UAAU,YAAY,OAAO,OAAO,CAAC,MAAM,EAAE,QAAQ,KAAK,QAAQ,SAAS,CAAC,IAAI;AAAA,EAC9F;AAAA;AAAA;AAAA,EAIU,WAAW,UAAuC;AAC1D,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,UAAM,QAAQ,iBAAiB,IAAI,EAAE;AAGrC,UAAM,CAAC,MAAM,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AACvD,UAAM,QAAQ,KAAK,MAAM;AACzB,UAAM,KAAK,UAAU,SAAS,OAAO,UAAU,UAAU,QAAQ,SAAS,IAAI,EAAE;AAChF,UAAM,SAAS,KAAK,MAAM,eAAe,QAAQ,CAAC,YAAY,KAAK,MAAM,QAAQ,IAAI,KAAK,MAAM,eAAe,WAAW,YAAY,KAAK,MAAM,QAAQ,IAAI;AAC7J,UAAM,IAAI,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,OAAO,OAAO,MAAM,GAAG,GAAG,MAAM;AACtE,WAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,OAAO,MAAM;AAAA,EAC/C;AAAA,EAEU,cAA0B;AAClC,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAGU,QAAQ,UAAmD;AACnE,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,UAAM,EAAE,YAAY,YAAY,IAAI,KAAK;AACzC,QAAI,CAAC,cAAc,CAAC,YAAa,QAAO,EAAE,GAAG,IAAI,GAAG,GAAG;AACvD,WAAO,cAAc,IAAI,IAAI,SAAS,OAAO,SAAS,QAAQ,YAAY,WAAW;AAAA,EACvF;AAAA;AAAA;AAAA;AAAA,EAKmB,cAAc,OAAgD;AAC/E,UAAM,WAAY,MAAM,iBAAiB;AACzC,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,UAAM,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI;AAC5D,UAAM,gBAA+B,WAAW,aAAa,SAAS,UAAU,WAAW,aAAa,UAAU,SAAS;AAC3H,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,eAAe,iBAAiB,MAAM,gBAAgB,OAAO,WAAW,CAAC,EAAE;AAAA,EAC7G;AAAA;AAAA,EAGU,aAAsB;AAC9B,WAAO,KAAK,MAAM,mBAAmB,KAAK,UAAU;AAAA,EACtD;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,MAAM,KAAK,QAAQ,QAAQ;AACjC,QAAI,CAAC,IAAK;AACV,QAAI,KAAK,MAAM,WAAW;AACxB,WAAK,eAAe,KAAK,UAAU,GAAG;AACtC;AAAA,IACF;AAEA,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,UAAU;AACd,QAAI,KAAK,MAAM,aAAa,QAAS,UAAS,KAAK,IAAI,GAAG,IAAI,GAAG,KAAK,MAAM,SAAS;AACrF,QAAI,KAAK,MAAM,YAAY,QAAS,UAAS,KAAK,IAAI,GAAG,IAAI,GAAG,KAAK,MAAM,SAAS;AACpF,QAAI,OAAO,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;AAC3B,QAAI,OAAO,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;AAC3B,QAAI,OAAO;AACX,SAAK,WAAW,KAAK,QAAQ;AAC7B,SAAK,WAAW,KAAK,QAAQ;AAC7B,SAAK,WAAW,KAAK,QAAQ;AAC7B,SAAK,iBAAiB,KAAK,QAAQ;AAAA,EACrC;AAAA;AAAA,EAGQ,WAAW,KAA+B,UAA0B;AAC1E,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,QAAI,KAAK,MAAM,aAAa;AAC1B,YAAM,MAAM,SAAS,IAAI,EAAE;AAC3B,UAAI,KAAK;AACT,UAAI,YAAY,CAAC,CAAC;AAClB,UAAI,YAAY,KAAK,MAAM;AAC3B,UAAI,UAAU;AACd,UAAI,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,SAAS,GAAG,GAAG,KAAK,KAAK,CAAC;AACzE,UAAI,KAAK;AACT,UAAI,QAAQ;AAAA,IACd;AACA,QAAI,KAAK,MAAM,iBAAiB;AAC9B,YAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,iBAAW,KAAK,KAAK,YAAY,EAAE,KAAK,GAAG,EAAE,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,GAAG,KAAK,OAAO,EAAE,OAAO,SAAS,YAAY,UAAU,KAAK,MAAM,WAAW,GAAG,EAAE,CAAC;AACrJ,iBAAW,KAAK,KAAK,YAAY,EAAE,KAAK,GAAG,EAAE,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,GAAG,KAAK,OAAO,EAAE,YAAY,UAAU,KAAK,MAAM,WAAW,GAAG,EAAE,CAAC;AAAA,IACvI;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,WAAW,KAA+B,UAA0B;AAC1E,QAAI,CAAC,KAAK,WAAW,EAAG;AACxB,UAAM,OAAO,KAAK,UAAU,QAAQ;AACpC,QAAI,KAAK,WAAW,EAAG;AACvB,UAAM,KAAK,KAAK,WAAW,QAAQ;AACnC,QAAI,CAAC,GAAI;AACT,UAAM,OAAqB,EAAE,GAAG,KAAK,OAAO,UAAU,iBAAiB,MAAM,OAAO,QAAQ,MAAM;AAClG,UAAM,QAAQ,WAAW,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,MAAM,YAAY,IAAI,CAAC;AAChE,UAAMD,OAAM,EAAE,GAAG,OAAO,GAAG,KAAK,MAAM,GAAG,MAAM,IAAI,EAAE,GAAG,GAAG,KAAK,MAAM,GAAG,SAAS,GAAG,MAAM,IAAI,KAAK,GAAG,MAAM,IAAI,KAAK,MAAM,MAAM,EAAE;AACpI,kBAAc,KAAKA,MAAK,MAAM,OAAO,IAAI,CAAC;AAAA,EAC5C;AAAA;AAAA,EAGQ,WAAW,UAA8D;AAC/E,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,UAAM,CAAC,MAAM,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AACvD,UAAM,UAAU,CAAC,OAAsB,EAAE,GAAG,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG,GAAG,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,EAAE;AAChH,UAAM,QAAQ,KAAK,MAAM;AACzB,UAAM,IAAI,UAAU,SAAS,OAAO,UAAU,WAAW,MAAM,UAAU,UAAU,QAAQ,IAAI,EAAE,IAAI,SAAS,QAAQ,OAAO,OAAO;AACpI,WAAO,EAAE,OAAO,QAAQ,CAAC,GAAG,QAAQ,MAAM,KAAK,KAAK,EAAE;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKU,UAAU,UAAgC;AAClD,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO,CAAC;AACtB,UAAM,OAAmB,CAAC;AAC1B,UAAM,SAAS,EAAE,QAAQ,EAAE;AAC3B,UAAM,QAAkB,CAAC;AACzB,QAAI,KAAK,MAAM,eAAgB,OAAM,KAAK,KAAK,YAAY,MAAM,CAAC;AAClE,QAAI,KAAK,MAAM,mBAAmB;AAChC,YAAM,OAAO,EAAE,UAAU,IAAK,SAAS,KAAK,IAAI,EAAE,KAAK,IAAK,MAAM,GAAG,QAAQ,CAAC;AAC9E,YAAM,KAAK,MAAM,SAAS,IAAI,GAAG,OAAO,GAAG,GAAG,GAAG;AAAA,IACnD;AACA,QAAI,WAAW,MAAM,KAAK,GAAG;AAE7B,UAAM,OAAO,KAAK,SAAS;AAC3B,QAAI,KAAK,MAAM,kBAAkB,SAAS,QAAQ,OAAO,GAAG;AAC1D,YAAM,QAAQ,QAAQ,KAAK,MAAM,SAAS,IAAI,CAAC;AAC/C,iBAAW,WAAW,GAAG,QAAQ,KAAK,KAAK,KAAK;AAAA,IAClD;AACA,QAAI,SAAU,MAAK,KAAK,EAAE,MAAM,SAAS,MAAM,SAAS,CAAC;AACzD,UAAM,OAAiB,CAAC;AACxB,QAAI,KAAK,MAAM,eAAe;AAC5B,YAAM,OAAO,SAAS,YAAY,EAAE,MAAM,EAAE,IAAI;AAChD,UAAI,SAAS,KAAM,MAAK,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC,OAAO;AAAA,IACzD;AACA,QAAI,KAAK,MAAM,mBAAmB;AAChC,YAAM,OAAO,KAAK,IAAI,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,CAAC;AACrD,UAAI,OAAO,SAAS,IAAI,KAAK,OAAO,EAAG,MAAK,KAAK,KAAK,SAAS,IAAI,SAAS,IAAI,CAAC,MAAM,SAAS,IAAI,CAAC;AAAA,IACvG;AACA,QAAI,UAAU,KAAK,KAAK,GAAG;AAC3B,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,KAAK,MAAM,gBAAgB,MAAM,IAAI;AACvC,YAAM,WAAW,aAAa,KAAK,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AAC9E,gBAAU,UAAU,GAAG,OAAO,KAAK,QAAQ,KAAK;AAAA,IAClD;AACA,QAAI,QAAS,MAAK,KAAK,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AACtD,QAAI,KAAK,MAAM,aAAa,MAAM,GAAI,MAAK,KAAK,EAAE,MAAM,SAAS,MAAM,IAAK,CAAC,QAAQ,IAAI,EAAE,IAAI,MAAO,KAAK,IAAI,QAAQ,CAAC,CAAC,OAAI,CAAC;AAC9H,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,iBAAiB,MAAgC,WAA2B;AAAA,EAAC;AAAA,EAEvF,QAAQ,OAAc,UAA6B;AACjD,UAAM,MAAM,KAAK,QAAQ,QAAQ;AACjC,QAAI,CAAC,IAAK,QAAO;AACjB,WAAO,kBAAkB,OAAO,IAAI,GAAG,IAAI,CAAC,KAAK,aAAa,KAAK,MAAM,SAAS,KAAK,KAAK,SAAS,OAAO,QAAQ;AAAA,EACtH;AAAA;AAAA;AAAA,EAKQ,eAAe,KAA+B,UAAoB,KAAmC;AAC3G,gBAAY,KAAK,KAAK,KAAK;AAC3B,kBAAc,KAAK,IAAI,GAAG,IAAI,CAAC;AAC/B,QAAI,KAAK,MAAM,YAAY,QAAS,gBAAe,KAAK,IAAI,GAAG,IAAI,GAAG,KAAK,KAAK;AAChF,QAAI,KAAK,MAAM,aAAa,QAAS,gBAAe,KAAK,IAAI,GAAG,IAAI,GAAG,KAAK,KAAK;AACjF,SAAK,WAAW,KAAK,QAAQ;AAC7B,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,MAAM,IAAI;AACZ,YAAM,YAAY,iBAAiB,IAAI,EAAE;AACzC,YAAM,CAAC,MAAM,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AACvD,UAAI,KAAK,UAAW,MAAK,WAAW,KAAK,QAAQ;AAAA,eACxC,KAAK,MAAM,MAAM;AACxB,cAAM,QAAQ,KAAK,MAAM;AACzB,cAAM,KAAK,UAAU,SAAS,OAAO,UAAU,UAAU,QAAQ,SAAS,IAAI,EAAE;AAChF,cAAM,SAAS,OAAO,KAAK,MAAM,UAAU,KAAK,OAAO;AACvD,YAAI,KAAK;AACT,YAAI,UAAU,GAAG,GAAG,GAAG,CAAC;AACxB,YAAI,OAAO,SAAS;AACpB,mBAAW,KAAK,KAAK,MAAM,MAAM,EAAE,GAAG,GAAG,GAAG,OAAO,EAAE,GAAG,KAAK,OAAO,EAAE,OAAO,UAAU,SAAS,SAAS,UAAU,UAAU,UAAU,UAAU,UAAU,OAAO,SAAS,CAAC;AAC5K,YAAI,QAAQ;AAAA,MACd;AACA,YAAM,QAAQ,KAAK,WAAW,IAAI,KAAK,eAAe,QAAQ,IAAI;AAClE,UAAI,OAAO;AACT,cAAM,QAAQ,KAAK,MAAM;AACzB,cAAM,UAAU,CAAC,OAAsB,EAAE,GAAG,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG,GAAG,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,EAAE;AAChH,cAAM,IAAI,UAAU,SAAS,OAAO,UAAU,WAAW,MAAM,UAAU,UAAU,QAAQ,IAAI,EAAE,IAAI,SAAS,QAAQ,OAAO,OAAO;AACpI,cAAM,KAAK,QAAQ,CAAC;AAGpB,cAAM,UAAU,CAAC,CAAC,KAAK,MAAM,QAAQ,KAAK,MAAM,eAAe,UAAW,UAAU,YAAY,KAAK,MAAM,eAAe,YAAc,MAAM,QAAQ,KAAK,MAAM,eAAe,UAAY,MAAM,QAAQ,KAAK,MAAM,eAAe;AACpO,YAAI,KAAK;AACT,YAAI,UAAU,GAAG,GAAG,GAAG,CAAC;AACxB,YAAI,OAAO,SAAS;AACpB,mBAAW,KAAK,OAAO,EAAE,GAAG,GAAG,GAAG,UAAU,MAAM,IAAI,GAAG,KAAK,OAAO,EAAE,OAAO,UAAU,YAAY,UAAU,WAAW,IAAI,EAAE,CAAC;AAChI,YAAI,QAAQ;AAAA,MACd;AAAA,IACF;AACA,SAAK,iBAAiB,KAAK,QAAQ;AAAA,EACrC;AAAA;AAAA,EAGQ,eAAe,UAAmC;AACxD,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,UAAM,QAAkB,CAAC;AACzB,UAAM,SAAS,EAAE,QAAQ,EAAE;AAC3B,QAAI,KAAK,MAAM,eAAgB,OAAM,KAAK,GAAG,UAAU,IAAI,MAAM,EAAE,GAAG,KAAK,YAAY,MAAM,CAAC,EAAE;AAChG,QAAI,KAAK,MAAM,mBAAmB;AAChC,YAAM,MAAM,EAAE,UAAU,IAAK,SAAS,KAAK,IAAI,EAAE,KAAK,IAAK,MAAM;AACjE,YAAM,KAAK,GAAG,OAAO,IAAI,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,CAAC,GAAG;AAAA,IACvD;AACA,QAAI,KAAK,MAAM,gBAAgB;AAC7B,YAAM,OAAO,KAAK,SAAS;AAC3B,UAAI,SAAS,QAAQ,OAAO,GAAG;AAC7B,cAAM,QAAQ,KAAK,MAAM,SAAS,IAAI;AACtC,cAAM,KAAK,GAAG,SAAS,IAAI,MAAM,EAAE,GAAG,KAAK,EAAE;AAAA,MAC/C;AAAA,IACF;AACA,QAAI,KAAK,MAAM,eAAe;AAC5B,YAAM,OAAO,SAAS,YAAY,EAAE,MAAM,EAAE,IAAI;AAChD,UAAI,SAAS,KAAM,OAAM,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC,OAAO;AAAA,IAC1D;AACA,QAAI,KAAK,MAAM,mBAAmB;AAChC,YAAM,OAAO,KAAK,IAAI,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,CAAC;AACrD,UAAI,OAAO,SAAS,IAAI,KAAK,OAAO,EAAG,OAAM,KAAK,SAAS,IAAI,CAAC;AAAA,IAClE;AACA,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,UAAI,MAAM,GAAI,OAAM,KAAK,IAAI,CAAC,QAAQ,IAAI,EAAE,KAAK,MAAM,KAAK,KAAK,QAAQ,CAAC,CAAC,MAAG;AAAA,IAChF;AACA,WAAO,MAAM,SAAS,MAAM,KAAK,UAAO,IAAI;AAAA,EAC9C;AACF;AAEO,IAAM,MAAN,cAAkB,UAAU;AAAA,EACf,OAAO;AAAA,EAEN,eAA+B;AAChD,WAAO,EAAE,GAAG,YAAY,aAAa,KAAK;AAAA,EAC5C;AACF;AAEO,IAAM,eAAN,cAA2B,UAAU;AAAA,EACxB,OAAO;AAAA,EAEN,eAA+B;AAChD,WAAO,EAAE,GAAG,YAAY,YAAY,MAAM,aAAa,KAAK;AAAA,EAC9D;AACF;AAGO,IAAM,QAAN,cAAoB,UAAU;AAAA,EACjB,OAAO;AAAA,EAEN,eAA+B;AAChD,WAAO,EAAE,GAAG,YAAY,UAAU,QAAQ;AAAA,EAC5C;AAAA,EAEmB,SAAS,OAAc,UAAmC;AAC3E,WAAO,MAAM,SAAS,OAAO,QAAQ,MAAM,KAAK,UAAU,aAAa,SAAS;AAAA,EAClF;AACF;AAGO,IAAM,WAAN,cAAuB,UAAU;AAAA,EACpB,OAAO;AAAA,EAEN,eAA+B;AAChD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,MACnB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,mBAAmB;AAAA,MACnB,cAAc;AAAA,MACd,WAAW;AAAA,MACX,eAAe;AAAA,MACf,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA;AAAA,EAGmB,cAAc,OAAgD;AAC/E,UAAM,cAAc,KAAK;AACzB,UAAM,QAAiC,EAAE,cAAc,MAAM;AAC7D,QAAI,EAAE,uBAAuB,OAAQ,OAAM,oBAAoB;AAC/D,QAAI,EAAE,uBAAuB,OAAQ,OAAM,oBAAoB;AAC/D,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,MAAM;AAAA,EAC3C;AACF;AAMO,IAAM,aAAN,cAAyB,UAAU;AAAA,EACtB,OAAO;AAAA,EAEN,UAAmB;AACpC,WAAO;AAAA,EACT;AAAA,EAEmB,iBAAiB,KAA+B,UAA0B;AAC3F,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,QAAI,KAAK,MAAM,WAAW;AACxB,WAAK,gBAAgB,KAAK,IAAI,EAAE;AAChC;AAAA,IACF;AACA,UAAM,QAAQ,QAAQ,IAAI,EAAE;AAC5B,QAAI,KAAK;AACT,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,WAAW;AACf,QAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AACtB,QAAI,UAAU;AACd,QAAI,OAAO,GAAG,GAAG,GAAG,CAAC;AACrB,QAAI,OAAO,GAAG,IAAI,IAAI,GAAG,CAAC;AAC1B,QAAI,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,OAAO,QAAQ,CAAC;AAC3C,QAAI,OAAO;AACX,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,OAAO,OAAO,KAAK,KAAK;AAC5B,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,YAAY;AAChB,QAAI,eAAe;AACnB,QAAI,SAAS,IAAK,CAAC,QAAQ,MAAO,KAAK,IAAI,QAAQ,CAAC,CAAC,QAAK,GAAG,IAAI,MAAM,GAAG,IAAI,CAAC;AAC/E,QAAI,QAAQ;AAAA,EACd;AAAA;AAAA,EAGQ,gBAAgB,KAA+B,IAAW,IAAiB;AACjF,UAAM,QAAQ,QAAQ,IAAI,EAAE;AAC5B,UAAM,WAAW,CAAC,SAAS,MAAM,KAAK;AACtC,UAAM,SAAS,KAAK,IAAI,IAAI,KAAK,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC;AACpE,QAAI,SAAS,GAAG;AACd,UAAI,KAAK;AACT,kBAAY,KAAK,KAAK,KAAK;AAC3B,UAAI,YAAY;AAChB,UAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AACtB,UAAI,UAAU;AACd,UAAI,OAAO,GAAG,GAAG,GAAG,CAAC;AACrB,UAAI,OAAO,GAAG,IAAI,SAAS,IAAI,GAAG,CAAC;AACnC,UAAI,OAAO;AACX,UAAI,UAAU;AACd,UAAI,IAAI,GAAG,GAAG,GAAG,GAAG,QAAQ,GAAG,OAAO,QAAQ,CAAC;AAC/C,UAAI,OAAO;AACX,UAAI,QAAQ;AAAA,IACd;AACA,eAAW,KAAK,GAAG,SAAS,QAAQ,CAAC,CAAC,QAAK,EAAE,GAAG,GAAG,IAAI,SAAS,IAAI,GAAG,GAAG,EAAE,GAAG,KAAK,OAAO,EAAE,YAAY,UAAU,WAAW,IAAI,EAAE,CAAC;AAAA,EACvI;AACF;AAcA,IAAM,aAAa,CAACC,UAA2C,YAAiC,MAAoB,QAAkC;AACpJ,QAAM,WAAW,MAAeA,SAAQ,UAAU,cAAcA,SAAQ,UAAU;AAClF,QAAM,QAAQ,MAAe,IAAI,IAAIA,SAAQ,MAAM,YAAYA,SAAQ,KAAK,EAAE;AAC9E,SAAO,IAAI,UAAU;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,MAAM,MAAM,MAAM,CAAC;AAAA,IAC9B,SAAS,OAAO,IAAI,KAAK,SAAS,MAAMA,SAAQ,aAAa;AAAA,EAC/D,CAAC;AACH;AAIO,IAAM,iBAAN,cAA6B,UAA+B;AAAA,EACxD,OAAe;AAAA,EAEP,aAAkD;AAAA,IACjE;AAAA,MACE;AAAA,MACA,MAAM;AACJ,cAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,cAAM,WAAW,KAAK,YAAY;AAClC,eAAO,UAAU,WAAW,SAAS,IAAI,OAAO,KAAK,IAAI;AAAA,MAC3D;AAAA,MACA,MAAM,KAAK,YAAY,KAAK,QAAQ,CAAC,GAAG,SAAS,CAAC;AAAA,MAClD,MAAM,KAAK,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EAEmB,eAAoC;AACrD,WAAO,EAAE,MAAM,IAAI,WAAW,MAAM,YAAY,UAAU,YAAY,SAAS;AAAA,EACjF;AAAA,EAEmB,YAAiD;AAClE,WAAO,KAAK;AAAA,EACd;AAAA,EAEmB,YAAiF;AAClG,WAAO,EAAE,QAAQ,KAAK,QAAQ,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,OAAO,KAAK;AAAA,EAC7E;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAES,cAAmC;AAC1C,WAAO;AAAA,EACT;AAAA,EAEmB,mBAA2B;AAC5C,WAAO;AAAA,EACT;AAAA;AAAA,EAGS,iBAAiB,UAAoC;AAC5D,UAAM,IAAI,KAAK,OAAO,QAAQ;AAC9B,WAAO,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,GAAG,SAAS,QAAQ,iBAAiB,EAAE,CAAC;AAAA,EAChF;AAAA;AAAA,EAGU,OAAO,UAAmC;AAClD,UAAM,IAAI,SAAS,IAAI,KAAK,QAAQ,CAAC,GAAG,SAAS,GAAG;AACpD,WAAO,MAAM,QAAQ,CAAC,OAAO,SAAS,CAAC,IAAI,OAAO;AAAA,EACpD;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,QAAQ,KAAK,OAAO,QAAQ;AAClC,QAAI,UAAU,KAAM;AACpB,UAAM,IAAI,MAAM,OAAO,KAAK,MAAM,SAAS;AAC3C,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,UAAU,KAAK,SAAS;AAC5B,QAAI,WAAW;AACf,kBAAc,KAAK,EAAE,GAAG,KAAK,SAAS,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,SAAS,OAAO,EAAE,CAAC;AAC9E,SAAK,WAAW,KAAK,QAAQ;AAAA,EAC/B;AAAA;AAAA,EAGU,WAA0B;AAClC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIU,WAAW,UAAuC;AAC1D,UAAM,QAAQ,KAAK,OAAO,QAAQ;AAClC,QAAI,UAAU,KAAM,QAAO;AAC3B,UAAM,IAAI,MAAM,OAAO,KAAK,MAAM,SAAS;AAC3C,UAAM,QAAQ,KAAK,SAAS,QAAQ;AACpC,UAAM,QAAQ,KAAK,MAAM;AACzB,UAAM,IAAI,UAAU,SAAS,QAAQ,oBAAoB,UAAU,UAAU,SAAS,QAAQ,qBAAqB,QAAQ,SAAS,SAAS;AAC7I,UAAM,SAAS,KAAK,MAAM,eAAe,QAAQ,CAAC,YAAY,KAAK,MAAM,QAAQ,IAAI,KAAK,MAAM,eAAe,WAAW,YAAY,KAAK,MAAM,QAAQ,IAAI;AAC7J,WAAO,EAAE,GAAG,GAAG,IAAI,QAAQ,OAAO,GAAG,OAAO,MAAM;AAAA,EACpD;AAAA,EAEU,cAA0B;AAClC,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAGU,SAAS,WAA6B;AAC9C,WAAO;AAAA,EACT;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,YAAY,OAAO,YAAY,OAAO;AAAA,EACxE;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,IAAI,KAAK,OAAO,QAAQ;AAC9B,QAAI,MAAM,KAAM,QAAO;AACvB,UAAM,SAAS,MAAM,KAAK,KAAK,SAAS,QAAQ,IAAI,KAAK,KAAK,IAAI,MAAM,IAAI,CAAC,KAAK,aAAa,KAAK,MAAM,SAAS;AACnH,WAAO,UAAU,KAAK,SAAS,OAAO,QAAQ;AAAA,EAChD;AACF;AAIO,IAAM,gBAAN,cAA4B,eAAe;AAAA,EAC9B,OAAO;AAAA,EAER,gBAAqD;AAAA,IACpE;AAAA,MACE;AAAA,MACA,MAAM;AACJ,cAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,cAAM,WAAW,KAAK,YAAY;AAClC,eAAO,UAAU,WAAW,SAAS,IAAI,OAAO,IAAI,IAAI;AAAA,MAC1D;AAAA,MACA,MAAM,KAAK,WAAW,KAAK,QAAQ,CAAC,GAAG,IAAI;AAAA,MAC3C,OAAO,KAAK,UAAU,cAAc,KAAK,UAAU,cAAc,KAAK,aAAa;AAAA,IACrF;AAAA,EACF;AAAA,EAEmB,eAAoC;AACrD,WAAO,EAAE,MAAM,IAAI,WAAW,MAAM,YAAY,UAAU,YAAY,SAAS;AAAA,EACjF;AAAA,EAEmB,YAAiD;AAClE,WAAO,KAAK;AAAA,EACd;AAAA,EAEmB,YAAiF;AAClG,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,WAAO,EAAE,QAAQ,SAAS,CAAC,OAAO,KAAK,IAAI,MAAM,OAAO,SAAS,CAAC,OAAO,IAAI,IAAI,KAAK;AAAA,EACxF;AAAA,EAES,cAAmC;AAC1C,WAAO;AAAA,EACT;AAAA,EAEmB,mBAA2B;AAC5C,WAAO;AAAA,EACT;AAAA,EAES,iBAAiB,UAAoC;AAC5D,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAM,IAAI,SAAS,KAAK,cAAc,QAAQ,QAAQ,IAAI;AAC1D,WAAO,IAAI,CAAC,EAAE,OAAO,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC;AAAA,EAC/C;AAAA,EAEmB,UAAmB;AACpC,WAAO;AAAA,EACT;AAAA,EAEmB,WAA0B;AAC3C,WAAO;AAAA,EACT;AAAA,EAEmB,SAAS,UAA4B;AACtD,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,WAAO,IAAI,EAAE,IAAI;AAAA,EACnB;AACF;AAiBO,IAAM,eAAN,cAA2B,UAA6B;AAAA,EACpD,OAAO;AAAA,EAEC,aAAkD;AAAA,IACjE;AAAA,MACE;AAAA,MACA,MAAM;AACJ,cAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,cAAM,WAAW,KAAK,YAAY;AAClC,eAAO,UAAU,WAAW,SAAS,IAAI,OAAO,IAAI,IAAI;AAAA,MAC1D;AAAA,MACA,MAAM,KAAK,WAAW,KAAK,QAAQ,CAAC,GAAG,IAAI;AAAA,MAC3C,MAAM,KAAK,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EAEmB,eAAkC;AACnD,WAAO,EAAE,MAAM,IAAI,UAAU,MAAM,YAAY,UAAU,YAAY,UAAU,iBAAiB,WAAW;AAAA,EAC7G;AAAA,EAEmB,YAAiD;AAClE,WAAO,KAAK;AAAA,EACd;AAAA,EAEmB,YAAiF;AAClG,WAAO,EAAE,QAAQ,MAAM,OAAO,KAAK,QAAQ,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;AAAA,EAC5E;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAES,cAAmC;AAC1C,WAAO;AAAA,EACT;AAAA,EAEmB,mBAA2B;AAC5C,WAAO;AAAA,EACT;AAAA;AAAA,EAGS,iBAAiB,UAAoC;AAC5D,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,WAAO,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,GAAG,GAAG,SAAS,SAAS,gBAAgB,CAAC;AAAA,EACjF;AAAA,EAEQ,MAAM,UAAmC;AAC/C,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,WAAO,SAAS,SAAS,IAAI,OAAO,IAAI,IAAI;AAAA,EAC9C;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,iBAAiB,cAAc,YAAY,OAAO,YAAY,QAAQ;AAAA,EACxG;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,QAAI,SAAS,KAAM;AACnB,UAAM,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS;AAC1C,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,UAAU;AACd,QAAI,WAAW;AACf,kBAAc,KAAK,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,SAAS,OAAO,CAAC;AACzD,SAAK,WAAW,KAAK,QAAQ;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKU,WAAW,UAAuC;AAC1D,UAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,QAAI,SAAS,KAAM,QAAO;AAC1B,UAAM,IAAI,MAAM,MAAM,KAAK,MAAM,SAAS;AAC1C,UAAM,EAAE,YAAY,OAAO,YAAY,QAAQ,gBAAgB,IAAI,KAAK;AACxE,UAAM,MAAM,YAAY,KAAK,MAAM,QAAQ;AAC3C,QAAI,oBAAoB,cAAc;AACpC,YAAMC,KAAI,UAAU,QAAQ,MAAM,UAAU,WAAW,SAAS,SAAS,MAAM,SAAS,SAAS;AACjG,YAAMC,MAAK,WAAW,SAAS,IAAI,IAAI,WAAW,UAAU,IAAI,IAAI;AACpE,aAAO,EAAE,GAAGA,KAAI,GAAAD,IAAG,OAAO,GAAG,OAAO,WAAW,SAAS,UAAU,WAAW,UAAU,SAAS,SAAS;AAAA,IAC3G;AACA,UAAM,IAAI,UAAU,QAAQ,oBAAoB,UAAU,WAAW,SAAS,SAAS,oBAAoB,SAAS,SAAS;AAC7H,UAAM,KAAK,WAAW,SAAS,IAAI,MAAM,WAAW,UAAU,IAAI,MAAM;AACxE,WAAO,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,KAAK,GAAG,OAAO,UAAU,QAAQ,UAAU,UAAU,WAAW,SAAS,SAAS;AAAA,EACpH;AAAA,EAEU,cAA0B;AAClC,QAAI,KAAK,MAAM,oBAAoB,aAAc,QAAO,KAAK,MAAM,eAAe,QAAQ,WAAW,KAAK,MAAM,eAAe,WAAW,QAAQ;AAClJ,WAAO,KAAK,MAAM,eAAe,SAAS,QAAQ,KAAK,MAAM,eAAe,UAAU,WAAW;AAAA,EACnG;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,QAAI,SAAS,KAAM,QAAO;AAC1B,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,KAAK,aAAa,KAAK,MAAM,SAAS,KAAK,KAAK,SAAS,OAAO,QAAQ;AAAA,EACxG;AACF;AAWO,IAAM,YAAN,cAAwB,QAAwB;AAAA,EAC5C,OAAO;AAAA,EAEC,aAAkD;AAAA,IACjE;AAAA,MACE;AAAA,MACA,MAAM;AACJ,cAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,cAAM,WAAW,KAAK,YAAY;AAClC,eAAO,UAAU,WAAW,SAAS,IAAI,OAAO,KAAK,IAAI;AAAA,MAC3D;AAAA,MACA,MAAM,KAAK,YAAY,KAAK,QAAQ,CAAC,GAAG,SAAS,CAAC;AAAA,MAClD,MAAM,KAAK,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EAEiB,aAAkD;AAAA,IACjE;AAAA,MACE;AAAA,MACA,MAAM;AACJ,cAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,cAAM,WAAW,KAAK,YAAY;AAClC,eAAO,UAAU,WAAW,SAAS,IAAI,OAAO,IAAI,IAAI;AAAA,MAC1D;AAAA,MACA,MAAM,KAAK,WAAW,KAAK,QAAQ,CAAC,GAAG,IAAI;AAAA,MAC3C,MAAM,KAAK,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EAEmB,eAA+B;AAChD,WAAO,EAAE,WAAW,MAAM,UAAU,KAAK;AAAA,EAC3C;AAAA,EAEmB,YAAiD;AAClE,WAAO,KAAK;AAAA,EACd;AAAA,EAEmB,YAAiD;AAClE,WAAO,KAAK;AAAA,EACd;AAAA,EAEmB,YAAiF;AAClG,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,WAAO,EAAE,QAAQ,SAAS,CAAC,OAAO,KAAK,IAAI,MAAM,OAAO,SAAS,CAAC,OAAO,IAAI,IAAI,KAAK;AAAA,EACxF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAES,iBAA0B;AACjC,WAAO;AAAA,EACT;AAAA,EAEmB,SAAS,OAAc,UAAmC;AAC3E,WAAO,KAAK,iBAAiB,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,IAAI,MAAM,GAAG,EAAE,IAAI,MAAM,CAAC,KAAK,GAAG,IAAI,YAAY;AAAA,EACpH;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ;AACb,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG;AACR,UAAM,QAAQ,KAAK,MAAM;AACzB,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,UAAU;AACd,QAAI,WAAW;AACf,kBAAc,KAAK,EAAE,GAAG,GAAG,GAAG,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,SAAS,OAAO,GAAG,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;AAC9F,kBAAc,KAAK,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,GAAG,GAAG,SAAS,OAAO,CAAC;AAAA,EACjG;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,YAAY,aAAa,KAAK,MAAM,SAAS;AACnD,WAAO,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK,aAAa,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK;AAAA,EAC5E;AACF;;;AChkCA,SAAS,aAAaE,UAAoC;AACxD,SAAOA,SAAQ,MAAM,mBAAmB,QAAQ,OAAO,UAAUA,SAAQ,KAAK;AAChF;AAEA,SAASC,cAAa,WAA2B;AAC/C,SAAO,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACtC;AAEA,SAAS,eAAe,GAAU,SAAoC;AACpE,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,GAAG,IAAI,QAAQ,QAAQ,IAAI,KAAK;AACnE,UAAM,IAAI,QAAQ,CAAC;AACnB,UAAM,IAAI,QAAQ,CAAC;AACnB,QAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG;AACpF,eAAS,CAAC;AAAA,IACZ;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,GAAU,SAA2B,WAAmB,OAAyB;AACxG,QAAM,OAAO,QAAQ,QAAQ,SAAS,QAAQ,SAAS;AACvD,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,QAAI,kBAAkB,GAAG,QAAQ,CAAC,GAAG,SAAS,IAAI,KAAK,QAAQ,MAAM,CAAC,KAAK,UAAW,QAAO;AAAA,EAC/F;AACA,SAAO;AACT;AAGA,SAAS,aACP,KACA,SACAD,UACM;AACN,MAAI,QAAQ,SAAS,EAAG;AACxB,cAAY,KAAKA,SAAQ,KAAK;AAC9B,MAAI,UAAU;AACd,MAAI,OAAO,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AACrC,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,KAAI,OAAO,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC9E,MAAI,UAAU;AACd,QAAM,OAAO,aAAaA,QAAO;AACjC,MAAI,MAAM;AACR,QAAI,YAAY;AAChB,QAAI,KAAK;AAAA,EACX;AACA,MAAI,OAAO;AACb;AAkBO,IAAM,YAAN,cAAwB,QAAwB;AAAA,EAC5C,OAAO;AAAA,EAEG,eAA+B;AAChD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,YAAY;AAAA,IACd;AAAA,EACF;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,iBAAiB,KAAK,OAAO,WAAW,iBAAiB,KAAK,OAAO,WAAW,iBAAiB,SAAS;AAAA,EAC5I;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGmB,kBAAkB,QAA0D;AAC7F,WAAO;AAAA,MACL,GAAG,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,GAAG,CAAC,IAAI,OAAO;AAAA,MACpD,GAAG,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,GAAG,CAAC,IAAI,OAAO;AAAA,MACpD,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEU,QAAQ,UAAoC;AACpD,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AACzC,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AAErB,UAAM,OAAO,KAAK,MAAM,aAAa,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;AAC1D,UAAM,QAAQ,KAAK,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;AACzE,WAAO;AAAA,MACL,EAAE,GAAG,MAAM,GAAG,EAAE,EAAE;AAAA,MAClB,EAAE,GAAG,OAAO,GAAG,EAAE,EAAE;AAAA,MACnB,EAAE,GAAG,OAAO,GAAG,EAAE,EAAE;AAAA,MACnB,EAAE,GAAG,MAAM,GAAG,EAAE,EAAE;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,CAAC,QAAS;AACd,iBAAa,KAAK,SAAS,IAAI;AAC/B,QAAI,KAAK,MAAM,YAAY;AACzB,YAAM,QAAQ,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,EAAE,KAAK;AAC7C,UAAI,KAAK;AACT,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,KAAK,MAAM,iBAAiB,WAAW,KAAK,MAAM,iBAAiB,WAAW,KAAK,MAAM,gBAAgB,CAAC;AACvJ,UAAI,UAAU;AACd,UAAI,OAAO,QAAQ,CAAC,EAAE,GAAG,IAAI;AAC7B,UAAI,OAAO,QAAQ,CAAC,EAAE,GAAG,IAAI;AAC7B,UAAI,OAAO;AACX,UAAI,QAAQ;AAAA,IACd;AACA,QAAI,KAAK,MAAM,MAAM;AACnB,YAAM,MAAM,KAAK,IAAI,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC/C,YAAM,SAAS,KAAK,IAAI,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AAClD,YAAM,OAAO,KAAK,IAAI,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AAChD,YAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AACjD,YAAM,QAAQ,KAAK,MAAM;AACzB,YAAM,QAAQ,KAAK,MAAM;AACzB,YAAM,IAAI,UAAU,SAAS,OAAO,IAAI,UAAU,UAAU,QAAQ,KAAK,OAAO,SAAS;AACzF,YAAM,IAAI,UAAU,QAAQ,MAAM,IAAI,UAAU,WAAW,SAAS,KAAK,MAAM,UAAU;AACzF,iBAAW,KAAK,KAAK,MAAM,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO;AAAA,QACrD,OAAO,UAAU,SAAS,SAAS,UAAU,UAAU,UAAU;AAAA,QACjE,UAAU,UAAU,QAAQ,WAAW,UAAU,WAAW,QAAQ;AAAA,MACtE,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,YAAYC,cAAa,KAAK,MAAM,SAAS;AACnD,QAAI,gBAAgB,OAAO,SAAS,WAAW,IAAI,EAAG,QAAO;AAC7D,WAAO,aAAa,IAAI,MAAM,QAAQ,eAAe,OAAO,OAAO;AAAA,EACrE;AACF;AAMO,IAAM,mBAAN,cAA+B,QAAyB;AAAA,EACpD,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,EAAE,gBAAgB,KAAK;AAAA,EAChC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,QAAQ,UAAoC;AACpD,UAAM,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AAC5C,QAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAG,QAAO;AAC3B,UAAM,KAAK,EAAE,IAAI,EAAE;AACnB,UAAM,KAAK,EAAE,IAAI,EAAE;AACnB,UAAM,WAAW,KAAK,KAAK,KAAK;AAChC,QAAI,aAAa,EAAG,QAAO;AAE3B,UAAM,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,MAAM;AACnD,UAAM,KAAK,CAAC,KAAK;AACjB,UAAM,KAAK,KAAK;AAChB,WAAO,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,IAAI,IAAI,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,GAAG,EAAE,IAAI,IAAI,GAAG,EAAE,IAAI,GAAG,CAAC;AAAA,EAC1E;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,QAAS,cAAa,KAAK,SAAS,IAAI;AAAA,EAC9C;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,YAAYA,cAAa,KAAK,MAAM,SAAS;AACnD,QAAI,gBAAgB,OAAO,SAAS,WAAW,IAAI,EAAG,QAAO;AAC7D,WAAO,aAAa,IAAI,MAAM,QAAQ,eAAe,OAAO,OAAO;AAAA,EACrE;AACF;AAGO,IAAM,WAAN,cAAuB,QAAyB;AAAA,EAC5C,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,EAAE,gBAAgB,KAAK;AAAA,EAChC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,SAAS,KAAK,aAAa,QAAQ,EAAE,OAAO,CAAC,MAAkB,CAAC,CAAC,CAAC;AACxE,QAAI,OAAO,WAAW,EAAG,cAAa,KAAK,QAAQ,IAAI;AAAA,EACzD;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,SAAS,KAAK,aAAa,QAAQ,EAAE,OAAO,CAAC,MAAkB,CAAC,CAAC,CAAC;AACxE,QAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,UAAM,YAAYA,cAAa,KAAK,MAAM,SAAS;AACnD,QAAI,gBAAgB,OAAO,QAAQ,WAAW,IAAI,EAAG,QAAO;AAC5D,WAAO,aAAa,IAAI,MAAM,QAAQ,eAAe,OAAO,MAAM;AAAA,EACpE;AACF;AAQO,IAAM,SAAN,cAAqB,QAAyB;AAAA,EAC1C,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,EAAE,MAAM,IAAI,gBAAgB,KAAK;AAAA,EAC1C;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGmB,kBAAkB,QAA0D;AAC7F,UAAM,SAAS,OAAO,CAAC;AACvB,WAAO,SAAS,EAAE,GAAG,OAAO,GAAG,GAAG,OAAO,GAAG,OAAO,EAAE,IAAI,MAAM,kBAAkB,MAAM;AAAA,EACzF;AAAA,EAEU,SAAS,UAA8D;AAC/E,UAAM,CAAC,QAAQ,GAAG,IAAI,KAAK,aAAa,QAAQ;AAChD,QAAI,CAAC,UAAU,CAAC,IAAK,QAAO;AAC5B,WAAO,EAAE,QAAQ,QAAQ,KAAK,MAAM,IAAI,IAAI,OAAO,GAAG,IAAI,IAAI,OAAO,CAAC,EAAE;AAAA,EAC1E;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,QAAI,CAAC,IAAK;AACV,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,UAAU;AACd,QAAI,IAAI,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,QAAQ,GAAG,KAAK,KAAK,CAAC;AAC9D,UAAM,OAAO,aAAa,IAAI;AAC9B,QAAI,MAAM;AACR,UAAI,YAAY;AAChB,UAAI,KAAK;AAAA,IACX;AACA,QAAI,OAAO;AACX,QAAI,KAAK,MAAM,KAAM,YAAW,KAAK,KAAK,MAAM,MAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,OAAO,SAAS,CAAC;AAAA,EACnG;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,WAAW,KAAK,MAAM,MAAM,IAAI,IAAI,OAAO,GAAG,MAAM,IAAI,IAAI,OAAO,CAAC;AAC1E,QAAI,KAAK,IAAI,WAAW,IAAI,MAAM,KAAKA,cAAa,KAAK,MAAM,SAAS,EAAG,QAAO;AAClF,WAAO,aAAa,IAAI,MAAM,QAAQ,WAAW,IAAI;AAAA,EACvD;AACF;AAMO,IAAM,UAAN,cAAsB,QAAyB;AAAA,EAC3C,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,EAAE,MAAM,IAAI,gBAAgB,KAAK;AAAA,EAC1C;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGmB,kBAAkB,QAA0D;AAC7F,UAAM,CAAC,GAAG,CAAC,IAAI;AACf,WAAO,KAAK,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,EAAE,IAAI,MAAM,kBAAkB,MAAM;AAAA,EACvG;AAAA,EAEU,SAAS,UAAsE;AACvF,UAAM,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AAC5C,QAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAG,QAAO;AAC3B,UAAM,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE;AACxD,UAAM,KAAK,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI;AACjC,UAAM,KAAK,KAAK,IAAI,EAAE,IAAI,OAAO,CAAC;AAClC,QAAI,OAAO,KAAK,OAAO,EAAG,QAAO;AACjC,WAAO,EAAE,QAAQ,IAAI,GAAG;AAAA,EAC1B;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,QAAI,CAAC,IAAK;AACV,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,UAAU;AACd,QAAI,QAAQ,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,IAAI,IAAI,IAAI,GAAG,GAAG,KAAK,KAAK,CAAC;AACzE,UAAM,OAAO,aAAa,IAAI;AAC9B,QAAI,MAAM;AACR,UAAI,YAAY;AAChB,UAAI,KAAK;AAAA,IACX;AACA,QAAI,OAAO;AACX,QAAI,KAAK,MAAM,KAAM,YAAW,KAAK,KAAK,MAAM,MAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,OAAO,SAAS,CAAC;AAAA,EACnG;AAAA;AAAA;AAAA;AAAA,EAKS,iBAAiB,UAAoC;AAC5D,UAAM,SAAS,MAAM,iBAAiB,QAAQ;AAC9C,UAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,WAAO,MAAM,OAAO,IAAI,CAAC,UAAW,MAAM,UAAU,IAAI,EAAE,GAAG,OAAO,GAAG,IAAI,OAAO,EAAE,IAAI,KAAM,IAAI;AAAA,EACpG;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,QAAI,CAAC,IAAK,QAAO;AAEjB,UAAM,MAAM,MAAM,IAAI,IAAI,OAAO,KAAK,IAAI;AAC1C,UAAM,MAAM,MAAM,IAAI,IAAI,OAAO,KAAK,IAAI;AAC1C,UAAM,SAAS,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAC1C,UAAM,YAAYA,cAAa,KAAK,MAAM,SAAS,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,EAAE;AAC9E,QAAI,KAAK,IAAI,SAAS,CAAC,KAAK,UAAW,QAAO;AAC9C,WAAO,aAAa,IAAI,MAAM,QAAQ,SAAS;AAAA,EACjD;AACF;AAGA,SAAS,aAAa,UAA4B,UAAU,IAAa;AACvE,QAAM,MAAe,CAAC;AACtB,WAAS,IAAI,GAAG,KAAK,SAAS,KAAK;AACjC,UAAM,IAAI,IAAI;AACd,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,CAAC,IAAI,IAAI,EAAE,IAAI;AACrB,YAAM,IAAI,IAAI;AACd,UAAI,KAAK;AAAA,QACP,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG;AAAA,QAChD,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG;AAAA,MAClD,CAAC;AAAA,IACH,OAAO;AACL,YAAM,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI;AACzB,YAAM,IAAI,IAAI;AACd,UAAI,KAAK;AAAA,QACP,GAAG,KAAK,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG;AAAA,QAC7E,GAAG,KAAK,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG;AAAA,MAC/E,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,KAA+BD,UAAqB,SAAwB;AAChG,MAAI,QAAQ,SAAS,EAAG;AAExB,QAAM,OAAO,aAAaA,QAAO;AACjC,MAAI,MAAM;AACR,QAAI,KAAK;AACT,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,OAAO,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AACrC,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,KAAI,OAAO,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC9E,QAAI,UAAU;AACd,QAAI,KAAK;AACT,QAAI,QAAQ;AAAA,EACd;AACA,cAAY,KAAKA,SAAQ,KAAK;AAC9B,MAAI,UAAU;AACd,MAAI,OAAO,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AACrC,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,KAAI,OAAO,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC9E,MAAI,OAAO;AACb;AAUA,IAAM,cAA0B,EAAE,gBAAgB,OAAO,YAAY,OAAO,aAAa,OAAO,SAAS,UAAU,UAAU,SAAS;AAGtI,SAAS,eAAeA,UAAmD;AACzE,SAAO,EAAE,gBAAgBA,SAAQ,MAAM,cAAc,EAAE;AACzD;AAIA,SAAS,gBAAgB,SAAkB,UAAoB,OAA6C;AAC1G,QAAM,MAAgC,CAAC;AACvC,QAAM,IAAI,QAAQ;AAClB,MAAI,IAAI,EAAG,QAAO;AAClB,MAAI,MAAM,YAAY;AACpB,UAAM,MAAM,cAAc,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAG,SAAS,OAAO,SAAS,QAAQ,MAAM,KAAK;AAC9F,QAAI,IAAK,KAAI,KAAK,EAAE,GAAG,IAAI,GAAG,GAAG,QAAQ,CAAC,EAAE,CAAC;AAAA,EAC/C;AACA,MAAI,MAAM,aAAa;AACrB,UAAM,MAAM,cAAc,QAAQ,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,GAAG,SAAS,OAAO,SAAS,QAAQ,OAAO,IAAI;AACtG,QAAI,IAAK,KAAI,KAAK,EAAE,GAAG,QAAQ,IAAI,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC;AAAA,EACnD;AACA,SAAO;AACT;AAGA,SAAS,eAAe,KAA+BA,UAAqB,SAAkB,UAAoB,OAAyB;AACzI,eAAa,KAAKA,UAAS,OAAO;AAClC,QAAM,OAAO,gBAAgB,SAAS,UAAU,KAAK;AACrD,MAAI,KAAK,QAAQ;AACf,gBAAY,KAAKA,SAAQ,KAAK;AAC9B,QAAI,UAAU;AACd,eAAW,OAAO,MAAM;AACtB,UAAI,OAAO,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;AAC3B,UAAI,OAAO,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;AAAA,IAC7B;AACA,QAAI,OAAO;AAAA,EACb;AACA,QAAM,IAAI,QAAQ;AAClB,MAAI,IAAI,EAAG;AACX,MAAI,MAAM,YAAY,QAAS,gBAAe,KAAK,QAAQ,CAAC,GAAG,QAAQ,CAAC,GAAGA,SAAQ,KAAK;AACxF,MAAI,MAAM,aAAa,QAAS,gBAAe,KAAK,QAAQ,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,GAAGA,SAAQ,KAAK;AACnG;AAEA,SAAS,WAAW,OAAc,SAAkB,WAA4B;AAC9E,WAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,GAAG,KAAK;AAC3C,QAAI,kBAAkB,OAAO,QAAQ,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC,KAAK,UAAW,QAAO;AAAA,EAChF;AACA,SAAO;AACT;AAMO,IAAM,QAAN,cAAoB,QAAoB;AAAA,EACpC,OAAO;AAAA,EAEG,eAA2B;AAC5C,WAAO,EAAE,GAAG,YAAY;AAAA,EAC1B;AAAA,EAEmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,eAAe,IAAI,EAAE;AAAA,EAC1D;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,QAAQ,UAAoC;AACpD,UAAM,CAAC,GAAG,GAAG,IAAI,IAAI,KAAK,aAAa,QAAQ;AAC/C,QAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAM,QAAO;AAC9B,UAAM,UAAU,EAAE,GAAG,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,GAAG,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE;AACnF,WAAO,aAAa,CAAC,GAAG,SAAS,CAAC,CAAC;AAAA,EACrC;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,QAAS,gBAAe,KAAK,MAAM,SAAS,UAAU,KAAK,KAAK;AAAA,EACtE;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,YAAYC,cAAa,KAAK,MAAM,SAAS;AACnD,WAAO,WAAW,OAAO,SAAS,SAAS,KAAK,gBAAgB,SAAS,UAAU,KAAK,KAAK,EAAE,KAAK,CAAC,QAAQ,kBAAkB,OAAO,IAAI,GAAG,IAAI,CAAC,KAAK,SAAS;AAAA,EAClK;AACF;AAGO,IAAM,cAAN,cAA0B,QAAoB;AAAA,EAC1C,OAAO;AAAA,EAEG,eAA2B;AAC5C,WAAO,EAAE,GAAG,YAAY;AAAA,EAC1B;AAAA,EAEmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,eAAe,IAAI,EAAE;AAAA,EAC1D;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,QAAQ,UAAoC;AACpD,UAAM,CAAC,GAAG,GAAG,OAAO,KAAK,IAAI,KAAK,aAAa,QAAQ;AACvD,QAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,MAAO,QAAO;AAEzC,UAAM,KAAK;AAAA,MACT,IAAI,KAAK,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,EAAE,KAAK;AAAA,MACvD,IAAI,KAAK,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,EAAE,KAAK;AAAA,IACzD;AACA,UAAM,KAAK;AAAA,MACT,IAAI,IAAI,EAAE,IAAI,IAAI,MAAM,IAAI,KAAK,MAAM,IAAI,IAAI,EAAE,KAAK;AAAA,MACtD,IAAI,IAAI,EAAE,IAAI,IAAI,MAAM,IAAI,KAAK,MAAM,IAAI,IAAI,EAAE,KAAK;AAAA,IACxD;AACA,WAAO,aAAa,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;AAAA,EACxC;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,QAAS,gBAAe,KAAK,MAAM,SAAS,UAAU,KAAK,KAAK;AAAA,EACtE;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,YAAYA,cAAa,KAAK,MAAM,SAAS;AACnD,WAAO,WAAW,OAAO,SAAS,SAAS,KAAK,gBAAgB,SAAS,UAAU,KAAK,KAAK,EAAE,KAAK,CAAC,QAAQ,kBAAkB,OAAO,IAAI,GAAG,IAAI,CAAC,KAAK,SAAS;AAAA,EAClK;AACF;AAGO,IAAM,MAAN,cAAkB,QAAyB;AAAA,EACvC,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,EAAE,gBAAgB,KAAK;AAAA,EAChC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,QAAQ,UAAoC;AACpD,UAAM,CAAC,GAAG,GAAG,IAAI,IAAI,KAAK,aAAa,QAAQ;AAC/C,QAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAM,QAAO;AAC9B,UAAM,UAAU,EAAE,GAAG,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,GAAG,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE;AACnF,WAAO,aAAa,CAAC,GAAG,SAAS,CAAC,CAAC;AAAA,EACrC;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,QAAS,cAAa,KAAK,MAAM,OAAO;AAAA,EAC9C;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,WAAO,CAAC,CAAC,WAAW,WAAW,OAAO,SAASA,cAAa,KAAK,MAAM,SAAS,CAAC;AAAA,EACnF;AACF;;;AC1iBO,SAAS,YAAY,MAA4B,GAAS,GAAsB;AACrF,QAAM,OAAO,KAAK,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAC1C,QAAM,KAAK,KAAK,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AACxC,MAAI,CAAC,OAAO,SAAS,IAAI,KAAK,CAAC,OAAO,SAAS,EAAE,EAAG,QAAO,CAAC;AAC5D,SAAO,KAAK,OAAO,CAAC,QAAQ;AAC1B,UAAM,IAAI,OAAO,IAAI,IAAI;AACzB,WAAO,KAAK,QAAQ,KAAK;AAAA,EAC3B,CAAC;AACH;AAGO,SAAS,MAAM,MAA4B,MAA8B;AAC9E,QAAM,IAAI,OAAO,IAAI;AACrB,MAAI,CAAC,OAAO,SAAS,CAAC,EAAG,QAAO;AAChC,MAAI,KAAK;AACT,MAAI,KAAK,KAAK,SAAS;AACvB,SAAO,MAAM,IAAI;AACf,UAAM,MAAO,KAAK,MAAO;AACzB,UAAM,KAAK,OAAO,KAAK,GAAG,EAAG,IAAI;AACjC,QAAI,OAAO,EAAG,QAAO,KAAK,GAAG;AAC7B,QAAI,KAAK,EAAG,MAAK,MAAM;AAAA,QAClB,MAAK,MAAM;AAAA,EAClB;AACA,SAAO;AACT;AAQO,IAAM,oBAA+C,CAAC,QAAQ,QAAQ,OAAO,SAAS,UAAU,OAAO,QAAQ,SAAS,OAAO;AAE/H,SAAS,SAAS,KAAgB,QAAgC;AACvE,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,IAAI;AAAA,IACb,KAAK;AACH,aAAO,IAAI;AAAA,IACb,KAAK;AACH,aAAO,IAAI;AAAA,IACb,KAAK;AACH,aAAO,IAAI,UAAU;AAAA,IACvB,KAAK;AACH,cAAQ,IAAI,OAAO,IAAI,OAAO;AAAA,IAChC,KAAK;AACH,cAAQ,IAAI,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,IAC5C,KAAK;AACH,cAAQ,IAAI,OAAO,IAAI,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,IACvD,KAAK;AACH,cAAQ,IAAI,OAAO,IAAI,MAAM,IAAI,QAAQ,KAAK;AAAA,IAChD;AACE,aAAO,IAAI;AAAA,EACf;AACF;AAGO,SAAS,iBACd,MACA,SAAyB,SACmC;AAC5D,QAAM,IAAI,KAAK;AACf,MAAI,IAAI,EAAG,QAAO;AAClB,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,IAAI,SAAS,KAAK,CAAC,GAAG,MAAM;AAClC,YAAQ;AACR,YAAQ;AACR,aAAS,IAAI;AACb,aAAS,IAAI;AAAA,EACf;AACA,QAAM,cAAc,IAAI,QAAQ,OAAO;AACvC,MAAI,gBAAgB,EAAG,QAAO;AAC9B,QAAM,SAAS,IAAI,QAAQ,OAAO,QAAQ;AAC1C,QAAM,aAAa,OAAO,QAAQ,QAAQ;AAC1C,MAAI,WAAW;AACf,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,WAAW,SAAS,KAAK,CAAC,GAAG,MAAM,KAAK,YAAY,QAAQ;AAClE,gBAAY,WAAW;AAAA,EACzB;AACA,SAAO,EAAE,OAAO,WAAW,OAAO,KAAK,KAAK,WAAW,CAAC,EAAE;AAC5D;AAGO,SAAS,WAAW,QAAwB;AACjD,QAAM,OAAO,KAAK,IAAI,MAAM;AAC5B,MAAI,QAAQ,IAAK,QAAO,IAAI,SAAS,KAAK,QAAQ,CAAC,CAAC;AACpD,MAAI,QAAQ,IAAK,QAAO,IAAI,SAAS,KAAK,QAAQ,CAAC,CAAC;AACpD,MAAI,QAAQ,IAAK,QAAO,IAAI,SAAS,KAAK,QAAQ,CAAC,CAAC;AACpD,SAAO,OAAO,KAAK,MAAM,MAAM,CAAC;AAClC;AAeO,SAAS,cAAc,MAA4B,MAAkC;AAC1F,QAAM,aAAa,KAAK,OAAO,CAAC,MAAM,OAAO,EAAE,WAAW,YAAY,EAAE,SAAS,CAAC;AAClF,MAAI,CAAC,WAAW,UAAU,OAAO,EAAG,QAAO;AAC3C,MAAI,MAAM;AACV,MAAI,MAAM;AACV,aAAW,OAAO,YAAY;AAC5B,UAAM,KAAK,IAAI,KAAK,IAAI,GAAG;AAC3B,UAAM,KAAK,IAAI,KAAK,IAAI,IAAI;AAAA,EAC9B;AACA,MAAI,EAAE,MAAM,KAAM,QAAO;AACzB,QAAM,UAAU,MAAM,OAAO;AAC7B,QAAM,OAAoB,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,OAAO;AAAA,IAChE,UAAU,MAAM,IAAI;AAAA,IACpB,WAAW,OAAO,IAAI,KAAK;AAAA,IAC3B,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,EACd,EAAE;AACF,aAAW,OAAO,YAAY;AAC5B,UAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,GAAG,KAAK,OAAO,IAAI,MAAM,OAAO,MAAM,CAAC,CAAC;AACnF,UAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,GAAG,KAAK,OAAO,IAAI,OAAO,OAAO,MAAM,CAAC,CAAC;AACrF,UAAM,OAAO,UAAU,SAAS;AAChC,UAAM,QAAS,IAAI,SAAoB;AACvC,UAAM,KAAK,IAAI,QAAQ,IAAI;AAC3B,aAAS,IAAI,QAAQ,KAAK,SAAS,KAAK;AACtC,WAAK,CAAC,EAAE,UAAU;AAClB,UAAI,GAAI,MAAK,CAAC,EAAE,YAAY;AAAA,UACvB,MAAK,CAAC,EAAE,cAAc;AAAA,IAC7B;AAAA,EACF;AACA,SAAO;AACT;;;ACxJA,IAAM,cAAc,oBAAI,IAAqD;AAItE,SAAS,aAAa,KAAa,QAA6C;AACrF,MAAI,OAAO,UAAU,YAAa,QAAO;AACzC,QAAM,SAAS,YAAY,IAAI,GAAG;AAClC,MAAI,kBAAkB,iBAAkB,QAAO;AAC/C,MAAI,WAAW,QAAW;AACxB,gBAAY,IAAI,KAAK,SAAS;AAC9B,UAAM,QAAQ,IAAI,MAAM;AACxB,UAAM,SAAS,MAAM;AACnB,kBAAY,IAAI,KAAK,KAAK;AAC1B,aAAO;AAAA,IACT;AACA,UAAM,UAAU,MAAM,YAAY,IAAI,KAAK,QAAQ;AACnD,UAAM,MAAM;AAAA,EACd;AACA,SAAO;AACT;;;ACJA,SAAS,MAAM,GAAUC,MAAU,MAAM,GAAY;AACnD,SAAO,EAAE,KAAKA,KAAI,IAAI,OAAO,EAAE,KAAKA,KAAI,IAAIA,KAAI,QAAQ,OAAO,EAAE,KAAKA,KAAI,IAAI,OAAO,EAAE,KAAKA,KAAI,IAAIA,KAAI,SAAS;AACnH;AAGA,SAAS,WAAWA,MAAU,QAAsB;AAClD,SAAO,EAAE,GAAG,KAAK,IAAIA,KAAI,GAAG,KAAK,IAAI,OAAO,GAAGA,KAAI,IAAIA,KAAI,KAAK,CAAC,GAAG,GAAG,KAAK,IAAIA,KAAI,GAAG,KAAK,IAAI,OAAO,GAAGA,KAAI,IAAIA,KAAI,MAAM,CAAC,EAAE;AACjI;AAIA,SAAS,WAAW,OAA6D;AAC/E,SAAO,MAAM,UAAU,WAAW,WAAW;AAC/C;AAGA,SAAS,aAAgB,OAA+B;AACtD,QAAM,QAAQ;AACd,MAAI,EAAE,WAAW,OAAQ,QAAO;AAChC,QAAM,EAAE,OAAO,QAAQ,GAAG,KAAK,IAAI;AACnC,OAAK;AACL,SAAO;AACT;AAkBA,IAAM,aAAa;AACnB,IAAM,YAAY;AAElB,IAAM,aAAa;AAEnB,IAAM,cAAc;AAyBb,IAAM,YAAN,cAAwB,QAAsB;AAAA,EAC1C,OAAe;AAAA,EAEL,eAA6B;AAC9C,WAAO,EAAE,MAAM,IAAI,gBAAgB,OAAO,YAAY,OAAO,UAAU,OAAO,eAAe,KAAK,WAAW,KAAK;AAAA,EACpH;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,gBAAgB,MAAM,WAAW,CAAC,EAAE;AAAA,EACtE;AAAA,EAES,WAAW,OAAoC;AACtD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,MAAM,UAAsC;AACpD,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,YAAY,KAAK,MAAM,WAAW,KAAK,MAAM,gBAAgB;AACnE,UAAM,EAAE,OAAO,YAAY,IAAI,KAAK,WAAW,YAAY,KAAK,KAAK,GAAG,SAAS;AACjF,UAAM,QAAQ,eAAe;AAC7B,UAAM,QAAQ,WAAW,KAAK,KAAK;AACnC,QAAI,KAAK,MAAM,WAAW;AACxB,YAAMC,cAAa,KAAK,MAAM,KAAK,MAAM,WAAW,IAAI;AACxD,YAAM,QAAQ,aAAa,MAAM;AACjC,aAAO;AAAA,QACL,GAAG,EAAE,IAAI;AAAA,QACT,GAAG,EAAE,IAAI;AAAA,QACT,YAAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,QAAQ,IAAI,QAAQ,MAAM,MAAM,SAASA,cAAa,GAAG;AAAA,MACzF;AAAA,IACF;AACA,UAAM,IAAI,KAAK,MAAM,EAAE,CAAC;AACxB,UAAM,IAAI,KAAK,MAAM,EAAE,CAAC;AACxB,UAAM,aAAa,KAAK,MAAM;AAC9B,UAAM,QAAQ,cAAc,cAAc,YAAY,QAAQ,MAAM,QAAQ;AAC5E,WAAO;AAAA,MACL,GAAG,IAAI;AAAA,MACP,GAAG,IAAI;AAAA,MACP;AAAA,MACA,OAAO,cAAc,YAAY,QAAS,aAAa,MAAM;AAAA,MAC7D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK,EAAE,GAAG,GAAG,OAAO,KAAK,MAAM,KAAK,IAAI,WAAW,QAAQ,MAAM,MAAM,SAAS,aAAa,UAAU;AAAA,IACzG;AAAA,EACF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,QAAI,CAAC,GAAI;AACT,UAAM,QAAQ,KAAK;AACnB,UAAM,aAAa,KAAK,MAAM,iBAAkB,UAAU,KAAK,KAAK,KAAK,SAAa;AACtF,UAAM,cAAc,KAAK,MAAM,aAAa,KAAK,MAAM,YAAY;AACnE,QAAI,KAAK,MAAM,aAAa,CAAC,OAAO;AAClC,YAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,qBAAe,KAAK,KAAK,MAAM,WAAW,SAAS,MAAM,KAAK,OAAO,KAAK,MAAM,aAAa,IAAI,MAAM,GAAG,KAAK,KAAK,OAAO,EAAE,YAAY,aAAa,OAAO,GAAG,MAAM,CAAC;AAAA,IACzK,OAAO;AACL,UAAI,cAAc,aAAa;AAC7B,YAAI,KAAK;AACT,YAAI,YAAY,CAAC,CAAC;AAClB,YAAI,UAAU;AACd,YAAI,KAAK,MAAM,UAAW,KAAI,UAAU,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,QAAQ,CAAC;AAAA,YACrF,KAAI,KAAK,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,MAAM;AAC7D,YAAI,YAAY;AACd,cAAI,YAAY;AAChB,cAAI,KAAK;AAAA,QACX;AACA,YAAI,aAAa;AACf,cAAI,cAAc;AAClB,cAAI,YAAY;AAChB,cAAI,OAAO;AAAA,QACb;AACA,YAAI,QAAQ;AAAA,MACd;AACA,qBAAe,KAAK;AAAA,QAClB,GAAG,GAAG;AAAA,QACN,GAAG,GAAG;AAAA,QACN,OAAO,GAAG;AAAA,QACV,YAAY,GAAG;AAAA,QACf,MAAM,OAAO,KAAK,KAAK;AAAA,QACvB,OAAO,KAAK,MAAM;AAAA,QAClB,OAAO,GAAG;AAAA,QACV,OAAO,GAAG;AAAA,QACV,aAAa,GAAG,cAAc,EAAE,OAAO,GAAG,aAAa,OAAO,YAAY,IAAI;AAAA,QAC9E;AAAA,QACA,SAAS,YAAY,KAAK,KAAK;AAAA,MACjC,CAAC;AAAA,IACH;AACA,QAAI,KAAK,UAAU,cAAc,KAAK,UAAU,UAAW,iBAAgB,KAAK,GAAG,KAAK,KAAK,MAAM,WAAW,SAAS,GAAG,cAAc,cAAc,CAAC;AAAA,EACzJ;AAAA,EAES,UAAU,UAA0C;AAC3D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,QAAI,CAAC,GAAI,QAAO;AAChB,WAAO;AAAA,MACL,GAAG,GAAG;AAAA,MACN,GAAG,GAAG;AAAA,MACN,OAAO,GAAG;AAAA,MACV,QAAQ,GAAG,eAAe,GAAG,OAAO,MAAM;AAAA,MAC1C,YAAY,GAAG;AAAA,MACf,MAAM,OAAO,KAAK,KAAK;AAAA,MACvB,OAAO,GAAG;AAAA,MACV,WAAW,GAAG;AAAA,MACd,OAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGS,iBAAiB,WAAqC;AAC7D,WAAO,CAAC;AAAA,EACV;AAAA;AAAA,EAGS,gBAAsB;AAAA,EAAC;AAAA,EAEhC,QAAQ,OAAc,UAA6B;AACjD,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,CAAC,CAAC,MAAM,MAAM,OAAO,GAAG,GAAG;AAAA,EACpC;AACF;AAUA,IAAM,YAA2B,EAAE,MAAM,IAAI,gBAAgB,MAAM,YAAY,OAAO,aAAa,UAAU;AAY7G,IAAM,gBAAgB;AACtB,IAAM,eAAe;AACrB,IAAM,mBAAmB;AACzB,IAAM,iBAAiB;AACvB,IAAM,cAAc;AACpB,IAAM,WAAW;AACjB,IAAM,cAAc,EAAE,OAAO,sBAAsB,MAAM,GAAG,SAAS,EAAE;AAYhE,IAAM,OAAN,cAAmB,QAAmB;AAAA,EAClC,OAAO;AAAA,EAEG,eAA0B;AAC3C,WAAO,EAAE,GAAG,WAAW,WAAW,KAAK;AAAA,EACzC;AAAA;AAAA;AAAA,EAImB,eAAe,SAA6B;AAC7D,WAAO,QAAQ,WAAW,IAAI,CAAC,QAAQ,CAAC,GAAI,EAAE,GAAG,QAAQ,CAAC,EAAG,CAAC,IAAI;AAAA,EACpE;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,gBAAgB,MAAM,YAAY,MAAM,aAAa,KAAK,OAAO,WAAW,WAAW,CAAC,EAAE;AAAA,EAC5H;AAAA,EAES,WAAW,OAAiC;AACnD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,MAAM,UAA2E;AACzF,UAAM,CAAC,OAAO,EAAE,IAAI,KAAK;AACzB,UAAM,SAAS,SAAS,KAAK,cAAc,OAAO,QAAQ;AAC1D,UAAM,QAAQ,MAAM,KAAK,cAAc,IAAI,QAAQ;AACnD,QAAI,CAAC,UAAU,CAAC,MAAO,QAAO;AAC9B,UAAM,EAAE,OAAO,YAAY,IAAI,KAAK,WAAW,YAAY,KAAK,KAAK,CAAC;AACtE,UAAM,QAAQ,eAAe;AAC7B,QAAI,KAAK,MAAM,WAAW;AACxB,YAAMA,cAAa,KAAK,MAAM,KAAK,MAAM,WAAW,IAAI;AACxD,YAAMD,OAAM,EAAE,GAAG,MAAM,GAAG,GAAG,MAAM,GAAG,OAAO,MAAM,QAAQ,IAAI,QAAQ,MAAM,MAAM,SAASC,cAAa,GAAG;AAC5G,aAAO,EAAE,KAAAD,MAAK,GAAGA,KAAI,IAAI,GAAG,GAAGA,KAAI,IAAI,GAAG,YAAAC,aAAY,OAAO,aAAa,QAAQ,MAAM;AAAA,IAC1F;AACA,UAAM,aAAa,KAAK,MAAM;AAC9B,UAAM,QAAQ,KAAK,MAAM,MAAM,KAAK,IAAI;AACxC,UAAM,SAAS,MAAM,MAAM,SAAS,aAAa;AACjD,UAAMD,OAAM,EAAE,GAAG,KAAK,MAAM,MAAM,CAAC,GAAG,GAAG,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,GAAG,OAAO,OAAO;AACzF,WAAO,EAAE,KAAAA,MAAK,GAAGA,KAAI,IAAI,eAAe,GAAGA,KAAI,IAAI,cAAc,YAAY,OAAO,aAAa,QAAQ,MAAM;AAAA,EACjH;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,QAAI,CAAC,GAAI;AACT,UAAM,QAAQ,KAAK;AACnB,UAAM,aAAa,KAAK,MAAM,iBAAkB,UAAU,KAAK,KAAK,KAAK,SAAa;AACtF,UAAM,cAAc,KAAK,MAAM,aAAa,KAAK,MAAM,cAAc;AACrE,QAAI,KAAK,MAAM,WAAW;AAExB,YAAM,OAAO,WAAW,GAAG,KAAK,GAAG,MAAM;AACzC,UAAI,KAAK,MAAM,GAAG,OAAO,KAAK,KAAK,MAAM,GAAG,OAAO,GAAG;AACpD,YAAI,KAAK;AACT,oBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,GAAG,WAAW,QAAQ,CAAC;AACpE,sBAAc,KAAK,GAAG,QAAQ,IAAI;AAClC,YAAI,QAAQ;AAAA,MACd;AACA,UAAI,CAAC,OAAO;AACV,uBAAe,KAAK,KAAK,MAAM,QAAQ,KAAK,GAAG,KAAK,KAAK,OAAO,EAAE,YAAY,aAAa,OAAO,WAAW,KAAK,KAAK,EAAE,CAAC;AAC1H;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM,KAAK,KAAK,MAAM,GAAG,OAAO,CAAC;AACjC,YAAM,KAAK,KAAK,MAAM,GAAG,OAAO,CAAC;AACjC,YAAM,KAAK,KAAK,MAAM,GAAG,MAAM,CAAC;AAChC,YAAM,KAAK,KAAK,MAAM,GAAG,MAAM,CAAC;AAChC,UAAI,KAAK;AACT,UAAI,YAAY,CAAC,CAAC;AAClB,UAAI,OAAO,MAAM,OAAO,IAAI;AAE1B,YAAI,cAAc,KAAK,MAAM;AAC7B,YAAI,YAAY;AAChB,YAAI,UAAU;AACd,YAAI,OAAO,KAAK,KAAK,KAAK,GAAG;AAC7B,YAAI,OAAO,KAAK,KAAK,KAAK,GAAG;AAC7B,YAAI,OAAO;AAAA,MACb;AACA,UAAI,YAAY,KAAK,MAAM;AAC3B,UAAI,UAAU;AACd,UAAI,IAAI,IAAI,IAAI,UAAU,GAAG,KAAK,KAAK,CAAC;AACxC,UAAI,KAAK;AACT,UAAI,QAAQ;AAAA,IACd;AACA,QAAI,cAAc,aAAa;AAC7B,UAAI,KAAK;AACT,UAAI,YAAY,CAAC,CAAC;AAClB,UAAI,UAAU;AACd,UAAI,KAAK,MAAM,UAAW,KAAI,UAAU,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,QAAQ,CAAC;AAAA,UACrF,KAAI,UAAU,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,QAAQ,WAAW;AAC/E,UAAI,YAAY;AACd,YAAI,CAAC,KAAK,MAAM,WAAW;AACzB,cAAI,cAAc,YAAY;AAC9B,cAAI,aAAa,YAAY;AAC7B,cAAI,gBAAgB,YAAY;AAAA,QAClC;AACA,YAAI,YAAY;AAChB,YAAI,KAAK;AACT,YAAI,cAAc;AAAA,MACpB;AACA,UAAI,aAAa;AACf,YAAI,cAAc;AAClB,YAAI,YAAY;AAChB,YAAI,OAAO;AAAA,MACb;AACA,UAAI,QAAQ;AAAA,IACd;AACA,mBAAe,KAAK;AAAA,MAClB,GAAG,GAAG;AAAA,MACN,GAAG,GAAG;AAAA,MACN,QAAQ,GAAG,eAAe,GAAG,OAAO;AAAA,MACpC,YAAY,GAAG;AAAA,MACf,MAAM,OAAO,KAAK,KAAK;AAAA,MACvB,OAAO,KAAK,MAAM;AAAA,MAClB,OAAO,KAAK,MAAM,YAAY,WAAW,KAAK,KAAK,IAAI;AAAA,MACvD,OAAO,GAAG;AAAA,MACV,aAAa,GAAG,cAAc,EAAE,OAAO,GAAG,aAAa,OAAO,kBAAkB,IAAI;AAAA,MACpF;AAAA,MACA,SAAS,YAAY,KAAK,KAAK;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAES,UAAU,UAA0C;AAC3D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,KAAK,WAAW,IAAI,OAAO,KAAK,KAAK,GAAG,KAAK,MAAM,YAAY,WAAW,KAAK,KAAK,IAAI,MAAM,IAAI;AAAA,EAC3G;AAAA;AAAA,EAGS,eAAe,OAAc,UAAqC;AACzE,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,MAAM,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,CAAC,IAAI;AAAA,EAC5C;AAAA;AAAA,EAGS,QAAQ,OAAc,UAA6B;AAC1D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,CAAC,CAAC,MAAM,MAAM,OAAO,GAAG,GAAG;AAAA,EACpC;AAAA;AAAA,EAGmB,SAAS,OAAc,UAAmC;AAC3E,WAAO,KAAK,UAAU,cAAc,KAAK,QAAQ,OAAO,QAAQ,IAAI,SAAS;AAAA,EAC/E;AAAA;AAAA,EAGS,gBAAsB;AAAA,EAAC;AAAA,EAEhC,QAAQ,OAAc,UAA6B;AACjD,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,QAAI,CAAC,GAAI,QAAO;AAChB,QAAI,MAAM,OAAO,GAAG,GAAG,EAAG,QAAO;AACjC,QAAI,KAAK,MAAM,MAAM,IAAI,GAAG,OAAO,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,WAAW,EAAG,QAAO;AACrF,UAAM,OAAO,KAAK,MAAM,YAAY,WAAW,GAAG,KAAK,GAAG,MAAM,IAAI,GAAG;AACvE,WAAO,kBAAkB,OAAO,GAAG,QAAQ,IAAI,KAAK;AAAA,EACtD;AACF;AAWA,IAAM,cAAc;AACpB,IAAM,iBAAiB;AACvB,IAAM,uBAAuB;AAE7B,IAAM,oBAAoB;AAc1B,SAAS,WAAW,IAAgB,MAAc,QAA2B,QAAQ,SAAS,GAAG,eAAe,GAAG,OAAO,OAAsB;AAC9I,SAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,OAAO,QAAQ,GAAG,eAAe,GAAG,OAAO,MAAM,QAAQ,YAAY,GAAG,YAAY,MAAM,OAAO,WAAW,MAAM,OAAO,EAAE;AACxJ;AAUO,IAAM,UAAN,cAAsB,QAAsB;AAAA,EACxC,OAAO;AAAA,EAEG,eAA6B;AAC9C,WAAO,EAAE,MAAM,IAAI,WAAW,KAAK;AAAA,EACrC;AAAA,EAEmB,aAAa,OAAqD;AACnF,WAAO,aAAa,KAAK;AAAA,EAC3B;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,CAAC,EAAE;AAAA,EAChD;AAAA,EAES,WAAW,OAAoC;AACtD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIU,MAAM,UAA4D;AAC1E,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,EAAE,OAAO,YAAY,IAAI,KAAK,WAAW,YAAY,KAAK,KAAK,CAAC;AACtE,UAAM,QAAQ,eAAe;AAC7B,QAAI,KAAK,MAAM,WAAW;AACxB,YAAMC,cAAa,KAAK,MAAM,KAAK,MAAM,WAAW,IAAI;AACxD,YAAMC,SAAQ,MAAM,QAAQ;AAC5B,YAAMC,UAAS,MAAM,MAAM,SAASF,cAAa;AACjD,YAAMD,OAAM,EAAE,GAAG,EAAE,IAAI,IAAI,GAAG,EAAE,IAAI,KAAKG,SAAQ,OAAAD,QAAO,QAAAC,QAAO;AAC/D,aAAO,EAAE,KAAAH,MAAK,GAAGA,KAAI,IAAI,GAAG,GAAGA,KAAI,IAAI,GAAG,YAAAC,aAAY,OAAO,aAAa,OAAO,EAAE;AAAA,IACrF;AACA,UAAM,aAAa,KAAK,MAAM;AAC9B,UAAM,QAAQ,KAAK,MAAM,MAAM,KAAK,IAAI,cAAc;AACtD,UAAM,SAAS,MAAM,MAAM,SAAS,aAAa,cAAc;AAC/D,UAAMD,OAAM,EAAE,GAAG,KAAK,MAAM,EAAE,CAAC,IAAI,GAAG,GAAG,KAAK,MAAM,EAAE,CAAC,IAAI,IAAI,QAAQ,OAAO,OAAO;AACrF,WAAO,EAAE,KAAAA,MAAK,GAAGA,KAAI,IAAI,aAAa,GAAGA,KAAI,IAAI,aAAa,YAAY,OAAO,aAAa,OAAO,EAAE;AAAA,EACzG;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,QAAI,CAAC,GAAI;AACT,UAAM,QAAQ,KAAK;AACnB,UAAM,OAAO,UAAU,KAAK,KAAK,KAAK;AACtC,QAAI,KAAK,MAAM,aAAa,CAAC,OAAO;AAClC,YAAMA,OAAM,eAAe,KAAK,KAAK,MAAM,QAAQ,KAAK,GAAG,KAAK,KAAK,OAAO,EAAE,YAAY,MAAM,aAAa,KAAK,MAAM,UAAU,CAAC;AACnI,WAAK,eAAe,KAAKA,MAAK,GAAG,OAAO,IAAI;AAC5C;AAAA,IACF;AACA,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,YAAY;AAChB,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,KAAK,MAAM,UAAW,KAAI,UAAU,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,QAAQ,CAAC;AAAA,QAErF,KAAI,UAAU,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,GAAG,GAAG,IAAI,SAAS,GAAG,CAAC,gBAAgB,gBAAgB,gBAAgB,oBAAoB,CAAC;AAC9J,QAAI,KAAK;AACT,QAAI,OAAO;AACX,QAAI,QAAQ;AACZ,QAAI,KAAK,MAAM,UAAW,MAAK,eAAe,KAAK,GAAG,KAAK,GAAG,OAAO,IAAI;AACzE,UAAM,UAAU,YAAY,KAAK,KAAK;AACtC,mBAAe,KAAK;AAAA,MAClB,GAAG,GAAG;AAAA,MACN,GAAG,GAAG;AAAA,MACN,QAAQ,GAAG,eAAe,GAAG,OAAO;AAAA,MACpC,YAAY,GAAG;AAAA,MACf,MAAM,OAAO,KAAK,KAAK;AAAA,MACvB,OAAO,KAAK,MAAM;AAAA,MAClB,OAAO;AAAA,MACP,OAAO,GAAG;AAAA,MACV,aAAa,GAAG,cAAc,EAAE,OAAO,GAAG,aAAa,OAAO,kBAAkB,IAAI;AAAA,MACpF;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,eAAe,KAA+BA,MAAU,OAAc,MAAoB;AAChG,QAAI,KAAK;AACT,QAAI,YAAY;AAChB,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,YAAY;AAChB,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,UAAU;AACd,QAAI,OAAOA,KAAI,IAAI,GAAGA,KAAI,IAAIA,KAAI,MAAM;AACxC,QAAI,OAAO,MAAM,GAAG,MAAM,CAAC;AAC3B,QAAI,OAAOA,KAAI,IAAI,IAAIA,KAAI,IAAIA,KAAI,MAAM;AACzC,QAAI,UAAU;AACd,QAAI,KAAK;AACT,QAAI,OAAO;AACX,QAAI,QAAQ;AAAA,EACd;AAAA,EAES,UAAU,UAA0C;AAC3D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,KAAK,WAAW,IAAI,OAAO,KAAK,KAAK,CAAC,IAAI;AAAA,EACnD;AAAA;AAAA,EAGS,gBAAsB;AAAA,EAAC;AAAA;AAAA,EAGb,SAAS,OAAc,UAAmC;AAC3E,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,KAAK,UAAU,cAAc,MAAM,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,SAAS;AAAA,EAC/E;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,CAAC,CAAC,MAAM,MAAM,OAAO,GAAG,GAAG;AAAA,EACpC;AACF;AAkBA,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AACzB,IAAM,eAAe;AACrB,IAAM,iBAAiB;AACvB,IAAM,eAAe;AAiBrB,SAAS,YAAYA,MAAU,KAAgC;AAC7D,QAAM,IAAIA,KAAI;AACd,QAAM,IAAIA,KAAI;AACd,QAAM,IAAIA,KAAI,IAAIA,KAAI;AACtB,QAAM,IAAIA,KAAI,IAAIA,KAAI;AACtB,QAAM,SAAS,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI,IAAI,UAAU;AAC1D,QAAM,OAAO,IAAI,IAAI,IAAI,QAAQ,IAAI,IAAI,IAAI,WAAW;AACxD,QAAM,IAAI,KAAK,IAAI,gBAAgBA,KAAI,QAAQ,GAAGA,KAAI,SAAS,CAAC;AAChE,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,cAAcA,KAAI,QAAQ,IAAI,GAAGA,KAAI,SAAS,IAAI,CAAC,CAAC;AACnF,QAAM,IAAI,KAAK,IAAI,cAAcA,KAAI,OAAOA,KAAI,MAAM;AACtD,QAAM,KAAK,IAAIA,KAAI,QAAQ;AAC3B,QAAM,KAAK,IAAIA,KAAI,SAAS;AAC5B,QAAM,OAAO,CAAC,MAA2B,MAAa,QAA4B,EAAE,MAAM,MAAM,IAAI,IAAI;AACxG,MAAI,SAAS,SAAS,WAAW,OAAQ,QAAO,KAAK,YAAY,EAAE,GAAG,GAAG,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC;AACvG,MAAI,SAAS,SAAS,WAAW,QAAS,QAAO,KAAK,aAAa,EAAE,GAAG,IAAI,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC;AACzG,MAAI,SAAS,YAAY,WAAW,QAAS,QAAO,KAAK,gBAAgB,EAAE,GAAG,GAAG,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC;AAC/G,MAAI,SAAS,YAAY,WAAW,OAAQ,QAAO,KAAK,eAAe,EAAE,GAAG,IAAI,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC;AAC7G,MAAI,SAAS,MAAO,QAAO,KAAK,OAAO,EAAE,GAAG,KAAK,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;AAC/E,MAAI,SAAS,SAAU,QAAO,KAAK,UAAU,EAAE,GAAG,KAAK,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;AACrF,MAAI,WAAW,QAAS,QAAO,KAAK,SAAS,EAAE,GAAG,GAAG,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,KAAK,EAAE,CAAC;AACrF,MAAI,WAAW,OAAQ,QAAO,KAAK,QAAQ,EAAE,GAAG,GAAG,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,KAAK,EAAE,CAAC;AACnF,SAAO;AACT;AAIA,SAAS,aAAa,KAA+BA,MAAU,MAAgC;AAC7F,QAAM,IAAIA,KAAI;AACd,QAAM,IAAIA,KAAI;AACd,QAAM,IAAIA,KAAI,IAAIA,KAAI;AACtB,QAAM,IAAIA,KAAI,IAAIA,KAAI;AACtB,QAAM,IAAI,KAAK,IAAI,gBAAgBA,KAAI,QAAQ,GAAGA,KAAI,SAAS,CAAC;AAChE,QAAM,KAAK,MAAM;AACjB,QAAM,MAAM,MAAY;AACtB,QAAI,OAAO,KAAM,KAAK,GAAG,KAAM,KAAK,CAAC;AACrC,QAAI,OAAO,KAAM,IAAI,GAAG,KAAM,IAAI,CAAC;AACnC,QAAI,OAAO,KAAM,GAAG,GAAG,KAAM,GAAG,CAAC;AAAA,EACnC;AAEA,MAAI,OAAO,WAAY,KAAI,OAAO,KAAM,GAAG,GAAG,KAAM,GAAG,CAAC;AAAA,MACnD,KAAI,OAAO,IAAI,GAAG,CAAC;AACxB,MAAI,OAAO,MAAO,KAAI;AACtB,MAAI,OAAO,YAAa,KAAI;AAAA,MACvB,KAAI,MAAM,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC;AAChC,MAAI,OAAO,QAAS,KAAI;AACxB,MAAI,OAAO,eAAgB,KAAI;AAAA,MAC1B,KAAI,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC;AAChC,MAAI,OAAO,SAAU,KAAI;AACzB,MAAI,OAAO,cAAe,KAAI;AAAA,MACzB,KAAI,MAAM,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC;AAChC,MAAI,OAAO,OAAQ,KAAI;AACvB,MAAI,OAAO,WAAY,KAAI;AAAA,MACtB,KAAI,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC;AAChC,MAAI,UAAU;AAChB;AAGA,SAAS,OAAO,GAAU,MAA4B;AACpD,QAAM,OAAO,CAAC,GAAU,OAAsB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;AAChG,QAAM,KAAK,KAAK,KAAK,MAAM,KAAK,GAAG;AACnC,QAAM,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AACjC,QAAM,KAAK,KAAK,KAAK,IAAI,KAAK,IAAI;AAClC,SAAQ,MAAM,KAAK,MAAM,KAAK,MAAM,KAAO,MAAM,KAAK,MAAM,KAAK,MAAM;AACzE;AAaO,IAAM,UAAN,cAAsB,QAAsB;AAAA,EACxC,OAAe;AAAA,EAEL,eAA6B;AAC9C,WAAO,EAAE,MAAM,IAAI,UAAU,OAAO,eAAe,KAAK,aAAa,MAAM,WAAW,KAAK;AAAA,EAC7F;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,aAAa,GAAG,WAAW,CAAC,EAAE;AAAA,EAChE;AAAA,EAES,WAAW,OAAoC;AACtD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,MAAM,UAAoF;AAClG,UAAM,CAAC,SAAS,KAAK,IAAI,KAAK;AAC9B,UAAM,MAAM,WAAW,KAAK,cAAc,SAAS,QAAQ;AAC3D,UAAM,KAAK,SAAS,KAAK,cAAc,OAAO,QAAQ;AACtD,QAAI,CAAC,OAAO,CAAC,GAAI,QAAO;AACxB,UAAM,YAAY,KAAK,MAAM,WAAW,KAAK,MAAM,gBAAgB;AACnE,UAAM,EAAE,OAAO,YAAY,IAAI,KAAK,WAAW,YAAY,KAAK,KAAK,GAAG,SAAS;AACjF,UAAM,QAAQ,eAAe;AAC7B,QAAI,KAAK,MAAM,WAAW;AACxB,YAAMC,cAAa,KAAK,MAAM,KAAK,MAAM,WAAW,IAAI;AACxD,YAAMD,OAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,QAAQ,aAAa,MAAM,SAAS,IAAI,QAAQ,MAAM,MAAM,SAASC,cAAa,GAAG;AACrH,aAAO,EAAE,KAAAD,MAAK,GAAGA,KAAI,IAAI,GAAG,GAAGA,KAAI,IAAI,GAAG,YAAAC,aAAY,OAAO,aAAa,KAAK,UAAU;AAAA,IAC3F;AACA,UAAM,aAAa,KAAK,MAAM;AAC9B,UAAM,SAAS,aAAa,MAAM,SAAS;AAC3C,UAAM,SAAS,MAAM,MAAM,SAAS,aAAa;AACjD,UAAMD,OAAM,EAAE,GAAG,GAAG,IAAI,OAAO,GAAG,GAAG,IAAI,SAAS,GAAG,OAAO,OAAO;AACnE,WAAO,EAAE,KAAAA,MAAK,GAAGA,KAAI,IAAI,kBAAkB,GAAGA,KAAI,IAAI,kBAAkB,YAAY,OAAO,aAAa,KAAK,UAAU;AAAA,EACzH;AAAA;AAAA,EAGQ,aAAqB;AAC3B,UAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,WAAO,KAAK,MAAM,WAAW,SAAS,MAAM,KAAK,OAAO,KAAK,MAAM,aAAa,IAAI;AAAA,EACtF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,QAAI,CAAC,GAAI;AACT,UAAM,QAAQ,KAAK;AACnB,UAAM,OAAO,UAAU,KAAK,KAAK,KAAK;AACtC,UAAM,cAAc,KAAK,MAAM,eAAe,KAAK,MAAM;AACzD,QAAI,KAAK,MAAM,WAAW;AACxB,UAAI,KAAK;AACT,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,QAAQ,CAAC;AACtD,oBAAc,KAAK,GAAG,KAAK,WAAW,GAAG,KAAK,GAAG,GAAG,CAAC;AACrD,UAAI,QAAQ;AACZ,UAAI,CAAC,OAAO;AACV,uBAAe,KAAK,KAAK,WAAW,GAAG,GAAG,KAAK,KAAK,OAAO,EAAE,YAAY,MAAM,aAAa,KAAK,MAAM,WAAW,YAAY,CAAC;AAC/H;AAAA,MACF;AACA,UAAI,KAAK;AACT,UAAI,YAAY,CAAC,CAAC;AAClB,UAAI,UAAU;AACd,UAAI,UAAU,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,QAAQ,CAAC;AAChE,UAAI,YAAY;AAChB,UAAI,KAAK;AACT,UAAI,cAAc,GAAG;AACnB,YAAI,cAAc,KAAK,MAAM;AAC7B,YAAI,YAAY;AAChB,YAAI,OAAO;AAAA,MACb;AACA,UAAI,QAAQ;AAAA,IACd,OAAO;AACL,UAAI,KAAK;AACT,UAAI,YAAY,CAAC,CAAC;AAClB,UAAI,UAAU;AACd,mBAAa,KAAK,GAAG,KAAK,YAAY,GAAG,KAAK,GAAG,GAAG,CAAC;AAErD,UAAI,cAAc,GAAG;AACnB,YAAI,cAAc,KAAK,MAAM;AAC7B,YAAI,YAAY;AAChB,YAAI,OAAO;AAAA,MACb;AACA,UAAI,YAAY;AAChB,UAAI,KAAK;AACT,UAAI,QAAQ;AAAA,IACd;AACA,mBAAe,KAAK;AAAA,MAClB,GAAG,GAAG;AAAA,MACN,GAAG,GAAG;AAAA,MACN,OAAO,GAAG,cAAc,GAAG,eAAe,GAAG,OAAO;AAAA,MACpD,YAAY,GAAG;AAAA,MACf,MAAM,OAAO,KAAK,KAAK;AAAA,MACvB,OAAO,KAAK,MAAM;AAAA,MAClB,OAAO;AAAA,MACP,OAAO,GAAG;AAAA,MACV,aAAa,GAAG,cAAc,EAAE,OAAO,GAAG,aAAa,OAAO,kBAAkB,IAAI;AAAA,MACpF;AAAA,MACA,SAAS,YAAY,KAAK,KAAK;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAES,UAAU,UAA0C;AAC3D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,QAAI,CAAC,GAAI,QAAO;AAChB,WAAO,EAAE,GAAG,WAAW,IAAI,OAAO,KAAK,KAAK,GAAG,QAAQ,GAAG,cAAc,GAAG,eAAe,GAAG,OAAO,KAAK,GAAG,WAAW,GAAG,UAAU;AAAA,EACtI;AAAA;AAAA,EAGS,eAAe,OAAc,UAAqC;AACzE,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,MAAM,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,CAAC,IAAI;AAAA,EAC5C;AAAA;AAAA,EAGS,QAAQ,OAAc,UAA6B;AAC1D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,CAAC,CAAC,MAAM,MAAM,OAAO,GAAG,GAAG;AAAA,EACpC;AAAA;AAAA,EAGS,gBAAsB;AAAA,EAAC;AAAA,EAEhC,QAAQ,OAAc,UAA6B;AACjD,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,QAAI,CAAC,GAAI,QAAO;AAChB,QAAI,MAAM,OAAO,GAAG,GAAG,EAAG,QAAO;AACjC,QAAI,KAAK,MAAM,UAAW,QAAO,kBAAkB,OAAO,GAAG,KAAK,WAAW,GAAG,KAAK,GAAG,GAAG,CAAC,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,IAAI,CAAC;AACzI,UAAM,OAAO,YAAY,GAAG,KAAK,GAAG,GAAG;AACvC,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,OAAO,OAAO,IAAI,KAAK,kBAAkB,OAAO,KAAK,MAAM,KAAK,GAAG,KAAK,KAAK,kBAAkB,OAAO,KAAK,IAAI,KAAK,GAAG,KAAK;AAAA,EACrI;AACF;AAWA,IAAM,cAAc,EAAE,OAAO,GAAG,IAAI,IAAI,QAAQ,KAAK,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,GAAG,KAAK,EAAE;AAIrF,IAAM,YAAY,CAAC,aAA6B,KAAK,IAAI,IAAI,WAAW,EAAE;AAC1E,IAAM,cAAc,CAAC,aAA6B,KAAK,MAAM,UAAU,QAAQ,IAAI,IAAI,WAAW,GAAG;AAM9F,IAAM,aAAN,cAAyB,QAAwB;AAAA,EAC7C,OAAO;AAAA,EAEG,eAA+B;AAChD,WAAO,EAAE,WAAW,KAAK;AAAA,EAC3B;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,KAAK,OAAO,WAAW,aAAa,KAAK;AACpF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,CAAC,EAAE;AAAA,EAChD;AAAA,EAES,WAAW,OAAsC;AACxD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA;AAAA,EAGU,KAAK,UAAqE;AAClF,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,OAAO,KAAK,YAAY,OAAO,KAAK;AAC1C,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,EAAE,OAAAE,QAAO,QAAAC,QAAO,IAAI,iBAAiB,MAAM,KAAK,KAAK;AAC3D,aAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,IAAI,GAAG,EAAE,KAAKA,UAAS,MAAM,GAAG,OAAOD,SAAQ,IAAI,QAAQC,UAAS,GAAG,GAAG,MAAM,OAAO,EAAE;AAAA,IACpH;AACA,UAAM,SAAS,UAAU,KAAK,MAAM,QAAQ;AAC5C,UAAM,QAAQ,YAAY,KAAK,KAAK,EAAE,IAAI,IAAI,YAAY,MAAM;AAChE,WAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,YAAY,OAAO,GAAG,EAAE,IAAI,YAAY,KAAK,QAAQ,OAAO,OAAO,GAAG,MAAM,OAAO,EAAE;AAAA,EAChH;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,KAAK,KAAK,KAAK,QAAQ;AAC7B,QAAI,CAAC,GAAI;AACT,UAAM,EAAE,KAAAH,MAAK,OAAO,EAAE,IAAI;AAC1B,UAAM,OAAO,UAAU,KAAK,KAAK,KAAK;AACtC,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,YAAY;AAChB,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,KAAK,MAAM,WAAW;AACxB,UAAI,YAAY;AAChB,UAAI,UAAU;AACd,UAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,UAAI,OAAOA,KAAI,GAAGA,KAAI,IAAIA,KAAI,SAAS,IAAI,CAAC;AAC5C,UAAI,OAAOA,KAAI,GAAGA,KAAI,IAAIA,KAAI,SAAS,IAAI,CAAC;AAC5C,UAAI,UAAU;AACd,UAAI,KAAK;AACT,UAAI,OAAO;AACX,UAAI,UAAU;AACd,UAAI,UAAUA,KAAI,GAAGA,KAAI,GAAGA,KAAI,OAAOA,KAAI,QAAQ,CAAC;AACpD,UAAI,KAAK;AACT,UAAI,OAAO;AACX,UAAI,QAAQ;AACZ,qBAAe,KAAK,GAAG,MAAM,EAAE,GAAGA,KAAI,GAAG,GAAGA,KAAI,EAAE,GAAG,KAAK,KAAK;AAC/D;AAAA,IACF;AACA,QAAI,YAAY;AAChB,UAAM,CAAC,MAAM,EAAE,IAAI,YAAY;AAC/B,QAAI,UAAU;AACd,QAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,QAAI,OAAO,EAAE,IAAI,MAAM,EAAE,IAAI,YAAY,EAAE;AAC3C,QAAI,OAAO,EAAE,IAAI,IAAI,EAAE,IAAI,YAAY,EAAE;AACzC,QAAI,UAAU;AACd,QAAI,KAAK;AACT,QAAI,OAAO;AACX,QAAI,UAAU;AACd,QAAI,UAAUA,KAAI,GAAGA,KAAI,GAAGA,KAAI,OAAOA,KAAI,QAAQ,YAAY,MAAM;AACrE,QAAI,KAAK;AACT,QAAI,OAAO;AACX,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,QAAI,IAAI,EAAE,GAAG,EAAE,GAAG,YAAY,KAAK,GAAG,KAAK,KAAK,CAAC;AACjD,QAAI,KAAK;AACT,QAAI,OAAO,OAAO,KAAK,KAAK;AAC5B,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,YAAY;AAChB,QAAI,eAAe;AACnB,QAAI,SAAS,GAAG,MAAMA,KAAI,IAAI,YAAY,KAAKA,KAAI,IAAI,YAAY,KAAK,MAAM,QAAQ,CAAC;AACvF,QAAI,QAAQ;AAAA,EACd;AAAA,EAES,cAA2B;AAClC,WAAO,KAAK,MAAM,YAAY,WAAW;AAAA,EAC3C;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,KAAK,KAAK,KAAK,QAAQ;AAC7B,QAAI,CAAC,GAAI,QAAO;AAChB,QAAI,MAAM,OAAO,GAAG,KAAK,CAAC,EAAG,QAAO;AAEpC,UAAM,CAAC,MAAM,EAAE,IAAI,YAAY;AAC/B,UAAM,OAAO,EAAE,GAAG,GAAG,MAAM,KAAK,OAAO,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,YAAY,GAAG;AAC/E,WAAO,kBAAkB,OAAO,GAAG,OAAO,IAAI,KAAK;AAAA,EACrD;AACF;AAMA,IAAM,aAAa,EAAE,MAAM,MAAM,YAAY,IAAI,OAAO,KAAK,QAAQ,GAAG;AAKxE,IAAe,YAAf,cAAiC,QAAoC;AAAA,EAGhD,eAA2C;AAC5D,WAAO,EAAE,MAAM,IAAI,WAAW,KAAK;AAAA,EACrC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,CAAC,EAAE;AAAA,EAChD;AAAA,EAES,WAAW,OAAkD;AACpE,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA;AAAA,EAGQ,IAAI,UAAmE;AAC7E,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG,QAAO;AACf,WAAO,EAAE,GAAG,KAAK,MAAM,EAAE,CAAC,IAAI,KAAK,GAAG,KAAK,MAAM,EAAE,CAAC,GAAG,MAAM,KAAK,UAAU,MAAM,OAAO,IAAI,GAAG;AAAA,EAClG;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,MAAM,WAAW;AACxB,WAAK,WAAW,KAAK,QAAQ;AAC7B;AAAA,IACF;AACA,UAAM,IAAI,KAAK,IAAI,QAAQ;AAC3B,QAAI,CAAC,EAAG;AACR,UAAM,EAAE,MAAM,YAAY,OAAO,OAAO,IAAI;AAC5C,UAAM,IAAI,EAAE;AACZ,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,QAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,QAAI,OAAO,EAAE,IAAI,MAAM,EAAE,IAAI,IAAI,UAAU;AAC3C,QAAI,OAAO,EAAE,IAAI,OAAO,EAAE,IAAI,IAAI,UAAU;AAC5C,QAAI,OAAO,EAAE,IAAI,OAAO,EAAE,IAAI,IAAI,MAAM;AACxC,QAAI,OAAO,EAAE,IAAI,OAAO,EAAE,IAAI,IAAI,MAAM;AACxC,QAAI,OAAO,EAAE,IAAI,OAAO,EAAE,IAAI,IAAI,UAAU;AAC5C,QAAI,OAAO,EAAE,IAAI,MAAM,EAAE,IAAI,IAAI,UAAU;AAC3C,QAAI,UAAU;AACd,QAAI,KAAK;AACT,QAAI,QAAQ;AACZ,QAAI,KAAK,MAAM,MAAM;AACnB,YAAM,EAAE,OAAO,OAAO,IAAI,iBAAiB,KAAK,MAAM,MAAM,KAAK,KAAK;AACtE,qBAAe,KAAK,KAAK,MAAM,MAAM,EAAE,GAAG,EAAE,KAAK,QAAQ,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,IAAI,SAAS,IAAI,EAAE,IAAI,SAAS,IAAI,SAAS,GAAG,GAAG,KAAK,KAAK;AAAA,IAC9I;AAAA,EACF;AAAA;AAAA,EAGQ,WAAW,KAA+B,UAA0B;AAC1E,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAM,IAAI,UAAU,KAAK,cAAc,QAAQ,QAAQ;AACvD,QAAI,CAAC,EAAG;AACR,UAAM,OAAO,IAAI,KAAK,MAAM,YAAY;AACxC,UAAM,KAAK,KAAK,UAAU,MAAM;AAChC,UAAM,OAAO,KAAK,IAAI;AACtB,QAAI,KAAK;AACT,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,UAAU;AACd,QAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,QAAI,OAAO,EAAE,IAAI,MAAM,EAAE,IAAI,OAAO,IAAI;AACxC,QAAI,OAAO,EAAE,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,IAAI;AAC5C,QAAI,OAAO,EAAE,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,OAAO,CAAC;AAChD,QAAI,OAAO,EAAE,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,OAAO,CAAC;AAChD,QAAI,OAAO,EAAE,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,IAAI;AAC5C,QAAI,OAAO,EAAE,IAAI,MAAM,EAAE,IAAI,OAAO,IAAI;AACxC,QAAI,UAAU;AACd,QAAI,KAAK;AACT,QAAI,QAAQ;AACZ,QAAI,KAAK,MAAM,MAAM;AACnB,YAAM,EAAE,OAAO,OAAO,IAAI,iBAAiB,KAAK,MAAM,MAAM,KAAK,KAAK;AACtE,qBAAe,KAAK,KAAK,MAAM,MAAM,EAAE,GAAG,EAAE,KAAK,QAAQ,MAAM,GAAG,GAAG,KAAK,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,SAAS,GAAG,GAAG,KAAK,KAAK;AAAA,IAC/I;AAAA,EACF;AAAA,EAES,cAA2B;AAClC,WAAO,KAAK,MAAM,YAAY,WAAW;AAAA,EAC3C;AAAA;AAAA,EAGS,gBAAsB;AAAA,EAAC;AAAA,EAEhC,QAAQ,OAAc,UAA6B;AACjD,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,YAAM,IAAI,UAAU,KAAK,cAAc,QAAQ,QAAQ;AACvD,UAAI,CAAC,EAAG,QAAO;AACf,YAAM,OAAO,IAAI,KAAK,MAAM,YAAY;AACxC,YAAM,KAAK,KAAK,UAAU,MAAM;AAChC,aAAO,MAAM,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,MAAM,GAAG,EAAE,GAAG,OAAO,OAAO,GAAG,QAAQ,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,MAAM,GAAG,EAAE,IAAI,OAAO,GAAG,OAAO,OAAO,GAAG,QAAQ,OAAO,EAAE,GAAG,CAAC;AAAA,IACpK;AACA,UAAM,IAAI,KAAK,IAAI,QAAQ;AAC3B,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,EAAE,MAAM,OAAO,IAAI;AACzB,WAAO,MAAM,OAAO,EAAE,GAAG,EAAE,IAAI,MAAM,GAAG,EAAE,OAAO,IAAI,EAAE,IAAI,EAAE,IAAI,QAAQ,OAAO,OAAO,GAAG,QAAQ,OAAO,GAAG,CAAC;AAAA,EAC/G;AACF;AAGO,IAAM,cAAN,cAA0B,UAAU;AAAA,EAChC,OAAO;AAAA,EAEN,YAA2B;AACnC,WAAO;AAAA,EACT;AACF;AAGO,IAAM,gBAAN,cAA4B,UAAU;AAAA,EAClC,OAAO;AAAA,EAEN,YAA2B;AACnC,WAAO;AAAA,EACT;AACF;AAIA,IAAMI,UAAmF;AAAA,EACvF,KAAK,EAAE,GAAG,IAAI,UAAU,SAAS;AAAA,EACjC,QAAQ,EAAE,GAAG,GAAG,UAAU,SAAS;AAAA,EACnC,QAAQ,EAAE,GAAG,GAAG,UAAU,MAAM;AAClC;AAsBA,IAAM,YAAY,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,IAAI,KAAK,IAAI;AASnD,IAAM,YAAN,cAAwB,QAAwB;AAAA,EAC5C,OAAO;AAAA,EAEG,eAA+B;AAChD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,WAAW;AAAA,MACX,aAAa;AAAA,MACb,sBAAsB;AAAA,MACtB,kBAAkB;AAAA,MAClB,WAAW;AAAA,IACb;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMmB,cAAc,QAAiD;AAChF,UAAM,IAAI,KAAK;AACf,SAAK,SAAS;AAAA,MACZ,GAAG,KAAK;AAAA,MACR,gBAAgB,EAAE;AAAA,MAClB,eAAe,EAAE;AAAA,MACjB,WAAW,EAAE;AAAA,MACb,aAAa,EAAE;AAAA,MACf,sBAAsB,UAAU,CAAC,KAAK,UAAU,EAAE,WAAW,CAAC;AAAA,MAC9D,kBAAkB,EAAE;AAAA,MACpB,WAAW,CAAC;AAAA,IACd;AAAA,EACF;AAAA,EAES,WAAW,OAAsC;AACxD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA;AAAA,EAGU,SAAS,UAAsE;AACvF,UAAM,CAAC,OAAO,EAAE,IAAI,KAAK;AACzB,UAAM,SAAS,SAAS,KAAK,cAAc,OAAO,QAAQ;AAC1D,UAAM,IAAI,MAAM,KAAK,cAAc,IAAI,QAAQ;AAC/C,QAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAG,QAAO;AACpC,UAAM,QAAQ,KAAK,YAAY,MAAM,KAAK;AAC1C,UAAM,OAAO,KAAK,MAAM,OAAO,GAAG,KAAK;AAAA,EAAK,KAAK,MAAM,IAAI,KAAK;AAChE,UAAM,EAAE,OAAO,OAAO,IAAI,iBAAiB,QAAQ,KAAK,KAAK,KAAK;AAClE,WAAO,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,QAAQ,IAAI,QAAQ,SAAS,GAAG,GAAG,MAAM,OAAO;AAAA,EACzF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,WAAyB;AACjC,UAAM,IAAI,KAAK;AACf,WAAO,EAAE,GAAG,KAAK,OAAO,WAAW,EAAE,gBAAgB,UAAU,EAAE,eAAe,MAAM,EAAE,WAAW,QAAQ,EAAE,YAAY;AAAA,EAC3H;AAAA;AAAA,EAGU,IAAI,UAAuD;AACnE,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,UAAM,QAAQ,KAAK,QAAQ,CAAC;AAC5B,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAO,QAAO;AACjC,UAAM,OAAO,KAAK,YAAY,MAAM,KAAK;AACzC,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,QAAQ,KAAK,MAAM,YAAY,KAAK,EAAE,IAAI,IAAI,UAAU,IAAI;AAClE,UAAM,SAAS,UAAU,MAAM,QAAQ;AACvC,WAAO,EAAE,KAAK,EAAE,GAAG,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG,GAAG,IAAI,SAAS,GAAG,OAAO,OAAO,GAAG,KAAK;AAAA,EACrG;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,QAAQ,KAAK,SAAS,QAAQ;AACpC,UAAI,CAAC,MAAO;AACZ,kBAAY,KAAK,KAAK,KAAK;AAC3B,oBAAc,KAAK,MAAM,QAAQ,WAAW,MAAM,KAAK,MAAM,MAAM,CAAC;AACpE,qBAAe,KAAK,MAAM,QAAQ,KAAK,MAAM,KAAK,KAAK,OAAO,EAAE,YAAY,UAAU,KAAK,KAAK,KAAK,QAAW,aAAa,KAAK,MAAM,UAAU,CAAC;AACnJ;AAAA,IACF;AACA,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,QAAI,KAAK;AACT,gBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,GAAG,WAAW,QAAQ,CAAC;AACpE,kBAAc,KAAK,IAAI,EAAE;AACzB,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,QAAI,IAAI,GAAG,GAAG,GAAG,GAAG,UAAU,KAAK,GAAG,KAAK,KAAK,CAAC;AACjD,QAAI,KAAK;AACT,QAAI,QAAQ;AACZ,UAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,QAAI,KAAK;AACP,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,KAAK;AACT,UAAI,YAAY,CAAC,CAAC;AAClB,UAAI,UAAU;AACd,UAAI,UAAU,IAAI,IAAI,GAAG,IAAI,IAAI,GAAG,IAAI,IAAI,OAAO,IAAI,IAAI,QAAQ,UAAU,MAAM;AACnF,UAAI,YAAY,KAAK,MAAM;AAC3B,UAAI,KAAK;AACT,UAAI,cAAc,KAAK,MAAM;AAC7B,UAAI,YAAY;AAChB,UAAI,OAAO;AACX,UAAI,OAAO,OAAO,KAAK;AACvB,UAAI,YAAY,MAAM;AACtB,UAAI,YAAY;AAChB,UAAI,eAAe;AACnB,UAAI,SAAS,IAAI,MAAM,IAAI,IAAI,IAAI,UAAU,KAAK,IAAI,IAAI,IAAI,YAAY,MAAM,QAAQ,CAAC;AACzF,UAAI,QAAQ;AAAA,IACd;AACA,QAAI,KAAK,MAAM,MAAM;AAEnB,YAAM,CAAC,MAAM,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AACvD,YAAM,QAAQ,KAAK,MAAM;AACzB,YAAM,KAAK,UAAU,SAAS,OAAO,UAAU,UAAU,QAAQ,SAAS,IAAI,EAAE;AAChF,YAAM,SAASA,QAAO,KAAK,MAAM,UAAU,KAAKA,QAAO;AACvD,UAAI,KAAK;AACT,UAAI,UAAU,GAAG,GAAG,GAAG,CAAC;AACxB,UAAI,OAAO,iBAAiB,IAAI,EAAE,CAAC;AACnC,iBAAW,KAAK,KAAK,MAAM,MAAM,EAAE,GAAG,GAAG,GAAG,OAAO,EAAE,GAAG,KAAK,OAAO,EAAE,OAAO,UAAU,SAAS,SAAS,UAAU,UAAU,UAAU,UAAU,UAAU,OAAO,SAAS,CAAC;AAC5K,UAAI,QAAQ;AAAA,IACd;AAAA,EACF;AAAA;AAAA,EAGS,gBAAsB;AAAA,EAAC;AAAA,EAEhC,QAAQ,OAAc,UAA6B;AACjD,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,QAAQ,KAAK,SAAS,QAAQ;AACpC,aAAO,CAAC,CAAC,UAAU,MAAM,OAAO,MAAM,GAAG,KAAK,kBAAkB,OAAO,MAAM,QAAQ,WAAW,MAAM,KAAK,MAAM,MAAM,CAAC,KAAK;AAAA,IAC/H;AACA,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,QAAI,kBAAkB,OAAO,IAAI,EAAE,KAAK,EAAG,QAAO;AAClD,UAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,WAAO,CAAC,CAAC,OAAO,MAAM,OAAO,IAAI,GAAG;AAAA,EACtC;AACF;AAWA,IAAM,aAAa,EAAE,MAAM,OAAO,MAAM,GAAG,MAAM,IAAI,MAAM,EAAE;AAK7D,IAAM,UAAU,EAAE,OAAO,KAAK,MAAM,KAAK,SAAS,IAAI,SAAS,GAAG,UAAU,IAAI,QAAQ,GAAG,MAAM,MAAM,SAAS,EAAE,MAAM,KAAK,OAAO,EAAE,EAAE;AAYjI,IAAM,MAAN,cAAkB,QAAkB;AAAA,EAChC,OAAO;AAAA,EAEG,eAAyB;AAC1C,WAAO,EAAE,GAAG,WAAW,WAAW,KAAK;AAAA,EACzC;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,WAAW,aAAa,KAAK;AACxE,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,gBAAgB,MAAM,YAAY,OAAO,WAAW,CAAC,EAAE;AAAA,EACzF;AAAA,EAES,WAAW,OAAgC;AAClD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIQ,OAAO,UAAmF;AAChG,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAM,IAAI,UAAU,KAAK,cAAc,QAAQ,QAAQ;AACvD,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,OAAO,KAAK,MAAM,EAAE,CAAC;AAC3B,UAAM,MAAM,KAAK,MAAM,EAAE,CAAC,IAAI;AAC9B,WAAO,EAAE,GAAG,OAAO,KAAK,MAAM,KAAK,MAAM,MAAM,WAAW,KAAK;AAAA,EACjE;AAAA;AAAA,EAGQ,WAAoB;AAC1B,WAAO,KAAK,WAAW,KAAK,UAAU,cAAc,KAAK,UAAU,aAAa,CAAC,CAAC,KAAK;AAAA,EACzF;AAAA;AAAA,EAGU,MAAM,UAAuE;AACrF,UAAM,IAAI,KAAK,OAAO,QAAQ;AAC9B,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,aAAa,KAAK,MAAM,KAAK,MAAM,WAAW,IAAI;AACxD,UAAM,EAAE,OAAO,YAAY,IAAI,KAAK,WAAW,YAAY,KAAK,KAAK,GAAG,QAAQ,IAAI;AACpF,UAAM,QAAQ,eAAe;AAC7B,UAAM,SAAS,MAAM,MAAM,SAAS,aAAa,QAAQ;AACzD,UAAM,SAAS,EAAE,MAAM,QAAQ;AAC/B,UAAMJ,OAAM,EAAE,GAAG,EAAE,OAAO,QAAQ,QAAQ,GAAG,GAAG,SAAS,QAAQ,OAAO,QAAQ,OAAO,OAAO;AAC9F,WAAO,EAAE,KAAAA,MAAK,GAAGA,KAAI,IAAI,QAAQ,SAAS,GAAGA,KAAI,IAAI,QAAQ,SAAS,YAAY,OAAO,aAAa,KAAK,EAAE,KAAK,IAAI,EAAE,EAAE;AAAA,EAC5H;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,MAAM,WAAW;AACxB,WAAK,WAAW,KAAK,QAAQ;AAC7B;AAAA,IACF;AACA,UAAM,IAAI,KAAK,OAAO,QAAQ;AAC9B,QAAI,CAAC,EAAG;AACR,UAAM,EAAE,MAAM,MAAM,KAAK,IAAI;AAC7B,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,QAAI,OAAO,EAAE,GAAG,EAAE,GAAG;AACrB,QAAI,iBAAiB,EAAE,IAAI,MAAM,EAAE,OAAO,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI;AAClE,QAAI,IAAI,EAAE,GAAG,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AACrC,QAAI,iBAAiB,EAAE,IAAI,MAAM,EAAE,OAAO,MAAM,EAAE,GAAG,EAAE,GAAG;AAC1D,QAAI,UAAU;AACd,QAAI,OAAO,EAAE,IAAI,MAAM,EAAE,IAAI;AAC7B,QAAI,IAAI,EAAE,GAAG,EAAE,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC;AACzC,QAAI,KAAK,SAAS;AAClB,QAAI,QAAQ;AACZ,QAAI,CAAC,KAAK,SAAS,EAAG;AACtB,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,QAAI,CAAC,GAAI;AACT,UAAM,EAAE,KAAAA,KAAI,IAAI;AAChB,UAAM,EAAE,MAAM,MAAM,IAAI,QAAQ;AAChC,UAAM,SAASA,KAAI,IAAIA,KAAI;AAC3B,UAAM,aAAa,KAAK,MAAM,iBAAiB,UAAU,KAAK,KAAK,IAAI;AACvE,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,UAAU;AACd,QAAI,UAAUA,KAAI,GAAGA,KAAI,GAAGA,KAAI,OAAOA,KAAI,QAAQ,QAAQ,MAAM;AACjE,QAAI,OAAO,GAAG,KAAK,MAAM,MAAM;AAC/B,QAAI,OAAO,GAAG,IAAI,SAAS,KAAK;AAChC,QAAI,OAAO,GAAG,KAAK,MAAM,MAAM;AAC/B,QAAI,UAAU;AACd,QAAI,YAAY;AACd,UAAI,cAAc,YAAY;AAC9B,UAAI,aAAa,YAAY;AAC7B,UAAI,gBAAgB,YAAY;AAChC,UAAI,YAAY;AAChB,UAAI,KAAK;AACT,UAAI,cAAc;AAAA,IACpB;AACA,QAAI,KAAK,MAAM,YAAY;AACzB,UAAI,cAAc,KAAK,MAAM;AAC7B,UAAI,YAAY;AAChB,UAAI,OAAO;AAAA,IACb;AACA,QAAI,QAAQ;AACZ,mBAAe,KAAK;AAAA,MAClB,GAAG,GAAG;AAAA,MACN,GAAG,GAAG;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,YAAY,GAAG;AAAA,MACf,MAAM,OAAO,KAAK,KAAK;AAAA,MACvB,OAAO,KAAK,MAAM;AAAA,MAClB,OAAO;AAAA,MACP,OAAO,GAAG;AAAA,MACV,aAAa,GAAG,cAAc,EAAE,OAAO,GAAG,aAAa,OAAO,kBAAkB,IAAI;AAAA,MACpF,OAAO,KAAK;AAAA,MACZ,SAAS,YAAY,KAAK,KAAK;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,WAAW,KAA+B,UAA0B;AAC1E,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAM,IAAI,UAAU,KAAK,cAAc,QAAQ,QAAQ;AACvD,QAAI,CAAC,EAAG;AACR,UAAM,IAAI;AACV,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,QAAI,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,GAAG,GAAG,KAAK,KAAK,MAAM,KAAK,KAAK,IAAI;AAC3D,QAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,QAAI,UAAU;AACd,QAAI,KAAK;AACT,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,GAAG,IAAI,KAAK,GAAG,KAAK,KAAK,CAAC;AACjD,QAAI,KAAK;AACT,QAAI,QAAQ;AACZ,QAAI,KAAK,MAAM,MAAM;AACnB,YAAM,EAAE,MAAM,IAAI,iBAAiB,KAAK,MAAM,MAAM,KAAK,KAAK;AAC9D,qBAAe,KAAK,KAAK,MAAM,MAAM,EAAE,GAAG,EAAE,KAAK,QAAQ,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO;AAAA,QAC1F,YAAY,KAAK,MAAM,iBAAkB,UAAU,KAAK,KAAK,KAAK,SAAa;AAAA,QAC/E,aAAa,KAAK,MAAM,aAAa,KAAK,MAAM,cAAc;AAAA,MAChE,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAES,UAAU,UAA0C;AAC3D,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,KAAK,EAAE,GAAG,WAAW,IAAI,OAAO,KAAK,KAAK,GAAG,QAAQ,QAAQ,IAAI,GAAG,WAAW,QAAQ,KAAK,IAAI;AAAA,EACzG;AAAA;AAAA,EAGS,QAAQ,OAAc,UAA6B;AAC1D,QAAI,KAAK,MAAM,aAAa,CAAC,KAAK,SAAS,EAAG,QAAO;AACrD,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,CAAC,CAAC,MAAM,MAAM,OAAO,GAAG,KAAK,CAAC;AAAA,EACvC;AAAA;AAAA,EAGmB,SAAS,OAAc,UAAmC;AAC3E,WAAO,KAAK,UAAU,cAAc,KAAK,QAAQ,OAAO,QAAQ,IAAI,SAAS;AAAA,EAC/E;AAAA,EAES,cAA2B;AAClC,WAAO,KAAK,MAAM,YAAY,WAAW;AAAA,EAC3C;AAAA;AAAA,EAGS,gBAAsB;AAAA,EAAC;AAAA,EAEhC,QAAQ,OAAc,UAA6B;AACjD,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,YAAM,IAAI,UAAU,KAAK,cAAc,QAAQ,QAAQ;AACvD,aAAO,CAAC,CAAC,KAAK,MAAM,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,IAAI,OAAO,IAAI,QAAQ,GAAG,GAAG,CAAC;AAAA,IAClF;AACA,UAAM,IAAI,KAAK,OAAO,QAAQ;AAC9B,QAAI,CAAC,EAAG,QAAO;AACf,QAAI,KAAK,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,IAAI,EAAE,IAAI,KAAK,WAAW,OAAO,EAAG,QAAO;AAE/E,UAAM,QAAQ,MAAM,IAAI,EAAE;AAC1B,QAAI,SAAS,KAAK,MAAM,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK,WAAW,QAAQ,IAAI,QAAQ,WAAW,QAAQ,EAAG,QAAO;AACjI,QAAI,CAAC,KAAK,SAAS,EAAG,QAAO;AAC7B,UAAM,KAAK,KAAK,MAAM,QAAQ;AAC9B,WAAO,CAAC,CAAC,MAAM,MAAM,OAAO,EAAE,GAAG,GAAG,KAAK,QAAQ,GAAG,IAAI,SAAS,QAAQ,QAAQ,MAAM,GAAG,CAAC;AAAA,EAC7F;AACF;AAkBA,IAAM,WAAW;AACjB,IAAM,oBAAoB;AAC1B,IAAM,kBAAkB;AACxB,IAAM,eAAe;AACrB,IAAM,WAAW;AAYV,IAAM,WAAN,cAAuB,QAAuB;AAAA,EAC1C,OAAO;AAAA,EAEG,eAA8B;AAC/C,WAAO,EAAE,MAAM,IAAI,WAAW,OAAO,OAAO,aAAM,UAAU,MAAM,WAAW,KAAK;AAAA,EACpF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,CAAC,EAAE;AAAA,EAChD;AAAA,EAES,WAAW,OAAqC;AACvD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA;AAAA,EAGU,WAAW,UAAmD;AACtE,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAM,IAAI,UAAU,MAAM,cAAc,QAAQ,QAAQ;AACxD,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,EAAE,OAAO,OAAO,IAAI,iBAAiB,KAAK,MAAM,QAAQ,KAAK,KAAK,KAAK;AAC7E,WAAO,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,QAAQ,MAAM,GAAG,GAAG,EAAE,IAAI,KAAK,QAAQ,OAAO,QAAQ,IAAI,QAAQ,SAAS,GAAG,GAAG,EAAE;AAAA,EAC/G;AAAA,EAEU,eAAe,KAA+B,UAA0B;AAChF,UAAM,QAAQ,KAAK,WAAW,QAAQ;AACtC,QAAI,CAAC,MAAO;AACZ,UAAM,EAAE,KAAAA,MAAK,EAAE,IAAI;AACnB,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,QAAI,OAAO,EAAE,GAAGA,KAAI,IAAIA,KAAI,MAAM;AAClC,QAAI,OAAO;AACX,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,QAAI,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,KAAK,KAAK,CAAC;AACnC,QAAI,KAAK;AACT,QAAI,QAAQ;AACZ,mBAAe,KAAK,KAAK,MAAM,QAAQ,KAAK,EAAE,GAAGA,KAAI,GAAG,GAAGA,KAAI,EAAE,GAAG,KAAK,OAAO,EAAE,YAAY,UAAU,WAAW,IAAI,GAAG,aAAa,KAAK,MAAM,UAAU,CAAC;AAAA,EAC/J;AAAA;AAAA,EAGS,SAAS,QAA6C;AAC7D,UAAM,SAAS,MAAM;AACrB,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAM,WAAW,KAAK,YAAY;AAClC,QAAI,KAAK,MAAM,aAAa,KAAK,MAAM,aAAa,QAAQ,CAAC,UAAU,CAAC,SAAU;AAClF,UAAM,QAAQ,KAAK,QAAQ,QAAQ,QAAQ;AAC3C,QAAI,CAAC,MAAO;AACZ,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,UAAU,MAAM,SAAS;AACzD,SAAK,SAAS,CAAC,IAAI,MAAM;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKU,QAAQ,OAAe,UAAiE;AAChG,UAAM,IAAI,SAAS,IAAI,MAAM,KAAK;AAClC,QAAI,MAAM,QAAQ,EAAE,SAAS,SAAS,GAAI,QAAO;AACjD,UAAM,MAAM,MAAM,KAAK,KAAK,GAAG,MAAM,IAAI;AACzC,UAAM,QAAQ,MAAM,SAAS,IAAI,IAAI,IAAI,IAAI;AAC7C,UAAM,OAAO,MAAM,SAAS,IAAI,IAAI,GAAG,IAAI;AAC3C,QAAI,CAAC,OAAO,UAAU,QAAQ,SAAS,KAAM,QAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,GAAG,UAAU,EAAE;AACpH,QAAI,IAAI,KAAM,QAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,MAAM,OAAO,IAAI,IAAI,GAAG,UAAU,GAAG,IAAI,QAAQ,SAAS,UAAU,IAAI;AACrH,WAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,MAAM,OAAO,IAAI,KAAK,GAAG,UAAW,KAAK,IAAI,GAAG,QAAQ,CAAC,IAAI,SAAS,SAAU,IAAI;AAAA,EACrH;AAAA;AAAA,EAGU,MAAM,UAAoB,SAA6B,KAAK,QAAQ,CAAC,GAAyD;AACtI,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,SAAS,IAAI,OAAO,IAAI;AAClC,QAAI,MAAM,KAAM,QAAO;AACvB,UAAM,WAAW,KAAK,MAAM;AAC5B,QAAI,aAAa,MAAM;AACrB,YAAM,IAAI,SAAS,IAAI,OAAO,KAAK;AACnC,aAAO,MAAM,OAAO,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,OAAO,KAAK;AAAA,IAC5E;AACA,UAAM,MAAM,MAAM,KAAK,KAAK,GAAG,OAAO,IAAI;AAC1C,UAAM,QAAQ,SAAS,IAAI,MAAO,YAAY,IAAI,IAAI,OAAO,IAAI,MAAO,OAAO,KAAK;AACpF,QAAI,UAAU,KAAM,QAAO;AAC3B,WAAO,EAAE,MAAM,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,EAAE,GAAG,GAAG,QAAS,WAAW,MAAO,SAAS,OAAO,GAAG,OAAO,YAAY,EAAE;AAAA,EACpH;AAAA;AAAA,EAGS,cAAc,QAAgB,UAAkC;AACvE,QAAI,KAAK,MAAM,UAAW,QAAO,MAAM,cAAc,QAAQ,QAAQ;AACrE,WAAO,KAAK,MAAM,UAAU,MAAM,GAAG,SAAS;AAAA,EAChD;AAAA;AAAA;AAAA,EAIS,aAAa,OAAe,QAAsB;AACzD,UAAM,UAAU,KAAK,QAAQ,CAAC;AAC9B,UAAM,WAAW,KAAK,YAAY;AAClC,QAAI,UAAU,KAAK,CAAC,WAAW,KAAK,MAAM,WAAW;AACnD,YAAM,aAAa,OAAO,MAAM;AAChC;AAAA,IACF;AACA,UAAM,WAAW,KAAK,MAAM;AAC5B,QAAI,OAAO,UAAU,QAAQ,SAAS,aAAa,MAAM;AACvD,YAAM,MAAM,MAAM,KAAK,KAAK,GAAG,OAAO,IAAI;AAC1C,YAAM,aAAa,GAAG,EAAE,MAAM,OAAO,MAAM,OAAO,MAAO,YAAY,IAAI,IAAI,OAAO,IAAI,MAAO,OAAO,MAAM,CAAC;AAC7G;AAAA,IACF;AACA,UAAM,QAAQ,WAAW,KAAK,QAAQ,QAAQ,QAAQ,IAAI;AAC1D,QAAI,CAAC,OAAO;AACV,YAAM,aAAa,GAAG,MAAM;AAC5B;AAAA,IACF;AACA,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,UAAU,MAAM,SAAS;AACzD,UAAM,aAAa,GAAG,MAAM,MAAM;AAAA,EACpC;AAAA;AAAA,EAGU,MAAM,UAAwK;AACtL,UAAM,QAAQ,KAAK,MAAM,QAAQ;AACjC,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,EAAE,OAAO,YAAY,IAAI,KAAK,WAAW,YAAY,KAAK,KAAK,CAAC;AACtE,UAAM,QAAQ,eAAe;AAC7B,UAAM,aAAa,KAAK,MAAM,KAAK,MAAM,WAAW,IAAI;AACxD,UAAM,QAAQ,KAAK,MAAM,aAAa,KAAK,MAAM,QAAQ,KAAK,MAAM,KAAK,MAAM,WAAW,GAAG,IAAI;AACjG,UAAM,MAAM,SAAS,MAAM,QAAQ,IAAI;AACvC,UAAM,UAAU,QAAQ,MAAM,MAAM;AACpC,UAAM,aAAa,MAAM,MAAM,SAAS;AACxC,UAAM,QAAQ,KAAK,IAAI,OAAO,UAAU;AACxC,UAAM,QAAQ,KAAK,MAAM,UAAU,iBAAiB;AACpD,UAAM,SAAS,QAAQ;AACvB,UAAM,KAAK,KAAK,MAAM,MAAM,MAAM,CAAC;AACnC,UAAM,KAAK,KAAK,MAAM,MAAM,MAAM,CAAC;AAEnC,UAAMA,OAAM,EAAE,GAAG,KAAK,KAAK,MAAM,QAAQ,CAAC,GAAG,GAAG,KAAK,SAAS,GAAG,OAAO,OAAO;AAC/E,UAAM,QAAQ,KAAK,UAAU;AAC7B,UAAM,MAAMA,KAAI,IAAI,kBAAkB;AACtC,UAAM,QAAQ,EAAE,KAAAA,MAAK,GAAG,QAAQ,QAAQ,KAAK,GAAG,OAAO,QAAQ,cAAc,GAAG,YAAY,OAAO,YAAY;AAC/G,UAAM,QAAQ,KAAK,MAAM,MAAM,KAAK,CAAC;AACrC,UAAM,OAAO,MAAM,QAAQ,EAAE,MAAM,KAAK,GAAG,IAAI,QAAQ,WAAW,EAAE,IAAI,EAAE,MAAM,QAAQ,UAAU,IAAIA,KAAI,EAAE;AAC5G,WAAO;AAAA,MACL,KAAAA;AAAA,MACA;AAAA,MACA,OAAO,QAAQ,EAAE,GAAG,OAAO,GAAG,OAAO,QAAQ,SAAS,GAAG,MAAM,MAAM,IAAI;AAAA,MACzE,MAAM,KAAK,KAAK,KAAK,OAAO,EAAE,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,MAAM,aAAa,CAAC,KAAK,WAAW;AAC3C,WAAK,eAAe,KAAK,QAAQ;AACjC;AAAA,IACF;AACA,UAAM,QAAQ,KAAK,MAAM,QAAQ;AACjC,QAAI,CAAC,MAAO;AACZ,UAAM,EAAE,KAAAA,MAAK,MAAM,IAAI;AACvB,UAAM,OAAO,KAAK,KAAK;AACvB,UAAM,SAAS,CAAC,CAAC,MAAM;AACvB,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,YAAY;AAChB,QAAI,MAAM,MAAM;AACd,UAAI,cAAc;AAClB,UAAI,UAAU;AACd,UAAI,OAAO,MAAM,KAAK,GAAG,MAAM,KAAK,IAAI;AACxC,UAAI,OAAO,MAAM,KAAK,GAAG,MAAM,KAAK,EAAE;AACtC,UAAI,OAAO;AAAA,IACb;AAEA,QAAI,UAAU;AACd,QAAI,UAAUA,KAAI,IAAI,KAAKA,KAAI,IAAI,KAAKA,KAAI,QAAQ,GAAGA,KAAI,SAAS,GAAG,YAAY;AACnF,QAAI,QAAQ;AACV,UAAI,YAAY,KAAK,MAAM;AAC3B,UAAI,KAAK;AAAA,IACX;AACA,QAAI,cAAc,SAAS,KAAK,MAAM,YAAY,KAAK;AACvD,QAAI,OAAO;AACX,QAAI,QAAQ;AACZ,QAAI,MAAM,OAAO;AACf,YAAM,EAAE,GAAG,GAAG,KAAK,IAAI,MAAM;AAC7B,YAAM,MAAM,KAAK,SAAS,KAAK,MAAM,KAAK;AAC1C,YAAM,MAAM,MAAM,aAAa,KAAK,MAAM,KAAK,cAAc,CAAC,IAAI;AAClE,UAAI,IAAK,KAAI,UAAU,KAAK,GAAG,GAAG,MAAM,IAAI;AAAA,WACvC;AACH,YAAI,KAAK;AACT,YAAI,OAAO,GAAG,IAAI;AAClB,YAAI,eAAe;AACnB,YAAI,YAAY;AAChB,YAAI,YAAY;AAChB,YAAI,SAAS,KAAK,MAAM,OAAO,GAAG,CAAC;AACnC,YAAI,QAAQ;AAAA,MACd;AAAA,IACF;AACA,mBAAe,KAAK;AAAA,MAClB,GAAG,MAAM;AAAA,MACT,GAAG,MAAM;AAAA,MACT,QAAQ,MAAM,eAAe,MAAM,OAAO;AAAA,MAC1C,YAAY,MAAM;AAAA,MAClB,MAAM,OAAO,KAAK,KAAK;AAAA,MACvB,OAAO,SAAS,MAAM,KAAK,MAAM,SAAS,IAAI,KAAK;AAAA,MACnD,OAAO;AAAA,MACP,OAAO,MAAM;AAAA,MACb,aAAa,MAAM,cAAc,EAAE,OAAO,MAAM,aAAa,OAAO,kBAAkB,IAAI;AAAA,MAC1F,OAAO,KAAK;AAAA,MACZ,SAAS,YAAY,KAAK,KAAK;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAES,UAAU,UAA0C;AAC3D,UAAM,QAAQ,KAAK,MAAM,QAAQ;AACjC,WAAO,QAAQ,WAAW,MAAM,OAAO,OAAO,KAAK,KAAK,GAAG,QAAQ,IAAI;AAAA,EACzE;AAAA;AAAA,EAGS,cAA2B;AAClC,WAAO;AAAA,EACT;AAAA;AAAA,EAGS,aAAa,OAAe,QAAsB;AACzD,UAAM,UAAU,KAAK,QAAQ,KAAK;AAClC,SAAK,aAAa,OAAO,WAAW,CAAC,KAAK,MAAM,YAAY,EAAE,MAAM,QAAQ,MAAM,OAAO,OAAO,MAAM,IAAI,MAAM;AAAA,EAClH;AAAA;AAAA,EAGS,QAAQ,OAAc,UAA6B;AAC1D,QAAI,KAAK,MAAM,UAAW,QAAO,KAAK,QAAQ,OAAO,QAAQ;AAC7D,UAAM,QAAQ,KAAK,MAAM,QAAQ;AACjC,WAAO,CAAC,CAAC,SAAS,MAAM,OAAO,MAAM,GAAG;AAAA,EAC1C;AAAA;AAAA,EAGmB,SAAS,OAAc,UAAmC;AAC3E,WAAO,KAAK,UAAU,cAAc,KAAK,QAAQ,OAAO,QAAQ,IAAI,SAAS;AAAA,EAC/E;AAAA;AAAA,EAGS,gBAAsB;AAAA,EAAC;AAAA,EAEhC,QAAQ,OAAc,UAA6B;AACjD,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,QAAQ,KAAK,WAAW,QAAQ;AACtC,aAAO,CAAC,CAAC,SAAS,MAAM,OAAO,MAAM,GAAG;AAAA,IAC1C;AACA,UAAM,QAAQ,KAAK,MAAM,QAAQ;AACjC,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI,MAAM,OAAO,MAAM,GAAG,EAAG,QAAO;AACpC,WAAO,CAAC,CAAC,MAAM,QAAQ,KAAK,IAAI,MAAM,IAAI,MAAM,KAAK,CAAC,KAAK,KAAK,MAAM,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK;AAAA,EAC/H;AACF;AAKA,IAAM,eAAe,EAAE,MAAM,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM,EAAE;AAQjE,IAAM,cAAN,cAA0B,QAAoC;AAAA,EAC1D,OAAO;AAAA,EAEG,eAA2C;AAC5D,WAAO,EAAE,MAAM,IAAI,WAAW,KAAK;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKmB,cAAc,QAAiD;AAChF,UAAM,CAAC,KAAK,IAAI,IAAI,KAAK;AACzB,QAAI,OAAO,KAAM,MAAK,WAAW,CAAC,MAAM,GAAG;AAC3C,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,CAAC,EAAE;AAAA,EAChD;AAAA,EAES,WAAW,OAAkD;AACpE,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,SAAS,UAAuF;AACtG,UAAM,CAAC,MAAM,GAAG,IAAI,KAAK,aAAa,QAAQ;AAC9C,QAAI,CAAC,QAAQ,CAAC,IAAK,QAAO;AAC1B,WAAO,EAAE,MAAM,KAAK,QAAQ,KAAK,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,CAAC,GAAG,OAAO,KAAK,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,CAAC,EAAE;AAAA,EAC5H;AAAA;AAAA,EAGQ,QAAQ,QAAoC;AAClD,UAAM,OAAO,SAAS,aAAa;AACnC,UAAM,QAAQ,SAAS,aAAa;AACpC,UAAM,QAAQ,SAAS,aAAa;AACpC,UAAM,OAAO,KAAK,IAAI,aAAa,MAAM,KAAK;AAC9C,WAAO;AAAA,MACL,CAAC,GAAG,CAAC,IAAI;AAAA,MACT,CAAC,MAAM,CAAC,KAAK;AAAA,MACb,CAAC,MAAM,CAAC,KAAK;AAAA,MACb,CAAC,QAAQ,CAAC;AAAA,MACV,CAAC,MAAM,KAAK;AAAA,MACZ,CAAC,MAAM,KAAK;AAAA,MACZ,CAAC,GAAG,IAAI;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,MAAM,WAAW;AACxB,WAAK,WAAW,KAAK,QAAQ;AAC7B;AAAA,IACF;AACA,UAAM,IAAI,KAAK,SAAS,QAAQ;AAChC,QAAI,CAAC,EAAG;AACR,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,UAAU,EAAE,KAAK,GAAG,EAAE,KAAK,CAAC;AAChC,QAAI,OAAO,EAAE,KAAK;AAClB,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,SAAK,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,MAAO,MAAM,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,CAAE;AAC7F,QAAI,UAAU;AACd,QAAI,KAAK;AACT,QAAI,QAAQ;AACZ,SAAK,WAAW,KAAK,EAAE,MAAM,EAAE,GAAG;AAAA,EACpC;AAAA;AAAA,EAGQ,WAAW,KAA+B,MAAa,KAAkB;AAC/E,QAAI,CAAC,KAAK,MAAM,KAAM;AACtB,UAAM,EAAE,OAAO,OAAO,IAAI,iBAAiB,KAAK,MAAM,MAAM,KAAK,KAAK;AACtE,UAAM,QAAQ,KAAK,KAAK,IAAI;AAC5B,mBAAe,KAAK,KAAK,MAAM,MAAM,EAAE,GAAG,KAAK,KAAK,QAAQ,MAAM,GAAG,GAAG,QAAQ,KAAK,IAAI,SAAS,KAAK,IAAI,KAAK,IAAI,EAAE,GAAG,KAAK,KAAK;AAAA,EACrI;AAAA;AAAA,EAGQ,WAAW,KAA+B,UAA0B;AAC1E,UAAM,IAAI,KAAK,SAAS,QAAQ;AAChC,QAAI,CAAC,EAAG;AACR,UAAM,MAAM,KAAK,IAAI,IAAI,EAAE,MAAM;AACjC,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC;AAC9C,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,UAAU,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC;AAC9B,QAAI,OAAO,EAAE,QAAQ,KAAK,EAAE;AAC5B,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,QAAI,OAAO,GAAG,CAAC;AACf,QAAI,OAAO,GAAG,CAAC,CAAC;AAChB,QAAI,OAAO,GAAG,CAAC,IAAI,CAAC;AACpB,QAAI,OAAO,KAAK,CAAC,IAAI,CAAC;AACtB,QAAI,OAAO,KAAK,IAAI,CAAC;AACrB,QAAI,OAAO,GAAG,IAAI,CAAC;AACnB,QAAI,OAAO,GAAG,CAAC;AACf,QAAI,UAAU;AACd,QAAI,KAAK;AACT,QAAI,QAAQ;AACZ,SAAK,WAAW,KAAK,EAAE,MAAM,EAAE,GAAG;AAAA,EACpC;AAAA;AAAA,EAGS,gBAAsB;AAAA,EAAC;AAAA,EAEhC,QAAQ,OAAc,UAA6B;AACjD,UAAM,IAAI,KAAK,SAAS,QAAQ;AAChC,QAAI,CAAC,EAAG,QAAO;AAEf,UAAM,KAAK,MAAM,IAAI,EAAE,KAAK;AAC5B,UAAM,KAAK,MAAM,IAAI,EAAE,KAAK;AAC5B,UAAM,QAAQ,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,KAAK;AAC5D,UAAM,SAAS,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,KAAK,KAAK,IAAI,EAAE,KAAK,CAAC;AACxE,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC;AACjE,aAAO,SAAS,MAAM,SAAS,KAAK,IAAI,IAAI,EAAE,MAAM,IAAI,KAAK,UAAU,IAAI;AAAA,IAC7E;AACA,QAAI,QAAQ,MAAM,QAAQ,EAAE,SAAS,EAAG,QAAO;AAC/C,UAAM,OAAO,EAAE,SAAS,aAAa;AACrC,UAAM,QACJ,SAAS,OACL,aAAa,QAAQ,EAAE,SAAS,aAAa,QAAQ,aAAa,QAAQ,KAAK,IAAI,GAAG,QAAQ,KAAK,IAAI,MAAM,CAAC,CAAC,IAC/G,EAAE,SAAS,aAAa,QAAQ,KAAK,IAAI,IAAI,EAAE,SAAS,SAAS,KAAK,IAAI,EAAE,SAAS,MAAM,CAAC,CAAC;AACnG,WAAO,UAAU,QAAQ;AAAA,EAC3B;AACF;AAQA,IAAM,OAAO,EAAE,MAAM,IAAI,MAAM,GAAG,IAAI,IAAI,QAAQ,IAAI,OAAO,EAAE;AAMxD,IAAM,WAAN,cAAuB,QAAmB;AAAA,EACtC,OAAO;AAAA,EAEG,eAA0B;AAC3C,WAAO,EAAE,WAAW,KAAK;AAAA,EAC3B;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,CAAC,EAAE;AAAA,EAChD;AAAA,EAES,WAAW,OAAiC;AACnD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,KAAK,UAAkC;AAC7C,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAM,IAAI,UAAU,KAAK,cAAc,QAAQ,QAAQ;AACvD,WAAO,IAAI,EAAE,GAAG,KAAK,MAAM,EAAE,CAAC,GAAG,GAAG,KAAK,MAAM,EAAE,CAAC,EAAE,IAAI;AAAA,EAC1D;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,MAAM,WAAW;AACxB,WAAK,WAAW,KAAK,QAAQ;AAC7B;AAAA,IACF;AACA,UAAM,IAAI,KAAK,KAAK,QAAQ;AAC5B,QAAI,CAAC,EAAG;AACR,UAAM,MAAM,EAAE,IAAI,KAAK;AACvB,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,cAAc;AAClB,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,OAAO,EAAE,IAAI,KAAK,GAAG;AACzB,QAAI,OAAO,EAAE,IAAI,KAAK,EAAE,CAAC;AACzB,QAAI,OAAO;AACX,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,QAAI,OAAO,EAAE,IAAI,KAAK,MAAM,GAAG;AAC/B,QAAI,OAAO,EAAE,IAAI,KAAK,IAAI,GAAG;AAC7B,QAAI,OAAO,EAAE,IAAI,KAAK,KAAK,KAAK,OAAO,MAAM,KAAK,SAAS,CAAC;AAC5D,QAAI,OAAO,EAAE,IAAI,KAAK,IAAI,MAAM,KAAK,MAAM;AAC3C,QAAI,OAAO,EAAE,IAAI,KAAK,MAAM,MAAM,KAAK,MAAM;AAC7C,QAAI,UAAU;AACd,QAAI,KAAK;AACT,QAAI,QAAQ;AAAA,EACd;AAAA;AAAA,EAGQ,WAAW,KAA+B,UAA0B;AAC1E,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAM,IAAI,UAAU,KAAK,cAAc,QAAQ,QAAQ;AACvD,QAAI,CAAC,EAAG;AACR,UAAM,SAAS;AACf,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,QAAI,OAAO,EAAE,GAAG,EAAE,IAAI,MAAM;AAC5B,QAAI,OAAO;AACX,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,UAAU;AACd,QAAI,OAAO,EAAE,GAAG,EAAE,IAAI,MAAM;AAC5B,QAAI,OAAO,EAAE,IAAI,IAAI,EAAE,IAAI,SAAS,CAAC;AACrC,QAAI,OAAO,EAAE,GAAG,EAAE,IAAI,SAAS,EAAE;AACjC,QAAI,UAAU;AACd,QAAI,KAAK;AACT,QAAI,QAAQ;AAAA,EACd;AAAA,EAES,cAA2B;AAClC,WAAO,KAAK,MAAM,YAAY,WAAW;AAAA,EAC3C;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,YAAMK,KAAI,UAAU,KAAK,cAAc,QAAQ,QAAQ;AACvD,aAAO,CAAC,CAACA,MAAK,MAAM,OAAO,EAAE,GAAGA,GAAE,IAAI,GAAG,GAAGA,GAAE,IAAI,IAAI,OAAO,IAAI,QAAQ,GAAG,CAAC;AAAA,IAC/E;AACA,UAAM,IAAI,KAAK,KAAK,QAAQ;AAC5B,QAAI,CAAC,EAAG,QAAO;AACf,WAAO,MAAM,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,KAAK,MAAM,OAAO,KAAK,KAAK,GAAG,QAAQ,KAAK,OAAO,GAAG,CAAC,KAAK,MAAM,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,KAAK,MAAM,OAAO,GAAG,QAAQ,KAAK,KAAK,GAAG,CAAC;AAAA,EACxL;AACF;;;AC/9DA,SAAS,IAAI,GAAU,GAAmE;AACxF,SAAO;AAAA,IACL,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;AAAA,IACpB,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;AAAA,IACpB,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA,IACzB,QAAQ,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA,EAC5B;AACF;AAEA,SAASC,OAAM,GAAU,GAA4D,MAAM,GAAY;AACrG,SAAO,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,OAAO,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS;AACvG;AAkCA,IAAM,cAA+B;AAAA,EACnC,MAAM;AAAA,EACN,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,gBAAgB;AAClB;AAIA,SAAS,aAAwC,OAAmB,OAAyC;AAC3G,QAAM,QAAQ;AACd,QAAM,MAA+B,EAAE,GAAG,MAAM;AAChD,QAAM,UAA8B;AAAA,IAClC,CAAC,kBAAkB,gBAAgB;AAAA,IACnC,CAAC,eAAe,mBAAmB;AAAA,IACnC,CAAC,YAAY,eAAe;AAAA,IAC5B,CAAC,gBAAgB,mBAAmB;AAAA,EACtC;AACA,aAAW,CAAC,MAAM,EAAE,KAAK,SAAS;AAChC,QAAI,QAAQ,KAAK;AACf,UAAI,EAAE,MAAM,KAAM,KAAI,EAAE,IAAI,IAAI,IAAI;AACpC,aAAO,IAAI,IAAI;AAAA,IACjB;AAAA,EACF;AACA,MAAI,YAAY,KAAK;AACnB,QAAI,IAAI,WAAW;AAAM,iBAAW,QAAQ,MAAO,KAAI,EAAE,QAAQ,KAAM,KAAI,IAAc,IAAI;AAAA;AAC7F,WAAO,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAGA,IAAe,aAAf,cAA6D,QAAW;AAAA,EACtE,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,OAAO,UAAmD;AAClE,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AACzC,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,WAAO,EAAE,GAAG,EAAE;AAAA,EAChB;AAAA;AAAA,EAGmB,kBAAkB,QAA0D;AAC7F,UAAM,CAAC,GAAG,CAAC,IAAI;AACf,WAAO,KAAK,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,EAAE,IAAI,MAAM,kBAAkB,MAAM;AAAA,EACvG;AAAA;AAAA,EAGU,KAAK,GAAU,GAAU,WAA8E;AAC/G,WAAO,IAAI,GAAG,CAAC;AAAA,EACjB;AAAA,EAEU,MAAM,UAA8B;AAC5C,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO,CAAC;AACtB,UAAM,MAAgB,CAAC;AACvB,QAAI,KAAK,cAAc,GAAG;AACxB,YAAM,SAAS,EAAE,QAAQ,EAAE;AAC3B,YAAM,MAAM,EAAE,UAAU,IAAK,SAAS,KAAK,IAAI,EAAE,KAAK,IAAK,MAAM;AACjE,YAAM,OAAO,KAAK,SAAS;AAC3B,YAAM,QAAkB,CAAC;AACzB,UAAI,KAAK,MAAM,eAAgB,OAAM,KAAK,GAAG,UAAU,IAAI,MAAM,EAAE,GAAG,KAAK,YAAY,MAAM,CAAC,EAAE;AAChG,UAAI,KAAK,MAAM,kBAAmB,OAAM,KAAK,IAAI,OAAO,IAAI,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,CAAC,IAAI;AAEzF,UAAI,KAAK,MAAM,kBAAkB,QAAQ,OAAO,EAAG,OAAM,KAAK,OAAO,KAAK,MAAM,SAAS,IAAI,CAAC,CAAC;AAC/F,UAAI,MAAM,OAAQ,KAAI,KAAK,MAAM,KAAK,GAAG,CAAC;AAAA,IAC5C;AACA,QAAI,KAAK,aAAa,GAAG;AACvB,UAAI,KAAK,MAAM,eAAe;AAC5B,cAAM,OAAO,SAAS,YAAY,EAAE,MAAM,EAAE,IAAI;AAChD,YAAI,SAAS,KAAM,KAAI,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC,OAAO;AAAA,MACxD;AACA,UAAI,KAAK,MAAM,mBAAmB;AAChC,cAAM,OAAO,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI;AAC3C,YAAI,OAAO,SAAS,IAAI,KAAK,SAAS,EAAG,KAAI,KAAKC,UAAS,KAAK,IAAI,IAAI,CAAC,CAAC;AAAA,MAC5E;AACA,UAAI,KAAK,MAAM,YAAY;AACzB,cAAM,QAAQ,YAAY,KAAK,KAAK,GAAG,EAAE,MAAM,EAAE,IAAI;AACrD,cAAM,QAAQ,MAAM,OAAO,CAAC,KAAK,QAAQ,OAAO,IAAI,UAAU,IAAI,CAAC;AACnE,YAAI,QAAQ,EAAG,KAAI,KAAK,OAAO,WAAW,KAAK,CAAC,EAAE;AAAA,MACpD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAMU,YAAY,MAAgC,IAAmE;AAAA,EAAC;AAAA;AAAA;AAAA,EAIvG,cAAc,QAAiD;AAChF,UAAM,IAAI,KAAK;AACf,SAAK,SAAS,EAAE,GAAG,GAAG,WAAW,EAAE,WAAW,aAAa,KAAK,IAAI,MAAM,EAAE,WAAW,EAAE;AACzF,SAAK,SAAS;AAAA,MACZ,GAAG,KAAK;AAAA,MACR,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,YAAY,EAAE;AAAA,MACd,eAAe,EAAE;AAAA,MACjB,qBAAqB;AAAA,MACrB,sBAAsB,UAAU,WAAW,IAAI;AAAA,MAC/C,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,KAAK,KAAK,OAAO,QAAQ;AAC/B,QAAI,CAAC,GAAI;AACT,UAAM,EAAE,GAAG,EAAE,IAAI;AACjB,UAAM,IAAI,KAAK,KAAK,GAAG,GAAG,QAAQ;AAClC,UAAM,OAAO,KAAK,MAAM,mBAAmB,QAAQ,UAAU,KAAK,KAAK,IAAI;AAC3E,QAAI,MAAM;AACR,UAAI,KAAK;AACT,UAAI,YAAY;AAChB,UAAI,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM;AACxC,UAAI,QAAQ;AAAA,IACd;AACA,SAAK,YAAY,KAAK,CAAC;AACvB,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,KAAK,cAAc,GAAG;AACxB,YAAM,KAAK,EAAE,IAAI,EAAE,KAAK;AACxB,oBAAc,KAAK,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC;AAC/C,qBAAe,KAAK,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,KAAK,KAAK;AAAA,IAC9D;AACA,QAAI,KAAK,aAAa,GAAG;AACvB,YAAM,IAAI,KAAK,cAAc,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK;AACpE,oBAAc,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAC/C,qBAAe,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,KAAK;AAAA,IAC9D;AACA,UAAM,QAAQ,KAAK,MAAM,QAAQ;AACjC,QAAI,MAAM,QAAQ;AAChB,YAAM,QAAQ,IAAI,GAAG,CAAC;AACtB,YAAM,QAAQ,CAAC,KAAK,MAAM;AAC1B,YAAM,MAAoB,EAAE,GAAG,KAAK,OAAO,WAAW,KAAK,MAAM,YAAY,UAAU,KAAK,MAAM,eAAe,GAAI,QAAQ,EAAE,MAAM,OAAO,QAAQ,MAAM,IAAI,CAAC,EAAG;AAClK,iBAAW,KAAK,MAAM,KAAK,UAAO,GAAG,EAAE,GAAG,MAAM,IAAI,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,MAAM,SAAS,GAAG,GAAG,KAAK;AAAA,QAC1G,OAAO;AAAA,QACP,GAAI,KAAK,MAAM,wBAAwB,QAAQ,EAAE,YAAY,KAAK,MAAM,qBAAqB,IAAI,CAAC;AAAA,MACpG,CAAC;AAAA,IACH;AACA,QAAI,KAAK,MAAM,MAAM;AACnB,YAAM,SAAS,IAAI,GAAG,CAAC;AACvB,iBAAW,KAAK,KAAK,MAAM,MAAM,EAAE,GAAG,OAAO,IAAI,OAAO,QAAQ,GAAG,GAAG,OAAO,IAAI,OAAO,SAAS,EAAE,GAAG,KAAK,OAAO,EAAE,OAAO,SAAS,CAAC;AAAA,IACvI;AAAA,EACF;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,KAAK,KAAK,OAAO,QAAQ;AAC/B,QAAI,CAAC,GAAI,QAAO;AAChB,WAAOD,OAAM,OAAO,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA,EACrC;AACF;AAGO,IAAM,aAAN,cAAyB,WAA4B;AAAA,EACjD,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,EAAE,GAAG,aAAa,gBAAgB,MAAM,mBAAmB,MAAM,gBAAgB,MAAM,YAAY,MAAM,YAAY,OAAO,aAAa,MAAM;AAAA,EACxJ;AAAA,EAEmB,aAAa,OAA2D;AACzF,WAAO,aAAa,OAAO,CAAC,cAAc,aAAa,CAAC;AAAA,EAC1D;AAAA,EAEmB,KAAK,GAAU,GAAU,UAA6E;AACvH,UAAM,IAAI,IAAI,GAAG,CAAC;AAClB,UAAM,OAAO,KAAK,MAAM,aAAa,IAAI,EAAE;AAC3C,UAAM,QAAQ,KAAK,MAAM,cAAc,SAAS,QAAQ,EAAE,IAAI,EAAE;AAChE,WAAO,EAAE,GAAG,MAAM,GAAG,EAAE,GAAG,OAAO,QAAQ,MAAM,QAAQ,EAAE,OAAO;AAAA,EAClE;AAAA,EAEU,gBAAyB;AACjC,WAAO;AAAA,EACT;AAAA,EAEU,eAAwB;AAChC,WAAO;AAAA,EACT;AACF;AAGO,IAAM,YAAN,cAAwB,WAA2B;AAAA,EAC/C,OAAO;AAAA,EAEG,eAA+B;AAChD,WAAO,EAAE,GAAG,aAAa,eAAe,MAAM,mBAAmB,MAAM,YAAY,MAAM,WAAW,OAAO,cAAc,MAAM;AAAA,EACjI;AAAA,EAEmB,aAAa,OAAyD;AACvF,WAAO,aAAa,OAAO,CAAC,aAAa,cAAc,CAAC;AAAA,EAC1D;AAAA,EAEmB,KAAK,GAAU,GAAU,UAA6E;AACvH,UAAM,IAAI,IAAI,GAAG,CAAC;AAClB,UAAM,MAAM,KAAK,MAAM,YAAY,IAAI,EAAE;AACzC,UAAM,SAAS,KAAK,MAAM,eAAe,SAAS,SAAS,EAAE,IAAI,EAAE;AACnE,WAAO,EAAE,GAAG,EAAE,GAAG,GAAG,KAAK,OAAO,EAAE,OAAO,QAAQ,SAAS,IAAI;AAAA,EAChE;AAAA,EAEU,gBAAyB;AACjC,WAAO;AAAA,EACT;AAAA,EAEU,eAAwB;AAChC,WAAO;AAAA,EACT;AACF;AAGO,IAAM,iBAAN,cAA6B,WAAgC;AAAA,EACzD,OAAO;AAAA,EAEG,eAAoC;AACrD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,MACnB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,mBAAmB;AAAA,MACnB,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEmB,aAAa,OAAmE;AACjG,WAAO,aAAa,OAAO,CAAC,cAAc,aAAa,CAAC;AAAA,EAC1D;AAAA,EAEmB,KAAK,GAAU,GAAU,UAA6E;AACvH,UAAM,IAAI,IAAI,GAAG,CAAC;AAClB,UAAM,OAAO,KAAK,MAAM,aAAa,IAAI,EAAE;AAC3C,UAAM,QAAQ,KAAK,MAAM,cAAc,SAAS,QAAQ,EAAE,IAAI,EAAE;AAChE,WAAO,EAAE,GAAG,MAAM,GAAG,EAAE,GAAG,OAAO,QAAQ,MAAM,QAAQ,EAAE,OAAO;AAAA,EAClE;AAAA,EAEmB,YAAY,KAA+B,GAAkE;AAC9H,QAAI,CAAC,KAAK,MAAM,WAAY;AAC5B,QAAI,KAAK;AACT,gBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,KAAK,MAAM,aAAa,WAAW,KAAK,MAAM,aAAa,WAAW,QAAQ,CAAC;AAC5H,QAAI,WAAW,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM;AAC1C,QAAI,QAAQ;AAAA,EACd;AAAA,EAEU,gBAAyB;AACjC,WAAO;AAAA,EACT;AAAA,EAEU,eAAwB;AAChC,WAAO;AAAA,EACT;AACF;AAEA,IAAM,aAAa;AACnB,IAAM,eAAe;AAOd,IAAM,UAAN,cAAsB,QAAQ;AAAA,EAC1B,OAAO;AAAA,EAEhB,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAG;AAC5B,UAAM,KAAK,EAAE,SAAS,EAAE;AACxB,UAAM,QAAQ,KAAK,aAAa;AAChC,UAAM,IAAI,IAAI,IAAI,EAAE;AACpB,QAAI,EAAE,QAAQ,KAAK,EAAE,SAAS,EAAG;AACjC,UAAM,aAA2B,EAAE,GAAG,KAAK,OAAO,WAAW,OAAO,WAAW,IAAI;AAEnF,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,YAAY,UAAU,OAAO,IAAI;AACrC,QAAI,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM;AAIxC,UAAM,KAAK,EAAE,IAAI,EAAE,QAAQ;AAC3B,UAAM,KAAK,EAAE,IAAI,EAAE,SAAS;AAC5B,QAAI,cAAc;AAClB,QAAI,YAAY;AAChB,QAAI,EAAE,UAAU,GAAG;AACjB,YAAM,OAAO,EAAE,GAAG,IAAI,GAAG,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;AACnD,YAAM,KAAK,EAAE,GAAG,IAAI,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO;AACjD,oBAAc,KAAK,MAAM,EAAE;AAC3B,qBAAe,KAAK,MAAM,IAAI,UAAU;AAAA,IAC1C;AACA,QAAI,EAAE,SAAS,GAAG;AAChB,YAAM,YAAY,GAAG,KAAK,GAAG;AAC7B,YAAM,OAAO,EAAE,GAAG,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,GAAG;AACzD,YAAM,KAAK,EAAE,GAAG,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAG,GAAG;AACvD,oBAAc,KAAK,MAAM,EAAE;AAC3B,qBAAe,KAAK,MAAM,IAAI,UAAU;AAAA,IAC1C;AAGA,UAAM,SAAS,EAAE,QAAQ,EAAE;AAC3B,UAAM,MAAM,EAAE,UAAU,IAAK,SAAS,KAAK,IAAI,EAAE,KAAK,IAAK,MAAM;AAEjE,UAAM,OAAO,KAAK,SAAS;AAC3B,UAAM,QAAQ,SAAS,QAAQ,OAAO,IAAI,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI;AAChF,UAAM,QAAQ,CAAC,GAAG,KAAK,YAAY,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC,IAAI;AACjE,QAAI,QAAQ,KAAK,OAAO,SAAS,KAAK,EAAG,OAAM,CAAC,KAAK,IAAI,KAAK;AAC9D,UAAM,OAAO,SAAS,YAAY,EAAE,MAAM,EAAE,IAAI;AAChD,UAAM,OAAO,KAAK,IAAI,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,CAAC;AACrD,UAAME,SAAkB,CAAC;AACzB,QAAI,SAAS,KAAM,CAAAA,OAAM,KAAK,GAAG,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,OAAO;AAClE,QAAI,OAAO,SAAS,IAAI,KAAK,OAAO,EAAG,CAAAA,OAAM,KAAKD,UAAS,IAAI,CAAC;AAChE,UAAM,QAAQC,OAAM,SAAS,CAAC,MAAM,CAAC,GAAGA,OAAM,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAErE,QAAI,OAAO,OAAO,KAAK,MAAM,QAAQ;AACrC,QAAI,YAAY;AAChB,QAAI,eAAe;AACnB,UAAM,QAAQ,KAAK,MAAM,KAAK,MAAM,WAAW,IAAI;AACnD,UAAM,QAAQ,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,IAAI,YAAY,CAAC,EAAE,KAAK,CAAC;AACpE,UAAM,QAAQ,QAAQ;AACtB,UAAM,QAAQ,MAAM,SAAS,QAAQ;AACrC,UAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,QAAQ,GAAG,SAAS,QAAQ,QAAQ,CAAC,CAAC;AAC9E,UAAM,QAAQ,KAAK,KAAK,IAAI,GAAG,EAAE,IAAI,QAAQ,EAAE,IAAI,KAAK,IAAI,SAAS,SAAS,QAAQ,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE;AAC5G,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,UAAU,OAAO,OAAO,OAAO,OAAO,CAAC;AAC3C,QAAI,KAAK;AACT,QAAI,YAAY;AAChB,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAI,SAAS,MAAM,CAAC,GAAG,QAAQ,QAAQ,GAAG,QAAQ,IAAI,QAAQ,IAAI,QAAQ,CAAC;AAAA,IAC7E;AACA,QAAI,QAAQ;AAAA,EACd;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,WAAOF,OAAM,OAAO,IAAI,IAAI,EAAE,CAAC;AAAA,EACjC;AACF;AAGA,SAASC,UAAS,SAAyB;AACzC,QAAM,IAAI,KAAK,MAAM,UAAU,KAAK;AACpC,QAAM,IAAI,KAAK,MAAO,UAAU,QAAS,IAAI;AAC7C,QAAM,IAAI,KAAK,MAAO,UAAU,OAAQ,EAAE;AAC1C,QAAM,IAAI,KAAK,MAAM,UAAU,EAAE;AACjC,MAAI,IAAI,EAAG,QAAO,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;AAC9C,MAAI,IAAI,EAAG,QAAO,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;AAC9C,MAAI,IAAI,EAAG,QAAO,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;AAC9C,SAAO,GAAG,CAAC;AACb;;;ACpZA,IAAM,gBAA6C;AAAA,EACjD,CAAC,GAAG,SAAS;AAAA,EACb,CAAC,MAAM,SAAS;AAAA,EAChB,CAAC,OAAO,SAAS;AAAA,EACjB,CAAC,KAAK,SAAS;AAAA,EACf,CAAC,OAAO,SAAS;AAAA,EACjB,CAAC,MAAM,SAAS;AAAA,EAChB,CAAC,GAAG,SAAS;AACf;AAGO,IAAM,eAAe,MAAkB,cAAc,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,EAAE,OAAO,SAAS,MAAM,MAAM,EAAE;AAM9G,SAAS,SAAS,GAAU,GAAU,SAA4B;AACvE,QAAM,CAAC,QAAQ,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AAC9C,SAAO,EAAE,QAAQ,KAAK,MAAM,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,QAAQ,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE;AACjI;AAGO,IAAM,SAAS,CAACE,MAAe,UAA0BA,KAAI,IAAI,KAAKA,KAAI,OAAO,IAAIA,KAAI,IAAI,KAAK;AAClG,IAAM,QAAQ,CAACA,MAAe,UAA0BA,KAAI,IAAI,KAAKA,KAAI,OAAO,IAAIA,KAAI,IAAI,KAAK;AAKjG,SAAS,eAAe,KAA+B,OAA+B,OAAiCA,MAAe,OAAyD;AACpM,QAAM,YAAY,QAAQ,CAAC,OAAO,MAAM;AACtC,QAAI,CAAC,MAAM,QAAS;AACpB,UAAM,IAAI,OAAOA,MAAK,MAAM,KAAK;AACjC,UAAM,MAAM,EAAE,GAAG,OAAO,WAAW,MAAM,OAAO,CAAC,EAAE;AACnD,QAAI,MAAM,eAAgB,YAAW,KAAK,OAAO,MAAM,KAAK,GAAG,EAAE,GAAGA,KAAI,OAAO,GAAG,EAAE,GAAG,KAAK,EAAE,OAAO,QAAQ,CAAC;AAC9G,QAAI,MAAM,gBAAiB,YAAW,KAAK,OAAO,MAAM,KAAK,GAAG,EAAE,GAAGA,KAAI,QAAQ,GAAG,EAAE,GAAG,KAAK,EAAE,OAAO,OAAO,CAAC;AAAA,EACjH,CAAC;AACD,QAAM,WAAW,QAAQ,CAAC,OAAO,MAAM;AACrC,QAAI,CAAC,MAAM,QAAS;AACpB,UAAM,IAAI,MAAMA,MAAK,MAAM,KAAK;AAChC,UAAM,MAAM,EAAE,GAAG,OAAO,WAAW,MAAM,OAAO,CAAC,EAAE;AACnD,QAAI,MAAM,cAAe,YAAW,KAAK,OAAO,MAAM,KAAK,GAAG,EAAE,GAAG,GAAGA,KAAI,MAAM,EAAE,GAAG,KAAK,EAAE,OAAO,UAAU,UAAU,SAAS,CAAC;AACjI,QAAI,MAAM,iBAAkB,YAAW,KAAK,OAAO,MAAM,KAAK,GAAG,EAAE,GAAG,GAAGA,KAAI,SAAS,EAAE,GAAG,KAAK,EAAE,OAAO,UAAU,UAAU,MAAM,CAAC;AAAA,EACtI,CAAC;AACH;AAGO,SAAS,iBAA2C,OAA+B;AACxF,QAAM,QAAQ;AACd,MAAI,CAAC,MAAM,QAAQ,MAAM,MAAM,KAAK,iBAAiB,MAAO,QAAO;AACnE,QAAM,EAAE,QAAQ,GAAG,KAAK,IAAI;AAC5B,SAAO,EAAE,GAAG,MAAM,aAAa,OAAO;AACxC;;;ACjDA,IAAM,eAAuC;AAAA,EAC3C,KAAK;AAAA,EACL,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,KAAK;AAAA,EACL,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACX;AAEA,IAAM,kBAAkB,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAExG,SAAS,cAAc,OAAiB,OAAuB;AACpE,SAAO,MAAM,SAAS,aAAa,OAAO,MAAM,KAAK,CAAC,KAAK,gBAAgB,QAAQ,gBAAgB,MAAM;AAC3G;AAIO,IAAM,qBAA+D,CAAC,WAAW,SAAS;AAG1F,SAAS,iBAAiB,QAA4C;AAC3E,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,QAAM,SAAS,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,MAAM,cAAc,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC;AACtF,SAAO,OAAO,SAAS,IAAI,cAAc,OAAO,CAAC,GAAI,CAAC,IAAI;AAC5D;AAIA,IAAM,aAAkC;AAAA,EACtC,EAAE,OAAO,GAAG,SAAS,MAAM,OAAO,UAAU;AAAA,EAC5C,EAAE,OAAO,OAAO,SAAS,MAAM,OAAO,UAAU;AAAA,EAChD,EAAE,OAAO,OAAO,SAAS,MAAM,OAAO,UAAU;AAAA,EAChD,EAAE,OAAO,KAAK,SAAS,MAAM,OAAO,UAAU;AAAA,EAC9C,EAAE,OAAO,OAAO,SAAS,MAAM,OAAO,UAAU;AAAA,EAChD,EAAE,OAAO,OAAO,SAAS,MAAM,OAAO,UAAU;AAAA,EAChD,EAAE,OAAO,GAAG,SAAS,MAAM,OAAO,UAAU;AAAA,EAC5C,EAAE,OAAO,OAAO,SAAS,MAAM,OAAO,UAAU;AAAA,EAChD,EAAE,OAAO,OAAO,SAAS,MAAM,OAAO,UAAU;AAAA,EAChD,EAAE,OAAO,OAAO,SAAS,MAAM,OAAO,UAAU;AAAA,EAChD,EAAE,OAAO,OAAO,SAAS,MAAM,OAAO,UAAU;AAAA,EAChD,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,UAAU;AAAA,EACjD,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,UAAU;AAAA,EACjD,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,UAAU;AAAA,EACjD,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,UAAU;AAAA,EACjD,EAAE,OAAO,GAAG,SAAS,OAAO,OAAO,UAAU;AAAA,EAC7C,EAAE,OAAO,GAAG,SAAS,OAAO,OAAO,UAAU;AAAA,EAC7C,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,UAAU;AAAA,EACjD,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,UAAU;AAAA,EACjD,EAAE,OAAO,GAAG,SAAS,OAAO,OAAO,UAAU;AAAA,EAC7C,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,UAAU;AAAA,EACjD,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,UAAU;AAAA,EACjD,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,UAAU;AAAA,EACjD,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,UAAU;AACnD;AAEA,IAAM,eAAe;AAErB,SAASC,cAAa,WAA2B;AAC/C,SAAO,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACtC;AA0CA,IAAM,gBAAiD;AAAA,EACrD,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,aAAa;AAAA,EACb,eAAe;AAAA,EACf,eAAe;AACjB;AAEA,IAAM,oBAAyD;AAAA,EAC7D,GAAG;AAAA,EACH,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,kBAAkB;AACpB;AAGA,SAAS,kBAAyD,OAA+B;AAC/F,QAAM,QAAQ;AACd,MAAI,EAAE,gBAAgB,OAAQ,QAAO;AACrC,QAAM,EAAE,YAAY,GAAG,KAAK,IAAI;AAChC,SAAQ,oBAAoB,OAAO,OAAO,EAAE,GAAG,MAAM,gBAAgB,eAAe,MAAM;AAC5F;AAGA,SAAS,eAAe,OAAe,WAA4B;AACjE,SAAO,YAAY,GAAG,QAAQ,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,OAAO,KAAK;AAC1E;AAGA,IAAM,eAAiF;AAAA,EACrF,KAAK,EAAE,IAAI,IAAI,UAAU,SAAS;AAAA,EAClC,QAAQ,EAAE,IAAI,GAAG,UAAU,SAAS;AAAA,EACpC,QAAQ,EAAE,IAAI,GAAG,UAAU,MAAM;AACnC;AAMA,SAAS,WAAW,GAAe,GAAe,GAAU,GAAqB;AAC/E,QAAM,SAAS,aAAa,CAAC;AAC7B,QAAM,CAAC,OAAO,GAAG,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AAChD,MAAI,MAAM,OAAQ,QAAO,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,GAAG,GAAG,MAAM,IAAI,OAAO,GAAG,GAAG,OAAO,SAAS,UAAU,OAAO,SAAS;AACrH,MAAI,MAAM,QAAS,QAAO,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,GAAG,GAAG,OAAO,QAAQ,UAAU,OAAO,SAAS;AACjH,QAAM,MAAM,SAAS,OAAO,GAAG;AAC/B,SAAO,EAAE,IAAI,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,GAAG,GAAG,OAAO,UAAU,UAAU,OAAO,SAAS;AAC9F;AAIA,SAAS,UAAU,GAAe,GAAe,GAAU,GAAqB;AAC9E,QAAM,SAAS,aAAa,CAAC;AAC7B,QAAM,CAAC,OAAO,GAAG,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AAChD,MAAI,MAAM,OAAQ,QAAO,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,GAAG,GAAG,MAAM,IAAI,OAAO,GAAG,GAAG,OAAO,QAAQ,UAAU,OAAO,SAAS;AACpH,MAAI,MAAM,QAAS,QAAO,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,GAAG,GAAG,OAAO,SAAS,UAAU,OAAO,SAAS;AAClH,QAAM,MAAM,SAAS,OAAO,GAAG;AAC/B,SAAO,EAAE,IAAI,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,GAAG,GAAG,OAAO,UAAU,UAAU,OAAO,SAAS;AAC9F;AAIA,SAAS,aAAa,MAAc,IAAY,UAAkB,KAAsB;AACtF,MAAI,OAAO,OAAO,KAAK,KAAK,EAAG,QAAO,KAAK,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,IAAI,KAAK,QAAQ;AAC1G,SAAO,QAAQ,KAAK,QAAQ;AAC9B;AAcA,SAAS,gBAAgB,KAA+BC,UAA2B,OAAmC;AACpH,QAAM,EAAE,OAAO,MAAM,IAAIA;AACzB,MAAI,MAAM,kBAAkB,MAAM,oBAAoB,GAAG;AACvD,UAAM,UAAU,MAAM,cAAc,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,QAAQ,EAAE,MAAM,KAAK;AACtI,aAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,GAAG,KAAK;AAC3C,YAAM,OAAO,QAAQ,CAAC;AACtB,YAAM,KAAK,QAAQ,IAAI,CAAC;AACxB,UAAI,YAAY,UAAU,GAAG,OAAO,MAAM,iBAAiB;AAC3D,UAAI,UAAU;AACd,UAAI,OAAO,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC;AAC7B,UAAI,OAAO,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC;AAC7B,UAAI,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;AACzB,UAAI,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;AACzB,UAAI,UAAU;AACd,UAAI,KAAK;AAAA,IACX;AAAA,EACF;AACA,aAAWC,SAAQ,OAAO;AACxB,QAAI,KAAK;AACT,gBAAY,KAAK,EAAE,GAAG,OAAO,WAAWA,MAAK,MAAM,CAAC;AACpD,kBAAc,KAAKA,MAAK,GAAGA,MAAK,CAAC;AACjC,QAAI,QAAQ;AAAA,EACd;AACA,QAAM,MAAM,CAAC,WAAiC,EAAE,GAAG,OAAO,WAAW,MAAM;AAC3E,aAAWA,SAAQ,OAAO;AACxB,UAAM,QAAkB,CAAC;AACzB,QAAI,MAAM,iBAAiBA,MAAK,MAAM,KAAM,OAAM,KAAKA,MAAK,MAAM,IAAI;AACtE,QAAI,MAAM,WAAY,OAAM,KAAK,eAAeA,MAAK,MAAM,OAAO,MAAM,gBAAgB,CAAC;AACzF,QAAI,MAAM,cAAc,OAAO,SAASA,MAAK,KAAK,EAAG,OAAM,KAAK,IAAID,SAAQ,OAAOC,MAAK,KAAK,CAAC,GAAG;AACjG,QAAI,MAAM,QAAQ;AAChB,YAAM,QAAmB,MAAM,gBAAgB,EAAE,IAAI,EAAE,GAAGA,MAAK,EAAE,IAAI,GAAG,GAAGA,MAAK,EAAE,EAAE,GAAG,OAAO,SAAS,UAAU,SAAS,IAAI,WAAW,MAAM,cAAc,MAAM,cAAcA,MAAK,GAAGA,MAAK,CAAC;AAC/L,iBAAW,KAAK,MAAM,KAAK,GAAG,GAAG,MAAM,IAAI,IAAIA,MAAK,KAAK,GAAG,EAAE,OAAO,MAAM,OAAO,UAAU,MAAM,SAAS,CAAC;AAAA,IAC9G;AACA,QAAI,CAAC,MAAM,iBAAiB,MAAM,YAAYA,MAAK,MAAM,QAAQ,MAAM,cAAc,MAAM,YAAY;AACrG,YAAM,QAAQ,UAAU,MAAM,YAAY,MAAM,YAAYA,MAAK,GAAGA,MAAK,CAAC;AAC1E,iBAAW,KAAKA,MAAK,MAAM,MAAM,MAAM,IAAI,IAAIA,MAAK,KAAK,GAAG,EAAE,OAAO,MAAM,OAAO,UAAU,MAAM,SAAS,CAAC;AAAA,IAC9G;AAAA,EACF;AACF;AAGO,IAAM,iBAAN,cAA6B,QAA6B;AAAA,EACtD,OAAe;AAAA,EAEL,eAAoC;AACrD,WAAO,EAAE,QAAQ,WAAW,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,GAAG,GAAG,kBAAkB;AAAA,EAC3E;AAAA,EAEmB,aAAa,OAAmE;AACjG,WAAO,kBAAkB,KAAK;AAAA,EAChC;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,OAAO,mBAAmB,MAAM,aAAa,MAAM,eAAe,MAAM,eAAe,KAAK;AAAA,EACzI;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,UAAU,UAA6B;AAC/C,WAAO,KAAK,MAAM,oBAAoB,SAAS,aAAa;AAAA,EAC9D;AAAA;AAAA,EAGU,QAAQ,OAAe,UAA4B;AAC3D,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,UAAM,CAAC,MAAM,EAAE,IAAI,KAAK,MAAM,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AACtD,WAAO,aAAa,KAAK,OAAO,GAAG,OAAO,OAAO,KAAK,UAAU,QAAQ,CAAC;AAAA,EAC3E;AAAA,EAEU,KAAK,UAA2D;AACxE,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,WAAO;AAAA,MACL,MAAM,KAAK,MAAM,aAAa,IAAI,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC;AAAA,MACrD,MAAM,KAAK,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC;AAAA,IACrE;AAAA,EACF;AAAA;AAAA,EAGU,WAAW,UAAiC;AACpD,UAAM,OAAO,KAAK,KAAK,QAAQ;AAC/B,QAAI,CAAC,KAAM,QAAO,CAAC;AACnB,UAAM,MAAmB,CAAC;AAC1B,SAAK,MAAM,OAAO,QAAQ,CAAC,OAAO,MAAM;AACtC,UAAI,CAAC,MAAM,QAAS;AACpB,YAAM,QAAQ,KAAK,QAAQ,MAAM,OAAO,QAAQ;AAChD,YAAM,IAAI,SAAS,IAAI,KAAK;AAC5B,UAAI,MAAM,KAAM;AAChB,UAAI,KAAK,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,KAAK,MAAM,EAAE,GAAG,GAAG,EAAE,GAAG,KAAK,MAAM,EAAE,GAAG,MAAM,CAAC;AAAA,IAC3G,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,YAAY,UAA6B;AACjD,WAAO,KAAK,aAAa,QAAQ,EAAE,OAAO,CAAC,MAAkB,MAAM,IAAI;AAAA,EACzE;AAAA,EAEU,UAA4B;AACpC,WAAO,EAAE,OAAO,KAAK,OAAO,OAAO,KAAK,OAAO,QAAQ,CAAC,UAAU,KAAK,YAAY,KAAK,EAAE;AAAA,EAC5F;AAAA;AAAA,EAGU,aAA2B;AACnC,WAAO,EAAE,GAAG,KAAK,OAAO,WAAW,KAAK,MAAM,gBAAgB,WAAW,KAAK,MAAM,gBAAgB,WAAW,KAAK,MAAM,eAAe;AAAA,EAC3I;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,QAAQ,SAAS,KAAK,gBAAgB,EAAG;AAClD,oBAAgB,KAAK,KAAK,QAAQ,GAAG,KAAK,WAAW,QAAQ,CAAC;AAC9D,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,SAAS,KAAK,YAAY,QAAQ;AACxC,UAAI,KAAK;AACT,kBAAY,KAAK,KAAK,WAAW,CAAC;AAClC,eAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,IAAK,eAAc,KAAK,OAAO,CAAC,GAAI,OAAO,IAAI,CAAC,CAAE;AACzF,UAAI,QAAQ;AAAA,IACd;AAAA,EACF;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,QAAI,KAAK,QAAQ,SAAS,KAAK,gBAAgB,EAAG,QAAO;AACzD,UAAM,YAAYF,cAAa,KAAK,MAAM,SAAS;AACnD,QAAI,KAAK,WAAW,QAAQ,EAAE,KAAK,CAACE,UAAS,kBAAkB,OAAOA,MAAK,GAAGA,MAAK,CAAC,KAAK,SAAS,EAAG,QAAO;AAC5G,QAAI,CAAC,KAAK,MAAM,UAAW,QAAO;AAClC,UAAM,SAAS,KAAK,YAAY,QAAQ;AACxC,UAAM,iBAAiBF,cAAa,KAAK,MAAM,cAAc;AAC7D,aAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,IAAK,KAAI,kBAAkB,OAAO,OAAO,CAAC,GAAI,OAAO,IAAI,CAAC,CAAE,KAAK,eAAgB,QAAO;AAC/H,WAAO;AAAA,EACT;AACF;AAGO,IAAM,eAAN,cAA2B,eAAe;AAAA,EAC7B,OAAO;AAAA;AAAA,EAGN,cAAc,OAAgD;AAC/E,UAAM,cAAc,KAAK;AACzB,UAAM,EAAE,WAAW,UAAU,IAAI,KAAK;AACtC,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,MAAM,gBAAgB,UAAU,WAAW,QAAQ,SAAS,IAAI,GAAG,GAAG,gBAAgB,WAAW,gBAAgB,SAAS;AAAA,EACvK;AAAA,EAES,kBAA0B;AACjC,WAAO;AAAA,EACT;AAAA,EAEmB,QAAQ,OAAe,UAA4B;AACpE,UAAM,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK;AACvB,UAAM,OAAO,KAAK,MAAM,UAAU,KAAK;AACvC,QAAI,KAAK,UAAU,QAAQ,KAAK,EAAE,QAAQ,KAAK,EAAE,QAAQ,KAAK,EAAE,QAAQ,EAAG,QAAO,KAAK,IAAI,KAAK,IAAI,EAAE,KAAK,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,KAAK,IAAI,EAAE,KAAK,KAAK,QAAQ,IAAI;AACrK,WAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,OAAO;AAAA,EAChD;AAAA,EAEmB,KAAK,UAA2D;AACjF,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC/C,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAI,QAAO;AAC9B,WAAO;AAAA,MACL,MAAM,KAAK,MAAM,aAAa,IAAI,GAAG;AAAA,MACrC,MAAM,KAAK,MAAM,cAAc,SAAS,QAAQ,GAAG,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;AAAA,IAC3F;AAAA,EACF;AACF;AAGO,IAAM,aAAN,cAAyB,QAAyB;AAAA,EAC9C,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,EAAE,QAAQ,WAAW,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,GAAG,GAAG,cAAc;AAAA,EACvE;AAAA,EAEmB,aAAa,OAA2D;AACzF,WAAO,kBAAkB,KAAK;AAAA,EAChC;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,mBAAmB,MAAM,eAAe,MAAM,eAAe,KAAK;AAAA,EACpG;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,MAAM,UAAiC;AAC/C,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC/C,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAI,QAAO,CAAC;AAC/B,UAAM,UAAU,GAAG,IAAI,GAAG,MAAO,GAAG,IAAI,GAAG,KAAM;AACjD,UAAM,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK;AAC1C,UAAM,EAAE,YAAY,YAAY,IAAI,KAAK;AACzC,UAAM,MAAmB,CAAC;AAC1B,SAAK,MAAM,OAAO,QAAQ,CAAC,OAAO,MAAM;AACtC,UAAI,CAAC,MAAM,QAAS;AACpB,YAAM,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,KAAK,MAAM,MAAM;AAChD,YAAM,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,KAAK,MAAM,MAAM;AAChD,YAAM,MAAM,cAAc,cAAc,cAAc,GAAG,GAAG,SAAS,OAAO,SAAS,QAAQ,YAAY,WAAW,IAAI,EAAE,GAAG,EAAE;AAG/H,YAAM,SAAS,KAAK,MAAM,gBAAgB,IAAI,IAAI;AAClD,UAAI,KAAK,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,OAAO,SAAS,QAAQ,OAAO,CAAC,KAAK,OAAO,IAAI,CAAC;AAAA,IACzH,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,oBAAgB,KAAK,EAAE,OAAO,KAAK,OAAO,OAAO,KAAK,OAAO,QAAQ,CAAC,UAAU,KAAK,YAAY,KAAK,EAAE,GAAG,KAAK,MAAM,QAAQ,CAAC;AAAA,EACjI;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,YAAYA,cAAa,KAAK,MAAM,SAAS;AACnD,WAAO,KAAK,MAAM,QAAQ,EAAE,KAAK,CAACE,UAAS,kBAAkB,OAAOA,MAAK,GAAGA,MAAK,CAAC,KAAK,SAAS;AAAA,EAClG;AACF;AAGA,SAAS,YAAY,OAA+B,OAAiB,OAA6B;AAChG,SAAO,EAAE,GAAG,OAAO,WAAW,OAAO,WAAW,MAAM,SAAS,MAAM,WAAW,WAAW,MAAM,SAAS,MAAM,UAAU;AAC5H;AAIA,SAAS,WAA8C,OAAmB,UAAyB;AACjG,QAAM,WAAW,kBAAkB,KAAiD;AACpF,QAAM,MAA+B,CAAC;AACtC,aAAW,OAAO,OAAO,KAAK,QAAQ,EAAG,KAAI,OAAO,SAAU,KAAI,GAAG,IAAI,SAAS,GAAG;AACrF,SAAO;AACT;AAGA,IAAM,gBAAgB,CAAC,QAAqE,UAC1F,OAAO,IAAI,CAAC,CAAC,OAAO,OAAO,OAAO,OAAO,EAAE,OAAO,SAAS,OAAO,OAAO,OAAO,QAAQ,EAAE;AAI5F,SAAS,mBAAmB,GAAe,GAAe,GAAW,QAA2B;AAC9F,QAAM,KAAK,EAAE,GAAG,MAAM,SAAS,IAAI,IAAI,MAAM,UAAU,IAAI,IAAI,GAAG,GAAG,MAAM,QAAQ,IAAI,MAAM,WAAW,SAAS,IAAI,SAAS,EAAE;AAChI,SAAO,EAAE,IAAI,OAAO,MAAM,SAAS,UAAU,MAAM,UAAU,SAAS,UAAU,UAAU,MAAM,QAAQ,QAAQ,MAAM,WAAW,WAAW,SAAS;AACvJ;AAOA,SAAS,oBACP,KACAD,UACA,QACA,UACM;AACN,QAAM,EAAE,OAAO,MAAM,IAAIA;AACzB,MAAI,MAAM,kBAAkB,MAAM,oBAAoB,GAAG;AACvD,UAAM,UAAU,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AACpD,aAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,GAAG,KAAK;AAC3C,UAAI,YAAY,UAAU,QAAQ,IAAI,CAAC,EAAG,OAAO,MAAM,iBAAiB;AACxE,UAAI,SAAS,QAAQ,CAAC,EAAG,GAAG,GAAG,QAAQ,IAAI,CAAC,EAAG,IAAI,QAAQ,CAAC,EAAG,GAAG,SAAS,MAAM;AAAA,IACnF;AAAA,EACF;AACA,aAAW,SAAS,QAAQ;AAC1B,QAAI,KAAK;AACT,gBAAY,KAAK,YAAY,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC;AAC7D,kBAAc,KAAK,EAAE,GAAG,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,GAAG,GAAG,SAAS,OAAO,CAAC;AAC3E,QAAI,QAAQ;AACZ,QAAI,MAAM,YAAY;AACpB,YAAM,QAAQ,mBAAmB,MAAM,cAAc,MAAM,cAAc,MAAM,GAAG,SAAS,MAAM;AACjG,iBAAW,KAAK,OAAO,MAAM,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,GAAG,OAAO,WAAW,MAAM,MAAM,GAAG,EAAE,OAAO,MAAM,OAAO,UAAU,MAAM,SAAS,CAAC;AAAA,IAC7I;AAAA,EACF;AACF;AAcA,IAAM,mBAAmB;AAAA,EACvB;AAAA,IACE,CAAC,GAAG,WAAW,IAAI;AAAA,IACnB,CAAC,GAAG,WAAW,IAAI;AAAA,IACnB,CAAC,GAAG,WAAW,IAAI;AAAA,IACnB,CAAC,GAAG,WAAW,IAAI;AAAA,IACnB,CAAC,GAAG,WAAW,IAAI;AAAA,IACnB,CAAC,GAAG,WAAW,IAAI;AAAA,IACnB,CAAC,IAAI,WAAW,IAAI;AAAA,IACpB,CAAC,IAAI,WAAW,IAAI;AAAA,IACpB,CAAC,IAAI,WAAW,IAAI;AAAA,IACpB,CAAC,IAAI,WAAW,IAAI;AAAA,IACpB,CAAC,IAAI,WAAW,IAAI;AAAA,EACtB;AAAA,EACA;AACF;AAGO,IAAM,cAAN,cAA0B,QAA0B;AAAA,EAChD,OAAO;AAAA,EAEG,eAAiC;AAClD,WAAO,EAAE,QAAQ,iBAAiB,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,GAAG,YAAY,MAAM,cAAc,SAAS,cAAc,UAAU,gBAAgB,OAAO,mBAAmB,IAAI;AAAA,EAC3K;AAAA,EAEmB,aAAa,OAA6D;AAC3F,WAAO,WAAW,OAAO,KAAK,aAAa,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,gBAAgB,OAAO,cAAc,SAAS,cAAc,SAAS;AAAA,EACvG;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,GAAG,UAAqC;AAChD,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO,CAAC;AACxB,UAAM,OAAO,GAAG,IAAI,GAAG;AACvB,QAAI,SAAS,EAAG,QAAO,CAAC;AACxB,WAAO,KAAK,MAAM,OACf,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,GAAG,GAAG,GAAG,IAAI,OAAO,MAAM,MAAM,EAAE,EAC3F,OAAO,CAAC,MAAM,EAAE,MAAM,WAAW,EAAE,KAAK,CAAC,SAAS,SAAS,EAAE,KAAK,SAAS,QAAQ,CAAC;AAAA,EACzF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,wBAAoB,KAAK,MAAM,KAAK,GAAG,QAAQ,GAAG,QAAQ;AAAA,EAC5D;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,WAAO,KAAK,GAAG,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,KAAKD,cAAa,EAAE,MAAM,SAAS,KAAK,MAAM,SAAS,CAAC;AAAA,EACrH;AACF;AAWA,IAAM,cAAc,CAAC,OAA+B,WAAkD;AAAA,EACpG,GAAG;AAAA,EACH,WAAW,MAAM;AAAA,EACjB,WAAW,MAAM;AAAA,EACjB,WAAW,MAAM;AACnB;AAGA,SAAS,WAAW,KAA+B,OAA+B,OAAgC,QAAgC;AAChJ,MAAI,CAAC,MAAM,aAAa,OAAO,SAAS,EAAG;AAC3C,MAAI,KAAK;AACT,cAAY,KAAK,YAAY,OAAO,KAAK,CAAC;AAC1C,WAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,IAAK,eAAc,KAAK,OAAO,CAAC,GAAI,OAAO,IAAI,CAAC,CAAE;AACzF,MAAI,QAAQ;AACd;AAGA,SAAS,UAAU,OAAc,OAAgC,QAAmC;AAClG,MAAI,CAAC,MAAM,UAAW,QAAO;AAC7B,QAAM,YAAYA,cAAa,MAAM,cAAc;AACnD,WAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,IAAK,KAAI,kBAAkB,OAAO,OAAO,CAAC,GAAI,OAAO,IAAI,CAAC,CAAE,KAAK,UAAW,QAAO;AAC1H,SAAO;AACT;AAMA,IAAM,oBAAoB;AAAA,EACxB;AAAA,IACE,CAAC,GAAG,WAAW,IAAI;AAAA,IACnB,CAAC,OAAO,WAAW,IAAI;AAAA,IACvB,CAAC,KAAK,WAAW,KAAK;AAAA,IACtB,CAAC,OAAO,WAAW,IAAI;AAAA,IACvB,CAAC,GAAG,WAAW,IAAI;AAAA,IACnB,CAAC,OAAO,WAAW,IAAI;AAAA,IACvB,CAAC,OAAO,WAAW,IAAI;AAAA,IACvB,CAAC,GAAG,WAAW,IAAI;AAAA,IACnB,CAAC,OAAO,WAAW,IAAI;AAAA,IACvB,CAAC,OAAO,WAAW,IAAI;AAAA,IACvB,CAAC,GAAG,WAAW,IAAI;AAAA,EACrB;AAAA,EACA;AACF;AAEA,IAAM,eAA8B,EAAE,WAAW,MAAM,gBAAgB,WAAW,gBAAgB,GAAG,gBAAgB,SAAS;AAGvH,IAAM,mBAAN,cAA+B,QAA+B;AAAA,EAC1D,OAAO;AAAA,EAEG,eAAsC;AACvD,WAAO,EAAE,QAAQ,kBAAkB,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,GAAG,GAAG,cAAc,YAAY,MAAM,cAAc,SAAS,cAAc,UAAU,gBAAgB,MAAM,mBAAmB,IAAI;AAAA,EAC5L;AAAA,EAEmB,aAAa,OAAuE;AACrG,WAAO,WAAW,OAAO,KAAK,aAAa,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,OAAO,gBAAgB,OAAO,cAAc,SAAS,cAAc,SAAS;AAAA,EACzH;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,GAAG,UAAqC;AAChD,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC/C,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAI,QAAO,CAAC;AAC/B,UAAM,OAAO,GAAG,IAAI,GAAG;AACvB,QAAI,SAAS,EAAG,QAAO,CAAC;AACxB,WAAO,KAAK,MAAM,OAAO,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,GAAG,GAAG,GAAG,IAAI,OAAO,MAAM,MAAM,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,OAAO;AAAA,EACrJ;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,wBAAoB,KAAK,MAAM,KAAK,GAAG,QAAQ,GAAG,QAAQ;AAC1D,eAAW,KAAK,KAAK,OAAO,KAAK,OAAO,KAAK,aAAa,QAAQ,EAAE,OAAO,CAAC,MAAkB,MAAM,IAAI,CAAC;AAAA,EAC3G;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,QAAI,KAAK,GAAG,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,KAAKA,cAAa,EAAE,MAAM,SAAS,KAAK,MAAM,SAAS,CAAC,EAAG,QAAO;AAC1H,WAAO,UAAU,OAAO,KAAK,OAAO,KAAK,aAAa,QAAQ,EAAE,OAAO,CAAC,MAAkB,MAAM,IAAI,CAAC;AAAA,EACvG;AACF;AAkBA,IAAM,cAAoD;AAAA,EACxD,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,KAAK,WAAW,IAAI;AAAA,EACrB,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,GAAG,WAAW,IAAI;AAAA,EACnB,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,OAAO,WAAW,IAAI;AACzB;AAGA,SAAS,SAAS,KAA+B,QAAe,OAAe,OAAe,OAAe,SAAiB,OAAO,GAAG,KAAK,KAAK,KAAK,GAAS;AAC9J,MAAI,KAAK;AACT,MAAI,YAAY,UAAU,OAAO,OAAO;AACxC,MAAI,UAAU;AACd,MAAI,IAAI,OAAO,GAAG,OAAO,GAAG,OAAO,MAAM,EAAE;AAC3C,MAAI,IAAI,OAAO,GAAG,OAAO,GAAG,OAAO,IAAI,MAAM,IAAI;AACjD,MAAI,UAAU;AACd,MAAI,KAAK;AACT,MAAI,QAAQ;AACd;AAGO,IAAM,aAAN,cAAyB,QAAyB;AAAA,EAC9C,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,EAAE,QAAQ,cAAc,aAAa,CAAC,GAAG,GAAG,cAAc,YAAY,MAAM,kBAAkB,OAAO,eAAe,OAAO,gBAAgB,MAAM,mBAAmB,IAAI;AAAA,EACjL;AAAA,EAEmB,aAAa,OAA2D;AACzF,WAAO,WAAW,OAAO,KAAK,aAAa,CAAC;AAAA,EAC9C;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,OAAO,gBAAgB,OAAO,eAAe,KAAK;AAAA,EAC/F;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,UAAM,OAAO,KAAK,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC;AAChD,QAAI,SAAS,EAAG;AAChB,UAAM,QAAQ,KAAK,MAAM,OAAO,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,GAAG,GAAG,OAAO,MAAM,MAAM,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,WAAW,EAAE,IAAI,CAAC;AAC9J,QAAI,KAAK,MAAM,kBAAkB,KAAK,MAAM,oBAAoB,GAAG;AACjE,YAAM,UAAU,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AACnD,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,UAAS,KAAK,IAAI,MAAM,IAAI,IAAI,QAAQ,IAAI,CAAC,EAAG,GAAG,QAAQ,CAAC,EAAG,GAAG,QAAQ,CAAC,EAAG,OAAO,KAAK,MAAM,iBAAiB;AAAA,IAC5J;AACA,eAAW,SAAS,OAAO;AACzB,UAAI,KAAK;AACT,kBAAY,KAAK,YAAY,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC;AAClE,UAAI,UAAU;AACd,UAAI,IAAI,GAAG,GAAG,GAAG,GAAG,MAAM,GAAG,GAAG,KAAK,KAAK,CAAC;AAC3C,UAAI,OAAO;AACX,UAAI,QAAQ;AACZ,UAAI,KAAK,MAAM,YAAY;AACzB,cAAM,QAAQ,KAAK,MAAM,oBAAoB,KAAK,MAAM,gBAAgB,GAAG,KAAK,MAAM,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,eAAe,MAAM,MAAM,OAAO,KAAK,MAAM,gBAAgB;AACjL,mBAAW,KAAK,OAAO,EAAE,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,MAAM,MAAM,CAAC;AAAA,MACtG;AAAA,IACF;AACA,eAAW,KAAK,KAAK,OAAO,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;AAAA,EAClD;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,UAAM,OAAO,KAAK,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC;AAChD,QAAI,SAAS,EAAG,QAAO;AACvB,UAAM,IAAI,KAAK,MAAM,MAAM,IAAI,GAAG,GAAG,MAAM,IAAI,GAAG,CAAC;AACnD,QAAI,KAAK,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,IAAI,OAAO,EAAE,KAAK,KAAKA,cAAa,EAAE,SAAS,KAAK,MAAM,SAAS,CAAC,EAAG,QAAO;AACtI,WAAO,UAAU,OAAO,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;AAAA,EAC9C;AACF;AASO,IAAM,UAAN,cAAsB,QAAsB;AAAA,EACxC,OAAO;AAAA,EAEG,eAA6B;AAC9C,WAAO,EAAE,QAAQ,cAAc,aAAa,CAAC,GAAG,GAAG,cAAc,YAAY,MAAM,aAAa,OAAO,gBAAgB,MAAM,mBAAmB,IAAI;AAAA,EACtJ;AAAA,EAEmB,aAAa,OAAqD;AACnF,WAAO,WAAW,OAAO,KAAK,aAAa,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,UAAM,EAAE,WAAW,UAAU,IAAI,KAAK;AACtC,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,MAAM,gBAAgB,UAAU,WAAW,QAAQ,SAAS,IAAI,IAAI,GAAG,gBAAgB,WAAW,gBAAgB,UAAU,gBAAgB,MAAM;AAAA,EAC/L;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,UAAM,OAAO,KAAK,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC;AAChD,QAAI,SAAS,EAAG;AAEhB,UAAM,OAAO,QAAQ,IAAI,EAAE;AAC3B,UAAM,CAAC,MAAM,EAAE,IAAI,KAAK,MAAM,cAAc,CAAC,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,GAAG,OAAO,KAAK,KAAK,CAAC;AACtG,UAAM,QAAQ,KAAK,MAAM,OAAO,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,GAAG,GAAG,OAAO,MAAM,MAAM,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,WAAW,EAAE,IAAI,CAAC;AAC9J,QAAI,KAAK,MAAM,kBAAkB,KAAK,MAAM,oBAAoB,GAAG;AACjE,YAAM,UAAU,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AACnD,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,UAAS,KAAK,IAAI,MAAM,IAAI,IAAI,QAAQ,IAAI,CAAC,EAAG,GAAG,QAAQ,CAAC,EAAG,GAAG,QAAQ,CAAC,EAAG,OAAO,KAAK,MAAM,mBAAmB,MAAM,EAAE;AAAA,IACtK;AACA,eAAW,SAAS,OAAO;AACzB,UAAI,KAAK;AACT,kBAAY,KAAK,YAAY,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC;AAClE,UAAI,UAAU;AACd,UAAI,IAAI,GAAG,GAAG,GAAG,GAAG,MAAM,GAAG,MAAM,EAAE;AACrC,UAAI,OAAO;AACX,UAAI,QAAQ;AACZ,UAAI,KAAK,MAAM,YAAY;AACzB,cAAM,KAAK,GAAG,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM;AACzC,cAAM,KAAK,GAAG,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM;AACzC,mBAAW,KAAK,OAAO,MAAM,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,GAAG,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,MAAM,MAAM,GAAG,EAAE,OAAO,SAAS,CAAC;AAAA,MACjI;AAAA,IACF;AACA,eAAW,KAAK,KAAK,OAAO,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;AAAA,EAClD;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,UAAM,OAAO,KAAK,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC;AAChD,QAAI,SAAS,EAAG,QAAO;AACvB,UAAM,IAAI,KAAK,MAAM,MAAM,IAAI,GAAG,GAAG,MAAM,IAAI,GAAG,CAAC;AACnD,QAAI,KAAK,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,IAAI,OAAO,EAAE,KAAK,KAAKA,cAAa,EAAE,SAAS,KAAK,MAAM,SAAS,CAAC,EAAG,QAAO;AACtI,WAAO,UAAU,OAAO,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;AAAA,EAC9C;AACF;AAWA,IAAM,eAAqD;AAAA,EACzD,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,KAAK,WAAW,IAAI;AAAA,EACrB,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,OAAO,WAAW,IAAI;AAAA,EACvB,CAAC,GAAG,WAAW,IAAI;AAAA,EACnB,CAAC,OAAO,WAAW,KAAK;AAAA,EACxB,CAAC,OAAO,WAAW,KAAK;AAAA,EACxB,CAAC,OAAO,WAAW,KAAK;AAAA,EACxB,CAAC,OAAO,WAAW,KAAK;AAAA,EACxB,CAAC,OAAO,WAAW,KAAK;AAC1B;AAGO,IAAM,WAAN,cAAuB,QAAuB;AAAA,EAC1C,OAAO;AAAA,EAEG,eAA8B;AAC/C,WAAO,EAAE,QAAQ,cAAc,cAAc,CAAC,GAAG,WAAW,MAAM,gBAAgB,WAAW,gBAAgB,GAAG,gBAAgB,SAAS,YAAY,MAAM,gBAAgB,MAAM,mBAAmB,IAAI;AAAA,EAC1M;AAAA,EAEmB,aAAa,OAAuD;AACrF,WAAO,WAAW,OAAO,KAAK,aAAa,CAAC;AAAA,EAC9C;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,UAAM,EAAE,WAAW,WAAW,UAAU,IAAI,KAAK;AACjD,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,MAAM,gBAAgB,WAAW,gBAAgB,WAAW,gBAAgB,WAAW,gBAAgB,MAAM;AAAA,EAC1J;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIU,SAAS,UAAkI;AACnJ,UAAM,CAAC,MAAM,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AACjD,QAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAI,QAAO;AAChC,UAAM,SAAS,KAAK,MAAM,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,CAAC;AACtD,QAAI,WAAW,EAAG,QAAO;AACzB,UAAM,KAAK,QAAQ,MAAM,EAAE;AAC3B,UAAM,KAAK,QAAQ,MAAM,EAAE;AAC3B,UAAM,CAAC,OAAO,GAAG,IAAI,KAAK,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AAC/D,UAAM,UAAW,MAAM,UAAU,KAAK,KAAK,KAAM,KAAK,KAAK,MAAM,KAAK,KAAK;AAC3E,WAAO,EAAE,MAAM,QAAQ,IAAI,IAAI,OAAO,KAAK,QAAQ,OAAO,UAAU,QAAQ,QAAQ,EAAE;AAAA,EACxF;AAAA;AAAA,EAGU,KAAK,KAAyE;AACtF,UAAM,MAAM,CAAC,OAAsB,EAAE,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,QAAQ,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,OAAO;AACxH,WAAO;AAAA,MACL,CAAC,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;AAAA,MACtB,CAAC,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,QAAI,CAAC,IAAK;AACV,UAAM,QAAQ,KAAK,MAAM,OAAO,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,GAAG,GAAG,IAAI,SAAS,MAAM,MAAM,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,WAAW,EAAE,IAAI,CAAC;AACpK,QAAI,KAAK,MAAM,kBAAkB,KAAK,MAAM,oBAAoB,GAAG;AACjE,YAAM,UAAU,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AACnD,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,UAAS,KAAK,IAAI,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI,CAAC,EAAG,GAAG,QAAQ,CAAC,EAAG,GAAG,QAAQ,CAAC,EAAG,OAAO,KAAK,MAAM,mBAAmB,IAAI,OAAO,IAAI,GAAG;AAAA,IACtL;AACA,eAAW,SAAS,OAAO;AACzB,UAAI,KAAK;AACT,kBAAY,KAAK,YAAY,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC;AAClE,UAAI,UAAU;AACd,UAAI,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,GAAG,MAAM,GAAG,IAAI,OAAO,IAAI,GAAG;AAC3D,UAAI,OAAO;AACX,UAAI,QAAQ;AACZ,UAAI,KAAK,MAAM,YAAY;AAEzB,cAAM,IAAI,MAAM,IAAI;AACpB,mBAAW,KAAK,OAAO,MAAM,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,QAAQ,IAAI,GAAG,GAAG,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,QAAQ,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,MAAM,MAAM,GAAG,EAAE,OAAO,SAAS,CAAC;AAAA,MACvM;AAAA,IACF;AACA,eAAW,OAAO,KAAK,KAAK,GAAG,EAAG,YAAW,KAAK,KAAK,OAAO,KAAK,OAAO,GAAG;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA,EAKS,iBAAiB,UAAoC;AAC5D,UAAM,SAAS,MAAM,iBAAiB,QAAQ;AAC9C,UAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,MAAM,KAAK,KAAK,GAAG,EAAE,CAAC,EAAG,CAAC;AAChC,WAAO,OAAO,IAAI,CAAC,UAAW,MAAM,UAAU,IAAI,EAAE,GAAG,OAAO,GAAG,IAAI,IAAI,KAAM;AAAA,EACjF;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,IAAI,KAAK,MAAM,MAAM,IAAI,IAAI,KAAK,GAAG,MAAM,IAAI,IAAI,KAAK,CAAC;AAC/D,UAAM,QAAQ,KAAK,MAAM,MAAM,IAAI,IAAI,KAAK,GAAG,MAAM,IAAI,IAAI,KAAK,CAAC;AACnE,UAAM,QAAS,QAAQ,IAAI,UAAU,KAAK,KAAK,KAAM,KAAK,KAAK,MAAM,KAAK,KAAK;AAC/E,QAAI,OAAO,IAAI,MAAM,IAAI,QAAQ,QAAQ,KAAK,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,IAAI,IAAI,SAAS,EAAE,KAAK,KAAKA,cAAa,EAAE,SAAS,KAAK,MAAM,SAAS,CAAC,EAAG,QAAO;AACjL,WAAO,KAAK,KAAK,GAAG,EAAE,KAAK,CAAC,QAAQ,UAAU,OAAO,KAAK,OAAO,GAAG,CAAC;AAAA,EACvE;AACF;AAiBA,IAAM,cAAoD;AAAA,EACxD,CAAC,MAAM,WAAW,KAAK;AAAA,EACvB,CAAC,OAAO,WAAW,KAAK;AAAA,EACxB,CAAC,KAAK,WAAW,IAAI;AAAA,EACrB,CAAC,OAAO,WAAW,KAAK;AAAA,EACxB,CAAC,MAAM,WAAW,KAAK;AAAA,EACvB,CAAC,GAAG,WAAW,IAAI;AAAA,EACnB,CAAC,KAAK,WAAW,KAAK;AAAA,EACtB,CAAC,MAAM,WAAW,KAAK;AAAA,EACvB,CAAC,GAAG,WAAW,KAAK;AACtB;AAGA,IAAM,wBAA6C,CAAC,GAAG,MAAM,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,SAAS,KAAK,EAAE;AAG7G,IAAM,WAAN,cAAuB,QAAuB;AAAA,EAC1C,OAAO;AAAA,EAEG,eAA8B;AAC/C,WAAO,EAAE,aAAa,WAAW,aAAa,GAAG,aAAa,SAAS,QAAQ,cAAc,aAAa,CAAC,GAAG,gBAAgB,MAAM,mBAAmB,KAAK,WAAW,KAAK;AAAA,EAC9K;AAAA,EAEmB,aAAa,OAAuD;AACrF,UAAM,QAAQ,WAAW,OAAO,KAAK,aAAa,CAAC;AAEnD,QAAI,MAAM,QAAQ,MAAM,MAAM,EAAG,OAAM,SAAS,MAAM,OAAO,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC;AACxF,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKmB,cAAc,OAAgD;AAC/E,UAAM,OAAO,EAAE,QAAQ,MAAM,QAAQ,MAAM,MAAM,IAAI,MAAM,SAAS,uBAAuB,YAAY,MAAM,eAAe,MAAM;AAClI,UAAM,SAAS,YAAY,IAAI;AAC/B,UAAM,EAAE,WAAW,WAAW,UAAU,IAAI,KAAK;AACjD,UAAM,OAAO,OAAO,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC;AAClD,SAAK,SAAS;AAAA,MACZ,GAAG,KAAK;AAAA,MACR,aAAa,QAAQ,IAAI,cAAc,OAAO,IAAI,GAAI,IAAI,IAAI;AAAA,MAC9D,aAAa;AAAA,MACb,aAAa;AAAA,MACb,QAAQ,OAAO,QAAQ,CAAC,GAAG,MAAO,EAAE,UAAU,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,SAAS,EAAE,SAAS,OAAO,cAAc,GAAG,CAAC,GAAG,OAAO,WAAW,OAAO,UAAU,CAAC,CAAE;AAAA,MAChK,gBAAgB;AAAA,MAChB,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EAES,WAAW,OAAqC;AACvD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA;AAAA;AAAA,EAIU,UAAU,MAA8B,UAA4E;AAC5H,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC/C,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAI,QAAO,CAAC;AAC/B,UAAM,MAAM,SAAS,IAAI,EAAE;AAC3B,WAAO,YAAY,IAAI,EACpB,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,EAAE,EAAE,EAC7D,OAAO,CAAC,MAAM,EAAE,MAAM,OAAO,EAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,UAAU,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,EAAE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM;AACvF,YAAM,UAAU,EAAE,GAAG,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,EAAE;AAC/E,aAAO,EAAE,OAAO,EAAE,MAAM,OAAO,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,cAAc,IAAI,SAAS,SAAS,OAAO,SAAS,QAAQ,OAAO,IAAI,EAAE,EAAE;AAAA,IACtI,CAAC,CAAC;AAAA,EACN;AAAA,EAEU,eAAe,KAA+B,MAA8B,UAA0B;AAC9G,eAAW,OAAO,KAAK,UAAU,MAAM,QAAQ,GAAG;AAChD,UAAI,KAAK;AACT,kBAAY,KAAK,KAAK,KAAK;AAC3B,UAAI,cAAc,IAAI;AACtB,oBAAc,KAAK,IAAI,GAAG,IAAI,CAAC;AAC/B,UAAI,QAAQ;AACZ,UAAI,KAAK,eAAe,OAAO;AAC7B,cAAM,IAAI;AACV,mBAAW,KAAK,OAAO,IAAI,KAAK,GAAG,EAAE,GAAG,IAAI,EAAE,KAAK,IAAI,EAAE,IAAI,IAAI,EAAE,KAAK,GAAG,GAAG,IAAI,EAAE,KAAK,IAAI,EAAE,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,IAAI,MAAM,GAAG,EAAE,OAAO,SAAS,CAAC;AAAA,MACrL;AAAA,IACF;AAAA,EACF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,WAAW,QAAe,SAAgB,UAA4C;AAC9F,WAAO,EAAE,GAAG,QAAQ,GAAG,cAAc,QAAQ,SAAS,SAAS,OAAO,SAAS,QAAQ,OAAO,IAAI,EAAE,EAAE;AAAA,EACxG;AAAA;AAAA,EAGU,IAAI,UAA6I;AACzJ,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC/C,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAI,QAAO;AAC9B,UAAM,MAAM,SAAS,IAAI,EAAE;AAC3B,QAAI,IAAI,MAAM,GAAG,KAAK,IAAI,MAAM,GAAG,EAAG,QAAO;AAC7C,UAAM,OAA+E,CAAC;AACtF,SAAK,MAAM,OAAO,QAAQ,CAAC,OAAO,MAAM;AACtC,UAAI,CAAC,MAAM,WAAW,MAAM,UAAU,EAAG;AACzC,iBAAW,QAAQ,CAAC,GAAG,EAAE,GAAY;AACnC,cAAM,IAAI,MAAM,QAAQ;AACxB,aAAK,KAAK,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,GAAG,MAAM,GAAG,KAAK,WAAW,IAAI,EAAE,GAAG,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;AAAA,MAC/J;AAAA,IACF,CAAC;AACD,WAAO,EAAE,QAAQ,KAAK,WAAW,IAAI,KAAK,QAAQ,GAAG,KAAK;AAAA,EAC5D;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,MAAM,WAAW;AACxB,WAAK,eAAe,KAAK,KAAK,MAAM,WAAW,QAAQ;AACvD;AAAA,IACF;AACA,UAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,QAAI,CAAC,IAAK;AACV,QAAI,KAAK,MAAM,kBAAkB,KAAK,MAAM,oBAAoB,GAAG;AACjE,iBAAW,QAAQ,CAAC,GAAG,EAAE,GAAY;AACnC,cAAM,UAAU,IAAI,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,QAAQ,EAAE,MAAM,KAAK;AACpG,YAAI,QAAQ,IAAI;AAChB,mBAAW,OAAO,SAAS;AACzB,cAAI,KAAK;AACT,cAAI,YAAY,UAAU,IAAI,OAAO,KAAK,MAAM,iBAAiB;AACjE,cAAI,UAAU;AACd,cAAI,OAAO,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;AAC3B,cAAI,OAAO,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;AAC/B,cAAI,OAAO,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;AAC3B,cAAI,UAAU;AACd,cAAI,KAAK;AACT,cAAI,QAAQ;AACZ,kBAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AACA,eAAW,OAAO,IAAI,MAAM;AAC1B,UAAI,KAAK;AACT,kBAAY,KAAK,YAAY,KAAK,OAAO,IAAI,OAAO,IAAI,KAAK,CAAC;AAC9D,oBAAc,KAAK,IAAI,GAAG,IAAI,CAAC;AAC/B,UAAI,QAAQ;AAAA,IACd;AACA,QAAI,KAAK;AACT,gBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,KAAK,MAAM,aAAa,WAAW,KAAK,MAAM,aAAa,WAAW,KAAK,MAAM,YAAY,CAAC;AAC3I,kBAAc,KAAK,IAAI,OAAO,GAAG,IAAI,OAAO,CAAC;AAC7C,QAAI,QAAQ;AAAA,EACd;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,QAAI,KAAK,MAAM,WAAW;AACxB,YAAM,YAAYA,cAAa,KAAK,MAAM,SAAS;AACnD,aAAO,KAAK,UAAU,KAAK,MAAM,WAAW,QAAQ,EAAE,KAAK,CAAC,QAAQ,kBAAkB,OAAO,IAAI,GAAG,IAAI,CAAC,KAAK,SAAS;AAAA,IACzH;AACA,UAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,QAAI,CAAC,IAAK,QAAO;AACjB,QAAI,kBAAkB,OAAO,IAAI,OAAO,GAAG,IAAI,OAAO,CAAC,KAAKA,cAAa,KAAK,MAAM,WAAW,EAAG,QAAO;AACzG,WAAO,IAAI,KAAK,KAAK,CAAC,QAAQ,kBAAkB,OAAO,IAAI,GAAG,IAAI,CAAC,KAAKA,cAAa,IAAI,MAAM,SAAS,KAAK,MAAM,SAAS,CAAC;AAAA,EAC/H;AACF;AAiBA,IAAM,yBAA8C,CAAC,MAAM,OAAO,KAAK,OAAO,MAAM,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,SAAS,KAAK,EAAE;AAGzH,IAAM,cAAN,cAA0B,QAA0B;AAAA,EAChD,OAAO;AAAA,EAEG,eAAiC;AAClD,WAAO;AAAA,MACL,aAAa,aAAa;AAAA,MAC1B,YAAY,aAAa;AAAA,MACzB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,MACnB,MAAM;AAAA,MACN,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,MACX,SAAS;AAAA,MACT,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EAEmB,aAAa,OAA6D;AAC3F,WAAO,WAAW,iBAAiB,KAAK,GAAG,KAAK,aAAa,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMmB,cAAc,OAAgD;AAC/E,UAAM,OAAO;AAAA,MACX,QAAQ,MAAM,QAAQ,MAAM,MAAM,IAAI,MAAM,SAAS;AAAA,MACrD,YAAY,MAAM,eAAe;AAAA,MACjC,YAAY,MAAM,eAAe;AAAA,IACnC;AACA,SAAK,SAAS;AAAA,MACZ,GAAG,KAAK;AAAA,MACR,YAAY,KAAK,OAAO,WAAW,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,MAAM,EAAE;AAAA,MACxE,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,kBAAkB;AAAA,MAClB,WAAW;AAAA,IACb;AAAA,EACF;AAAA,EAES,WAAW,OAAwC;AAC1D,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA;AAAA;AAAA,EAIU,UAAU,MAA8B,UAAyF;AACzI,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,EAAG,QAAO,CAAC;AACzC,WAAO,YAAY,IAAI,EACpB,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,EAAE,EAAE,EAC7D,OAAO,CAAC,MAAM,EAAE,MAAM,OAAO,EAC7B,IAAI,CAAC,MAAM;AACV,YAAM,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,EAAE,MAAM;AACzC,aAAO,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,cAAc,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,SAAS,OAAO,SAAS,QAAQ,OAAO,IAAI,EAAE,EAAE;AAAA,IAChH,CAAC;AAAA,EACL;AAAA,EAEU,eAAe,KAA+B,MAA8B,UAA0B;AAC9G,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,QAAI,KAAK;AACT,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,cAAc;AAClB,QAAI,YAAY,YAAY,UAAU,KAAK,MAAM,SAAS,CAAC;AAC3D,QAAI,WAAW,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;AACvG,QAAI,QAAQ;AACZ,eAAW,OAAO,KAAK,UAAU,MAAM,QAAQ,GAAG;AAChD,UAAI,KAAK;AACT,kBAAY,KAAK,KAAK,KAAK;AAC3B,UAAI,cAAc,IAAI;AACtB,oBAAc,KAAK,IAAI,GAAG,IAAI,CAAC;AAC/B,UAAI,QAAQ;AACZ,UAAI,KAAK,eAAe,SAAS,KAAK,eAAe,SAAS,IAAI,MAAM,MAAM;AAC5E,cAAM,QAAQ,SAAS,QAAQ,IAAI,CAAC;AACpC,cAAM,QAAQ;AAAA,UACZ,IAAI,MAAM,QAAQ;AAAA,UAClB,KAAK,eAAe,QAAQ,OAAO,IAAI,MAAM,KAAK,IAAI;AAAA,UACtD,KAAK,eAAe,SAAS,UAAU,OAAO,IAAI,KAAK,YAAY,KAAK,CAAC,MAAM;AAAA,QACjF,EAAE,OAAO,CAAC,MAAmB,MAAM,IAAI;AACvC,mBAAW,KAAK,MAAM,KAAK,GAAG,GAAG,EAAE,GAAG,GAAG,IAAI,GAAG,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,IAAI,MAAM,CAAC;AAAA,MACrG;AAAA,IACF;AAAA,EACF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,IAAI,UAAqC;AACjD,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AACzC,QAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAG,QAAO;AACnD,WAAO,SAAS,GAAG,GAAG,KAAK,MAAM,OAAO;AAAA,EAC1C;AAAA;AAAA;AAAA,EAIU,KAAKG,MAAe,UAAsG;AAClI,UAAM,MAAwF,CAAC;AAC/F,UAAM,MAAM,CAAC,aAA4C,EAAE,GAAGA,KAAI,QAAQ,GAAG,cAAcA,KAAI,QAAQ,SAAS,SAAS,OAAO,SAAS,QAAQ,OAAO,IAAI,EAAE,EAAE;AAChK,SAAK,MAAM,YAAY,QAAQ,CAAC,OAAO,MAAM;AAC3C,UAAI,MAAM,QAAS,KAAI,KAAK,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,GAAG,MAAM,SAAS,GAAG,IAAI,EAAE,GAAGA,KAAI,IAAI,GAAG,GAAG,OAAOA,MAAK,MAAM,KAAK,EAAE,CAAC,EAAE,CAAC;AAAA,IAC7I,CAAC;AACD,SAAK,MAAM,WAAW,QAAQ,CAAC,OAAO,MAAM;AAC1C,UAAI,MAAM,QAAS,KAAI,KAAK,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,GAAG,MAAM,QAAQ,GAAG,IAAI,EAAE,GAAG,MAAMA,MAAK,MAAM,KAAK,GAAG,GAAGA,KAAI,IAAI,EAAE,CAAC,EAAE,CAAC;AAAA,IAC3I,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,MAAM,WAAW;AACxB,WAAK,eAAe,KAAK,KAAK,MAAM,WAAW,QAAQ;AACvD;AAAA,IACF;AACA,UAAMA,OAAM,KAAK,IAAI,QAAQ;AAC7B,QAAI,CAACA,KAAK;AACV,UAAM,OAAO,KAAK,KAAKA,MAAK,QAAQ;AACpC,QAAI,KAAK,MAAM,kBAAkB,KAAK,MAAM,oBAAoB,GAAG;AACjE,iBAAW,QAAQ,CAAC,SAAS,MAAM,GAAY;AAC7C,cAAM,UAAU,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,QAAQ,EAAE,MAAM,KAAK;AAChG,iBAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,cAAI,KAAK;AACT,cAAI,YAAY,UAAU,QAAQ,CAAC,EAAG,OAAO,KAAK,MAAM,iBAAiB;AACzE,cAAI,UAAU;AACd,cAAI,OAAOA,KAAI,OAAO,GAAGA,KAAI,OAAO,CAAC;AACrC,cAAI,OAAO,QAAQ,IAAI,CAAC,EAAG,EAAE,GAAG,QAAQ,IAAI,CAAC,EAAG,EAAE,CAAC;AACnD,cAAI,OAAO,QAAQ,CAAC,EAAG,EAAE,GAAG,QAAQ,CAAC,EAAG,EAAE,CAAC;AAC3C,cAAI,UAAU;AACd,cAAI,KAAK;AACT,cAAI,QAAQ;AAAA,QACd;AAAA,MACF;AAAA,IACF;AACA,QAAI,KAAK,MAAM,MAAM;AACnB,UAAI,KAAK;AACT,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,KAAK,MAAM,WAAW,WAAW,KAAK,MAAM,WAAW,WAAW,KAAK,MAAM,UAAU,CAAC;AACrI,iBAAW,SAAS,KAAK,MAAM,YAAa,KAAI,MAAM,QAAS,eAAc,KAAK,EAAE,GAAGA,KAAI,MAAM,GAAG,OAAOA,MAAK,MAAM,KAAK,EAAE,GAAG,EAAE,GAAGA,KAAI,OAAO,GAAG,OAAOA,MAAK,MAAM,KAAK,EAAE,CAAC;AAC7K,iBAAW,SAAS,KAAK,MAAM,WAAY,KAAI,MAAM,QAAS,eAAc,KAAK,EAAE,GAAG,MAAMA,MAAK,MAAM,KAAK,GAAG,GAAGA,KAAI,IAAI,GAAG,EAAE,GAAG,MAAMA,MAAK,MAAM,KAAK,GAAG,GAAGA,KAAI,OAAO,CAAC;AAC1K,UAAI,QAAQ;AAAA,IACd;AACA,eAAW,KAAK,MAAM;AACpB,UAAI,KAAK;AACT,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,EAAE,MAAM,CAAC;AACtD,oBAAc,KAAK,EAAE,GAAG,EAAE,CAAC;AAC3B,UAAI,QAAQ;AAAA,IACd;AACA,mBAAe,KAAK,KAAK,OAAO,KAAK,OAAOA,MAAK,aAAa;AAAA,EAChE;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,YAAYH,cAAa,KAAK,MAAM,SAAS;AACnD,QAAI,KAAK,MAAM,UAAW,QAAO,KAAK,UAAU,KAAK,MAAM,WAAW,QAAQ,EAAE,KAAK,CAAC,MAAM,kBAAkB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS;AAC3I,UAAMG,OAAM,KAAK,IAAI,QAAQ;AAC7B,QAAI,CAACA,KAAK,QAAO;AACjB,WAAO,KAAK,KAAKA,MAAK,QAAQ,EAAE,KAAK,CAAC,MAAM,kBAAkB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS;AAAA,EAC7F;AACF;AASO,IAAM,YAAN,cAAwB,QAAwB;AAAA,EAC5C,OAAO;AAAA,EAEG,eAA+B;AAChD,WAAO,EAAE,kBAAkB,MAAM;AAAA,EACnC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,QAAQ,UAAoC;AACpD,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,UAAM,SAAS,KAAK,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC;AAClD,QAAI,WAAW,EAAG,QAAO;AACzB,UAAM,SAAS,KAAK,IAAI,YAAY,KAAK,KAAK,KAAK;AACnD,UAAM,YAAY,QAAQ,IAAI,EAAE;AAEhC,UAAM,OAAO,KAAK,MAAM,mBAAmB,KAAK;AAChD,UAAM,SAAkB,CAAC;AAEzB,aAAS,QAAQ,CAAC,KAAK,KAAK,GAAG,SAAS,KAAK,KAAK,GAAG,SAAS,KAAK,KAAK,IAAI;AAC1E,YAAM,IAAI,SAAS,KAAK,IAAI,SAAS,KAAK;AAC1C,UAAI,IAAI,IAAK;AACb,aAAO,KAAK,EAAE,GAAG,GAAG,IAAI,KAAK,IAAI,YAAY,OAAO,KAAK,IAAI,GAAG,GAAG,GAAG,IAAI,KAAK,IAAI,YAAY,OAAO,KAAK,IAAI,EAAE,CAAC;AAAA,IACpH;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,SAAS,KAAK,QAAQ,QAAQ;AACpC,QAAI,CAAC,UAAU,OAAO,SAAS,EAAG;AAClC,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,UAAU;AACd,QAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,KAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AAC3E,QAAI,OAAO;AAAA,EACb;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,SAAS,KAAK,QAAQ,QAAQ;AACpC,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,YAAYH,cAAa,KAAK,MAAM,SAAS;AACnD,aAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;AAC1C,UAAI,kBAAkB,OAAO,OAAO,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,KAAK,UAAW,QAAO;AAAA,IAC9E;AACA,WAAO;AAAA,EACT;AACF;;;ACr0CA,SAASI,cAAa,WAA2B;AAC/C,SAAO,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACtC;AAaA,SAAS,kBAAkB,KAA+B,MAAc,OAAgB,OAAqC;AAC3H,aAAW,KAAK,MAAM,EAAE,GAAG,MAAM,EAAE,IAAI,GAAG,GAAG,MAAM,EAAE,IAAI,GAAG,GAAG,KAAK;AACtE;AAYA,SAAS,QAAQ,OAAgB,OAAgB,GAAe,GAAoF;AAClJ,QAAM,QAAQ,MAAM,SAAS,IAAI,MAAM,UAAU,IAAI;AACrD,QAAM,KAAK,CAAC,OAAuB,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,OAAO,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,MAAM;AAC5G,QAAM,MAAM,GAAG,KAAK;AACpB,QAAM,SAAS,GAAG,KAAK;AACvB,QAAM,QAAyB,MAAM,SAAS,SAAS,MAAM,UAAU,UAAU;AACjF,MAAI,MAAM,MAAO,QAAO,EAAE,IAAI,EAAE,GAAG,IAAI,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,OAAO,UAAU,SAAS;AACxG,MAAI,MAAM,SAAU,QAAO,EAAE,IAAI,EAAE,GAAG,OAAO,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,OAAO,UAAU,MAAM;AAC3G,SAAO,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI,OAAO,KAAK,GAAG,IAAI,IAAI,IAAI,OAAO,KAAK,EAAE,GAAG,OAAO,UAAU,SAAS;AACnG;AAGA,IAAM,UAAU,CAAC,GAAY,OAAqC,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AAG5H,SAAS,SAAS,KAA+B,MAAc,GAAY,GAAkB;AAC3F,MAAI,KAAK;AACT,MAAI,YAAY;AAChB,MAAI,UAAU;AACd,MAAI,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AACvB,MAAI,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AACvB,MAAI,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AACvB,MAAI,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AACvB,MAAI,UAAU;AACd,MAAI,KAAK;AACT,MAAI,QAAQ;AACd;AAcA,IAAM,kBAA8B;AAAA,EAClC,EAAE,OAAO,OAAO,SAAS,OAAO,OAAO,WAAW,OAAO,GAAG,OAAO,QAAQ;AAAA,EAC3E,EAAE,OAAO,GAAG,SAAS,MAAM,OAAO,WAAW,OAAO,GAAG,OAAO,QAAQ;AAAA,EACtE,EAAE,OAAO,MAAM,SAAS,OAAO,OAAO,WAAW,OAAO,GAAG,OAAO,QAAQ;AAAA,EAC1E,EAAE,OAAO,KAAK,SAAS,MAAM,OAAO,WAAW,OAAO,GAAG,OAAO,SAAS;AAAA,EACzE,EAAE,OAAO,MAAM,SAAS,OAAO,OAAO,WAAW,OAAO,GAAG,OAAO,QAAQ;AAAA,EAC1E,EAAE,OAAO,GAAG,SAAS,MAAM,OAAO,WAAW,OAAO,GAAG,OAAO,QAAQ;AAAA,EACtE,EAAE,OAAO,MAAM,SAAS,OAAO,OAAO,WAAW,OAAO,GAAG,OAAO,QAAQ;AAC5E;AAMO,IAAM,kBAAN,cAA8B,QAA8B;AAAA,EACxD,OAAO;AAAA,EAEG,eAAqC;AACtD,WAAO,EAAE,MAAM,IAAI,YAAY,OAAO,YAAY,QAAQ,aAAa,OAAO,QAAQ,gBAAgB,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,GAAG,YAAY,OAAO,aAAa,OAAO,gBAAgB,KAAK;AAAA,EAC5L;AAAA;AAAA,EAGmB,aAAa,OAAqE;AACnG,UAAM,QAAQ;AACd,QAAI,EAAE,gBAAgB,OAAQ,QAAO;AACrC,UAAM,EAAE,YAAY,GAAG,KAAK,IAAI;AAChC,QAAI,YAAY,KAAM,QAAO;AAC7B,WAAO,EAAE,GAAG,MAAM,QAAQ,gBAAgB,IAAI,CAAC,MAAO,EAAE,UAAU,MAAM,EAAE,GAAG,GAAG,SAAS,eAAe,KAAK,IAAI,EAAE,GAAG,EAAE,CAAE,EAAE;AAAA,EAC9H;AAAA;AAAA;AAAA,EAImB,cAAc,OAAgD;AAC/E,UAAM,EAAE,WAAW,WAAW,UAAU,IAAI,KAAK;AACjD,UAAM,SAAS,MAAM,eAAe;AACpC,UAAM,SAAS,gBAAgB,IAAI,CAAC,OAAiB;AAAA,MACnD,GAAG;AAAA,MACH,SAAS,EAAE,UAAU,KAAK,EAAE,UAAU,KAAM,EAAE,UAAU,OAAO;AAAA,MAC/D,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO,EAAE,UAAU,MAAM,WAAW;AAAA,IACtC,EAAE;AACF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,QAAQ,aAAa,KAAK;AAAA,EAC5D;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,OAAO,UAAiE;AAChF,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC/C,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAI,QAAO;AAC9B,WAAO,EAAE,IAAI,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,GAAG,MAAO,GAAG,IAAI,GAAG,KAAM,KAAK;AAAA,EAC9F;AAAA;AAAA,EAGU,UAAU,GAAyC,OAAe,UAA6B;AACvG,UAAM,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,KAAK,MAAM;AAChD,UAAM,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,KAAK,MAAM;AAChD,UAAM,EAAE,YAAY,YAAY,IAAI,KAAK;AACzC,WAAO,cAAc,cAAc,cAAc,GAAG,GAAG,SAAS,OAAO,SAAS,QAAQ,YAAY,WAAW,IAAI,EAAE,GAAG,EAAE;AAAA,EAC5H;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,IAAI,KAAK,OAAO,QAAQ;AAC9B,QAAI,CAAC,EAAG;AACR,UAAM,OAAO,KAAK,UAAU,GAAG,GAAG,QAAQ;AAC1C,UAAM,MAAM,KAAK,UAAU,GAAG,GAAG,QAAQ;AACzC,UAAM,OAAO,KAAK,MAAM,mBAAmB,QAAQ,UAAU,KAAK,KAAK,IAAI;AAC3E,QAAI,KAAM,UAAS,KAAK,MAAM,MAAM,GAAG;AACvC,SAAK,MAAM,OAAO,QAAQ,CAAC,OAAO,MAAM;AACtC,UAAI,CAAC,MAAM,QAAS;AACpB,UAAI,KAAK;AACT,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,cAAc,OAAO,CAAC,GAAG,WAAW,MAAM,SAAS,KAAK,MAAM,WAAW,WAAW,MAAM,SAAS,KAAK,MAAM,UAAU,CAAC;AACtK,YAAMC,QAAO,KAAK,UAAU,GAAG,MAAM,OAAO,QAAQ;AACpD,oBAAc,KAAKA,MAAK,GAAGA,MAAK,CAAC;AACjC,UAAI,QAAQ;AAAA,IACd,CAAC;AACD,QAAI,KAAK,MAAM,QAAQ,KAAK,MAAM,YAAa,mBAAkB,KAAK,KAAK,MAAM,MAAM,MAAM,KAAK,KAAK;AAAA,aAC9F,KAAK,MAAM,MAAM;AACxB,YAAM,CAAC,OAAO,KAAK,IAAI,QAAQ,MAAM,GAAG;AACxC,YAAM,QAAQ,QAAQ,OAAO,OAAO,KAAK,MAAM,YAAY,KAAK,MAAM,UAAU;AAChF,iBAAW,KAAK,KAAK,MAAM,MAAM,MAAM,IAAI,KAAK,OAAO,EAAE,OAAO,MAAM,OAAO,UAAU,MAAM,SAAS,CAAC;AAAA,IACzG;AAAA,EACF;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,IAAI,KAAK,OAAO,QAAQ;AAC9B,QAAI,CAAC,EAAG,QAAO;AACf,eAAW,SAAS,KAAK,MAAM,QAAQ;AACrC,UAAI,CAAC,MAAM,QAAS;AACpB,YAAMA,QAAO,KAAK,UAAU,GAAG,MAAM,OAAO,QAAQ;AACpD,UAAI,kBAAkB,OAAOA,MAAK,GAAGA,MAAK,CAAC,KAAKD,cAAa,MAAM,SAAS,KAAK,MAAM,SAAS,EAAG,QAAO;AAAA,IAC5G;AAEA,UAAM,OAAO,KAAK,UAAU,GAAG,GAAG,QAAQ;AAC1C,UAAM,MAAM,KAAK,UAAU,GAAG,GAAG,QAAQ;AACzC,UAAM,OAAO,KAAK,IAAI,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC;AACxC,UAAM,OAAO,KAAK,IAAI,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC;AACxC,QAAI,MAAM,IAAI,QAAQ,MAAM,IAAI,KAAM,QAAO;AAC7C,UAAM,KAAK,MAAM,IAAI,KAAK,EAAE,MAAM,KAAK,EAAE,IAAI,KAAK,EAAE,KAAK;AACzD,UAAM,QAAQ,KAAK,EAAE,KAAK,KAAK,EAAE,IAAI,KAAK,EAAE,KAAK;AACjD,UAAM,OAAO,IAAI,EAAE,KAAK,IAAI,EAAE,IAAI,IAAI,EAAE,KAAK;AAC7C,WAAO,MAAM,KAAK,KAAK,IAAI,OAAO,IAAI,KAAK,MAAM,KAAK,KAAK,IAAI,OAAO,IAAI;AAAA,EAC5E;AACF;AAiBA,IAAM,eAAe,CAAC,SAA+B;AAAA,EACnD,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,YAAY;AAAA,EACZ,cAAc;AAChB;AAGA,SAAS,eAAe,OAAqD;AAC3E,QAAM,QAAQ;AACd,MAAI,EAAE,gBAAgB,OAAQ,QAAO;AACrC,QAAM,EAAE,YAAY,aAAa,GAAG,KAAK,IAAI;AAC7C,OAAK;AACL,SAAO;AACT;AAGA,SAAS,aAAa,KAA+BE,UAA0G,OAA2B,QAAkC;AAC1N,QAAM,EAAE,OAAO,MAAM,IAAIA;AACzB,QAAM,OAAO,MAAM,mBAAmB,QAAQ,UAAU,KAAK,IAAI;AACjE,MAAI,KAAM,UAAS,KAAK,MAAM,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAChD,cAAY,KAAK,KAAK;AACtB,aAAW,QAAQ,OAAO;AACxB,kBAAc,KAAK,KAAK,GAAG,KAAK,CAAC;AACjC,QAAI,MAAM,YAAY,QAAS,gBAAe,KAAK,KAAK,GAAG,KAAK,GAAG,KAAK;AACxE,QAAI,MAAM,aAAa,QAAS,gBAAe,KAAK,KAAK,GAAG,KAAK,GAAG,KAAK;AAAA,EAC3E;AACA,MAAI,MAAM,YAAY;AACpB,UAAM,MAAoB,EAAE,GAAG,OAAO,WAAW,MAAM,aAAa,UAAU,MAAM,gBAAgB,MAAM,MAAM,YAAY,QAAQ,MAAM,aAAa;AACvJ,UAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,YAAM,CAAC,MAAM,KAAK,IAAI,OAAO,CAAC;AAC9B,iBAAW,KAAKA,SAAQ,OAAO,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,GAAG,GAAG,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,OAAO,QAAQ,CAAC;AAC/F,iBAAW,KAAKA,SAAQ,OAAO,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,GAAG,GAAG,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,OAAO,OAAO,CAAC;AAAA,IACjG,CAAC;AAAA,EACH;AACA,MAAI,MAAM,QAAQ,MAAM,YAAa,mBAAkB,KAAK,MAAM,MAAM,MAAM,CAAC,GAAG,KAAK;AAAA,WAC9E,MAAM,MAAM;AACnB,UAAM,CAAC,OAAO,KAAK,IAAI,QAAQ,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AACjD,UAAM,QAAQ,QAAQ,OAAO,OAAO,MAAM,YAAY,MAAM,UAAU;AACtE,eAAW,KAAK,MAAM,MAAM,MAAM,IAAI,OAAO,EAAE,OAAO,MAAM,OAAO,UAAU,MAAM,SAAS,CAAC;AAAA,EAC/F;AACF;AAMO,IAAM,gBAAN,cAA4B,QAAsB;AAAA,EAC9C,OAAO;AAAA,EAEG,eAA6B;AAC9C,WAAO,aAAa,SAAS;AAAA,EAC/B;AAAA,EAEmB,aAAa,OAAqD;AACnF,WAAO,eAAe,KAAK;AAAA,EAC7B;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,aAAa,KAAK;AAAA,EACpD;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,WAAW,UAA8D;AACjF,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC/C,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAI,QAAO;AAC9B,UAAM,EAAE,YAAY,YAAY,IAAI,KAAK;AACzC,UAAM,QAAQ,cAAc,cAAc,cAAc,IAAI,IAAI,SAAS,OAAO,SAAS,QAAQ,YAAY,WAAW,IAAI,EAAE,GAAG,IAAI,GAAG,GAAG;AAC3I,WAAO,EAAE,OAAO,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE;AAAA,EACvF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,IAAI,KAAK,WAAW,QAAQ;AAClC,QAAI,CAAC,EAAG;AACR,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK;AAC1B,iBAAa,KAAK,EAAE,OAAO,KAAK,OAAO,OAAO,KAAK,OAAO,QAAQ,CAAC,MAAM,KAAK,YAAY,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,GAAG;AAAA,MACjH,CAAC,GAAI,OAAO,GAAI,KAAK;AAAA,MACrB,CAAC,GAAI,OAAO,GAAI,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKS,iBAAiB,UAAoC;AAC5D,UAAM,SAAS,MAAM,iBAAiB,QAAQ;AAC9C,UAAM,MAAM,OAAO,KAAK,CAAC,UAAU,MAAM,UAAU,CAAC;AACpD,WAAO,MAAM,OAAO,IAAI,CAAC,UAAW,MAAM,UAAU,IAAI,EAAE,GAAG,OAAO,GAAG,IAAI,EAAE,IAAI,KAAM,IAAI;AAAA,EAC7F;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,IAAI,KAAK,WAAW,QAAQ;AAClC,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,YAAYF,cAAa,KAAK,MAAM,SAAS;AACnD,QAAI,kBAAkB,OAAO,EAAE,MAAM,GAAG,EAAE,MAAM,CAAC,KAAK,UAAW,QAAO;AACxE,QAAI,kBAAkB,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,CAAC,KAAK,UAAW,QAAO;AACtE,UAAM,OAAO,KAAK,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AAC9C,UAAM,OAAO,KAAK,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AAC9C,QAAI,MAAM,IAAI,QAAQ,MAAM,IAAI,KAAM,QAAO;AAC7C,UAAM,KAAK,MAAM,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK;AAClE,UAAM,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK;AAC3D,WAAO,MAAM,KAAK,KAAK,IAAI,QAAQ,EAAE,KAAK,EAAE,CAAC,KAAK,MAAM,KAAK,KAAK,IAAI,QAAQ,EAAE,KAAK,EAAE,CAAC;AAAA,EAC1F;AACF;AAIO,IAAM,kBAAN,cAA8B,QAAsB;AAAA,EAChD,OAAO;AAAA,EAEG,eAA6B;AAC9C,WAAO,aAAa,SAAS;AAAA,EAC/B;AAAA,EAEmB,aAAa,OAAqD;AACnF,WAAO,eAAe,KAAK;AAAA,EAC7B;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,aAAa,KAAK;AAAA,EACpD;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,WAAW,UAA8D;AACjF,UAAM,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AACnD,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAI,QAAO;AACrC,UAAM,EAAE,YAAY,YAAY,IAAI,KAAK;AACzC,UAAMC,QAAO,CAAC,GAAU,MAAuB,cAAc,cAAc,cAAc,GAAG,GAAG,SAAS,OAAO,SAAS,QAAQ,YAAY,WAAW,IAAI,EAAE,GAAG,EAAE;AAClK,WAAO,EAAE,KAAKA,MAAK,IAAI,EAAE,GAAG,QAAQA,MAAK,IAAI,EAAE,EAAE;AAAA,EACnD;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,IAAI,KAAK,WAAW,QAAQ;AAClC,QAAI,CAAC,EAAG;AACR,UAAM,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,KAAK;AAC9B,iBAAa,KAAK,EAAE,OAAO,KAAK,OAAO,OAAO,KAAK,OAAO,QAAQ,CAAC,MAAM,KAAK,YAAY,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG;AAAA,MACjH,CAAC,GAAI,OAAO,GAAI,KAAK;AAAA,MACrB,CAAC,GAAI,OAAO,GAAI,KAAK;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,IAAI,KAAK,WAAW,QAAQ;AAClC,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,YAAYD,cAAa,KAAK,MAAM,SAAS;AACnD,WAAO,kBAAkB,OAAO,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC,KAAK,aAAa,kBAAkB,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,KAAK;AAAA,EACxH;AACF;;;AC5UA,IAAMG,eAAoD;AAAA,EACxD,CAAC,MAAM,WAAW,KAAK;AAAA,EACvB,CAAC,OAAO,WAAW,KAAK;AAAA,EACxB,CAAC,KAAK,WAAW,IAAI;AAAA,EACrB,CAAC,OAAO,WAAW,KAAK;AAAA,EACxB,CAAC,MAAM,WAAW,KAAK;AAAA,EACvB,CAAC,GAAG,WAAW,IAAI;AAAA,EACnB,CAAC,KAAK,WAAW,KAAK;AAAA,EACtB,CAAC,MAAM,WAAW,KAAK;AAAA,EACvB,CAAC,GAAG,WAAW,KAAK;AACtB;AAcA,IAAMC,eAAc,CAAC,OAA+B,OAAkB,WAAiC;AAAA,EACrG,GAAG;AAAA,EACH,WAAW;AAAA,EACX,WAAW,MAAM,SAAS,MAAM;AAAA,EAChC,WAAW,MAAM,SAAS,MAAM;AAClC;AAOO,IAAM,YAAN,cAAwB,QAAwB;AAAA,EAC5C,OAAe;AAAA;AAAA,EAGd,iBAA8B;AACtC,WAAO;AAAA,EACT;AAAA,EAEmB,eAA+B;AAChD,WAAO;AAAA,MACL,SAAS,KAAK,eAAe;AAAA,MAC7B,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa;AAAA,MACb,QAAQD,aAAY,IAAI,CAAC,CAAC,OAAO,OAAO,OAAO,OAAO,EAAE,OAAO,SAAS,OAAO,OAAO,GAAG,OAAO,QAAQ,EAAE;AAAA,MAC1G,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,MACnB,aAAa;AAAA,IACf;AAAA,EACF;AAAA;AAAA,EAGmB,aAAa,OAAyD;AACvF,UAAM,QAAQ;AACd,QAAI,EAAE,gBAAgB,OAAQ,QAAO;AACrC,UAAM,EAAE,YAAY,GAAG,KAAK,IAAI;AAChC,WAAO,oBAAoB,OAAO,OAAO,EAAE,GAAG,MAAM,gBAAgB,eAAe,MAAM;AAAA,EAC3F;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,UAAM,EAAE,WAAW,WAAW,UAAU,IAAI,KAAK;AACjD,UAAM,SAAS,KAAK,OAAO,OAAO,IAAI,CAAC,OAAkB,EAAE,GAAG,GAAG,OAAO,EAAE,SAAS,WAAW,OAAO,WAAW,OAAO,UAAU,EAAE;AACnI,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,aAAa,WAAW,aAAa,WAAW,aAAa,WAAW,QAAQ,aAAa,KAAK;AAAA,EACpI;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,KAAK,UAAyC;AACtD,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC/C,QAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAI,QAAO;AAC9B,UAAM,MAAM,SAAS,IAAI,EAAE;AAC3B,UAAM,UAAU,KAAK,MAAM;AAC3B,UAAM,SACJ,YAAY,WACR,SAAS,IAAI,EAAE,IACf,YAAY,oBACV,EAAE,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE,IAChC,YAAY,WACV,MACA;AAEV,UAAM,MAAM,YAAY,WAAW,EAAE,GAAG,IAAI,IAAI,GAAG,GAAG,GAAG,IAAI,IAAI,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,OAAO,GAAG,GAAG,IAAI,IAAI,OAAO,EAAE;AACrH,QAAI,IAAI,MAAM,KAAK,IAAI,MAAM,EAAG,QAAO;AACvC,WAAO,EAAE,QAAQ,KAAK,KAAK,WAAW,EAAE,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE,EAAE;AAAA,EAC7E;AAAA;AAAA,EAGU,YAAY,MAAoB,IAAW,UAA4C;AAE/F,UAAM,SAAS,SAAS,QAAQ,SAAS,UAAU,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC;AACpF,UAAM,IAAI,EAAE,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI,OAAO,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI,MAAM;AACvE,UAAM,IAAI,KAAK,MAAM,cAAc,EAAE,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI,OAAO,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI,MAAM,IAAI;AACpG,WAAO,EAAE,GAAG,EAAE;AAAA,EAChB;AAAA,EAEU,WAAW,MAAoB,OAAsB;AAC7D,WAAO,EAAE,GAAG,KAAK,IAAI,IAAI,KAAK,UAAU,IAAI,OAAO,GAAG,KAAK,IAAI,IAAI,KAAK,UAAU,IAAI,MAAM;AAAA,EAC9F;AAAA;AAAA,EAGU,cAAqD;AAC7D,WAAO,KAAK,MAAM,OACf,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,EAAE,EAAE,EAC7D,OAAO,CAAC,MAAM,EAAE,MAAM,WAAW,EAAE,MAAM,QAAQ,CAAC,EAClD,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,QAAQ,EAAE,MAAM,KAAK;AAAA,EACjD;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,OAAO,KAAK,KAAK,QAAQ;AAC/B,QAAI,CAAC,KAAM;AACX,UAAM,QAAQ,KAAK,YAAY;AAE/B,QAAI,KAAK,MAAM,kBAAkB,KAAK,MAAM,oBAAoB,GAAG;AAGjE,UAAI,KAAK;AACT,iBAAW,QAAQ,CAAC,GAAG,EAAE,GAAG;AAC1B,YAAI,QAAQ;AACZ,mBAAW,CAAC,GAAG,KAAK,KAAK,MAAM,QAAQ,GAAG;AACxC,cAAI,YAAY,KAAK,MAAM,cAAc,UAAU,KAAK,MAAM,WAAW,OAAO,QAAQ,MAAM,SAAS,EAAE,IAAI,UAAU,MAAM,OAAO,KAAK,MAAM,iBAAiB;AAChK,gBAAM,QAAQ,KAAK,YAAY,MAAM,KAAK,WAAW,MAAM,QAAQ,IAAI,GAAG,QAAQ;AAClF,gBAAM,QAAQ,KAAK,YAAY,MAAM,KAAK,WAAW,MAAM,MAAM,MAAM,QAAQ,IAAI,GAAG,QAAQ;AAC9F,cAAI,UAAU;AACd,cAAI,OAAO,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;AAC/B,cAAI,OAAO,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;AAC/B,cAAI,OAAO,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;AAC/B,cAAI,OAAO,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;AAC/B,cAAI,UAAU;AACd,cAAI,KAAK;AACT,kBAAQ,MAAM,MAAM;AAAA,QACtB;AAAA,MACF;AACA,UAAI,QAAQ;AAAA,IACd;AAGA,eAAW,SAAS,OAAO;AACzB,UAAI,KAAK;AACT,kBAAY,KAAKC,aAAY,KAAK,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC;AAClE,iBAAW,QAAQ,CAAC,GAAG,EAAE,GAAG;AAC1B,cAAMC,QAAO,KAAK,YAAY,MAAM,KAAK,WAAW,MAAM,MAAM,MAAM,QAAQ,IAAI,GAAG,QAAQ;AAC7F,sBAAc,KAAKA,MAAK,GAAGA,MAAK,CAAC;AAAA,MACnC;AACA,UAAI,QAAQ;AAAA,IACd;AAEA,QAAI,KAAK;AACT,gBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,KAAK,MAAM,aAAa,WAAW,KAAK,MAAM,aAAa,WAAW,KAAK,MAAM,YAAY,CAAC;AAC3I,UAAM,SAAS,KAAK,YAAY,MAAM,KAAK,KAAK,QAAQ;AACxD,kBAAc,KAAK,KAAK,MAAM,cAAc,OAAO,IAAI,KAAK,QAAQ,OAAO,CAAC;AAC5E,QAAI,QAAQ;AAAA,EACd;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,OAAO,KAAK,KAAK,QAAQ;AAC/B,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,SAAS,KAAK,YAAY,MAAM,KAAK,KAAK,QAAQ;AACxD,QAAI,kBAAkB,OAAO,KAAK,MAAM,cAAc,OAAO,IAAI,KAAK,QAAQ,OAAO,CAAC,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,IAAI,CAAC,EAAG,QAAO;AAC/I,eAAW,EAAE,MAAM,KAAK,KAAK,YAAY,GAAG;AAC1C,YAAM,YAAY,KAAK,IAAI,IAAI,MAAM,SAAS,KAAK,MAAM,aAAa,IAAI,CAAC;AAC3E,iBAAW,QAAQ,CAAC,GAAG,EAAE,GAAG;AAC1B,cAAMA,QAAO,KAAK,YAAY,MAAM,KAAK,WAAW,MAAM,MAAM,QAAQ,IAAI,GAAG,QAAQ;AACvF,YAAI,kBAAkB,OAAOA,MAAK,GAAGA,MAAK,CAAC,KAAK,UAAW,QAAO;AAAA,MACpE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAGO,IAAM,kBAAN,cAA8B,UAAU;AAAA,EAC3B,OAAO;AAAA,EAEN,iBAA8B;AAC/C,WAAO;AAAA,EACT;AACF;AAGO,IAAM,0BAAN,cAAsC,UAAU;AAAA,EACnC,OAAO;AAAA,EAEN,iBAA8B;AAC/C,WAAO;AAAA,EACT;AACF;AAGO,IAAM,kBAAN,cAA8B,UAAU;AAAA,EAC3B,OAAO;AAAA,EAEN,iBAA8B;AAC/C,WAAO;AAAA,EACT;AACF;;;ACrOA,SAASC,cAAa,WAA2B;AAC/C,SAAO,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACtC;AAiBA,IAAM,mBAAwC,CAAC,GAAG,MAAM,OAAO,KAAK,OAAO,MAAM,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,SAAS,KAAK,EAAE;AAI7H,SAAS,iBAAiB,QAAyC;AACjE,MAAI,QAAQ;AACZ,SAAO,OAAO,IAAI,CAAC,OAAO,OAAO,EAAE,GAAG,OAAO,OAAO,MAAM,SAAS,cAAc,OAAO,MAAM,UAAU,UAAU,CAAC,EAAE,EAAE;AACzH;AAGO,IAAM,UAAN,cAAsB,QAAsB;AAAA,EACxC,OAAe;AAAA,EAEL,eAA6B;AAC9C,WAAO;AAAA,MACL,aAAa,aAAa;AAAA,MAC1B,YAAY,aAAa;AAAA,MACzB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,kBAAkB;AAAA,MAClB,qBAAqB;AAAA,MACrB,wBAAwB;AAAA,MACxB,oBAAoB;AAAA,MACpB,uBAAuB;AAAA,MACvB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEmB,aAAa,OAAqD;AACnF,UAAM,QAAQ,iBAAiB,KAAK;AACpC,UAAM,MAA+B,CAAC;AACtC,UAAM,WAAW,KAAK,aAAa;AACnC,eAAW,OAAO,OAAO,KAAK,QAAQ,EAAG,KAAI,OAAO,MAAO,KAAI,GAAG,IAAK,MAAkC,GAAG;AAG5G,QAAI,MAAM,QAAQ,MAAM,WAAW,KAAK,EAAE,gBAAgB,OAAQ,KAAI,aAAa,MAAM,YAAY,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAC1H,QAAI,OAAO,MAAM,eAAe,aAAa,EAAE,yBAAyB,OAAQ,KAAI,sBAAsB,IAAI,qBAAqB,MAAM;AACzI,QAAI,OAAO,MAAM,eAAe,aAAa,EAAE,oBAAoB,OAAQ,KAAI,iBAAiB,IAAI,kBAAkB,IAAI,gBAAgB,IAAI,mBAAmB,MAAM;AACvK,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKmB,cAAc,OAAgD;AAC/E,UAAM,SAAS,iBAAiB,MAAM,QAAQ,MAAM,MAAM,IAAI,YAAY,KAAK,IAAI,gBAAgB;AACnG,UAAM,SAAS,MAAM,eAAe;AACpC,SAAK,SAAS;AAAA,MACZ,GAAG,KAAK;AAAA,MACR,aAAa;AAAA,MACb,YAAY,OAAO,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAAA,MACxC,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,kBAAkB;AAAA,MAClB,qBAAqB;AAAA,MACrB,oBAAoB;AAAA,MACpB,MAAM,MAAM,eAAe,QAAQ,OAAO,UAAU,KAAK,OAAO,WAAW,IAAI;AAAA,IACjF;AAAA,EACF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,IAAI,UAAqC;AACjD,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AACzC,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,WAAO,SAAS,GAAG,GAAG,KAAK,MAAM,OAAO;AAAA,EAC1C;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAMC,OAAM,KAAK,IAAI,QAAQ;AAC7B,QAAI,CAACA,KAAK;AACV,UAAM,EAAE,MAAM,IAAI;AAClB,QAAI,MAAM,MAAM;AACd,UAAI,YAAY,MAAM;AACtB,UAAI,SAASA,KAAI,MAAMA,KAAI,KAAKA,KAAI,QAAQA,KAAI,MAAMA,KAAI,SAASA,KAAI,GAAG;AAAA,IAC5E;AAGA,UAAM,QAAQ,CAAC,QAAoB,SAAiB,IAA2B,SAA2E;AACxJ,YAAM,QAAQ,OAAO,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,QAAQ,EAAE,MAAM,KAAK;AAC/J,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAI,YAAY,UAAU,MAAM,CAAC,EAAG,OAAO,OAAO;AAClD,YAAI,SAAS,GAAG,KAAK,GAAG,MAAM,IAAI,CAAC,EAAG,MAAM,KAAK,GAAG,GAAG,MAAM,CAAC,EAAG,MAAM,KAAK,CAAC,CAAC;AAAA,MAChF;AAAA,IACF;AACA,QAAI,MAAM,uBAAuB,MAAM,yBAAyB,EAAG,OAAM,MAAM,aAAa,MAAM,wBAAwB,CAAC,MAAM,OAAOA,MAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAACA,KAAI,MAAM,KAAK,IAAI,GAAG,CAAC,GAAGA,KAAI,QAAQA,KAAI,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC;AAC5N,QAAI,MAAM,sBAAsB,MAAM,wBAAwB,EAAG,OAAM,MAAM,YAAY,MAAM,uBAAuB,CAAC,MAAM,MAAMA,MAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,GAAGA,KAAI,KAAK,KAAK,IAAI,IAAI,CAAC,GAAGA,KAAI,SAASA,KAAI,GAAG,CAAC;AACtN,UAAM,YAAY,QAAQ,CAAC,OAAO,MAAM;AACtC,UAAI,CAAC,MAAM,QAAS;AACpB,UAAI,KAAK;AACT,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,cAAc,OAAO,CAAC,EAAE,CAAC;AACtE,oBAAc,KAAK,EAAE,GAAGA,KAAI,MAAM,GAAG,OAAOA,MAAK,MAAM,KAAK,EAAE,GAAG,EAAE,GAAGA,KAAI,OAAO,GAAG,OAAOA,MAAK,MAAM,KAAK,EAAE,CAAC;AAC9G,UAAI,QAAQ;AAAA,IACd,CAAC;AACD,UAAM,WAAW,QAAQ,CAAC,OAAO,MAAM;AACrC,UAAI,CAAC,MAAM,QAAS;AACpB,UAAI,KAAK;AACT,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,cAAc,OAAO,CAAC,EAAE,CAAC;AACtE,oBAAc,KAAK,EAAE,GAAG,MAAMA,MAAK,MAAM,KAAK,GAAG,GAAGA,KAAI,IAAI,GAAG,EAAE,GAAG,MAAMA,MAAK,MAAM,KAAK,GAAG,GAAGA,KAAI,OAAO,CAAC;AAC5G,UAAI,QAAQ;AAAA,IACd,CAAC;AACD,QAAI,MAAM,QAAQ;AAChB,UAAI,KAAK;AACT,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,MAAM,YAAY,CAAC;AAChE,oBAAc,KAAK,EAAE,GAAGA,KAAI,MAAM,GAAGA,KAAI,IAAI,GAAG,EAAE,GAAGA,KAAI,OAAO,GAAGA,KAAI,OAAO,CAAC;AAC/E,oBAAc,KAAK,EAAE,GAAGA,KAAI,MAAM,GAAGA,KAAI,OAAO,GAAG,EAAE,GAAGA,KAAI,OAAO,GAAGA,KAAI,IAAI,CAAC;AAC/E,UAAI,QAAQ;AAAA,IACd;AACA,mBAAe,KAAK,KAAK,OAAO,OAAOA,MAAK,aAAa;AAAA,EAC3D;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAMA,OAAM,KAAK,IAAI,QAAQ;AAC7B,QAAI,CAACA,KAAK,QAAO;AACjB,UAAM,YAAYD,cAAa,KAAK,MAAM,SAAS;AACnD,UAAM,MAAM,MAAM,KAAKC,KAAI,OAAO,aAAa,MAAM,KAAKA,KAAI,QAAQ;AACtE,UAAM,MAAM,MAAM,KAAKA,KAAI,MAAM,aAAa,MAAM,KAAKA,KAAI,SAAS;AACtE,QAAI,CAAC,OAAO,CAAC,IAAK,QAAO;AACzB,QAAI,KAAK,MAAM,YAAY,KAAK,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,MAAM,IAAI,OAAOA,MAAK,EAAE,KAAK,CAAC,KAAK,SAAS,EAAG,QAAO;AACnH,QAAI,KAAK,MAAM,WAAW,KAAK,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,MAAM,IAAI,MAAMA,MAAK,EAAE,KAAK,CAAC,KAAK,SAAS,EAAG,QAAO;AACjH,QAAI,CAAC,KAAK,MAAM,OAAQ,QAAO;AAC/B,WAAO,kBAAkB,OAAO,EAAE,GAAGA,KAAI,MAAM,GAAGA,KAAI,IAAI,GAAG,EAAE,GAAGA,KAAI,OAAO,GAAGA,KAAI,OAAO,CAAC,KAAK,aAAa,kBAAkB,OAAO,EAAE,GAAGA,KAAI,MAAM,GAAGA,KAAI,OAAO,GAAG,EAAE,GAAGA,KAAI,OAAO,GAAGA,KAAI,IAAI,CAAC,KAAK;AAAA,EAC1M;AACF;AAkCA,IAAMC,QAAO,CAAC,OAAe,aAAgC,EAAE,SAAS,OAAO,OAAO,EAAE;AACxF,IAAM,QAAQ,CAAC,GAAW,GAAW,OAAe,aAAqC,EAAE,GAAG,GAAG,SAAS,OAAO,OAAO,EAAE;AAG1H,IAAM,gBAAgB,MAAkB,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS,EAAE,IAAI,CAAC,MAAMA,MAAK,GAAG,IAAI,CAAC;AAGnI,IAAM,cAAc,MAAuB;AAAA,EACzC,MAAM,GAAG,GAAG,WAAW,KAAK;AAAA,EAC5B,MAAM,GAAG,GAAG,WAAW,KAAK;AAAA,EAC5B,MAAM,GAAG,GAAG,WAAW,KAAK;AAAA,EAC5B,MAAM,GAAG,GAAG,WAAW,KAAK;AAAA,EAC5B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,KAAK;AAAA,EAC5B,MAAM,GAAG,GAAG,WAAW,KAAK;AAAA,EAC5B,MAAM,GAAG,GAAG,WAAW,KAAK;AAAA,EAC5B,MAAM,GAAG,GAAG,WAAW,KAAK;AAC9B;AAGA,IAAM,cAAc,MAAuB;AAAA,EACzC,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,KAAK,GAAG,WAAW,IAAI;AAAA,EAC7B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,IAAI;AAAA,EAC3B,MAAM,GAAG,GAAG,WAAW,IAAI;AAC7B;AAEA,IAAM,eAAe,OAAwB,EAAE,QAAQ,cAAc,GAAG,MAAM,YAAY,GAAG,MAAM,YAAY,GAAG,gBAAgB,MAAM,mBAAmB,KAAK,SAAS,OAAO,WAAW,KAAK;AAIzL,IAAM,gBAAgB,CAAC,MAAwC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;AAGnF,IAAM,gBAAgB,CAAC,UAA4B,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,YAAY,OAAO,GAAG,UAAU,QAAQ;AAI1J,SAAS,YAAuC,OAAmB,UAAyB;AAC1F,QAAM,OAAO;AACb,QAAM,MAA+B,CAAC;AACtC,aAAW,OAAO,OAAO,KAAK,QAAQ,GAAG;AACvC,QAAI,EAAE,OAAO,MAAO;AACpB,SAAK,QAAQ,YAAY,QAAQ,UAAU,QAAQ,WAAW,CAAC,cAAc,KAAK,GAAG,CAAC,EAAG;AACzF,QAAI,GAAG,IAAI,KAAK,GAAG;AAAA,EACrB;AACA,MAAI,OAAO,KAAK,eAAe,aAAa,EAAE,oBAAoB,MAAO,KAAI,iBAAiB,KAAK;AACnG,SAAO;AACT;AAKA,SAAS,cAAc,KAA+B,OAA+B,MAA8B,GAAU,GAAgB;AAC3I,QAAM,SAAS,YAAY,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO;AACxD,MAAI,KAAK,eAAe,OAAO;AAC7B,QAAI,KAAK;AACT,QAAI,YAAY,UAAU,MAAM,WAAW,IAAI;AAC/C,QAAI,SAAS,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7F,QAAI,QAAQ;AAAA,EACd;AACA,aAAW,CAAC,GAAG,KAAK,KAAK,OAAO,QAAQ,GAAG;AACzC,UAAM,QAAQ,cAAc,OAAO,CAAC;AACpC,QAAI,KAAK;AACT,gBAAY,KAAK,KAAK;AACtB,QAAI,cAAc;AAClB,UAAM,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,MAAM;AACpC,kBAAc,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAC/C,UAAM,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,MAAM;AACpC,kBAAc,KAAK,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC;AAC/C,QAAI,QAAQ;AACZ,QAAI,KAAK,eAAe,MAAO,YAAW,KAAK,OAAO,MAAM,KAAK,GAAG,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,WAAW,MAAM,GAAG,EAAE,OAAO,QAAQ,CAAC;AAAA,EAC1J;AACF;AAGA,SAAS,aAAa,OAAc,WAAmB,MAA8B,GAAU,GAAmB;AAChH,QAAM,MAAM,MAAM,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,aAAa,MAAM,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI;AACzF,QAAM,MAAM,MAAM,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,aAAa,MAAM,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI;AACzF,MAAI,CAAC,OAAO,CAAC,IAAK,QAAO;AACzB,SAAO,YAAY,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,MAAM,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,aAAa,KAAK,IAAI,MAAM,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,UAAU;AACtL;AAOA,IAAM,YAAY,CAAC,SACjB,KACG,OAAO,CAAC,MAAM,EAAE,OAAO,EACvB,IAAI,CAAC,SAAS,EAAE,KAAK,GAAG,KAAK,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,EAAE,EACnD,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,EACrB,KAAK,CAAC,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AAItB,IAAe,iBAAf,cAAiE,QAAW;AAAA,EACjF,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAImB,cAAc,OAAgD;AAC/E,UAAM,OAAO;AAAA,MACX,QAAQ,MAAM,QAAQ,MAAM,MAAM,IAAI,MAAM,SAAS;AAAA,MACrD,YAAY,MAAM,eAAe;AAAA,MACjC,YAAY,MAAM,eAAe;AAAA,IACnC;AACA,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,KAAK;AAAA,EAClD;AAAA,EAES,WAAW,OAAyB;AAC3C,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA;AAAA,EAGU,SAAS,UAAmD;AACpE,WAAO,KAAK,QAAQ,QAAQ;AAAA,EAC9B;AAAA;AAAA,EAGU,iBAAiB,MAAgC,IAAW,IAAiB;AAAA,EAAC;AAAA;AAAA,EAG9E,QAAQ,UAAmD;AACnE,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AACzC,QAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAG,QAAO;AACnD,WAAO,EAAE,GAAG,EAAE;AAAA,EAChB;AAAA,EAEU,MAAM,UAAwC;AACtD,UAAM,IAAI,KAAK,QAAQ,QAAQ;AAC/B,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,CAAC,QAAQ,GAAG,IAAI,KAAK,MAAM,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;AACjE,WAAO;AAAA,MACL;AAAA,MACA,KAAK,IAAI,IAAI,OAAO,KAAK;AAAA,MACzB,KAAK,IAAI,IAAI,OAAO,KAAK;AAAA,MACzB,MAAM,KAAK,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AAAA,MAC3B,OAAO,KAAK,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AAAA,MAC5B,KAAK,KAAK,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AAAA,MAC1B,QAAQ,KAAK,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AAAA,IAC/B;AAAA,EACF;AAAA;AAAA;AAAA,EAIU,GAAG,GAAgB,GAAW,GAAkB;AACxD,WAAO,EAAE,GAAG,EAAE,OAAO,IAAI,EAAE,KAAK,GAAG,GAAG,EAAE,OAAO,IAAI,EAAE,KAAK,EAAE;AAAA,EAC9D;AAAA;AAAA,EAGU,OAAO,GAAgB,KAA2B;AAC1D,UAAM,QAAQ,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC;AACvC,WAAO,KAAK,GAAG,GAAG,IAAI,IAAI,OAAO,IAAI,IAAI,KAAK;AAAA,EAChD;AAAA;AAAA;AAAA,EAIU,SAAS,KAA+B,GAAgB,GAAW,OAAO,OAAa;AAC/F,QAAI,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO,GAAG,KAAK,IAAI,EAAE,EAAE,IAAI,GAAG,KAAK,IAAI,EAAE,EAAE,IAAI,GAAG,GAAG,OAAO,KAAK,KAAK,IAAI,GAAG,OAAO,IAAI,KAAK,KAAK,GAAG,IAAI;AAAA,EACrI;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,MAAM,WAAW;AACxB,YAAMD,OAAM,KAAK,SAAS,QAAQ;AAClC,UAAI,CAACA,KAAK;AACV,oBAAc,KAAK,KAAK,OAAO,KAAK,MAAM,WAAWA,KAAI,GAAGA,KAAI,CAAC;AACjE,WAAK,iBAAiB,KAAKA,KAAI,GAAGA,KAAI,CAAC;AACvC;AAAA,IACF;AACA,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG;AACR,UAAM,EAAE,MAAM,IAAI;AAClB,QAAI,KAAK;AACT,QAAI,UAAU;AACd,QAAI,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG;AAC1D,QAAI,KAAK;AACT,UAAM,OAAO,UAAU,MAAM,IAAI;AACjC,QAAI,MAAM,kBAAkB,MAAM,oBAAoB,GAAG;AAEvD,WAAK,QAAQ,CAAC,EAAE,KAAK,EAAE,GAAG,MAAM;AAC9B,YAAI,YAAY,UAAU,IAAI,OAAO,MAAM,iBAAiB;AAC5D,YAAI,UAAU;AACd,aAAK,SAAS,KAAK,GAAG,CAAC;AACvB,YAAI,IAAI,EAAG,MAAK,SAAS,KAAK,GAAG,KAAK,IAAI,CAAC,EAAG,GAAG,IAAI;AACrD,YAAI,KAAK;AAAA,MACX,CAAC;AAAA,IACH;AACA,eAAW,EAAE,KAAK,EAAE,KAAK,MAAM;AAC7B,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,IAAI,OAAO,WAAW,IAAI,OAAO,WAAW,QAAQ,CAAC;AAClG,UAAI,UAAU;AACd,WAAK,SAAS,KAAK,GAAG,CAAC;AACvB,UAAI,OAAO;AAAA,IACb;AACA,UAAM,OAAO,QAAQ,CAAC,OAAO,MAAM;AACjC,UAAI,CAAC,MAAM,QAAS;AACpB,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,MAAM,OAAO,WAAW,MAAM,OAAO,WAAW,QAAQ,CAAC;AACtG,YAAM,IAAI,KAAK,GAAG,GAAG,GAAG,CAAC;AACzB,oBAAc,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,CAAC;AAChE,oBAAc,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,OAAO,CAAC;AAAA,IAClE,CAAC;AACD,eAAW,OAAO,MAAM,MAAM;AAC5B,UAAI,CAAC,IAAI,WAAW,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,EAAG;AACjD,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,IAAI,OAAO,WAAW,IAAI,OAAO,WAAW,QAAQ,CAAC;AAClG,oBAAc,KAAK,EAAE,QAAQ,KAAK,OAAO,GAAG,GAAG,CAAC;AAAA,IAClD;AACA,QAAI,QAAQ;AAAA,EACd;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,YAAYD,cAAa,KAAK,MAAM,SAAS;AACnD,QAAI,KAAK,MAAM,WAAW;AACxB,YAAMC,OAAM,KAAK,SAAS,QAAQ;AAClC,aAAO,CAAC,CAACA,SAAQ,aAAa,OAAO,WAAW,KAAK,MAAM,WAAWA,KAAI,GAAGA,KAAI,CAAC,KAAK,KAAK,gBAAgB,OAAO,WAAWA,KAAI,GAAGA,KAAI,CAAC;AAAA,IAC5I;AACA,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG,QAAO;AACf,QAAI,MAAM,IAAI,EAAE,OAAO,aAAa,MAAM,IAAI,EAAE,QAAQ,aAAa,MAAM,IAAI,EAAE,MAAM,aAAa,MAAM,IAAI,EAAE,SAAS,UAAW,QAAO;AAC3I,eAAW,CAAC,GAAG,KAAK,KAAK,KAAK,MAAM,OAAO,QAAQ,GAAG;AACpD,UAAI,CAAC,MAAM,QAAS;AACpB,YAAM,IAAI,KAAK,GAAG,GAAG,GAAG,CAAC;AACzB,UAAI,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK,aAAa,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK,UAAW,QAAO;AAAA,IAC3F;AACA,eAAW,OAAO,KAAK,MAAM,MAAM;AACjC,UAAI,IAAI,WAAW,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,kBAAkB,OAAO,EAAE,QAAQ,KAAK,OAAO,GAAG,GAAG,CAAC,KAAK,UAAW,QAAO;AAAA,IAChI;AAGA,UAAM,KAAK,KAAK,IAAI,EAAE,EAAE,KAAK;AAC7B,UAAM,KAAK,KAAK,IAAI,EAAE,EAAE,KAAK;AAC7B,UAAM,QAAQ,KAAK,OAAO,MAAM,IAAI,EAAE,OAAO,KAAK,KAAK,MAAM,IAAI,EAAE,OAAO,KAAK,EAAE;AACjF,WAAO,UAAU,KAAK,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,QAAQ,CAAC,KAAK,YAAY,KAAK,IAAI,IAAI,EAAE,CAAC;AAAA,EACvG;AAAA;AAAA,EAGU,gBAAgB,QAAe,YAAoB,IAAW,IAAoB;AAC1F,WAAO;AAAA,EACT;AACF;AAIO,IAAM,aAAN,cAAyB,eAAqC;AAAA,EAC1D,OAAO;AAAA,EAEG,eAAqC;AACtD,WAAO,EAAE,GAAG,aAAa,GAAG,YAAY,MAAM,YAAY,KAAK;AAAA,EACjE;AAAA,EAEmB,aAAa,OAAqE;AACnG,WAAO,YAAY,OAAO,KAAK,aAAa,CAAC;AAAA,EAC/C;AAAA,EAES,WAAW,SAAyB;AAC3C,UAAM,WAAW,OAAO;AACxB,SAAK,UAAU;AAAA,EACjB;AAAA,EAES,aAAa,OAAe,QAAsB;AACzD,UAAM,aAAa,OAAO,MAAM;AAChC,SAAK,UAAU;AAAA,EACjB;AAAA,EAES,WAAW,OAA4C;AAC9D,UAAM,WAAW,KAAK;AACtB,QAAI,gBAAgB,MAAO,MAAK,UAAU;AAAA,EAC5C;AAAA;AAAA,EAGmB,iBAAiB,KAA+B,GAAU,GAAgB;AAC3F,QAAI,KAAK;AACT,gBAAY,KAAK,KAAK,KAAK;AAC3B,kBAAc,KAAK,GAAG,CAAC;AACvB,kBAAc,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC;AACzD,QAAI,QAAQ;AAAA,EACd;AAAA,EAEmB,gBAAgB,OAAc,WAAmB,GAAU,GAAmB;AAC/F,WAAO,kBAAkB,OAAO,GAAG,CAAC,KAAK,aAAa,kBAAkB,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC,KAAK;AAAA,EAC5H;AAAA;AAAA;AAAA,EAIQ,UAAU,UAAoB,GAAW,GAAW,MAA6B;AACvF,UAAM,KAAK,KAAK,cAAc,GAAG,QAAQ;AACzC,UAAM,KAAK,KAAK,cAAc,GAAG,QAAQ;AACzC,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,UAAM,KAAK,SAAS,QAAQ,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;AACxD,WAAO,OAAO,OAAO,OAAO,KAAK,IAAI,KAAK,EAAE,KAAK,IAAI,KAAK,IAAI,IAAI;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAkB;AAExB,QAAI,KAAK,MAAM,UAAW;AAC1B,UAAM,WAAW,KAAK,YAAY;AAClC,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,QAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAG;AAC3B,UAAM,OAAO,SAAS,YAAY,EAAE,MAAM,EAAE,IAAI;AAChD,QAAI,SAAS,QAAQ,SAAS,EAAG;AACjC,QAAI,SAAS,KAAK,MAAM;AACxB,QAAI,WAAW,QAAQ,EAAE,SAAS,IAAI;AACpC,eAAS,KAAK,UAAU,UAAU,GAAG,GAAG,IAAI;AAC5C,UAAI,WAAW,QAAQ,EAAE,SAAS,GAAI;AACtC,YAAM,WAAW,EAAE,YAAY,OAAO,CAAC;AAAA,IACzC;AACA,UAAM,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK,KAAK,SAAS,KAAK,IAAI,IAAI;AAC7E,QAAI,UAAU,EAAE,MAAO,OAAM,aAAa,GAAG,EAAE,GAAG,GAAG,MAAM,CAAC;AAAA,EAC9D;AAAA,EAES,MAAM,KAA+B,UAA0B;AACtE,UAAM,MAAM,KAAK,QAAQ;AACzB,QAAI,CAAC,KAAK,MAAM,cAAc,KAAK,MAAM,UAAW;AACpD,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,UAAM,OAAO,KAAK,IAAI,SAAS,YAAY,EAAE,MAAM,EAAE,IAAI,IAAI;AAC7D,QAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,SAAS,QAAQ,SAAS,EAAG;AACnD,UAAM,QAAQ,KAAK,IAAI,EAAE,QAAQ,EAAE,KAAK;AACxC,UAAM,SAAS,QAAQ,QAAQ,KAAK,IAAI,IAAI,GAAG,QAAQ,CAAC,CAAC;AACzD,UAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,KAAK,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,MAAM;AACtF,UAAM,MAAM,KAAK,MAAM,OAAO,CAAC,GAAG,SAAS,KAAK,MAAM;AACtD,eAAW,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,GAAG,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,IAAI,GAAG,EAAE,OAAO,UAAU,UAAU,MAAM,CAAC;AAAA,EAC/I;AACF;AAGO,IAAM,kBAAN,cAA8B,eAAgC;AAAA,EAC1D,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,aAAa;AAAA,EACtB;AAAA,EAEmB,aAAa,OAA2D;AACzF,WAAO,YAAY,OAAO,KAAK,aAAa,CAAC;AAAA,EAC/C;AAAA,EAEmB,QAAQ,UAAmD;AAC5E,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AACzC,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,UAAM,OAAO,KAAK,IAAI,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9D,QAAI,SAAS,EAAG,QAAO;AACvB,WAAO,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,GAAG,EAAE,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE;AAAA,EAC1G;AACF;AAYA,IAAM,aAAa,MAEf;AAAA,EACE,CAAC,IAAI,GAAG,SAAS;AAAA,EACjB,CAAC,IAAI,GAAG,SAAS;AAAA,EACjB,CAAC,IAAI,GAAG,SAAS;AAAA,EACjB,CAAC,IAAI,GAAG,SAAS;AAAA,EACjB,CAAC,GAAG,SAAS;AAAA,EACb,CAAC,GAAG,SAAS;AAAA,EACb,CAAC,GAAG,SAAS;AAAA,EACb,CAAC,GAAG,SAAS;AAAA,EACb,CAAC,GAAG,SAAS;AACf,EACA,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,EAAE,OAAO,SAAS,MAAM,OAAO,OAAO,GAAG,OAAO,QAAQ,EAAE;AAGhF,IAAM,eAAe,CAAC,UAA2B,SAAS,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC;AAGnH,IAAM,UAAN,cAAsB,QAAsB;AAAA,EACxC,OAAO;AAAA,EAEG,eAA6B;AAC9C,WAAO,EAAE,QAAQ,WAAW,GAAG,gBAAgB,MAAM,mBAAmB,KAAK,YAAY,KAAK;AAAA,EAChG;AAAA;AAAA,EAGmB,aAAa,OAAqD;AACnF,UAAM,OAAO;AACb,UAAM,MAA+B,CAAC;AACtC,eAAW,OAAO,OAAO,KAAK,KAAK,aAAa,CAAC,EAAG,KAAI,OAAO,KAAM,KAAI,GAAG,IAAI,KAAK,GAAG;AACxF,QAAI,OAAO,KAAK,eAAe,aAAa,EAAE,oBAAoB,MAAO,KAAI,iBAAiB,KAAK;AACnG,WAAO;AAAA,EACT;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,QAAQ,iBAAiB,KAAK,OAAO,MAAM,GAAG,gBAAgB,MAAM;AAAA,EACtG;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,KAAK,UAA8E;AAC3F,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,EAAG,QAAO,CAAC;AAC1D,UAAM,KAAK,GAAG,IAAI,GAAG;AACrB,UAAM,KAAK,GAAG,IAAI,GAAG;AACrB,WAAO,KAAK,MAAM,OACf,IAAI,CAAC,OAAO,OAAO,EAAE,OAAO,OAAO,cAAc,OAAO,CAAC,EAAE,EAAE,EAC7D,OAAO,CAAC,MAAM,EAAE,MAAM,WAAW,EAAE,MAAM,QAAQ,CAAC,EAClD,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,IAAI,GAAG,cAAc,IAAI,EAAE,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,KAAK,EAAE,MAAM,MAAM,GAAG,SAAS,OAAO,SAAS,QAAQ,OAAO,IAAI,EAAE,EAAE,EAAE;AAAA,EACvJ;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,OAAO,KAAK,KAAK,QAAQ;AAC/B,QAAI,KAAK,MAAM,kBAAkB,KAAK,MAAM,oBAAoB,GAAG;AAEjE,YAAM,UAAU,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,QAAQ,EAAE,MAAM,KAAK;AACtE,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,YAAI,KAAK;AACT,YAAI,YAAY,UAAU,QAAQ,CAAC,EAAG,OAAO,KAAK,MAAM,iBAAiB;AACzE,YAAI,UAAU;AACd,YAAI,OAAO,QAAQ,CAAC,EAAG,EAAE,GAAG,QAAQ,CAAC,EAAG,EAAE,CAAC;AAC3C,YAAI,OAAO,QAAQ,IAAI,CAAC,EAAG,EAAE,GAAG,QAAQ,IAAI,CAAC,EAAG,EAAE,CAAC;AACnD,YAAI,OAAO,QAAQ,CAAC,EAAG,EAAE,GAAG,QAAQ,CAAC,EAAG,EAAE,CAAC;AAC3C,YAAI,UAAU;AACd,YAAI,KAAK;AACT,YAAI,QAAQ;AAAA,MACd;AAAA,IACF;AACA,eAAW,OAAO,MAAM;AACtB,UAAI,KAAK;AACT,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,IAAI,OAAO,WAAW,IAAI,MAAM,SAAS,KAAK,MAAM,WAAW,WAAW,IAAI,MAAM,SAAS,KAAK,MAAM,UAAU,CAAC;AAChK,oBAAc,KAAK,IAAI,GAAG,IAAI,CAAC;AAC/B,UAAI,QAAQ;AACZ,UAAI,KAAK,MAAM,WAAY,YAAW,KAAK,aAAa,IAAI,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,EAAE,IAAI,GAAG,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,IAAI,MAAM,GAAG,EAAE,OAAO,QAAQ,CAAC;AAAA,IACvK;AAAA,EACF;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,WAAO,KAAK,KAAK,QAAQ,EAAE,KAAK,CAAC,QAAQ,kBAAkB,OAAO,IAAI,GAAG,IAAI,CAAC,KAAKD,cAAa,IAAI,MAAM,SAAS,KAAK,MAAM,SAAS,CAAC;AAAA,EAC1I;AACF;;;AC/nBO,SAAS,UAAU,OAAuB;AAC/C,SAAO,MAAM,QAAQ,CAAC;AACxB;;;ACFA,IAAM,SAAS;AACf,IAAM,OAAO;AAEb,IAAM,aAAa;AAKZ,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,IAAM,iBAAiB,CAAC,WAAW,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI;AAgChG,IAAM,gBAAyC,eAAe,OAAO,CAAC,SAAS,SAAS,UAAU,SAAS,MAAM;AAwB1G,IAAM,eAAN,cAA2B,QAAuB;AAAA,EAC9C,OAAe;AAAA,EAEL,eAA8B;AAC/C,WAAO;AAAA,MACL,aAAa;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,cAAc;AAAA,MACd,aAAa,UAAU,QAAQ,UAAU;AAAA,MACzC,WAAW,UAAU,MAAM,UAAU;AAAA,MACrC,YAAY;AAAA,MACZ,OAAO,CAAC,GAAG,aAAa;AAAA,MACxB,SAAS;AAAA,MACT,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA,EAImB,cAAc,OAAgD;AAC/E,UAAM,QAAQ,MAAM,YAAY,OAAO,cAAc,OAAO,CAAC,SAAS,SAAS,cAAc,SAAS,UAAU,IAAI,CAAC,GAAG,aAAa;AACrI,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,OAAO,iBAAiB,MAAM,GAAI,cAAc,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,EAAG;AAAA,EAChH;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,UAAmB;AAC3B,WAAO;AAAA,EACT;AAAA,EAEU,MAAM,UAMP;AACP,UAAM,CAAC,OAAO,QAAQ,IAAI,IAAI,KAAK,aAAa,QAAQ;AACxD,QAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAM,QAAO;AACvC,UAAM,OAAO,KAAK,IAAI,MAAM,GAAG,OAAO,CAAC;AACvC,UAAM,QAAQ,KAAK,IAAI,MAAM,GAAG,OAAO,CAAC;AACxC,QAAI,QAAQ,OAAO,EAAG,QAAO;AAC7B,WAAO,EAAE,MAAM,OAAO,QAAQ,MAAM,GAAG,SAAS,OAAO,GAAG,OAAO,KAAK,EAAE;AAAA,EAC1E;AAAA,EAEU,QAA8B;AACtC,UAAM,CAAC,OAAO,QAAQ,IAAI,IAAI,KAAK;AACnC,QAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAM,QAAO;AACvC,UAAM,EAAE,aAAa,MAAM,aAAa,SAAS,IAAI,KAAK;AAC1D,UAAM,MAAM,KAAK,MAAM,UAAU,IAAI,KAAK,MAAM,UAAU;AAC1D,UAAM,QAAQ,KAAK,QAAQ;AAE3B,UAAM,WAAW,KAAK,IAAI,OAAO,QAAQ,MAAM,KAAK;AACpD,UAAM,WAAW,KAAK,IAAI,MAAM,QAAQ,KAAK,KAAK;AAClD,UAAM,WAAW,gBAAgB,YAAa,cAAc,OAAQ,MAAM;AAG1E,UAAM,UAAU,WAAW,IAAI,WAAW,WAAW,MAAM;AAC3D,UAAM,SAAS,MAAM,QAAQ,IAAK,cAAc,KAAK,IAAI,GAAG,QAAQ,IAAK,MAAM,QAAQ,MAAM;AAC7F,UAAM,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,MAAM,CAAC;AAEjD,UAAM,aAAa,cAAc,WAAW,MAAM;AAClD,UAAM,aAAa,cAAc,WAAW,MAAM;AAClD,UAAMG,SAAQ,WAAW,IAAI,WAAW,WAAW;AAInD,UAAM,OAAO,QAAQ,KAAK;AAC1B,UAAM,OAAO,KAAK,KAAK;AACvB,UAAM,OAAO,KAAK,IAAI,OAAO,MAAM,IAAI,GAAG,OAAO,OAAO,IAAI,CAAC;AAC7D,UAAM,KAAK,KAAK,IAAI,OAAO,MAAM,IAAI,GAAG,OAAO,OAAO,IAAI,CAAC;AAC3D,QAAI,MAAM;AACV,QAAI,SAAS;AACb,QAAI,YAA2B;AAC/B,eAAW,OAAO,MAAM;AACtB,YAAM,IAAI,OAAO,IAAI,IAAI;AACzB,UAAI,IAAI,KAAM;AACd,UAAI,IAAI,GAAI;AACZ,kBAAY,IAAI;AAChB,YAAM,QAAQ,QAAQ,IAAI,OAAO,OAAO,QAAQ,IAAI,QAAQ,OAAO;AACnE,YAAM,QAAQ,QAAQ,IAAI,QAAQ,KAAK,QAAQ,IAAI,OAAO,KAAK;AAC/D,UAAI,OAAO;AACT,cAAM,CAAC,WAAW,MAAM;AACxB,iBAAS;AACT;AAAA,MACF;AACA,UAAI,OAAO;AACT,cAAM,WAAW,MAAM;AACvB,iBAAS;AACT;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,QAAQ;AAEX,YAAM,YAAY,cAAc,KAAK,SAAS,KAAK,KAAK,SAAS,CAAC,EAAG,QAAQ;AAC7E,YAAM,aAAa,OAAO,IAAI,QAAQ,YAAY,MAAM,SAAS,MAAM;AAAA,IACzE;AAEA,WAAO;AAAA,MACL;AAAA,MACA,OAAAA;AAAA,MACA;AAAA,MACA,WAAW,MAAM,UAAU,IAAK,WAAW,MAAM,QAAS,MAAM;AAAA,MAChE;AAAA,MACA,WAAW,MAAM,UAAU,IAAK,WAAW,MAAM,QAAS,MAAM;AAAA,MAChE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGU,QAAQ,KAAqB;AACrC,UAAM,YAAY,KAAK,MAAM;AAC7B,QAAI,cAAc,UAAW,QAAO,OAAO,MAAM,IAAI,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC;AAC/E,WAAO,IAAI,QAAQ,OAAO,SAAS,CAAC;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAS,MAAmB,QAAgB,SAAiB,QAAgB,IAAoB;AACvG,UAAM,QAAQ,CAAC,SAA2B,KAAK,MAAM,MAA4B,SAAS,IAAI;AAC9F,UAAM,UAAU,KAAK,MAAM;AAC3B,UAAM,OAAO,KAAK,SAAS;AAC3B,UAAM,OAAiB,CAAC;AACxB,QAAI,MAAM,GAAG,IAAI,aAAa,EAAG,MAAK,KAAK,KAAK,YAAY,MAAM,CAAC;AACnE,QAAI,MAAM,GAAG,IAAI,eAAe,EAAG,MAAK,KAAK,IAAI,QAAQ,QAAQ,CAAC,CAAC,IAAI;AACvE,QAAI,MAAM,GAAG,IAAI,YAAY,KAAK,QAAQ,OAAO,EAAG,MAAK,KAAK,OAAO,KAAK,MAAM,SAAS,IAAI,CAAC,CAAC;AAC/F,UAAM,QAAkB,CAAC;AACzB,QAAI,KAAK,OAAQ,OAAM,KAAK,UAAU,KAAK,KAAK,GAAG,IAAI,GAAG,SAAS,OAAO,WAAW,MAAM,KAAK,KAAK,KAAK,GAAG,CAAC,EAAE;AAChH,QAAI,MAAM,GAAG,IAAI,QAAQ,EAAG,OAAM,KAAK,UAAU,UAAU,MAAM,IAAI,WAAW,UAAU,MAAM,CAAC,EAAE;AACnG,QAAI,MAAM,GAAG,IAAI,IAAI,EAAG,OAAM,KAAK,UAAU,UAAU,EAAE,IAAI,QAAQ,UAAU,EAAE,CAAC,EAAE;AACpF,WAAO,MAAM,KAAK,UAAU,WAAQ,IAAI;AAAA,EAC1C;AAAA;AAAA,EAGQ,SAAS,GAA0B;AACzC,UAAM,QAAQ,CAAC,SAAgC,KAAK,MAAM,MAAM,SAAS,IAAI;AAC7E,UAAM,UAAU,KAAK,MAAM;AAC3B,UAAM,QAAkB,CAAC;AACzB,QAAI,MAAM,aAAa,EAAG,OAAM,KAAK,UAAU,UAAU,EAAE,GAAG,IAAI,GAAG,EAAE,SAAS,eAAe,UAAU,KAAK,UAAU,EAAE,GAAG,CAAC,EAAE;AAChI,QAAI,MAAM,KAAK,EAAG,OAAM,KAAK,UAAU,KAAK,QAAQ,EAAE,GAAG,IAAI,QAAQ,KAAK,QAAQ,EAAE,GAAG,CAAC,EAAE;AAC1F,QAAI,MAAM,iBAAiB,EAAG,OAAM,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC,IAAI,sBAAsB,EAAE,MAAM,QAAQ,CAAC,CAAC,EAAE;AAClH,WAAO,MAAM,KAAK,UAAU,WAAQ,IAAI;AAAA,EAC1C;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG;AACR,UAAM,CAAC,OAAO,QAAQ,IAAI,IAAI,KAAK;AACnC,QAAI,KAAK;AACT,UAAM,YAAY,UAAU,KAAK,MAAM,aAAa,CAAC;AACrD,UAAM,UAAU,UAAU,KAAK,MAAM,WAAW,CAAC;AACjD,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,SAAS,EAAE,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,OAAO,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC;AACpG,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,SAAS,EAAE,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,KAAK,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC;AAChG,QAAI,QAAQ;AAEZ,QAAI,KAAK;AACT,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,cAAc;AAClB,kBAAc,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,EAAE,QAAQ,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAC5E,QAAI,cAAc;AAClB,kBAAc,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,EAAE,MAAM,CAAC;AACxE,QAAI,cAAc,KAAK,MAAM;AAC7B,kBAAc,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,EAAE,OAAO,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC;AAC1E,QAAI,QAAQ;AAEZ,UAAM,IAAI,KAAK,MAAM;AACrB,QAAI,MAAM,KAAK,MAAM,mBAAmB,KAAK,UAAU,WAAW;AAGhE,YAAM,OAAO,EAAE,OAAO,EAAE,SAAS;AACjC,YAAM,aAAa,KAAK,SAAS,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,KAAK,MAAM,UAAU,IAAI,KAAK,MAAM,UAAU,EAAE;AACpJ,YAAM,WAAW,KAAK,SAAS,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,OAAO,KAAK,MAAM,UAAU,IAAI,KAAK,MAAM,UAAU,EAAE;AACnJ,YAAM,YAAY,KAAK,SAAS,CAAC;AAGjC,UAAI,WAAY,YAAW,KAAK,YAAY,EAAE,GAAG,KAAK,GAAG,EAAE,QAAQ,GAAG,KAAK,OAAO,EAAE,OAAO,UAAU,YAAY,UAAU,CAAC;AAC5H,UAAI,SAAU,YAAW,KAAK,UAAU,EAAE,GAAG,KAAK,GAAG,EAAE,MAAM,GAAG,KAAK,OAAO,EAAE,OAAO,UAAU,YAAY,QAAQ,CAAC;AACpH,UAAI,UAAW,YAAW,KAAK,WAAW,EAAE,GAAG,KAAK,GAAG,EAAE,OAAO,GAAG,KAAK,OAAO,EAAE,OAAO,UAAU,YAAY,UAAU,CAAC;AAAA,IAC3H;AAEA,QAAI,KAAK,MAAM,YAAY;AACzB,iBAAW,KAAK,KAAK,YAAY,OAAQ,KAAK,GAAG,EAAE,GAAG,EAAE,QAAQ,GAAG,GAAG,EAAE,QAAQ,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,UAAU,CAAC;AAC1H,iBAAW,KAAK,KAAK,YAAY,KAAM,KAAK,GAAG,EAAE,GAAG,EAAE,QAAQ,GAAG,GAAG,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,QAAQ,CAAC;AAGpH,iBAAW,KAAK,KAAK,YAAY,MAAO,KAAK,GAAG,EAAE,GAAG,EAAE,QAAQ,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,KAAK,MAAM,UAAU,CAAC;AAAA,IACrI;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKS,iBAAiB,UAAoC;AAC5D,UAAM,SAAS,MAAM,iBAAiB,QAAQ;AAC9C,UAAM,OAAO,OAAO,KAAK,CAAC,UAAU,MAAM,UAAU,CAAC;AACrD,WAAO,OAAO,OAAO,IAAI,CAAC,UAAW,MAAM,UAAU,IAAI,EAAE,GAAG,OAAO,GAAG,KAAK,EAAE,IAAI,KAAM,IAAI;AAAA,EAC/F;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK;AACjD,UAAM,SAAS,KAAK,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK;AACpD,WAAO,MAAM,KAAK,EAAE,OAAO,KAAK,MAAM,KAAK,EAAE,QAAQ,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,SAAS;AAAA,EACtG;AACF;AAGO,IAAM,gBAAN,cAA4B,aAAa;AAAA,EAC5B,OAAO;AAAA,EAEN,UAAmB;AACpC,WAAO;AAAA,EACT;AACF;AAGA,SAAS,UACP,KACA,MACA,IACA,OACA,QACyD;AACzD,MAAI,KAAK;AACT,MAAI,OAAO,OAAO,KAAK;AACvB,MAAI,YAAY,CAAC,CAAC;AAClB,QAAM,QAAQ,IAAI,YAAY,IAAI,EAAE,QAAQ;AAC5C,QAAM,SAAS,MAAM,WAAW;AAChC,QAAMC,OAAM,EAAE,GAAG,GAAG,IAAI,QAAQ,GAAG,GAAG,GAAG,IAAI,SAAS,GAAG,OAAO,OAAO;AACvE,MAAI,UAAU;AACd,MAAI,UAAUA,KAAI,GAAGA,KAAI,GAAGA,KAAI,OAAOA,KAAI,QAAQ,CAAC;AACpD,MAAI,YAAY,OAAO;AACvB,MAAI,KAAK;AACT,MAAI,OAAO,QAAQ;AACjB,QAAI,cAAc,OAAO;AACzB,QAAI,YAAY;AAChB,QAAI,OAAO;AAAA,EACb;AACA,MAAI,YAAY,OAAO;AACvB,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,SAAS,MAAM,GAAG,GAAG,GAAG,CAAC;AAC7B,MAAI,QAAQ;AACZ,SAAOA;AACT;AAoBO,IAAM,WAAN,cAAuB,QAAuB;AAAA,EAC1C,OAAO;AAAA,EAEG,eAA8B;AAC/C,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,mBAAmB;AAAA,MACnB,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA,EAImB,cAAc,OAAgD;AAC/E,UAAM,UAAkC,EAAE,iBAAiB,WAAW,iBAAiB,QAAQ,mBAAmB,QAAQ,kBAAkB,OAAO;AACnJ,UAAM,UAAU,OAAO,YAAY,OAAO,QAAQ,OAAO,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,EAAE,OAAO,MAAM,CAAC;AAC7F,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,QAAQ;AAAA,EAC7C;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,UAAwC;AAC9C,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,UAAM,QAAQ,KAAK,IAAI,OAAO,EAAE,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;AACrD,UAAM,MAAM,KAAK,IAAI,OAAO,EAAE,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;AACnD,UAAM,KAAK,EAAE,SAAS,EAAE;AACxB,QAAI,SAAS;AACb,eAAW,OAAO,KAAK,KAAK,GAAG;AAC7B,YAAM,IAAI,OAAO,IAAI,IAAI;AACzB,eAAS,KAAK,IAAI,QAAQ,CAAC;AAC3B,UAAI,KAAK,SAAS,IAAI,IAAK;AAC3B,UAAI,KAAK,IAAI,QAAQ,EAAE,QAAQ,IAAI,OAAO,EAAE,MAAO,QAAO;AAAA,IAC5D;AACA,WAAO,SAAS,MAAM,YAAY;AAAA,EACpC;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,gBAAY,KAAK,KAAK,KAAK;AAC3B,kBAAc,KAAK,IAAI,EAAE;AACzB,mBAAe,KAAK,IAAI,IAAI,KAAK,KAAK;AACtC,UAAM,IAAI,KAAK;AACf,UAAM,KAAK,EAAE,SAAS,EAAE;AACxB,cAAU,KAAK,KAAK,YAAY,EAAE,KAAK,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,KAAK,KAAK,KAAK,GAAG,KAAK,OAAO;AAAA,MAC5F,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,QAAQ,EAAE;AAAA,IACZ,CAAC;AACD,cAAU,KAAK,KAAK,YAAY,EAAE,KAAK,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO;AAAA,MAC5F,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,QAAQ,EAAE;AAAA,IACZ,CAAC;AACD,UAAM,UAAU,KAAK,QAAQ;AAC7B,QAAI,SAAS;AACX,YAAM,MAAM,YAAY;AACxB,gBAAU,KAAK,SAAS,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO;AAAA,QAC1E,MAAM,MAAM,EAAE,mBAAmB,EAAE;AAAA,QACnC,MAAM,MAAM,EAAE,mBAAmB,EAAE;AAAA,MACrC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,WAAO,kBAAkB,OAAO,IAAI,EAAE,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,IAAI,CAAC;AAAA,EACrF;AACF;AAgBO,IAAM,SAAN,cAAqB,QAAqB;AAAA,EACtC,OAAO;AAAA,EAEG,eAA4B;AAC7C,WAAO,EAAE,QAAQ,0BAA0B,QAAQ,2BAA2B,gBAAgB,KAAK;AAAA,EACrG;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,UAAM,OAAO,UAAU,KAAK,MAAM;AAClC,SAAK,SAAS,OAAO,EAAE,GAAG,KAAK,QAAQ,QAAQ,MAAM,QAAQ,MAAM,gBAAgB,KAAK,IAAI,EAAE,GAAG,KAAK,QAAQ,gBAAgB,MAAM;AAAA,EACtI;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,IAAI,UAAsF;AAChG,UAAM,CAAC,QAAQ,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AACnD,QAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAI,QAAO;AAClC,UAAM,KAAK,KAAK,MAAM,GAAG,IAAI,OAAO,GAAG,GAAG,IAAI,OAAO,CAAC;AACtD,UAAM,KAAK,KAAK,MAAM,GAAG,IAAI,OAAO,GAAG,GAAG,IAAI,OAAO,CAAC;AACtD,UAAM,KAAK,KAAK,MAAM,GAAG,IAAI,OAAO,GAAG,GAAG,IAAI,OAAO,CAAC;AACtD,UAAM,KAAK,KAAK,MAAM,GAAG,IAAI,OAAO,GAAG,GAAG,IAAI,OAAO,CAAC;AACtD,QAAI,QAAQ,KAAK;AACjB,QAAI,QAAQ,KAAK,GAAI,UAAS,KAAK,KAAK;AACxC,QAAI,QAAQ,CAAC,KAAK,GAAI,UAAS,KAAK,KAAK;AACzC,UAAM,QAAQ;AACd,UAAM,UAAmB,CAAC;AAC1B,aAAS,IAAI,GAAG,KAAK,OAAO,KAAK;AAC/B,YAAM,IAAI,IAAI;AACd,YAAM,QAAQ,KAAK,QAAQ;AAC3B,YAAM,SAAS,MAAM,KAAK,MAAM;AAChC,cAAQ,KAAK,EAAE,GAAG,OAAO,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,GAAG,OAAO,IAAI,KAAK,IAAI,KAAK,IAAI,OAAO,CAAC;AAAA,IACjG;AACA,WAAO,EAAE,QAAQ,IAAI,IAAI,QAAQ;AAAA,EACnC;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,QAAI,CAAC,IAAK;AACV,QAAI,KAAK;AACT,QAAI,KAAK,MAAM,mBAAmB,OAAO;AACvC,YAAM,SAAS,KAAK,MAAM,IAAI,QAAQ,SAAS,CAAC;AAChD,YAAM,OAAO,CAAC,MAAc,IAAY,UAAwB;AAC9D,YAAI,YAAY;AAChB,YAAI,UAAU;AACd,YAAI,OAAO,IAAI,OAAO,GAAG,IAAI,OAAO,CAAC;AACrC,iBAAS,IAAI,MAAM,KAAK,IAAI,IAAK,KAAI,OAAO,IAAI,QAAQ,CAAC,EAAG,GAAG,IAAI,QAAQ,CAAC,EAAG,CAAC;AAChF,YAAI,UAAU;AACd,YAAI,KAAK;AAAA,MACX;AAEA,UAAI,KAAK,MAAM,WAAW,KAAK,MAAM,OAAQ,MAAK,GAAG,IAAI,QAAQ,SAAS,GAAG,KAAK,MAAM,MAAM;AAAA,WACzF;AACH,aAAK,GAAG,QAAQ,KAAK,MAAM,MAAM;AACjC,aAAK,QAAQ,IAAI,QAAQ,SAAS,GAAG,KAAK,MAAM,MAAM;AAAA,MACxD;AAAA,IACF;AACA,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,UAAU;AACd,QAAI,OAAO,IAAI,OAAO,GAAG,IAAI,OAAO,CAAC;AACrC,eAAW,KAAK,IAAI,QAAS,KAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AAChD,QAAI,UAAU;AACd,QAAI,OAAO;AACX,QAAI,QAAQ;AAAA,EACd;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,IAAI,CAAC;AAC1D,QAAI,kBAAkB,OAAO,IAAI,QAAQ,IAAI,QAAQ,CAAC,CAAC,KAAK,UAAW,QAAO;AAC9E,QAAI,kBAAkB,OAAO,IAAI,QAAQ,IAAI,QAAQ,IAAI,QAAQ,SAAS,CAAC,CAAC,KAAK,UAAW,QAAO;AACnG,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,SAAS,GAAG,KAAK;AAC/C,UAAI,kBAAkB,OAAO,IAAI,QAAQ,CAAC,GAAG,IAAI,QAAQ,IAAI,CAAC,CAAC,KAAK,UAAW,QAAO;AAAA,IACxF;AACA,WAAO;AAAA,EACT;AACF;;;ACxhBA,SAASC,cAAa,WAA2B;AAC/C,SAAO,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACtC;AAIO,SAAS,uBAAuB,WAA2B;AAChE,SAAO,aAAa,IAAI,KAAK,IAAI,YAAY,GAAG,EAAE,IAAI;AACxD;AAGA,IAAe,gBAAf,cAAgG,QAAW;AAAA,EACzG,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,OAAO,UAA6B;AAC5C,WAAO,KAAK,aAAa,QAAQ,EAAE,OAAO,CAAC,MAAkB,CAAC,CAAC,CAAC;AAAA,EAClE;AAAA,EAEU,UAAU,KAA+B,QAAiB,QAAuB;AACzF,QAAI,UAAU;AACd,QAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,QAAI,UAAU,OAAO,SAAS,GAAG;AAE/B,eAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;AAC1C,cAAM,QAAQ,OAAO,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK;AAC/C,cAAM,QAAQ,OAAO,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK;AAC/C,YAAI,iBAAiB,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,GAAG,MAAM,IAAI;AAAA,MAC3D;AACA,YAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,UAAI,OAAO,KAAK,GAAG,KAAK,CAAC;AAAA,IAC3B,OAAO;AACL,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,KAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AAAA,IAC7E;AAAA,EACF;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,SAAS,KAAK,OAAO,QAAQ;AACnC,UAAM,YAAYA,cAAa,KAAK,YAAY,CAAC;AACjD,aAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;AAC1C,UAAI,kBAAkB,OAAO,OAAO,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,KAAK,UAAW,QAAO;AAAA,IAC9E;AACA,WAAO;AAAA,EACT;AAAA,EAEU,cAAsB;AAC9B,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AAIA,IAAe,iBAAf,cAAiG,cAAiB;AAAA,EACvG,iBAAiB,WAAqC;AAC7D,WAAO,CAAC;AAAA,EACV;AACF;AAeA,SAAS,UAAU,KAA+B,QAAiB,MAAuB,OAA2B;AACnH,MAAI,KAAK,YAAY,QAAS,gBAAe,KAAK,OAAO,CAAC,GAAI,OAAO,CAAC,GAAI,KAAK;AAC/E,MAAI,KAAK,aAAa,QAAS,gBAAe,KAAK,OAAO,OAAO,SAAS,CAAC,GAAI,OAAO,OAAO,SAAS,CAAC,GAAI,KAAK;AAClH;AAGO,IAAM,QAAN,cAAoB,eAA2B;AAAA,EAC3C,OAAe;AAAA,EAEL,eAA2B;AAC5C,WAAO,EAAE,gBAAgB,OAAO,SAAS,UAAU,UAAU,SAAS;AAAA,EACxE;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,gBAAgB,KAAK,OAAO,cAAc,EAAE;AAAA,EAC9E;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,SAAS,KAAK,OAAO,QAAQ;AACnC,QAAI,OAAO,SAAS,EAAG;AACvB,QAAI,KAAK,MAAM,kBAAkB,KAAK,MAAM,cAAc,GAAG;AAC3D,UAAI,KAAK;AACT,UAAI,YAAY,UAAU,KAAK,MAAM,WAAW,KAAK,MAAM,WAAW;AACtE,WAAK,UAAU,KAAK,QAAQ,IAAI;AAChC,UAAI,UAAU;AACd,UAAI,KAAK;AACT,UAAI,QAAQ;AAAA,IACd;AACA,gBAAY,KAAK,KAAK,KAAK;AAC3B,SAAK,UAAU,KAAK,QAAQ,IAAI;AAChC,QAAI,OAAO;AACX,cAAU,KAAK,QAAQ,KAAK,OAAO,KAAK,KAAK;AAAA,EAC/C;AACF;AAOO,IAAM,cAAN,cAA0B,eAAe;AAAA,EAC5B,OAAO;AAAA,EAEzB,MAAM,KAA+B,UAA0B;AAC7D,UAAM,SAAS,KAAK,OAAO,QAAQ;AACnC,QAAI,OAAO,SAAS,EAAG;AACvB,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,UAAU;AACd,QAAI,WAAW;AACf,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,YAAY,uBAAuB,KAAK,MAAM,SAAS;AAC3D,SAAK,UAAU,KAAK,QAAQ,IAAI;AAChC,QAAI,OAAO;AACX,QAAI,QAAQ;AAAA,EACd;AAAA,EAEmB,cAAsB;AACvC,WAAO,uBAAuB,KAAK,MAAM,SAAS;AAAA,EACpD;AACF;AAGO,IAAM,WAAN,cAAuB,cAA+B;AAAA,EACzC,OAAO;AAAA,EAEN,eAAgC;AACjD,WAAO,EAAE,SAAS,UAAU,UAAU,QAAQ;AAAA,EAChD;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,SAAS,KAAK,OAAO,QAAQ;AACnC,QAAI,OAAO,SAAS,EAAG;AACvB,gBAAY,KAAK,KAAK,KAAK;AAC3B,SAAK,UAAU,KAAK,QAAQ,KAAK;AACjC,QAAI,OAAO;AACX,cAAU,KAAK,QAAQ,KAAK,OAAO,KAAK,KAAK;AAAA,EAC/C;AACF;AAQO,IAAM,WAAN,cAAuB,cAA6B;AAAA,EACvC,OAAO;AAAA,EAEN,eAA8B;AAC/C,WAAO,EAAE,gBAAgB,KAAK;AAAA,EAChC;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,SAAS,KAAK,OAAO,QAAQ;AACnC,QAAI,OAAO,SAAS,EAAG;AACvB,gBAAY,KAAK,KAAK,KAAK;AAC3B,SAAK,UAAU,KAAK,QAAQ,KAAK;AACjC,QAAI,OAAO,SAAS,GAAG;AACrB,UAAI,UAAU;AACd,UAAI,KAAK,MAAM,mBAAmB,SAAS,KAAK,MAAM,cAAc,GAAG;AACrE,YAAI,YAAY,UAAU,KAAK,MAAM,WAAW,KAAK,MAAM,WAAW;AACtE,YAAI,KAAK;AAAA,MACX;AAAA,IACF;AACA,QAAI,OAAO;AAAA,EACb;AAAA,EAES,QAAQ,OAAc,UAA6B;AAC1D,QAAI,MAAM,QAAQ,OAAO,QAAQ,EAAG,QAAO;AAC3C,UAAM,SAAS,KAAK,OAAO,QAAQ;AACnC,QAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,UAAM,YAAYA,cAAa,KAAK,MAAM,SAAS;AACnD,WAAO,kBAAkB,OAAO,OAAO,OAAO,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,KAAK;AAAA,EAC3E;AACF;;;AC/JA,IAAM,aAAa;AACnB,IAAM,UAAU;AAChB,IAAM,UAAU;AAChB,IAAM,UAAU;AAChB,IAAM,UAAU;AAChB,IAAM,aAAa;AACnB,IAAM,WAAW;AACjB,IAAM,cAAc;AACpB,IAAM,oBAAoB;AAC1B,IAAM,YAAY,EAAE,MAAM,GAAG,OAAO,IAAI;AACxC,IAAM,aAAa;AAGnB,IAAM,YAAY;AAClB,IAAM,YAAY;AAGlB,IAAM,UAAU,CAAC,SAA4B,SAAS,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI;AAGxE,SAAS,WAAW,OAA6B,OAA+D;AACrH,QAAM,OAAO,MAAM,MAAM,CAAC,GAAG,UAAU;AACvC,QAAM,KAAK,UAAU,OAAO,OAAO,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC;AACxE,QAAM,YAAY,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM,MAAM,UAAU,CAAC,KAAK,UAAU;AACzF,YAAU,OAAO,IAAI,GAAG,UAAU;AAClC,SAAO,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,MAAM,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC,CAAC,GAAG,UAAU;AACnG;AAGO,SAAS,QAAQ,OAA6B,OAAgE;AACnH,QAAM,OAAO,MAAM,MAAM;AACzB,QAAM,OAAO,MAAM,MAAM,CAAC,GAAG,UAAU;AACvC,QAAM,KAAK,UAAU,OAAO,OAAO,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC;AACxE,QAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM,MAAM,WAAW,CAAC,KAAK,CAAC;AAClF,aAAW,OAAO,IAAI,GAAG,CAAC;AAC1B,QAAM,QAAQ,MAAM,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC;AAC/C,QAAM,OAAO,IAAI,GAAG,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,MAAM,EAAE,CAAC;AAC1D,SAAO,EAAE,OAAO,WAAW;AAC7B;AAGO,SAAS,WAAW,OAA6B,KAA8D;AACpH,MAAI,MAAM,MAAM,UAAU,KAAK,MAAM,KAAK,OAAO,MAAM,MAAM,OAAQ,QAAO;AAC5E,SAAO,EAAE,OAAO,MAAM,MAAM,OAAO,CAAC,GAAG,MAAM,MAAM,GAAG,GAAG,YAAY,MAAM,WAAW,OAAO,CAAC,GAAG,MAAM,MAAM,GAAG,EAAE;AACpH;AAGO,SAAS,cAAc,OAA6B,KAA6D;AACtH,QAAM,OAAO,MAAM,MAAM,CAAC,GAAG,UAAU;AACvC,MAAI,QAAQ,KAAK,MAAM,KAAK,OAAO,KAAM,QAAO;AAChD,SAAO,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,MAAM,MAAM,GAAG,CAAC,GAAG,WAAW,MAAM,UAAU,OAAO,CAAC,GAAG,MAAM,MAAM,GAAG,EAAE;AACpI;AAIO,SAAS,SAAS,OAA6B,MAAiB,WAAW,OAAkB;AAClG,QAAM,OAAO,MAAM,MAAM;AACzB,QAAM,OAAO,MAAM,MAAM,CAAC,GAAG,UAAU;AACvC,QAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,IAAI;AACrC,QAAM,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,WAAW,QAAQ,IAAI,MAAM;AACvE,SAAO,EAAE,KAAK,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK;AACtD;AAYO,IAAM,YAAN,cAAwB,QAAoB;AAAA,EACxC,OAAO;AAAA,EAEG,eAA2B;AAC5C,WAAO;AAAA,MACL,OAAO;AAAA,QACL,CAAC,IAAI,IAAI,EAAE;AAAA,QACX,CAAC,IAAI,IAAI,EAAE;AAAA,QACX,CAAC,IAAI,IAAI,EAAE;AAAA,MACb;AAAA,MACA,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,WAAW,CAAC;AAAA,MACZ,YAAY,CAAC;AAAA,MACb,WAAW;AAAA,IACb;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKmB,cAAc,OAAgD;AAE/E,QAAI,EAAE,WAAW,OAAQ,MAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE;AACrF,QAAI,EAAE,eAAe,OAAQ,MAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,KAAK;AAC7E,UAAM,OAAO,KAAK,OAAO,MAAM,CAAC,GAAG,UAAU;AAC7C,UAAM,YAAY,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM,KAAK,OAAO,UAAU,CAAC,KAAK,EAAE;AACvF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,WAAW,CAAC,EAAE;AACzD,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,WAAW,UAAU,KAAK,OAAO,WAAW,IAAI,EAAE;AAAA,EACpF;AAAA,EAES,WAAW,OAAkC;AACpD,UAAM,WAAW,aAAa,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAIQ,eAAiC;AAAA;AAAA;AAAA,EAIzC,IAAI,cAAgC;AAClC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,SAAS,MAA8B;AACrC,SAAK,eAAe;AACpB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGQ,QAAQ,KAAa,KAAqB;AAChD,UAAM,OAAO,KAAK;AAClB,UAAM,QAAQ,KAAK;AACnB,QAAI,SAAS,QAAQ,KAAK,QAAQ,OAAO,KAAK,QAAQ,IAAK,QAAO,MAAM;AACxE,WAAO,KAAK,MAAM,MAAM,GAAG,IAAI,GAAG,KAAK;AAAA,EACzC;AAAA;AAAA,EAGA,UAAU,MAAyB;AACjC,WAAO,KAAK,MAAM,MAAM,KAAK,GAAG,IAAI,KAAK,GAAG,KAAK;AAAA,EACnD;AAAA;AAAA,EAIQ,aAAqB;AAC3B,WAAO,KAAK,MAAM,KAAK,MAAM,WAAW,cAAc,EAAE,IAAI;AAAA,EAC9D;AAAA,EAEQ,SAAS,GAAmB;AAClC,QAAI,KAAK,MAAM,UAAW,QAAO,KAAK,IAAI,SAAS,KAAK,MAAM,UAAU,CAAC,KAAK,UAAU;AACxF,WAAO,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,KAAK,MAAM,UAAU,CAAC,KAAK,UAAU,CAAC;AAAA,EACnF;AAAA;AAAA,EAGQ,WAAW,GAAmB;AACpC,UAAM,KAAK,KAAK,WAAW;AAC3B,UAAM,OAAO,KAAK,MAAM,MAAM,CAAC,GAAG,UAAU;AAC5C,QAAI,QAAQ;AACZ,aAAS,IAAI,GAAG,IAAI,MAAM,IAAK,SAAQ,KAAK,IAAI,OAAO,QAAQ,KAAK,QAAQ,GAAG,CAAC,CAAC,EAAE,MAAM;AACzF,WAAO,UAAU,IAAI,KAAK,WAAW,IAAI,oBAAoB,QAAQ,KAAK,WAAW;AAAA,EACvF;AAAA,EAEQ,UAAU,GAAmB;AACnC,QAAI,KAAK,MAAM,UAAW,QAAO,KAAK,IAAI,SAAS,KAAK,MAAM,WAAW,CAAC,KAAK,SAAS;AACxF,WAAO,KAAK,IAAI,KAAK,WAAW,CAAC,GAAG,KAAK,MAAM,WAAW,CAAC,KAAK,CAAC;AAAA,EACnE;AAAA;AAAA,EAGQ,UAA0C;AAChD,UAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,UAAM,OAAO,KAAK,MAAM,MAAM,CAAC,GAAG,UAAU;AAC5C,UAAM,KAAK,CAAC,CAAC;AACb,aAAS,IAAI,GAAG,IAAI,MAAM,IAAK,IAAG,KAAK,GAAG,CAAC,IAAK,KAAK,SAAS,CAAC,CAAC;AAChE,UAAM,KAAK,CAAC,CAAC;AACb,aAAS,IAAI,GAAG,IAAI,MAAM,IAAK,IAAG,KAAK,GAAG,CAAC,IAAK,KAAK,UAAU,CAAC,CAAC;AACjE,WAAO,EAAE,IAAI,GAAG;AAAA,EAClB;AAAA,EAEU,MAAM,UAAoF;AAClG,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,EAAE,IAAI,GAAG,IAAI,KAAK,QAAQ;AAChC,QAAI,GAAG,SAAS,KAAK,GAAG,SAAS,EAAG,QAAO;AAC3C,WAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,GAAG,GAAG,SAAS,CAAC,GAAI,QAAQ,GAAG,GAAG,SAAS,CAAC,EAAG;AAAA,EACjF;AAAA;AAAA;AAAA,EAIQ,WAAW,UAA2D;AAC5E,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,EAAE,IAAI,GAAG,IAAI,KAAK,QAAQ;AAChC,WAAO,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE;AAAA,EAC1F;AAAA;AAAA,EAGA,OAAO,OAAc,UAAwH;AAC3I,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,EAAE,IAAI,GAAG,IAAI,KAAK,QAAQ;AAChC,UAAM,KAAK,MAAM,IAAI,EAAE;AACvB,UAAM,KAAK,MAAM,IAAI,EAAE;AACvB,QAAI,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE,SAAS,KAAK,EAAE,OAAQ,QAAO;AAC9D,QAAI,MAAM;AACV,WAAO,MAAM,GAAG,SAAS,KAAK,MAAM,GAAG,MAAM,CAAC,EAAI;AAClD,QAAI,MAAM;AACV,WAAO,MAAM,GAAG,SAAS,KAAK,MAAM,GAAG,MAAM,CAAC,EAAI;AAClD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,GAAI,GAAG,EAAE,IAAI,GAAG,GAAG,GAAI,OAAO,GAAG,MAAM,CAAC,IAAK,GAAG,GAAG,GAAI,QAAQ,GAAG,MAAM,CAAC,IAAK,GAAG,GAAG,EAAG;AAAA,IAChH;AAAA,EACF;AAAA;AAAA;AAAA,EAIQ,eAAe,MAAiB,UAAwF;AAC9H,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,EAAE,IAAI,GAAG,IAAI,KAAK,QAAQ;AAChC,UAAM,OAAO,GAAG,KAAK,GAAG;AACxB,UAAM,QAAQ,GAAG,KAAK,MAAM,CAAC;AAC7B,UAAM,MAAM,GAAG,KAAK,GAAG;AACvB,QAAI,SAAS,UAAa,UAAU,UAAa,QAAQ,OAAW,QAAO;AAC3E,UAAM,KAAK,KAAK,WAAW;AAG3B,UAAM,SAAS,KAAK,MAAM,EAAE,IAAI,MAAM,WAAW,KAAK,IAAI,CAAC;AAC3D,WAAO,EAAE,GAAG,EAAE,IAAI,OAAO,YAAY,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,QAAQ,OAAO,aAAa,GAAG,YAAY,GAAG;AAAA,EACpH;AAAA,EAES,UAAU,UAA0C;AAC3D,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,KAAK,KAAK,eAAe,MAAM,QAAQ;AAC7C,QAAI,CAAC,GAAI,QAAO;AAChB,UAAM,QAAQ,KAAK,IAAI,GAAG,QAAQ,KAAK,QAAQ,KAAK,KAAK,KAAK,GAAG,CAAC,EAAE,MAAM;AAC1E,WAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,OAAO,OAAO,YAAY,GAAG,YAAY,MAAM,OAAO,KAAK,KAAK,GAAG,OAAO,KAAK,MAAM,cAAc,QAAQ,WAAW,MAAM,OAAO,EAAE;AAAA,EAC5K;AAAA;AAAA,EAIA,MAAM,KAA+B,UAA0B;AAC7D,QAAI,KAAK,MAAM,WAAW;AACxB,WAAK,WAAW,KAAK,QAAQ;AAC7B;AAAA,IACF;AACA,UAAM,OAAO,KAAK,WAAW,QAAQ;AACrC,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,UAAM,OAAO,KAAK,MAAM,MAAM,CAAC,GAAG,UAAU;AAC5C,UAAM,OAAO,KAAK,GAAG,CAAC;AACtB,UAAM,QAAQ,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;AACxC,UAAM,MAAM,KAAK,GAAG,CAAC;AACrB,UAAM,SAAS,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;AACzC,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,UAAM,OAAO,UAAU,KAAK,KAAK;AACjC,QAAI,MAAM;AACR,UAAI,YAAY;AAChB,UAAI,SAAS,MAAM,KAAK,QAAQ,OAAO,GAAG,SAAS,MAAM,CAAC;AAAA,IAC5D;AACA,QAAI,KAAK,MAAM,WAAW;AACxB,UAAI,YAAY,UAAU,KAAK,MAAM,WAAW,IAAI;AACpD,UAAI,SAAS,MAAM,KAAK,QAAQ,OAAO,GAAG,KAAK,GAAG,CAAC,IAAK,GAAG;AAAA,IAC7D;AAEA,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,eAAW,KAAK,KAAK,IAAI;AACvB,UAAI,OAAO,MAAM,IAAI,GAAG;AACxB,UAAI,OAAO,QAAQ,GAAG,IAAI,GAAG;AAAA,IAC/B;AACA,eAAW,KAAK,KAAK,IAAI;AACvB,UAAI,OAAO,IAAI,KAAK,GAAG;AACvB,UAAI,OAAO,IAAI,KAAK,SAAS,CAAC;AAAA,IAChC;AACA,QAAI,OAAO;AAEX,UAAM,UAAU,YAAY,KAAK,KAAK;AACtC,UAAM,QAAQ,KAAK,MAAM,cAAc;AACvC,UAAM,UAAU,KAAK;AACrB,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,eAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,cAAM,SAAS,CAAC,CAAC,WAAW,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,KAAK,CAAC,CAAC,KAAK;AAC7E,cAAM,QAAQ,KAAK,QAAQ,GAAG,CAAC;AAC/B,YAAI,CAAC,SAAS,CAAC,OAAQ;AACvB,cAAM,KAAK,KAAK,eAAe,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,QAAQ;AAC3D,YAAI,CAAC,GAAI;AACT,YAAI,KAAK;AACT,YAAI,UAAU;AACd,YAAI,KAAK,KAAK,GAAG,CAAC,IAAK,GAAG,KAAK,GAAG,CAAC,IAAK,GAAG,KAAK,GAAG,IAAI,CAAC,IAAK,KAAK,GAAG,CAAC,IAAK,GAAG,KAAK,GAAG,IAAI,CAAC,IAAK,KAAK,GAAG,CAAC,IAAK,CAAC;AAC/G,YAAI,KAAK;AACT,uBAAe,KAAK;AAAA,UAClB,GAAG,GAAG;AAAA,UACN,GAAG,GAAG;AAAA,UACN,OAAO,GAAG;AAAA,UACV,YAAY,GAAG;AAAA,UACf,MAAM,OAAO,KAAK,KAAK;AAAA,UACvB,OAAO,KAAK,MAAM;AAAA,UAClB;AAAA,UACA,OAAO,gBAAgB,OAAO,OAAO;AAAA,UACrC,aAAa;AAAA,UACb,OAAO,SAAS,KAAK,YAAY;AAAA,UACjC;AAAA,QACF,CAAC;AACD,YAAI,QAAQ;AAAA,MACd;AAAA,IACF;AACA,UAAM,OAAO,KAAK,KAAK;AAEvB,UAAMC,QAAO,KAAK,UAAU,aAAa,KAAK,YAAY,QAAQ,IAAI;AACtE,QAAIA,OAAM;AACR,UAAI,cAAc,UAAU;AAC5B,UAAI,YAAY,KAAK;AACrB,UAAIA,MAAK,WAAW,SAAU,KAAI,SAASA,MAAK,KAAK,UAAU,MAAM,KAAK,UAAU,OAAO,IAAI,GAAG,SAAS,MAAM,CAAC;AAAA,UAC7G,KAAI,SAAS,MAAMA,MAAK,KAAK,UAAU,MAAM,QAAQ,OAAO,GAAG,UAAU,OAAO,IAAI,CAAC;AAC1F,UAAI,cAAc;AAAA,IACpB;AAEA,QAAI,WAAW,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM;AACvD,YAAM,KAAK,KAAK,GAAG,QAAQ,GAAG;AAC9B,YAAM,KAAK,KAAK,GAAG,QAAQ,GAAG;AAC9B,UAAI,cAAc,KAAK;AACvB,UAAI,YAAY;AAChB,UAAI,WAAW,KAAK,YAAY,KAAK,YAAY,KAAK,GAAG,QAAQ,MAAM,CAAC,IAAK,KAAK,aAAa,GAAG,KAAK,GAAG,QAAQ,MAAM,CAAC,IAAK,KAAK,aAAa,CAAC;AAAA,IACnJ;AACA,QAAI,QAAQ;AAAA,EACd;AAAA;AAAA;AAAA,EAIQ,WAAW,KAA+B,UAA0B;AAC1E,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG;AACR,UAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,UAAM,OAAO,KAAK,MAAM,MAAM,CAAC,GAAG,UAAU;AAC5C,UAAM,EAAE,IAAI,GAAG,IAAI,KAAK,QAAQ;AAChC,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,UAAM,OAAO,UAAU,KAAK,KAAK;AACjC,QAAI,MAAM;AACR,UAAI,YAAY;AAChB,UAAI,UAAU;AACd,UAAI,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC;AAC5C,UAAI,KAAK;AAAA,IACX;AACA,QAAI,KAAK,MAAM,WAAW;AACxB,UAAI,YAAY,UAAU,KAAK,MAAM,WAAW,IAAI;AACpD,UAAI,UAAU;AACd,UAAI,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,CAAC,GAAI,CAAC;AAC1C,UAAI,KAAK;AAAA,IACX;AACA,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC;AAC5C,QAAI,OAAO;AACX,QAAI,UAAU;AACd,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,UAAI,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,CAAC,CAAE;AAC5B,UAAI,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,CAAE;AAAA,IACxC;AACA,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,UAAI,OAAO,EAAE,IAAI,GAAG,CAAC,GAAI,EAAE,CAAC;AAC5B,UAAI,OAAO,EAAE,IAAI,GAAG,CAAC,GAAI,EAAE,IAAI,EAAE,MAAM;AAAA,IACzC;AACA,QAAI,OAAO;AACX,QAAI,OAAO,OAAO,KAAK,KAAK;AAC5B,QAAI,eAAe;AACnB,UAAM,QAAQ,KAAK,MAAM,cAAc;AACvC,QAAI,YAAY;AAChB,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,eAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,cAAM,OAAO,KAAK,MAAM,MAAM,CAAC,EAAG,CAAC;AACnC,YAAI,CAAC,KAAM;AACX,YAAI,KAAK;AACT,YAAI,UAAU;AACd,YAAI,KAAK,EAAE,IAAI,GAAG,CAAC,IAAK,GAAG,EAAE,IAAI,GAAG,CAAC,IAAK,GAAG,GAAG,IAAI,CAAC,IAAK,GAAG,CAAC,IAAK,GAAG,GAAG,IAAI,CAAC,IAAK,GAAG,CAAC,IAAK,CAAC;AAC7F,YAAI,KAAK;AACT,YAAI,YAAY,KAAK,MAAM;AAC3B,cAAM,IAAI,UAAU,SAAS,EAAE,IAAI,GAAG,CAAC,IAAK,YAAY,UAAU,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC,IAAK,YAAY,EAAE,KAAK,GAAG,CAAC,IAAK,GAAG,IAAI,CAAC,KAAM;AACzI,YAAI,SAAS,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC,IAAK,GAAG,IAAI,CAAC,KAAM,CAAC;AACrD,YAAI,QAAQ;AAAA,MACd;AAAA,IACF;AACA,QAAI,QAAQ;AAAA,EACd;AAAA;AAAA;AAAA,EAKS,iBAAiB,UAAoC;AAC5D,WAAO,KAAK,MAAM,YAAY,MAAM,iBAAiB,QAAQ,IAAI,CAAC;AAAA,EACpE;AAAA;AAAA,EAGS,cAAc,UAA6B;AAClD,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG,QAAO,CAAC;AAChB,WAAO;AAAA,MACL,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE;AAAA,MACjB,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE;AAAA,MAC3B,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,EAAE,IAAI,EAAE,OAAO;AAAA,MACtC,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO;AAAA,IAC9B;AAAA,EACF;AAAA,EAES,YAAgC;AACvC,WAAO,KAAK,MAAM,YAAY,OAAO;AAAA,EACvC;AAAA;AAAA;AAAA,EAIQ,WAAmB;AACzB,UAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,UAAM,OAAO,KAAK,MAAM,MAAM,CAAC,GAAG,UAAU;AAC5C,WAAO,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB,OAAc,UAAmC;AAClE,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,EAAE,IAAI,GAAG,IAAI,KAAK,QAAQ;AAChC,UAAM,MAAM,MAAM,KAAK,EAAE,IAAI,KAAK,MAAM,KAAK,EAAE,IAAI,EAAE,SAAS;AAC9D,UAAM,MAAM,MAAM,KAAK,EAAE,IAAI,KAAK,MAAM,KAAK,EAAE,IAAI,EAAE,QAAQ;AAC7D,QAAI,KAAK;AACP,eAAS,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK;AACtC,YAAI,KAAK,IAAI,MAAM,KAAK,EAAE,IAAI,GAAG,CAAC,EAAG,KAAK,EAAG,QAAO,KAAK,IAAI;AAAA,MAC/D;AAAA,IACF;AACA,QAAI,KAAK;AACP,eAAS,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK;AACtC,YAAI,KAAK,IAAI,MAAM,KAAK,EAAE,IAAI,GAAG,CAAC,EAAG,KAAK,EAAG,QAAO,KAAK,GAAG,SAAS,MAAM,IAAI;AAAA,MACjF;AAAA,IACF;AACA,UAAM,OAAO,KAAK,SAAS;AAC3B,QAAI,OAAO,KAAK,IAAI,MAAM,KAAK,EAAE,IAAI,EAAE,MAAM,KAAK,EAAG,QAAO,OAAO;AACnE,QAAI,OAAO,KAAK,IAAI,MAAM,KAAK,EAAE,IAAI,EAAE,OAAO,KAAK,EAAG,QAAO,OAAO;AACpE,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIQ,YAAY,UAAqE;AACvF,UAAM,IAAI,KAAK;AACf,UAAM,OAAO,KAAK,WAAW,QAAQ;AACrC,QAAI,CAAC,KAAK,CAAC,KAAM,QAAO;AACxB,QAAI,KAAK,cAAc,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,EAAG,QAAO;AAC5F,UAAM,QAAQ,KAAK,mBAAmB,GAAG,QAAQ;AACjD,QAAI,UAAU,KAAM,QAAO;AAC3B,UAAM,OAAO,KAAK,MAAM,MAAM,CAAC,GAAG,UAAU;AAC5C,UAAM,OAAO,KAAK,SAAS;AAC3B,QAAI,UAAU,OAAO,EAAG,QAAO,EAAE,QAAQ,UAAU,IAAI,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC,EAAG;AACpF,QAAI,UAAU,OAAO,EAAG,QAAO,EAAE,QAAQ,OAAO,IAAI,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC,EAAG;AACjF,UAAM,UAAU,QAAQ;AACxB,WAAO,UAAU,OAAO,IAAI,EAAE,QAAQ,UAAU,IAAI,KAAK,GAAG,UAAU,CAAC,EAAG,IAAI,EAAE,QAAQ,OAAO,IAAI,KAAK,GAAG,WAAW,OAAO,KAAK,CAAC,EAAG;AAAA,EACxI;AAAA;AAAA;AAAA,EAImB,SAAS,OAAc,UAAmC;AAC3E,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,KAAK,KAAK,UAAU,WAAY,QAAO;AAC5C,UAAM,UAAU,KAAK,cAAc,QAAQ;AAC3C,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAI,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,EAAG,GAAG,MAAM,IAAI,QAAQ,CAAC,EAAG,CAAC,KAAK,EAAG,QAAO,IAAI,MAAM,IAAI,gBAAgB;AAAA,IAC9G;AACA,UAAM,UAAU,KAAK,mBAAmB,OAAO,QAAQ;AACvD,QAAI,YAAY,MAAM;AACpB,YAAM,OAAO,KAAK,MAAM,MAAM,CAAC,GAAG,UAAU;AAC5C,YAAM,OAAO,KAAK,SAAS;AAC3B,UAAI,WAAW,KAAM,QAAO,UAAU,OAAO,IAAI,cAAc;AAC/D,aAAO,UAAU,IAAI,OAAO,IAAI,cAAc;AAAA,IAChD;AACA,WAAO,KAAK,OAAO,OAAO,QAAQ,IAAI,SAAS;AAAA,EACjD;AAAA,EAES,SAAS,aAAqB,OAAc,UAA0B;AAC7E,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG;AACR,UAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,UAAM,OAAO,KAAK,MAAM,MAAM,CAAC,GAAG,UAAU;AAC5C,QAAI,CAAC,QAAQ,CAAC,KAAM;AAEpB,QAAI,cAAc,GAAG;AAGnB,YAAM,MAAM;AAAA,QACV,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,EAAE,IAAI,EAAE,OAAO;AAAA,QACtC,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO;AAAA,QAC5B,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE;AAAA,QACjB,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE;AAAA,MAC7B,EAAE,WAAW;AACb,YAAM,OAAO,KAAK,IAAI,OAAO,SAAS,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,CAAC;AAC/D,YAAM,OAAO,KAAK,IAAI,OAAO,SAAS,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,CAAC;AAC/D,YAAM,SAAS,OAAO,EAAE;AACxB,YAAM,SAAS,OAAO,EAAE;AACxB,YAAM,YAAY,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,KAAK,SAAS,CAAC,IAAI,MAAM,CAAC,CAAC;AACxH,YAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM,KAAK,IAAI,SAAS,KAAK,IAAI,KAAK,WAAW,CAAC,GAAG,KAAK,UAAU,CAAC,IAAI,MAAM,CAAC,CAAC;AACrI,WAAK,WAAW,EAAE,WAAW,WAAW,CAAwB;AAEhE,YAAM,EAAE,IAAAC,KAAI,IAAAC,IAAG,IAAI,KAAK,QAAQ;AAChC,YAAM,QAAQD,IAAGA,IAAG,SAAS,CAAC;AAC9B,YAAM,SAASC,IAAGA,IAAG,SAAS,CAAC;AAC/B,YAAM,OAAO,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,QAAQ,IAAI;AACnD,YAAM,MAAM,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,SAAS,IAAI;AACnD,YAAM,OAAO,SAAS,OAAO,IAAI;AACjC,YAAM,QAAQ,SAAS,QAAQ,GAAG;AAClC,UAAI,SAAS,QAAQ,UAAU,KAAM,MAAK,aAAa,GAAG,EAAE,MAAM,MAAM,CAAC;AACzE;AAAA,IACF;AAEA,UAAM,EAAE,IAAI,GAAG,IAAI,KAAK,QAAQ;AAChC,UAAM,OAAO,KAAK,SAAS;AAC3B,QAAI,eAAe,MAAM;AACvB,YAAM,QAAQ,cAAc;AAC5B,UAAI,UAAU,GAAG;AACf,cAAM,YAAY,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC;AACzE,kBAAU,OAAO,CAAC,IAAI,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,MAAM,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,EAAG,CAAC;AAC1F,aAAK,WAAW,EAAE,UAAU,CAAwB;AAAA,MACtD,WAAW,UAAU,GAAG;AACtB,cAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM,KAAK,MAAM,WAAW,CAAC,KAAK,CAAC;AACvF,mBAAW,OAAO,CAAC,IAAI,KAAK,IAAI,SAAS,KAAK,IAAI,KAAK,WAAW,OAAO,CAAC,GAAG,MAAM,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,EAAG,CAAC;AAC7G,aAAK,WAAW,EAAE,WAAW,CAAwB;AAAA,MACvD;AACA;AAAA,IACF;AAEA,UAAM,UAAU,cAAc;AAC9B,QAAI,UAAU,OAAO,GAAG;AACtB,YAAM,YAAY,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC;AACzE,gBAAU,OAAO,IAAI,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,MAAM,KAAK,EAAE,IAAI,GAAG,OAAO,EAAG,CAAC;AACxF,WAAK,WAAW,EAAE,UAAU,CAAwB;AACpD;AAAA,IACF;AACA,UAAM,WAAW,WAAW,OAAO;AACnC,QAAI,WAAW,OAAO,GAAG;AACvB,YAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,MAAM,KAAK,MAAM,WAAW,CAAC,KAAK,CAAC;AACvF,iBAAW,QAAQ,IAAI,KAAK,IAAI,SAAS,KAAK,IAAI,KAAK,WAAW,QAAQ,GAAG,MAAM,KAAK,EAAE,IAAI,GAAG,QAAQ,EAAG,CAAC;AAC7G,WAAK,WAAW,EAAE,WAAW,CAAwB;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG,QAAO;AACf,WAAO,MAAM,KAAK,EAAE,IAAI,KAAK,MAAM,KAAK,EAAE,IAAI,EAAE,QAAQ,KAAK,MAAM,KAAK,EAAE,IAAI,KAAK,MAAM,KAAK,EAAE,IAAI,EAAE,SAAS;AAAA,EACjH;AACF;;;ACzkBA,SAASC,cAAa,WAA2B;AAC/C,SAAO,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACtC;AAmBO,IAAe,kBAAf,cAAwE,QAAW;AAAA,EAGrE,eAAkB;AACnC,WAAO,EAAE,YAAY,KAAK;AAAA,EAC5B;AAAA;AAAA,EAGmB,aAAa,OAA+B;AAC7D,UAAM,QAAQ;AACd,QAAI,EAAE,UAAU,UAAU,MAAM,KAAM,QAAO;AAC7C,UAAM,EAAE,MAAM,OAAO,GAAG,KAAK,IAAI;AACjC,SAAK;AACL,WAAO;AAAA,EACT;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,YAAY,EAAE;AAAA,EAChD;AAAA,EAEU,OAAO,UAAsC;AACrD,WAAO,KAAK,aAAa,QAAQ;AAAA,EACnC;AAAA;AAAA,EAGU,SAAkB;AAC1B,WAAQ,KAAK,MAAuC,mBAAmB,SAAS,KAAK,MAAM,cAAc;AAAA,EAC3G;AAAA;AAAA,EAGU,YAAqB;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,SAAS,KAAK,OAAO,QAAQ,EAAE,OAAO,CAAC,MAAkB,CAAC,CAAC,CAAC;AAClE,QAAI,OAAO,SAAS,EAAG;AACvB,QAAI,KAAK,UAAU,GAAG;AACpB,kBAAY,KAAK,KAAK,KAAK;AAC3B,UAAI,UAAU;AACd,UAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,KAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AAC3E,UAAI,OAAO;AAAA,IACb;AACA,SAAK,YAAY,KAAK,QAAQ,QAAQ;AACtC,SAAK,YAAY,KAAK,MAAM;AAC5B,UAAM,OAAQ,KAAK,MAA6B;AAChD,QAAI,OAAO,SAAS,YAAY,MAAM;AAGpC,YAAM,WAAW,OAAO,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,EAAE,MAAM,OAAO,IAAI,CAAC,EAAG,KAAK,EAAE,MAAM,OAAO,IAAI,CAAC,EAAG,CAAC;AACxG,iBAAW,KAAK,MAAM,KAAK,kBAAkB,QAAQ,GAAG,KAAK,OAAO,EAAE,OAAO,SAAS,CAAC;AAAA,IACzF;AAAA,EACF;AAAA;AAAA,EAGS,kBAAkB,KAA+B,UAA0B;AAClF,SAAK,MAAM,KAAK,QAAQ;AAAA,EAC1B;AAAA,EAEU,YAAY,MAAgC,SAAkB,WAA2B;AAAA,EAAC;AAAA;AAAA;AAAA,EAI1F,YAAY,KAA+B,QAAuB;AAC1E,UAAM,SAAS,KAAK,OAAO;AAC3B,UAAM,SAAS,KAAK,MAAM,cAAc,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,MAAM,WAAW,IAAI,CAAC;AAC1F,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,OAAO,OAAO,KAAK,KAAK;AAC5B,QAAI,YAAY;AAChB,QAAI,eAAe;AACnB,aAAS,IAAI,GAAG,IAAI,OAAO,UAAU,IAAI,OAAO,QAAQ,KAAK;AAC3D,UAAI,CAAC,OAAO,CAAC,EAAG;AAChB,YAAM,IAAI,OAAO,CAAC;AAElB,YAAM,OAAO,OAAO,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC;AAC1C,YAAM,KAAK,QAAQ,KAAK,IAAI,EAAE,IAAI,EAAE,SAAS,KAAK,SAAS;AAC3D,YAAM,KAAK,EAAE,IAAI;AACjB,UAAI,YAAY,UAAU,WAAW,IAAI;AACzC,UAAI,UAAU;AACd,UAAI,IAAI,EAAE,GAAG,IAAI,QAAQ,GAAG,KAAK,KAAK,CAAC;AACvC,UAAI,KAAK;AACT,UAAI,cAAc,KAAK,MAAM;AAC7B,UAAI,YAAY;AAChB,UAAI,OAAO;AAEX,UAAI,YAAY,KAAK,MAAM;AAC3B,UAAI,SAAS,OAAO,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG;AAAA,IACvC;AACA,QAAI,QAAQ;AAAA,EACd;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,SAAS,KAAK,OAAO,QAAQ,EAAE,OAAO,CAAC,MAAkB,CAAC,CAAC,CAAC;AAClE,UAAM,YAAYA,cAAa,KAAK,MAAM,SAAS;AACnD,aAAS,IAAI,GAAG,IAAI,OAAO,SAAS,GAAG,KAAK;AAC1C,UAAI,kBAAkB,OAAO,OAAO,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,KAAK,UAAW,QAAO;AAAA,IAC9E;AACA,WAAO;AAAA,EACT;AACF;AAGA,SAAS,aACP,KACA,OACA,GACA,GACA,GACM;AACN,MAAI,KAAK;AACT,MAAI,YAAY,UAAU,MAAM,WAAW,MAAM,WAAW;AAC5D,MAAI,UAAU;AACd,MAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,MAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,MAAI,OAAO,EAAE,GAAG,EAAE,CAAC;AACnB,MAAI,UAAU;AACd,MAAI,KAAK;AACT,MAAI,QAAQ;AACd;AAGO,IAAM,eAAN,cAA2B,gBAA8B;AAAA,EACrD,OAAe;AAAA,EAEL,eAA6B;AAC9C,WAAO,EAAE,YAAY,MAAM,gBAAgB,KAAK;AAAA,EAClD;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAA4B;AACpC,WAAO,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,EACjC;AAAA,EAEmB,YAAY,KAA+B,QAAuB;AACnF,QAAI,CAAC,KAAK,OAAO,EAAG;AACpB,QAAI,OAAO,UAAU,EAAG,cAAa,KAAK,KAAK,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AACrF,QAAI,OAAO,UAAU,EAAG,cAAa,KAAK,KAAK,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,EACvF;AACF;AAGO,IAAM,gBAAN,cAA4B,aAAa;AAAA,EAC5B,OAAO;AAC3B;AAOO,IAAM,qBAAN,cAAiC,gBAAgB;AAAA,EAC7C,OAAO;AAAA,EAEhB,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAImB,eAAe,SAA6B;AAC7D,QAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,WAAO,CAAC,GAAG,SAAS,EAAE,GAAG,QAAQ,CAAC,EAAG,CAAC;AAAA,EACxC;AAAA,EAEU,SAA4B;AACpC,WAAO,CAAC,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAAA,EACzC;AACF;AAGO,IAAM,cAAN,cAA0B,gBAAgB;AAAA,EACtC,OAAO;AAAA,EAEhB,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAA4B;AACpC,WAAO,CAAC,KAAK,KAAK,KAAK,GAAG;AAAA,EAC5B;AAAA,EAEmB,YAAY,KAA+B,QAAuB;AACnF,QAAI,OAAO,UAAU,GAAG;AAEtB,UAAI,KAAK;AACT,kBAAY,KAAK,KAAK,KAAK;AAC3B,UAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AACtB,UAAI,cAAc;AAClB,UAAI,UAAU;AACd,UAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,UAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,UAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,UAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,UAAI,OAAO;AACX,UAAI,QAAQ;AAAA,IACd;AAAA,EACF;AACF;AAGO,IAAM,kBAAN,cAA8B,gBAA8B;AAAA,EACxD,OAAO;AAAA,EAEG,eAA6B;AAC9C,WAAO,EAAE,YAAY,MAAM,gBAAgB,KAAK;AAAA,EAClD;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAA4B;AACpC,WAAO,CAAC,KAAK,KAAK,KAAK,GAAG;AAAA,EAC5B;AAAA,EAEmB,YAAY,KAA+B,QAAuB;AACnF,QAAI,OAAO,SAAS,EAAG;AAEvB,QAAI,KAAK;AACT,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,cAAc;AAClB,QAAI,UAAU;AACd,QAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,QAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,QAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,QAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;AACnC,QAAI,OAAO;AACX,QAAI,QAAQ;AACZ,QAAI,KAAK,OAAO,EAAG,cAAa,KAAK,KAAK,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,EAClF;AACF;AAGO,IAAM,mBAAN,cAA+B,gBAA8B;AAAA,EACzD,OAAO;AAAA,EAEG,eAA6B;AAC9C,WAAO,EAAE,YAAY,MAAM,gBAAgB,KAAK;AAAA,EAClD;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAA4B;AAEpC,WAAO,CAAC,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,EAAE;AAAA,EACzC;AAAA,EAEmB,YAAY,KAA+B,QAAuB;AACnF,QAAI,OAAO,SAAS,EAAG;AAEvB,QAAI,KAAK;AACT,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AACtB,QAAI,UAAU;AACd,QAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,EAAE,OAAO,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,EAAE,MAAO,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,EAAE,KAAM,GAAG;AACtI,QAAI,OAAO,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,EAAE,OAAO,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,EAAE,MAAO,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,EAAE,KAAM,GAAG;AACtI,QAAI,OAAO;AACX,QAAI,QAAQ;AACZ,QAAI,CAAC,KAAK,OAAO,EAAG;AACpB,iBAAa,KAAK,KAAK,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAC7D,iBAAa,KAAK,KAAK,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAC7D,iBAAa,KAAK,KAAK,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,EAC/D;AACF;;;ACjSO,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeA,IAAM,cAAsC,EAAE,KAAK,KAAK,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,KAAK,IAAI;AACnG,IAAM,cAAsC,EAAE,KAAK,KAAK,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,KAAK,IAAI;AAU5F,SAAS,aAAa,MAAc,QAA0D;AACnG,QAAM,QAAQ,KAAK,IAAI,GAAG,gBAAgB,QAAQ,MAAM,CAAC;AACzD,QAAM,QAAQ,KAAK,MAAM,QAAQ,CAAC;AAClC,QAAM,QAAQ,QAAQ;AACtB,MAAI,OAAO;AACX,MAAI,UAAU,KAAK,IAAI,EAAG,QAAO,SAAS,IAAI,YAAY,IAAI,IAAK,UAAU,IAAI,YAAY,IAAI,IAAK;AAAA,WAC7F,UAAU,KAAK,IAAI,EAAG,QAAO,UAAU,KAAK,UAAU,IAAI,OAAO,KAAK,YAAY;AAC3F,SAAO,EAAE,MAAM,UAAU,IAAI,IAAI,IAAI,MAAM,MAAM,QAAQ,UAAU,EAAE;AACvE;AAKA,IAAe,cAAf,cAAmC,gBAA8B;AAAA,EAC5C,eAA6B;AAC9C,WAAO,EAAE,YAAY,MAAM,UAAU,MAAM,QAAQ,gBAAgB,YAAY,MAAM;AAAA,EACvF;AAAA;AAAA,EAGmB,cAAc,OAAgD;AAC/E,UAAM,cAAc,KAAK;AACzB,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,UAAU,MAAM,YAAY,KAAK;AAAA,EACnE;AAAA,EAEmB,YAAqB;AACtC,WAAO,KAAK,MAAM,aAAa;AAAA,EACjC;AAAA,EAEmB,YAAY,KAA+B,QAAuB;AACnF,QAAI,KAAK,MAAM,YAAY;AACzB,YAAM,YAAY,KAAK,MAAM;AAC7B;AAAA,IACF;AACA,UAAM,SAAS,KAAK,OAAO;AAC3B,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,OAAO,OAAO,KAAK,KAAK;AAC5B,QAAI,YAAY;AAChB,QAAI,eAAe;AACnB,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,YAAY;AAChB,UAAM,OAAO,KAAK,MAAM;AACxB,aAAS,IAAI,GAAG,IAAI,OAAO,UAAU,IAAI,OAAO,QAAQ,KAAK;AAC3D,UAAI,CAAC,OAAO,CAAC,EAAG;AAChB,YAAM,IAAI,OAAO,CAAC;AAClB,YAAM,OAAO,OAAO,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC;AAC1C,YAAM,IAAI,EAAE,KAAK,QAAQ,KAAK,IAAI,EAAE,IAAI,CAAC,OAAO;AAChD,YAAM,EAAE,MAAM,OAAO,IAAI,aAAa,OAAO,CAAC,GAAI,KAAK,MAAM,MAAM;AACnE,UAAI,SAAS,MAAM,EAAE,GAAG,CAAC;AACzB,UAAI,QAAQ;AACV,YAAI,UAAU;AACd,YAAI,IAAI,EAAE,GAAG,GAAG,KAAK,IAAI,IAAI,YAAY,IAAI,EAAE,QAAQ,GAAG,KAAK,MAAM,WAAW,CAAC,IAAI,GAAG,GAAG,KAAK,KAAK,CAAC;AACtG,YAAI,OAAO;AAAA,MACb;AAAA,IACF;AACA,QAAI,QAAQ;AAAA,EACd;AACF;AAGO,IAAM,iBAAN,cAA6B,YAAY;AAAA,EACrC,OAAe;AAAA,EAExB,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAA4B;AACpC,WAAO,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,EACtC;AACF;AAGO,IAAM,oBAAN,cAAgC,YAAY;AAAA,EACxC,OAAO;AAAA,EAEhB,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAA4B;AACpC,WAAO,CAAC,KAAK,KAAK,KAAK,GAAG;AAAA,EAC5B;AACF;AAGO,IAAM,kBAAN,cAA8B,YAAY;AAAA,EACtC,OAAO;AAAA,EAEhB,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAA4B;AACpC,WAAO,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,EACtC;AACF;AAGO,IAAM,qBAAN,cAAiC,YAAY;AAAA,EACzC,OAAO;AAAA,EAEhB,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAA4B;AACpC,WAAO,CAAC,KAAK,KAAK,KAAK,GAAG;AAAA,EAC5B;AACF;AAGO,IAAM,qBAAN,cAAiC,YAAY;AAAA,EACzC,OAAO;AAAA,EAEhB,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAA4B;AACpC,WAAO,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,EACtC;AACF;;;ACxKA,SAASC,cAAa,WAA2B;AAC/C,SAAO,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACtC;AAGO,IAAM,cAAN,cAA0B,QAAQ;AAAA,EAC9B,OAAO;AAAA,EAEhB,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,GAAG,UAA8B;AACzC,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AACzC,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO,CAAC;AACtB,UAAM,OAAO,EAAE,IAAI,EAAE;AACrB,QAAI,KAAK,IAAI,IAAI,IAAI,EAAG,QAAO,CAAC;AAChC,UAAM,MAAgB,CAAC;AACvB,aAAS,IAAI,EAAE,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,QAAQ,KAAK,IAAI,IAAI,GAAG,KAAK,KAAK,IAAI,IAAI,GAAG;AACzF,UAAI,KAAK,CAAC;AACV,UAAI,IAAI,SAAS,IAAK;AAAA,IACxB;AACA,WAAO,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,KAAK,SAAS,KAAK;AAAA,EACxD;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,gBAAY,KAAK,KAAK,KAAK;AAC3B,eAAW,KAAK,KAAK,GAAG,QAAQ,EAAG,eAAc,KAAK,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,SAAS,OAAO,CAAC;AAAA,EAC9F;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,YAAYA,cAAa,KAAK,MAAM,SAAS;AACnD,WAAO,KAAK,GAAG,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,IAAI,MAAM,IAAI,CAAC,KAAK,SAAS;AAAA,EACzE;AACF;AASO,IAAM,aAAN,cAAyB,QAAyB;AAAA,EAC9C,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,EAAE,gBAAgB,KAAK;AAAA,EAChC;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAAS,UAAwE;AACzF,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AACzC,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,UAAM,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,CAAC;AAC/B,QAAI,OAAO,EAAG,QAAO;AACrB,WAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK;AAAA,EACpD;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,QAAI,CAAC,IAAK;AACV,UAAM,OAAO,KAAK,MAAM,mBAAmB,QAAQ,UAAU,KAAK,KAAK,IAAI;AAC3E,QAAI,MAAM;AACR,UAAI,KAAK;AACT,UAAI,YAAY;AAChB,UAAI,YAAY,CAAC,CAAC;AAClB,UAAI,SAAS;AACb,eAAS,IAAI,IAAI,QAAQ,KAAK,SAAS,SAAS,SAAS,KAAK,KAAK,IAAI,MAAM,UAAU;AACrF,YAAI,UAAU;AACd,YAAI,IAAI,IAAI,IAAI,OAAO,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG,GAAG,KAAK,IAAI,IAAI;AAC/D,YAAI,UAAU;AACd,YAAI,KAAK;AAAA,MACX;AACA,UAAI,QAAQ;AAAA,IACd;AACA,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,UAAU;AACd,QAAI,QAAQ;AACZ,aAAS,IAAI,IAAI,QAAQ,KAAK,SAAS,SAAS,QAAQ,KAAK,KAAK,IAAI,MAAM,SAAS;AACnF,UAAI,OAAO,IAAI,IAAI,MAAM,IAAI,CAAC;AAC9B,UAAI,IAAI,IAAI,IAAI,OAAO,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG,GAAG,KAAK,IAAI,IAAI;AAAA,IACjE;AACA,QAAI,OAAO;AAAA,EACb;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,QAAI,CAAC,IAAK,QAAO;AACjB,QAAI,MAAM,IAAI,IAAI,OAAQ,QAAO;AACjC,UAAM,SAAS,IAAI,OAAO;AAC1B,UAAM,UAAU,MAAM,IAAI,IAAI,UAAU,IAAI;AAC5C,UAAM,KAAK,MAAM,IAAI,SAAS;AAC9B,UAAM,WAAW,KAAK,MAAM,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,CAAC;AACzD,WAAO,MAAM,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,WAAW,MAAM,KAAKA,cAAa,KAAK,MAAM,SAAS;AAAA,EACjG;AACF;AAGO,IAAM,WAAN,cAAuB,QAAQ;AAAA,EAC3B,OAAO;AAAA,EAEhB,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,QAAQ,UAAoC;AACpD,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,QAAQ;AACzC,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,UAAM,OAAO,EAAE,IAAI,EAAE;AACrB,QAAI,KAAK,IAAI,IAAI,IAAI,EAAG,QAAO;AAC/B,UAAM,YAAY,EAAE,IAAI,EAAE;AAC1B,UAAM,SAAS,KAAK,IAAI,IAAI,IAAI;AAChC,UAAM,MAAe,CAAC;AACtB,aAAS,IAAI,GAAG,KAAK,SAAS,OAAO,KAAK,KAAK,IAAI,GAAG,SAAS,EAAE,GAAG;AAClE,YAAM,SAAU,IAAI,EAAE,KAAK,OAAQ,KAAK,KAAK;AAC7C,UAAI,KAAK,EAAE,GAAG,GAAG,EAAE,IAAI,KAAK,IAAI,KAAK,IAAI,UAAU,CAAC;AAAA,IACtD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,CAAC,WAAW,QAAQ,SAAS,EAAG;AACpC,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,UAAU;AACd,QAAI,OAAO,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AACrC,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,KAAI,OAAO,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC9E,QAAI,OAAO;AAAA,EACb;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,YAAYA,cAAa,KAAK,MAAM,SAAS;AACnD,aAAS,IAAI,GAAG,IAAI,QAAQ,SAAS,GAAG,KAAK;AAC3C,UAAI,kBAAkB,OAAO,QAAQ,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC,KAAK,UAAW,QAAO;AAAA,IAChF;AACA,WAAO;AAAA,EACT;AACF;;;AC9IA,SAASC,cAAa,WAA2B;AAC/C,SAAO,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACtC;AAqCA,IAAM,mBAAoC;AAAA,EACxC,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AACb;AAGA,IAAM,YAAY;AAMX,IAAM,kBAAN,cAA8B,QAAyB;AAAA,EACnD,OAAO;AAAA,EAEG,eAAgC;AACjD,WAAO,EAAE,GAAG,iBAAiB;AAAA,EAC/B;AAAA;AAAA;AAAA,EAImB,aAAa,OAA2D;AACzF,QAAI,cAAc,SAAS,OAAO,MAAM,mBAAmB,SAAU,QAAO;AAC5E,WAAO,EAAE,GAAG,OAAO,gBAAgB,CAAC,MAAM,eAAe;AAAA,EAC3D;AAAA;AAAA;AAAA,EAImB,cAAc,QAAiD;AAChF,UAAM,EAAE,WAAW,WAAW,UAAU,IAAI,KAAK;AACjD,UAAM,OAAO,UAAU,WAAW,QAAQ,SAAS,IAAI,GAAG;AAC1D,SAAK,SAAS;AAAA,MACZ,GAAG,KAAK;AAAA,MACR,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,WAAW;AAAA,MACX,WAAW;AAAA,MACX,cAAc;AAAA,MACd,WAAW,UAAU,WAAW,IAAI;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,MAAuG;AAC/G,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,UAAM,QAAQ,YAAY,KAAK,KAAK,GAAG,EAAE,MAAM,EAAE,IAAI;AACrD,UAAM,MAAM,iBAAiB,OAAO,KAAK,MAAM,MAAM;AACrD,QAAI,CAAC,IAAK,QAAO;AACjB,WAAO,EAAE,OAAO,GAAG,KAAK,SAAS,UAAU,OAAO,KAAK,MAAM,MAAM,EAAE;AAAA,EACvE;AAAA,EAEU,MAAM,UAAsH;AACpI,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,QAAQ,IAAI,MAAM,CAAC;AACzB,UAAM,OAAO,IAAI,MAAM,IAAI,MAAM,SAAS,CAAC;AAC3C,UAAM,SAAS,CAAC,WAA0C;AACxD,YAAM,KAAK,SAAS,IAAI,IAAI,YAAY,MAAM;AAC9C,YAAM,KAAK,SAAS,IAAI,IAAI,YAAY,IAAI,SAAS,IAAI,MAAM,SAAS,KAAK,MAAM;AACnF,YAAM,KAAK,SAAS,IAAI,MAAM,IAAI;AAClC,YAAM,KAAK,SAAS,IAAI,KAAK,IAAI;AACjC,UAAI,OAAO,QAAQ,OAAO,QAAQ,OAAO,QAAQ,OAAO,KAAM,QAAO;AACrE,YAAM,IAAI,EAAE,GAAG,IAAI,GAAG,GAAG;AACzB,YAAM,IAAI,EAAE,GAAG,IAAI,GAAG,GAAG;AACzB,UAAI,CAAC,KAAK,MAAM,YAAa,QAAO,CAAC,GAAG,CAAC;AACzC,YAAM,MAAM,cAAc,GAAG,GAAG,SAAS,OAAO,SAAS,QAAQ,MAAM,IAAI;AAC3E,aAAO,CAAC,IAAI,GAAG,IAAI,CAAC;AAAA,IACtB;AACA,UAAM,OAAO,OAAO,CAAC;AACrB,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO;AAAA,MACL;AAAA,MACA,OAAO,KAAK,MAAM,WAAY,OAAO,IAAI,QAAQ,KAAK,MAAM,cAAc,KAAK,SAAa;AAAA,MAC5F,OAAO,KAAK,MAAM,WAAY,OAAO,IAAI,QAAQ,KAAK,MAAM,cAAc,KAAK,SAAa;AAAA,MAC5F,SAAS,IAAI;AAAA,IACf;AAAA,EACF;AAAA;AAAA,EAGU,UAA8E;AACtF,UAAM,IAAI,KAAK;AACf,WAAO;AAAA,MACL,MAAM,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,WAAW,OAAO,EAAE,WAAW,OAAO,EAAE,UAAU;AAAA,MACrF,IAAI,EAAE,MAAM,EAAE,QAAQ,OAAO,EAAE,SAAS,OAAO,EAAE,SAAS,OAAO,EAAE,QAAQ;AAAA,MAC3E,MAAM,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,WAAW,OAAO,EAAE,WAAW,OAAO,EAAE,UAAU;AAAA,IACvF;AAAA,EACF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,QAAQ,KAAK,MAAM,QAAQ;AACjC,QAAI,CAAC,OAAO;AACV,WAAK,iBAAiB,KAAK,QAAQ;AACnC;AAAA,IACF;AACA,UAAM,UAAU,KAAK,QAAQ;AAC7B,UAAM,OAAO,CAAC,MAAkC,UAAwB;AACtE,UAAI,CAAC,KAAM;AACX,UAAI,KAAK;AACT,UAAI,YAAY,UAAU,OAAO,QAAQ,KAAK,IAAI,SAAS;AAC3D,UAAI,UAAU;AACd,UAAI,OAAO,MAAM,KAAK,CAAC,EAAE,GAAG,MAAM,KAAK,CAAC,EAAE,CAAC;AAC3C,UAAI,OAAO,MAAM,KAAK,CAAC,EAAE,GAAG,MAAM,KAAK,CAAC,EAAE,CAAC;AAC3C,UAAI,OAAO,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;AAC/B,UAAI,OAAO,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;AAC/B,UAAI,UAAU;AACd,UAAI,KAAK;AACT,UAAI,QAAQ;AAAA,IACd;AACA,QAAI,KAAK,MAAM,cAAc,MAAM;AACjC,WAAK,MAAM,OAAO,QAAQ,GAAG,KAAK;AAClC,WAAK,MAAM,OAAO,QAAQ,KAAK,KAAK;AAAA,IACtC,WAAW,MAAM,SAAS,MAAM,OAAO;AACrC,UAAI,KAAK;AACT,UAAI,YAAY,KAAK,MAAM;AAC3B,UAAI,UAAU;AACd,UAAI,OAAO,MAAM,MAAM,CAAC,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC;AAC7C,UAAI,OAAO,MAAM,MAAM,CAAC,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC;AAC7C,UAAI,OAAO,MAAM,MAAM,CAAC,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC;AAC7C,UAAI,OAAO,MAAM,MAAM,CAAC,EAAE,GAAG,MAAM,MAAM,CAAC,EAAE,CAAC;AAC7C,UAAI,UAAU;AACd,UAAI,KAAK;AACT,UAAI,QAAQ;AAAA,IACd;AACA,UAAM,OAAO,CAACC,OAAkC,WAAiC;AAC/E,UAAI,CAACA,SAAQ,CAAC,OAAO,KAAM;AAC3B,UAAI,KAAK;AACT,kBAAY,KAAK,EAAE,GAAG,KAAK,OAAO,WAAW,OAAO,OAAO,WAAW,OAAO,OAAO,WAAW,OAAO,MAAM,CAAC;AAC7G,oBAAc,KAAKA,MAAK,CAAC,GAAGA,MAAK,CAAC,CAAC;AACnC,UAAI,QAAQ;AAAA,IACd;AACA,SAAK,MAAM,OAAO,QAAQ,EAAE;AAC5B,SAAK,MAAM,OAAO,QAAQ,IAAI;AAC9B,SAAK,MAAM,MAAM,QAAQ,IAAI;AAC7B,QAAI,KAAK,MAAM,gBAAgB,OAAO,SAAS,MAAM,OAAO,GAAG;AAE7D,YAAM,OAAO,MAAM,SAAS,MAAM,MAAM,CAAC;AACzC,iBAAW,KAAK,MAAM,QAAQ,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,UAAU,QAAQ,KAAK,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,UAAU,UAAU,MAAM,CAAC;AAAA,IAC5K;AAAA,EACF;AAAA,EAEU,iBAAiB,KAA+B,UAA0B;AAClF,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,QAAI,KAAK;AACT,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AACtB,QAAI,cAAc;AAClB,kBAAc,KAAK,IAAI,EAAE;AACzB,QAAI,QAAQ;AACZ,eAAW,KAAK,wBAAwB,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,GAAG,GAAG,KAAK,OAAO;AAAA,MACvG,OAAO;AAAA,MACP,YAAY,UAAU,WAAW,IAAI;AAAA,IACvC,CAAC;AAAA,EACH;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,QAAQ,KAAK,MAAM,QAAQ;AACjC,QAAI,CAAC,OAAO;AACV,YAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,aAAO,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,kBAAkB,OAAO,IAAI,EAAE,KAAKD,cAAa,KAAK,MAAM,SAAS;AAAA,IAC9F;AACA,UAAM,UAAU,KAAK,QAAQ;AAC7B,UAAM,QAAwD;AAAA,MAC5D,CAAC,MAAM,MAAM,QAAQ,IAAI;AAAA,MACzB,CAAC,MAAM,OAAO,QAAQ,EAAE;AAAA,MACxB,CAAC,MAAM,OAAO,QAAQ,IAAI;AAAA,IAC5B;AACA,WAAO,MAAM,KAAK,CAAC,CAACC,OAAM,MAAM,MAAM,CAAC,CAACA,SAAQ,OAAO,QAAQ,kBAAkB,OAAOA,MAAK,CAAC,GAAGA,MAAK,CAAC,CAAC,KAAKD,cAAa,OAAO,KAAK,CAAC;AAAA,EACzI;AACF;AAGA,SAAS,UAAU,MAA4B,QAAgC;AAC7E,QAAM,IAAI,KAAK;AACf,MAAI,IAAI,EAAG,QAAO,OAAO;AACzB,MAAI,OAAO;AACX,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAQ;AACR,YAAQ,SAAS,KAAK,CAAC,GAAI,MAAM;AAAA,EACnC;AACA,QAAM,QAAQ,OAAO;AACrB,QAAM,QAAQ,OAAO;AACrB,MAAI,aAAa;AACjB,MAAI,OAAO;AACX,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,KAAK,IAAI;AACf,UAAM,KAAK,SAAS,KAAK,CAAC,GAAI,MAAM,IAAI;AACxC,kBAAc,KAAK;AACnB,YAAQ,KAAK;AACb,YAAQ,KAAK;AAAA,EACf;AACA,SAAO,OAAO,KAAK,OAAO,IAAI,aAAa,KAAK,KAAK,OAAO,IAAI,IAAI,OAAO;AAC7E;AA0BO,IAAM,qBAAqB,CAAC,MAAM,MAAM,SAAS,QAAQ,QAAQ,OAAO,KAAK;AAuB7E,IAAe,sBAAf,cAAwG,QAAW;AAAA,EACxH,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,UAAgB;AACd,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,QAAI,CAAC,KAAK,CAAC,EAAG;AACd,UAAM,QAAQ,YAAY,KAAK,KAAK,GAAG,EAAE,MAAM,EAAE,IAAI;AACrD,QAAI,CAAC,MAAM,OAAQ;AACnB,SAAK,WAAW;AAAA,MACd,MAAM,MAAM,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,MAAM,GAAG,IAAI,MAAM,GAAG,IAAI,KAAK,GAAG,IAAI,MAAM,EAAE;AAAA,IACnF,CAA0B;AAAA,EAC5B;AAAA,EAEU,MAAM,UAAqF;AACnG,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,KAAK,WAAW,EAAG,QAAO;AAEvD,UAAM,UAAU,SAAS,IAAI,KAAK,QAAQ,CAAC,EAAE,KAAK;AAClD,UAAM,cAAc,SAAS,IAAI,KAAK,QAAQ,CAAC,EAAE,QAAQ,CAAC;AAC1D,QAAI,YAAY,QAAQ,gBAAgB,KAAM,QAAO;AACrD,UAAM,QAAQ,cAAc;AAC5B,WAAO,EAAE,IAAI,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,OAAO,GAAG,GAAG,MAAM;AAAA,EAClF;AAAA,EAEU,iBAAiB,KAA+B,UAA0B;AAClF,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI;AAChB,QAAI,KAAK;AACT,gBAAY,KAAK,KAAK,KAAK;AAC3B,QAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AACtB,QAAI,cAAc;AAClB,QAAI,WAAW,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AACrH,QAAI,QAAQ;AAAA,EACd;AACF;AAGO,IAAM,cAAN,cAA0B,oBAAsC;AAAA,EAC5D,OAAe;AAAA,EAEL,eAAiC;AAClD,WAAO,EAAE,MAAM,CAAC,GAAG,UAAU,OAAO,SAAS,OAAO,MAAM,MAAM,SAAS,MAAM;AAAA,EACjF;AAAA;AAAA;AAAA,EAImB,aAAa,OAA6D;AAC3F,WAAQ,MAAM,SAAgC,SAAS,EAAE,GAAG,OAAO,MAAM,MAAM,SAAS,KAAK,IAAI;AAAA,EACnG;AAAA;AAAA,EAGmB,cAAc,OAAgD;AAC/E,QAAI,EAAE,UAAU,OAAQ,MAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,SAAS,KAAK;AAAA,EACxE;AAAA,EAES,WAAW,OAAwC;AAC1D,UAAM,WAAW,UAAU,SAAS,EAAE,aAAa,SAAS,EAAE,GAAG,OAAO,SAAS,MAAM,IAAI,KAAK;AAAA,EAClG;AAAA,EAEQ,QAAQ,KAA0B;AACxC,UAAM,EAAE,KAAK,IAAI,KAAK;AACtB,QAAI,SAAS,OAAQ,QAAO,IAAI;AAChC,QAAI,SAAS,OAAQ,QAAO,IAAI;AAChC,QAAI,SAAS,MAAO,QAAO,IAAI;AAC/B,QAAI,SAAS,MAAO,SAAQ,IAAI,IAAI,IAAI,KAAK;AAC7C,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAGQ,SAAS,GAAyF;AACxG,UAAM,MAAM,KAAK,MAAM,UAAU,CAAC,GAAG,KAAK,MAAM,IAAI,EAAE,QAAQ,IAAI,KAAK,MAAM;AAC7E,UAAM,OAAO,IAAI,CAAC,EAAE;AACpB,UAAM,OAAO,KAAK,MAAM,WAAW,KAAK;AACxC,WAAO,EAAE,KAAK,KAAK,CAAC,MAAc,EAAE,SAAS,IAAI,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAC1E;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,GAAG;AACN,WAAK,iBAAiB,KAAK,QAAQ;AACnC;AAAA,IACF;AACA,UAAM,EAAE,KAAK,IAAI,IAAI,KAAK,SAAS,CAAC;AACpC,UAAM,SAAS,EAAE,KAAK,EAAE,MAAM,IAAI;AAGlC,QAAI,KAAK,MAAM,SAAS,QAAQ,KAAK,MAAM,SAAS,QAAQ,CAAC,KAAK,MAAM,SAAS;AAC/E,UAAI,KAAK;AACT,UAAI,YAAY,CAAC,CAAC;AAClB,UAAI,cAAc,KAAK,MAAM;AAC7B,UAAI,YAAY;AAChB,UAAI,UAAU;AACd,UAAI,WAAW;AACf,UAAI,UAAU;AACd,eAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,cAAM,IAAI,EAAE,KAAK,SAAS,IAAI;AAC9B,cAAM,IAAI,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC;AAClC,YAAI,MAAM,EAAG,KAAI,OAAO,GAAG,CAAC;AAAA,YACvB,KAAI,OAAO,GAAG,CAAC;AAAA,MACtB;AACA,UAAI,OAAO;AACX,UAAI,QAAQ;AACZ;AAAA,IACF;AAEA,UAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,QAAQ,GAAG,CAAC;AACpD,QAAI,KAAK,MAAM,SAAS;AACtB,UAAI,KAAK;AACT,UAAI,YAAY,CAAC,CAAC;AAClB,UAAI,cAAc,KAAK,MAAM;AAC7B,UAAI,YAAY,KAAK,MAAM;AAC3B,UAAI,YAAY;AAChB,eAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,cAAM,MAAM,IAAI,CAAC;AACjB,cAAM,KAAK,EAAE,KAAK,SAAS,IAAI;AAC/B,cAAM,KAAK,IAAI,IAAI,CAAC;AACpB,cAAM,KAAK,IAAI,IAAI,CAAC;AACpB,YAAI,UAAU;AACd,YAAI,OAAO,IAAI,IAAI,IAAI,CAAC,CAAC;AACzB,YAAI,OAAO,IAAI,IAAI,IAAI,CAAC,CAAC;AACzB,YAAI,OAAO;AACX,YAAI,SAAS,KAAK,QAAQ,GAAG,KAAK,IAAI,IAAI,EAAE,GAAG,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;AAAA,MACtF;AACA,UAAI,QAAQ;AACZ;AAAA,IACF;AAGA,UAAM,KAAK,KAAK,MAAM,SAAS;AAC/B,QAAI,KAAK;AACT,QAAI,YAAY,KAAK,MAAM;AAC3B,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,YAAM,MAAM,IAAI,CAAC;AACjB,YAAM,KAAK,EAAE,KAAK,SAAS,IAAI;AAC/B,YAAM,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC;AACjC,YAAM,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC;AACjC,UAAI,SAAS,KAAK,QAAQ,GAAG,KAAK,IAAI,IAAI,EAAE,GAAG,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;AAAA,IACtF;AACA,QAAI,QAAQ;AAAA,EACd;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,GAAG;AACN,YAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,UAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,aAAO,MAAM,KAAK,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,MAAM,KAAK,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,KAAK,IAAI,MAAM,IAAI,GAAG,CAAC,KAAK;AAAA,IAC3G;AACA,UAAM,EAAE,KAAK,IAAI,IAAI,KAAK,SAAS,CAAC;AACpC,QAAI,OAAO;AACX,QAAI,OAAO;AACX,eAAW,OAAO,KAAK;AACrB,aAAO,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;AAC5C,aAAO,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;AAAA,IAC9C;AACA,WAAO,MAAM,KAAK,EAAE,KAAK,KAAK,MAAM,KAAK,EAAE,KAAK,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,KAAK,OAAO;AAAA,EAChG;AACF;AAQO,IAAM,YAAN,cAAwB,QAAwB;AAAA,EAC5C,OAAO;AAAA,EAEG,eAA+B;AAChD,WAAO;AAAA,MACL,WAAW;AAAA,MACX,UAAU;AAAA,MACV,SAAS;AAAA,MACT,WAAW;AAAA,MACX,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,UAAgB;AACd,QAAI,KAAK,MAAM,YAAY,EAAG;AAC9B,UAAM,SAAS,KAAK,KAAK,EAAE,MAAM,GAAG;AACpC,QAAI,CAAC,OAAO,OAAQ;AACpB,UAAM,MAAM,OAAO,OAAO,CAAC,KAAK,QAAQ,MAAM,KAAK,IAAI,IAAI,OAAO,IAAI,GAAG,GAAG,CAAC,IAAI,OAAO;AACxF,QAAI,MAAM,EAAG,MAAK,WAAW,EAAE,WAAW,IAAI,CAA4B;AAAA,EAC5E;AAAA;AAAA,EAGQ,OAAe;AACrB,QAAI,KAAK,MAAM,YAAY,EAAG,QAAO,KAAK,MAAM;AAChD,UAAM,QAAQ,KAAK,IAAI,KAAK,QAAQ,CAAC,GAAG,SAAS,CAAC;AAClD,WAAO,QAAQ,IAAI,QAAQ,OAAQ;AAAA,EACrC;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAI;AAC5B,UAAM,WAAW,SAAS,YAAY,EAAE,MAAM,EAAE,IAAI;AACpD,UAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,IAAI,aAAa,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AAC5F,UAAM,SAAS,GAAG,IAAI,GAAG,KAAK;AAC9B,QAAI,CAAC,OAAO,SAAS,KAAK,KAAK,KAAK,IAAI,KAAK,IAAI,IAAK;AACtD,UAAM,MAAM,KAAK,KAAK;AACtB,UAAM,YAAY,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,IAAI;AAC5D,UAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,KAAK,MAAM,eAAe,GAAG,CAAC;AACxE,UAAM,SAAS,EAAE,QAAQ,EAAE,SAAS;AACpC,UAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC;AAC9D,QAAI,QAAQ,EAAE;AACd,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,YAAY;AAChB,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAE9B,YAAM,KAAK,KAAK,IAAI,IAAI,QAAQ;AAChC,YAAM,KAAK,KAAK,IAAI,IAAI,WAAW,GAAG;AACtC,YAAM,OAAO;AACb,YAAM,QAAQ,OAAO,QAAQ,KAAK,YAAY;AAC9C,YAAM,OAAO,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,IAAI,EAAE,IAAI,MAAM;AAC1D,YAAM,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,IAAI,EAAE,IAAI,MAAM;AACzD,YAAM,KAAK,GAAG,IAAI,SAAS,IAAI;AAC/B,YAAM,KAAK,EAAE,GAAG,SAAS,IAAI,IAAI,GAAG,GAAG,SAAS,IAAI,IAAI,GAAG,GAAG,SAAS,IAAI,GAAG,GAAG,GAAG,SAAS,IAAI,KAAK,EAAE;AACxG,UAAI,GAAG,MAAM,QAAQ,GAAG,MAAM,QAAQ,GAAG,MAAM,QAAQ,GAAG,MAAM,MAAM;AACpE,cAAM,KAAK,SAAS;AAEpB,cAAM,QAAQ,CAAC,MAAc,UAAU,GAAG,QAAQ,QAAQ,CAAC,CAAC;AAC5D,YAAI,KAAK,MAAM,UAAU;AACvB,cAAI,cAAc,MAAM,KAAK,MAAM,SAAS;AAC5C,cAAI,UAAU;AACd,cAAI,OAAO,IAAI,GAAG,CAAC;AACnB,cAAI,OAAO,IAAI,GAAG,CAAC;AACnB,cAAI,OAAO;AAAA,QACb;AACA,cAAM,MAAM,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC;AAC/B,cAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;AAC/C,YAAI,YAAY,MAAM,KAAK,KAAK,MAAM,UAAU,KAAK,MAAM,SAAS;AACpE,YAAI,SAAS,KAAK,QAAQ,GAAG,KAAK,OAAO,KAAK;AAC9C,YAAI,KAAK,MAAM,YAAY;AACzB,cAAI,cAAc,MAAM,KAAK,KAAK,MAAM,gBAAgB,KAAK,MAAM,eAAe;AAClF,cAAI,WAAW,KAAK,QAAQ,GAAG,KAAK,OAAO,KAAK;AAAA,QAClD;AAAA,MACF;AACA,cAAQ;AAAA,IACV;AACA,QAAI,QAAQ;AAAA,EACd;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,UAAM,OAAO,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC;AAChC,UAAM,OAAO,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC;AAChC,UAAM,OAAO,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,IAAI;AACpC,UAAM,OAAO,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,IAAI;AACpC,WAAO,MAAM,KAAK,QAAQ,MAAM,KAAK,QAAQ,MAAM,KAAK,QAAQ,MAAM,KAAK;AAAA,EAC7E;AACF;;;AC/jBA,SAASE,eAAa,WAA2B;AAC/C,SAAO,KAAK,IAAI,GAAG,YAAY,IAAI,CAAC;AACtC;AAGA,SAAS,SAAS,KAA2B,MAAyB;AACpE,QAAM,QAAQ,OAAO,IAAI;AACzB,MAAI,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO,CAAC;AACrC,SAAO,IAAI,OAAO,CAAC,QAAQ,OAAO,IAAI,IAAI,KAAK,KAAK;AACtD;AAwBA,IAAM,WAAW,CAAC,WAA6B,EAAE,SAAS,MAAM,OAAO,OAAO,GAAG,OAAO,QAAQ;AAChG,IAAM,cAAc,CAAC,WAAW,WAAW,SAAS;AAU7C,IAAM,eAAN,cAA2B,QAA2B;AAAA,EAClD,OAAO;AAAA,EAEG,eAAkC;AACnD,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,iBAAiB,CAAC,GAAG,GAAG,CAAC;AAAA,MACzB,SAAS,CAAC,MAAM,OAAO,KAAK;AAAA,MAC5B,YAAY,YAAY,IAAI,QAAQ;AAAA,MACpC,YAAY,YAAY,IAAI,QAAQ;AAAA,MACpC,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA;AAAA,EAGmB,cAAc,QAAiD;AAChF,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,SAAS,KAAK,OAAO,QAAQ,IAAI,MAAM,KAAK,EAAE;AAAA,EAChF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,SAAuB;AAC/B,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,UAAM,MAAM,SAAS,KAAK,KAAK,GAAG,OAAO,IAAI;AAC7C,UAAM,IAAI,KAAK;AACf,QAAI,QAAQ;AACZ,QAAI,SAAS;AACb,QAAI,OAAO;AACX,UAAM,MAAoB,CAAC;AAC3B,eAAW,OAAO,KAAK;AACrB,YAAM,SAAS,IAAI,UAAU;AAC7B,YAAM,QAAQ,SAAS,KAAK,EAAE,MAAM;AACpC,eAAS,QAAQ;AACjB,gBAAU,QAAQ,QAAQ;AAC1B,cAAQ;AACR,UAAI,QAAQ,EAAG;AACf,YAAM,OAAO,QAAQ;AACrB,YAAM,YAAY,KAAK,KAAK,KAAK,IAAI,GAAG,SAAS,OAAO,OAAO,IAAI,CAAC;AACpE,YAAM,UAAU,EAAE,gBAAgB,IAAI,CAAC,GAAG,MAAO,EAAE,QAAQ,CAAC,IAAK,EAAE,cAAc,YAAa,OAAO,IAAK,MAAM,YAAY,IAAK,IAAK;AACtI,UAAI,KAAK,EAAE,MAAM,IAAI,MAAM,MAAM,OAAO,QAAQ,IAAI,CAAC,MAAO,MAAM,OAAO,OAAO,OAAO,CAAE,GAAG,OAAO,QAAQ,IAAI,CAAC,MAAO,MAAM,OAAO,OAAO,OAAO,CAAE,EAAE,CAAC;AAAA,IACzJ;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,OAAO,SAAgC,OAAyC,UAA6B;AACnH,UAAM,MAAe,CAAC;AACtB,eAAW,KAAK,SAAS;AACvB,YAAM,IAAI,MAAM,CAAC;AACjB,UAAI,MAAM,KAAM;AAChB,YAAM,IAAI,SAAS,IAAI,EAAE,IAAI;AAC7B,YAAM,IAAI,SAAS,IAAI,CAAC;AACxB,UAAI,MAAM,QAAQ,MAAM,KAAM,KAAI,KAAK,EAAE,GAAG,EAAE,CAAC;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAEiB,aAAa;AAAA,IAC5B,IAAI,UAAU;AAAA,MACZ,YAAY,MAAM;AAChB,cAAM,WAAW,KAAK,YAAY;AAClC,cAAM,OAAO,KAAK,OAAO,EAAE,GAAG,EAAE;AAChC,eAAO,YAAY,OAAO,SAAS,IAAI,KAAK,IAAI,IAAI;AAAA,MACtD;AAAA,MACA,MAAM,MAAM;AACV,cAAM,OAAO,KAAK,OAAO,EAAE,GAAG,EAAE;AAChC,eAAO,OAAO,KAAK,YAAY,KAAK,IAAI,IAAI;AAAA,MAC9C;AAAA,MACA,OAAO,MAAM,UAAU,KAAK,MAAM,WAAW,CAAC;AAAA,MAC9C,SAAS,MAAM,KAAK,MAAM,kBAAkB,KAAK,aAAa;AAAA,IAChE,CAAC;AAAA,EACH;AAAA,EAEmB,YAAiD;AAClE,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,UAAU,KAAK,OAAO;AAC5B,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,UAAM,IAAI,SAAS,KAAK,cAAc,QAAQ,QAAQ,IAAI;AAC1D,QAAI,GAAG;AACL,UAAI,KAAK;AACT,UAAI,YAAY,CAAC,CAAC;AAClB,UAAI,YAAY,KAAK,MAAM;AAC3B,UAAI,UAAU;AACd,UAAI,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,GAAG,KAAK,KAAK,CAAC;AACrC,UAAI,KAAK;AACT,UAAI,QAAQ;AAAA,IACd;AACA,UAAMC,QAAO,KAAK,OAAO,SAAS,CAAC,MAAM,EAAE,MAAM,QAAQ;AACzD,QAAIA,MAAK,SAAS,GAAG;AACnB,UAAI,GAAG;AACL,mBAAW,KAAK,0BAA0B,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,GAAG,GAAG,KAAK,OAAO;AAAA,UACjF,YAAY,UAAU,WAAW,IAAI;AAAA,QACvC,CAAC;AAAA,MACH;AACA;AAAA,IACF;AACA,UAAM,QAAQ,KAAK;AAEnB,UAAM,OAAO,MAAM,kBAAkB,MAAM,QAAQ,CAAC,IAAI,UAAU,KAAK,KAAK,IAAI;AAChF,QAAI,MAAM;AACR,YAAM,QAAQ,KAAK,OAAO,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,QAAQ;AACtE,YAAM,QAAQ,KAAK,OAAO,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,QAAQ;AACtE,UAAI,MAAM,SAAS,KAAK,MAAM,SAAS,GAAG;AACxC,YAAI,KAAK;AACT,YAAI,YAAY;AAChB,YAAI,UAAU;AACd,YAAI,OAAO,MAAM,CAAC,EAAG,GAAG,MAAM,CAAC,EAAG,CAAC;AACnC,mBAAW,SAAS,MAAM,MAAM,CAAC,EAAG,KAAI,OAAO,MAAM,GAAG,MAAM,CAAC;AAC/D,mBAAW,SAAS,CAAC,GAAG,KAAK,EAAE,QAAQ,EAAG,KAAI,OAAO,MAAM,GAAG,MAAM,CAAC;AACrE,YAAI,UAAU;AACd,YAAI,KAAK;AACT,YAAI,QAAQ;AAAA,MACd;AAAA,IACF;AACA,UAAM,SAAS,CAAC,QAAiB,UAAwC;AACvE,UAAI,OAAO,SAAS,EAAG;AACvB,UAAI,KAAK;AACT,kBAAY,KAAK,KAAK;AACtB,UAAI,UAAU;AACd,UAAI,OAAO,OAAO,CAAC,EAAG,GAAG,OAAO,CAAC,EAAG,CAAC;AACrC,iBAAW,SAAS,OAAO,MAAM,CAAC,EAAG,KAAI,OAAO,MAAM,GAAG,MAAM,CAAC;AAChE,UAAI,OAAO;AACX,UAAI,QAAQ;AAAA,IACd;AACA,aAAS,IAAI,GAAG,IAAI,MAAM,gBAAgB,QAAQ,KAAK;AACrD,iBAAW,CAAC,OAAO,IAAI,KAAK;AAAA,QAC1B,CAAC,MAAM,YAAY,OAAO;AAAA,QAC1B,CAAC,MAAM,YAAY,OAAO;AAAA,MAC5B,GAAY;AACV,cAAM,OAAO,MAAM,CAAC;AACpB,YAAI,CAAC,MAAM,WAAW,CAAC,MAAM,QAAQ,CAAC,EAAG;AACzC,eAAO,KAAK,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,KAAK,MAAM,QAAQ,GAAG,EAAE,GAAG,KAAK,OAAO,WAAW,KAAK,OAAO,WAAW,KAAK,OAAO,WAAW,KAAK,MAAM,CAAC;AAAA,MAC1J;AAAA,IACF;AACA,WAAOA,OAAM,KAAK,KAAK;AAAA,EACzB;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAMA,QAAO,KAAK,OAAO,KAAK,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,QAAQ;AAC/D,QAAIA,MAAK,SAAS,GAAG;AACnB,YAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,YAAM,IAAI,SAAS,KAAK,cAAc,QAAQ,QAAQ,IAAI;AAC1D,aAAO,CAAC,CAAC,KAAK,KAAK,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC,KAAK;AAAA,IAC5D;AACA,UAAM,YAAYD,eAAa,KAAK,MAAM,SAAS;AACnD,aAAS,IAAI,GAAG,IAAIC,MAAK,SAAS,GAAG,KAAK;AACxC,UAAI,kBAAkB,OAAOA,MAAK,CAAC,GAAIA,MAAK,IAAI,CAAC,CAAE,KAAK,UAAW,QAAO;AAAA,IAC5E;AACA,WAAO;AAAA,EACT;AACF;AAOA,SAAS,iBACP,OACA,MACA,SACoK;AACpK,QAAM,aAAa,MAAM,OAAO,CAAC,MAAM,OAAO,EAAE,WAAW,YAAY,EAAE,SAAS,CAAC;AACnF,MAAI,WAAW,SAAS,KAAK,OAAO,EAAG,QAAO;AAC9C,MAAI,MAAM;AACV,MAAI,MAAM;AACV,aAAW,OAAO,YAAY;AAC5B,UAAM,KAAK,IAAI,KAAK,IAAI,GAAG;AAC3B,UAAM,KAAK,IAAI,KAAK,IAAI,IAAI;AAAA,EAC9B;AACA,MAAI,EAAE,MAAM,KAAM,QAAO;AACzB,QAAM,UAAU,MAAM,OAAO;AAC7B,QAAM,OAAO,IAAI,MAAc,IAAI,EAAE,KAAK,CAAC;AAC3C,QAAM,MAAM;AAAA,IACV,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,IACN,KAAK,CAAC;AAAA,EACR;AACA,MAAI,QAAQ;AACZ,aAAW,OAAO,YAAY;AAC5B,UAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,GAAG,KAAK,OAAO,IAAI,MAAM,OAAO,MAAM,CAAC,CAAC;AACnF,UAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,GAAG,KAAK,OAAO,IAAI,OAAO,OAAO,MAAM,CAAC,CAAC;AACrF,UAAM,QAAS,IAAI,UAAqB,UAAU,SAAS;AAC3D,aAAS,IAAI,QAAQ,KAAK,SAAS,IAAK,MAAK,CAAC,KAAK;AACnD,aAAS,IAAI;AACb,QAAI,WAAW;AACf,aAAS,IAAI,GAAG,IAAI,MAAM,IAAK,KAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAG,YAAW;AACxE,QAAI,IAAI,KAAK,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO,WAAW,OAAO,OAAO,CAAC;AACvE,QAAI,UAAU,GAAG;AACf,UAAI,MAAM;AACV,UAAI,OAAO;AACX,UAAI,UAAU,KAAK,QAAQ;AAC3B,aAAO,UAAU,QAAQ,YAAY,MAAM,KAAK,OAAO,OAAO,IAAI;AAChE,cAAM,QAAQ,MAAM,IAAI,KAAK,MAAM,CAAC,IAAI;AACxC,cAAM,QAAQ,OAAO,OAAO,IAAI,KAAK,OAAO,CAAC,IAAI;AACjD,YAAI,SAAS,MAAO,YAAW,KAAK,EAAE,IAAI;AAAA,YACrC,YAAW,KAAK,EAAE,GAAG;AAAA,MAC5B;AACA,UAAI,IAAI,KAAK,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO,OAAO,KAAK,OAAO,CAAC;AACjE,UAAI,IAAI,KAAK,EAAE,MAAM,IAAI,MAAM,OAAO,MAAM,MAAM,OAAO,CAAC;AAAA,IAC5D;AAAA,EACF;AACA,SAAO;AACT;AA+DA,IAAM,gBAAkE;AAAA,EACtE,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,eAAe;AAAA,EACf,cAAc;AAAA,EACd,aAAa;AACf;AAGA,IAAe,oBAAf,cAA2F,QAAW;AAAA,EAI1F,SAAS,OAAqC;AACtD,UAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO;AAC3C,QAAI,KAAK,MAAM,eAAe,SAAS;AACrC,UAAI,MAAM;AACV,UAAI,MAAM;AACV,iBAAW,OAAO,OAAO;AACvB,cAAM,KAAK,IAAI,KAAK,IAAI,GAAG;AAC3B,cAAM,KAAK,IAAI,KAAK,IAAI,IAAI;AAAA,MAC9B;AACA,UAAI,EAAE,MAAM,KAAM,QAAO;AAEzB,YAAM,OAAO,KAAK,SAAS;AAC3B,UAAI,SAAS,KAAM,QAAO;AAC1B,YAAM,OAAO,KAAK,MAAM,MAAM,QAAQ,OAAO,KAAK;AAClD,aAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,CAAC;AAAA,IACxC;AACA,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC;AAAA,EACpD;AAAA;AAAA;AAAA,EAIU,OAAO,OAAmD;AAClE,UAAM,OAAO,cAAc,OAAO,KAAK,SAAS,KAAK,CAAC;AACtD,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,WAAW,KAAK,OAAO,CAAC,MAAM,KAAK,MAAO,IAAI,SAAS,KAAK,IAAI,EAAG,SAAS,IAAI,MAAO,CAAC;AAC9F,UAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,eAAe,CAAC,IAAI;AACzE,UAAM,QAAQ,KAAK,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,QAAQ,CAAC;AACnD,QAAI,MAAM;AACV,QAAI,OAAO;AACX,QAAI,UAAU,KAAK,QAAQ,EAAG;AAC9B,WAAO,UAAU,KAAK,UAAU,QAAQ,YAAY,MAAM,KAAK,OAAO,KAAK,SAAS,IAAI;AACtF,YAAM,QAAQ,MAAM,IAAI,KAAK,MAAM,CAAC,EAAG,SAAS;AAChD,YAAM,QAAQ,OAAO,KAAK,SAAS,IAAI,KAAK,OAAO,CAAC,EAAG,SAAS;AAChE,UAAI,SAAS,MAAO,YAAW,KAAK,EAAE,IAAI,EAAG;AAAA,UACxC,YAAW,KAAK,EAAE,GAAG,EAAG;AAAA,IAC/B;AACA,WAAO,EAAE,MAAM,UAAU,KAAK,MAAM,QAAQ;AAAA,EAC9C;AAAA;AAAA,EAGU,cAA8E;AACtF,UAAM,IAAI,KAAK,OAAO,KAAK,MAAM,CAAC;AAClC,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,MAAM,EAAE,KAAK,EAAE,QAAQ;AAC7B,WAAO;AAAA,MACL,MAAM,IAAI,WAAW,IAAI,aAAa;AAAA,MACtC,KAAK,EAAE,UAAU,IAAI,EAAE,KAAK,EAAE,IAAI,EAAG,YAAY;AAAA,MACjD,KAAK,EAAE,UAAU,IAAI,EAAE,KAAK,EAAE,GAAG,EAAG,WAAW;AAAA,IACjD;AAAA,EACF;AAAA,EAEiB,aAAc,CAAC,OAAO,OAAO,KAAK,EAAY;AAAA,IAC7D,CAAC,QACC,IAAI,UAAU;AAAA,MACZ,YAAY,MAAM;AAChB,cAAM,WAAW,KAAK,YAAY;AAClC,cAAM,QAAQ,KAAK,YAAY,IAAI,GAAG;AACtC,eAAO,YAAY,UAAU,QAAQ,UAAU,SAAY,SAAS,IAAI,KAAK,IAAI;AAAA,MACnF;AAAA,MACA,MAAM,MAAM;AACV,cAAM,QAAQ,KAAK,YAAY,IAAI,GAAG;AACtC,eAAO,UAAU,QAAQ,UAAU,SAAY,KAAK,KAAK,YAAY,KAAK;AAAA,MAC5E;AAAA,MACA,OAAO,MAAM,UAAU,KAAK,MAAM,GAAG,GAAG,OAAO,GAAa,CAAC;AAAA,MAC7D,SAAS,MAAM,KAAK,MAAM,0BAA0B,KAAK,MAAM,GAAG,GAAG,SAAS,MAAM,QAAQ,KAAK,aAAa;AAAA,IAChH,CAAC;AAAA,EACL;AAAA,EAEmB,YAAiD;AAClE,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMmB,cAAc,OAAgD;AAC/E,UAAM,UAAU,OAAO,YAAY,OAAO,QAAQ,aAAa,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,EAAE,OAAO,UAAU,OAAO,KAAK,MAAM,CAAC;AACzH,UAAM,IAAI,EAAE,GAAG,KAAK,QAAQ,GAAG,QAAQ;AACvC,UAAM,KAAK,CAAC,OAAe,UAA0B,UAAU,OAAO,QAAQ,QAAQ,KAAK,CAAC;AAC5F,SAAK,SAAS;AAAA,MACZ,GAAG;AAAA,MACH,SAAS,GAAG,EAAE,SAAS,GAAG;AAAA,MAC1B,WAAW,GAAG,EAAE,WAAW,GAAG;AAAA,MAC9B,kBAAkB,GAAG,EAAE,kBAAkB,GAAG;AAAA,MAC5C,oBAAoB,GAAG,EAAE,oBAAoB,GAAG;AAAA,MAChD,UAAU,GAAG,EAAE,UAAU,GAAG;AAAA,MAC5B,UAAU,GAAG,EAAE,UAAU,GAAG;AAAA,MAC5B,UAAU,GAAG,EAAE,UAAU,GAAG;AAAA,MAC5B,oBAAoB,GAAG,EAAE,UAAU,GAAG;AAAA,MACtC,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,mBAAmB,GAAG,EAAE,UAAU,GAAG;AAAA,MACrC,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB,iBAAiB,KAAK,IAAI,IAAI,EAAE,eAAe;AAAA,MAC/C,UAAU,UAAU,EAAE,UAAU,CAAC;AAAA,MACjC,wBAAwB;AAAA,MACxB,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,OAAO,KAAK,KAAK,QAAQ;AAC/B,QAAI,CAAC,KAAM;AACX,UAAM,QAAQ,KAAK,MAAM;AACzB,UAAM,IAAI,KAAK;AAEf,QAAI,QAAQ,EAAE,QAAQ,IAAI,GAAG;AAC3B,UAAI,KAAK;AACT,UAAI,YAAY,EAAE;AAClB,UAAI,SAAS,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,IAAI,SAAS,MAAM;AAC3D,UAAI,QAAQ;AAAA,IACd;AACA,QAAI,EAAE,SAAS;AACb,UAAI,KAAK;AACT,UAAI,cAAc,UAAU,WAAW,GAAG;AAC1C,UAAI,YAAY;AAChB,UAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AACtB,UAAI,WAAW,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,IAAI,SAAS,MAAM;AAC7D,UAAI,QAAQ;AAAA,IACd;AACA,UAAM,IAAI,KAAK,OAAO,KAAK;AAC3B,QAAI,CAAC,GAAG;AACN,iBAAW,KAAK,6BAA6B,EAAE,IAAI,KAAK,KAAK,KAAK,MAAM,GAAG,GAAG,GAAG,GAAG,KAAK,OAAO;AAAA,QAC9F,OAAO;AAAA,QACP,YAAY,UAAU,WAAW,IAAI;AAAA,MACvC,CAAC;AACD;AAAA,IACF;AACA,UAAM,EAAE,MAAM,UAAU,KAAK,MAAM,QAAQ,IAAI;AAC/C,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AACvD,QAAI,aAAa,EAAG;AACpB,UAAM,YAAa,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,EAAE,YAAY,CAAC,IAAK;AACtF,UAAM,YAAY,EAAE,cAAc;AAElC,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,CAAC;AAClB,eAAW,CAAC,GAAG,GAAG,KAAK,KAAK,QAAQ,GAAG;AACrC,YAAM,KAAK,SAAS,IAAI,IAAI,SAAS;AACrC,YAAM,KAAK,SAAS,IAAI,IAAI,QAAQ;AACpC,UAAI,OAAO,QAAQ,OAAO,KAAM;AAChC,YAAM,MAAM,KAAK,IAAI,IAAI,EAAE;AAC3B,YAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,EAAE,IAAI,CAAC;AAC9C,YAAM,cAAc,UAAU,KAAK,KAAK,OAAO,KAAK;AACpD,YAAM,UAAU,cAAc,EAAE,mBAAmB,EAAE;AACrD,YAAM,YAAY,cAAc,EAAE,qBAAqB,EAAE;AAEzD,YAAM,OAAO,CAAC,QAAgB,MAAc;AAC1C,YAAI,UAAW,KAAI,SAAS,KAAK,KAAK,SAAS,GAAG,KAAK,GAAG,IAAI;AAAA,YACzD,KAAI,SAAS,KAAK,KAAK,QAAQ,KAAK,GAAG,IAAI;AAAA,MAClD;AACA,UAAI,QAAQ;AACZ,UAAI,EAAE,aAAa;AACjB,YAAI,EAAE,WAAW,UAAU;AACzB,gBAAM,MAAO,IAAI,WAAW,YAAa;AACzC,gBAAM,QAAS,IAAI,aAAa,YAAa;AAC7C,cAAI,YAAY;AAChB,eAAK,GAAG,GAAG;AACX,cAAI,YAAY;AAChB,eAAK,KAAK,KAAK;AACf,kBAAQ,MAAM;AAAA,QAChB,WAAW,EAAE,WAAW,SAAS;AAC/B,gBAAM,QAAQ,IAAI,WAAW,IAAI;AACjC,cAAI,YAAY,SAAS,IAAI,UAAU;AACvC,kBAAS,KAAK,IAAI,KAAK,IAAI,YAAa;AACxC,eAAK,GAAG,KAAK;AAAA,QACf,OAAO;AACL,cAAI,YAAY;AAChB,kBAAS,IAAI,SAAS,YAAa;AACnC,eAAK,GAAG,KAAK;AAAA,QACf;AAAA,MACF;AACA,UAAI,EAAE,YAAY;AAChB,cAAM,QAAQ,EAAE,WAAW,UAAU,IAAI,WAAW,IAAI,aAAa,IAAI;AACzE,cAAM,KAAK,EAAE,GAAG,YAAY,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,QAAQ,GAAG,GAAG,MAAM,OAAO,EAAE;AACzF,mBAAW,KAAK,WAAW,KAAK,GAAG,IAAI,EAAE,GAAG,KAAK,OAAO,WAAW,EAAE,YAAY,GAAG,EAAE,OAAO,YAAY,UAAU,OAAO,CAAC;AAAA,MAC7H;AAAA,IACF;AAEA,UAAM,QAAQ,CAAC,GAAkBA,UAAsB;AACrD,UAAI,MAAM,QAAQ,CAACA,MAAK,QAAS;AACjC,UAAI,cAAcA,MAAK;AACvB,UAAI,YAAYA,MAAK;AACrB,UAAI,YAAY,YAAYA,MAAK,OAAOA,MAAK,KAAK,CAAC;AACnD,UAAI,UAAU;AACd,UAAI,OAAO,KAAK,IAAI,CAAC;AACrB,UAAI,OAAO,KAAK,IAAI,CAAC;AACrB,UAAI,OAAO;AAAA,IACb;AACA,UAAM,MAAM,KAAK,QAAQ;AACzB,UAAM,SAAS,KAAK,IAAI,WAAW,IAAI,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,OAAO,EAAE,UAAU,OAAO,EAAE,UAAU,OAAO,EAAE,SAAS,CAAC;AAC1I,QAAI,UAAU,GAAG;AACf,YAAM,SAAS,IAAI,KAAK,IAAI,EAAG,SAAS,GAAG,EAAE,SAAS,EAAE,YAAY,OAAO,EAAE,UAAU,OAAO,EAAE,UAAU,OAAO,EAAE,SAAS,CAAC;AAC7H,YAAM,SAAS,IAAI,KAAK,GAAG,EAAG,QAAQ,GAAG,EAAE,SAAS,EAAE,YAAY,OAAO,EAAE,UAAU,OAAO,EAAE,UAAU,OAAO,EAAE,SAAS,CAAC;AAAA,IAC7H;AAEA,QAAI,EAAE,iBAAiB,EAAE,cAAc;AACrC,YAAM,aAAa,iBAAiB,OAAO,KAAK,SAAS,KAAK,GAAG,OAAO;AACxE,UAAI,YAAY;AACd,cAAM,WAAW,CAAC,QAAsDA,UAAsB;AAC5F,cAAI,cAAcA,MAAK;AACvB,cAAI,YAAYA,MAAK;AACrB,cAAI,YAAY,YAAYA,MAAK,OAAOA,MAAK,KAAK,CAAC;AACnD,cAAI,UAAU;AACd,cAAI,UAAU;AACd,qBAAW,SAAS,QAAQ;AAC1B,kBAAM,IAAI,SAAS,IAAI,MAAM,IAAI;AACjC,kBAAM,IAAI,SAAS,IAAI,MAAM,KAAK;AAClC,gBAAI,MAAM,QAAQ,MAAM,KAAM;AAC9B,gBAAI,QAAS,KAAI,OAAO,GAAG,CAAC;AAAA,gBACvB,KAAI,OAAO,GAAG,CAAC;AACpB,sBAAU;AAAA,UACZ;AACA,cAAI,QAAS,KAAI,OAAO;AAAA,QAC1B;AACA,YAAI,EAAE,cAAe,UAAS,WAAW,KAAK,EAAE,SAAS,MAAM,OAAO,EAAE,oBAAoB,OAAO,EAAE,oBAAoB,OAAO,EAAE,mBAAmB,CAAC;AACtJ,YAAI,EAAE,cAAc;AAClB,gBAAM,KAAK,EAAE,SAAS,MAAM,OAAO,EAAE,mBAAmB,OAAO,EAAE,mBAAmB,OAAO,EAAE,kBAAkB;AAC/G,mBAAS,WAAW,KAAK,EAAE;AAC3B,mBAAS,WAAW,KAAK,EAAE;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AACA,QAAI,QAAQ;AAAA,EACd;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,OAAO,KAAK,KAAK,QAAQ;AAC/B,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,MAAM,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK;AAAA,EACxD;AACF;AAQO,IAAM,0BAAN,cAAsC,kBAAqC;AAAA,EACvE,OAAO;AAAA,EAEG,eAAkC;AACnD,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,cAAc;AAAA,MACd,WAAW;AAAA,MACX,SAAS;AAAA,MACT,WAAW;AAAA,MACX,kBAAkB;AAAA,MAClB,oBAAoB;AAAA,MACpB,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,eAAe;AAAA,MACf,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB,UAAU;AAAA,MACV,wBAAwB;AAAA,MACxB,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,QAAqB;AAC7B,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK;AACpB,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO,CAAC;AACtB,QAAI,KAAK,MAAM,aAAa;AAC1B,aAAO,SAAS,KAAK,KAAK,GAAG,OAAO,EAAE,IAAI,KAAK,OAAO,EAAE,IAAI,IAAI,EAAE,OAAO,EAAE,IAAI;AAAA,IACjF;AACA,WAAO,YAAY,KAAK,KAAK,GAAG,EAAE,MAAM,EAAE,IAAI;AAAA,EAChD;AAAA,EAEU,KAAK,UAAuD;AACpE,UAAM,CAAC,IAAI,EAAE,IAAI,KAAK,aAAa,QAAQ;AAC3C,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,UAAM,KAAK,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC;AAC9B,WAAO,EAAE,IAAI,IAAI,KAAK,MAAM,cAAc,SAAS,QAAQ,KAAK,IAAI,GAAG,GAAG,GAAG,CAAC,EAAE;AAAA,EAClF;AACF;AAGO,IAAM,wBAAN,cAAoC,kBAAgC;AAAA,EAChE,OAAO;AAAA,EAEG,eAA6B;AAC9C,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,cAAc;AAAA,MACd,WAAW;AAAA,MACX,SAAS;AAAA,MACT,WAAW;AAAA,MACX,kBAAkB;AAAA,MAClB,oBAAoB;AAAA,MACpB,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,MACV,eAAe;AAAA,MACf,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,oBAAoB;AAAA,MACpB,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB,mBAAmB;AAAA,MACnB,UAAU;AAAA,MACV,wBAAwB;AAAA,MACxB,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,QAAqB;AAC7B,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,WAAO,SAAS,KAAK,KAAK,GAAG,OAAO,IAAI;AAAA,EAC1C;AAAA,EAEU,KAAK,UAAuD;AACpE,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,SAAS,IAAI,OAAO,IAAI;AAClC,QAAI,MAAM,KAAM,QAAO;AACvB,WAAO,EAAE,IAAI,GAAG,IAAI,SAAS,MAAM;AAAA,EACrC;AACF;;;ACttBA,SAASC,OAAM,GAAUC,MAA8D,MAAM,GAAY;AACvG,SACE,EAAE,KAAKA,KAAI,IAAI,OAAO,EAAE,KAAKA,KAAI,IAAIA,KAAI,QAAQ,OAAO,EAAE,KAAKA,KAAI,IAAI,OAAO,EAAE,KAAKA,KAAI,IAAIA,KAAI,SAAS;AAE9G;AAWO,IAAM,YAAN,cAAwB,QAAoB;AAAA,EACxC,OAAO;AAAA,EAER,UAAmC;AAAA,EACnC,cAAc;AAAA,EAEH,eAA2B;AAC5C,WAAO,EAAE,SAAS,IAAI,OAAO,KAAK,SAAS,EAAE;AAAA,EAC/C;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,MAAM,UAAoF;AAClG,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,MAAM,KAAK;AAC3C,UAAMC,SAAQ,KAAK,WAAW,KAAK,QAAQ,eAAe,IAAI,KAAK,QAAQ,gBAAgB,KAAK,QAAQ,eAAe;AACvH,WAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,QAAQ,QAAQA,OAAM;AAAA,EACxD;AAAA,EAEQ,eAAqB;AAC3B,UAAM,SAAS,KAAK,MAAM;AAC1B,QAAI,CAAC,UAAU,WAAW,KAAK,eAAe,OAAO,UAAU,YAAa;AAI5E,UAAM,OAAO,kBAAkB,MAAM;AACrC,QAAI,MAAM;AACR,WAAK,cAAc;AACnB,WAAK,UAAU;AACf;AAAA,IACF;AACA,SAAK,cAAc;AACnB,UAAM,QAAQ,IAAI,MAAM;AACxB,UAAM,SAAS,MAAM;AACnB,uBAAiB,QAAQ,KAAK;AAC9B,WAAK,UAAU;AACf,WAAK,cAAc;AAAA,IACrB;AACA,UAAM,MAAM;AAAA,EACd;AAAA;AAAA,EAGS,cAAc,UAA6B;AAClD,QAAI,CAAC,KAAK,MAAM,QAAS,QAAO,CAAC;AACjC,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG,QAAO,CAAC;AAChB,WAAO;AAAA,MACL,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE;AAAA,MACjB,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE;AAAA,MAC3B,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO;AAAA,MAC5B,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,EAAE,IAAI,EAAE,OAAO;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKS,SAAS,aAAqB,OAAc,UAA0B;AAC7E,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ;AACb,UAAM,SAAS,KAAK,cAAc,QAAQ,QAAQ;AAClD,QAAI,CAAC,OAAQ;AAEb,UAAM,KAAK,gBAAgB,KAAK,gBAAgB,IAAI,OAAO,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO;AAC1F,SAAK,WAAW,EAAE,OAAO,KAAK,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC,EAAE,CAAC;AAAA,EACzD;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,SAAK,aAAa;AAClB,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,QAAI,CAAC,EAAG;AACR,QAAI,KAAK,WAAW,KAAK,MAAM,SAAS;AACtC,UAAI,KAAK;AACT,UAAI,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC;AAC7D,UAAI,UAAU,KAAK,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM;AACvD,UAAI,QAAQ;AACZ,UAAI,KAAK,UAAU,cAAc,KAAK,UAAU,WAAW;AACzD,YAAI,KAAK;AACT,YAAI,cAAc,KAAK,MAAM;AAC7B,YAAI,YAAY;AAChB,YAAI,YAAY,CAAC,CAAC;AAClB,YAAI,WAAW,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM;AAC1C,YAAI,QAAQ;AAAA,MACd;AACA;AAAA,IACF;AAEA,QAAI,KAAK;AACT,QAAI,YAAY,CAAC,GAAG,CAAC,CAAC;AACtB,QAAI,cAAc,KAAK,MAAM;AAC7B,QAAI,YAAY;AAChB,QAAI,WAAW,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM;AAC1C,QAAI,YAAY,CAAC,CAAC;AAClB,QAAI,OAAO;AACX,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,YAAY;AAChB,QAAI,eAAe;AACnB,QAAI,SAAS,2BAA2B,EAAE,IAAI,EAAE,QAAQ,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC;AAC7E,QAAI,QAAQ;AAAA,EACd;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,IAAI,KAAK,MAAM,QAAQ;AAC7B,WAAO,CAAC,CAAC,KAAKF,OAAM,OAAO,CAAC;AAAA,EAC9B;AACF;AASO,IAAM,YAAN,cAAwB,QAAoB;AAAA,EACxC,OAAe;AAAA,EAEL,eAA2B;AAC5C,WAAO,EAAE,OAAO,aAAM,MAAM,GAAG;AAAA,EACjC;AAAA;AAAA,EAGU,YAAoB;AAC5B,WAAO;AAAA,EACT;AAAA,EAEmB,cAAc,OAAgD;AAC/E,QAAI,EAAE,UAAU,OAAQ,MAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,MAAM,KAAK,UAAU,EAAE;AAAA,EACjF;AAAA,EAEA,kBAA0B;AACxB,WAAO;AAAA,EACT;AAAA,EAEU,SAAiB;AACzB,WAAO,KAAK,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,IAAI;AAAA,EAC7C;AAAA;AAAA,EAGU,kBAA2B;AACnC,WAAO;AAAA,EACT;AAAA,EAEQ,aAAsC;AAC5C,QAAI,KAAK,gBAAgB,EAAG,QAAO;AACnC,UAAM,MAAM,KAAK,SAAS,KAAK,MAAM,KAAK;AAC1C,WAAO,MAAM,aAAa,KAAK,MAAM,KAAK,cAAc,CAAC,IAAI;AAAA,EAC/D;AAAA,EAEA,MAAM,KAA+B,UAA0B;AAC7D,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ;AACb,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG;AACR,UAAM,OAAO,KAAK,IAAI,IAAI,KAAK,MAAM,IAAI;AACzC,UAAM,QAAQ,KAAK,WAAW;AAC9B,QAAI,OAAO;AACT,UAAI,UAAU,OAAO,EAAE,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,GAAG,MAAM,IAAI;AAC/D;AAAA,IACF;AACA,QAAI,KAAK;AACT,QAAI,OAAO,GAAG,IAAI;AAClB,QAAI,YAAY;AAChB,QAAI,eAAe;AAEnB,QAAI,YAAY,KAAK,MAAM;AAC3B,QAAI,SAAS,KAAK,MAAM,SAAS,KAAK,EAAE,GAAG,EAAE,CAAC;AAC9C,QAAI,QAAQ;AAAA,EACd;AAAA;AAAA,EAGS,cAAc,UAA6B;AAClD,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG,QAAO,CAAC;AAChB,UAAM,IAAI,KAAK,OAAO;AACtB,WAAO;AAAA,MACL,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE;AAAA,MACzB,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE;AAAA,MACzB,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE;AAAA,MACzB,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE;AAAA,IAC3B;AAAA,EACF;AAAA,EAES,SAAS,cAAsB,OAAc,UAA0B;AAC9E,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ;AACb,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG;AACR,UAAM,IAAI,KAAK,IAAI,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,GAAG,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,CAAC;AACnE,SAAK,WAAW,EAAE,MAAM,KAAK,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAwB;AAAA,EACvG;AAAA,EAEA,QAAQ,OAAc,UAA6B;AACjD,UAAM,SAAS,KAAK,QAAQ,CAAC;AAC7B,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,IAAI,KAAK,cAAc,QAAQ,QAAQ;AAC7C,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,IAAI,KAAK,OAAO;AACtB,WAAO,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK,KAAK,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK;AAAA,EACpE;AACF;AAEO,IAAM,cAAN,cAA0B,UAAU;AAAA,EACvB,OAAO;AAAA,EAEN,eAA2B;AAC5C,WAAO,EAAE,OAAO,aAAM,MAAM,GAAG;AAAA,EACjC;AAAA,EAEmB,YAAoB;AACrC,WAAO;AAAA,EACT;AACF;AAEO,IAAM,WAAN,cAAuB,UAAU;AAAA,EACpB,OAAO;AAAA,EAEN,eAA2B;AAC5C,WAAO,EAAE,OAAO,UAAK,MAAM,GAAG;AAAA,EAChC;AAAA,EAEmB,YAAoB;AACrC,WAAO;AAAA,EACT;AAAA,EAEmB,kBAA2B;AAC5C,WAAO;AAAA,EACT;AACF;;;AC3HA,SAAS,KACP,MAOA,MACgB;AAChB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,CAAC,IAAI,SAAS,OAAO,SAAS,UACpC,IAAI,KAAK,IAAI,SAAS,OAAO,SAAS,KAA+B;AAAA,EACzE;AACF;AAGA,IAAM,YAAmC,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,SAAS,WAAW,WAAW,UAAU,GAAG;AAItI,IAAM,YAAY,CAAC,SAAwC,EAAE,WAAW,KAAK,WAAW,GAAG,WAAW,SAAS,WAAW,KAAK,aAAa,KAAK,WAAW,KAAK,UAAU,GAAG;AAI9K,IAAM,cAAc,CAAC,KAAa,YAA4C;AAAA,EAC5E,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,GAAI,SAAS,EAAE,WAAW,KAAK,aAAa,KAAK,IAAI,CAAC;AACxD;AAGA,IAAM,WAAkC,EAAE,WAAW,GAAG,WAAW,SAAS,UAAU,GAAG;AAIzF,IAAM,cAAc,CAAC,SAAwC,EAAE,WAAW,KAAK,WAAW,GAAG,WAAW,SAAS,WAAW,KAAK,aAAa,KAAK,WAAW,KAAK,UAAU,GAAG;AAIhL,IAAM,YAAY,CAACG,WAAyC,EAAE,WAAWA,OAAM,WAAW,GAAG,WAAW,SAAS,WAAW,WAAW,aAAa,MAAM,WAAW,WAAW,UAAU,GAAG;AAG7L,IAAM,WAAW,CAAC,WAA0C,EAAE,WAAW,OAAO,WAAW,GAAG,WAAW,QAAQ;AAG1G,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIA,IAAM,aAAa,EAAE,YAAY,EAAE,aAAa,MAAM,WAAW,OAAO,GAAG,uBAAuB,KAAK;AAEvG,IAAM,cAAgC;AAAA;AAAA,EAEpC,KAAK,WAAW,EAAE,MAAM,cAAc,MAAM,cAAc,UAAU,SAAS,SAAS,GAAG,OAAO,WAAW,GAAG,WAAW,CAAC;AAAA,EAC1H,KAAK,KAAK,EAAE,MAAM,OAAO,MAAM,OAAO,UAAU,SAAS,SAAS,GAAG,OAAO,WAAW,GAAG,WAAW,CAAC;AAAA,EACtG,KAAK,UAAU,EAAE,MAAM,aAAa,MAAM,aAAa,UAAU,SAAS,SAAS,GAAG,OAAO,WAAW,GAAG,WAAW,CAAC;AAAA,EACvH,KAAK,cAAc,EAAE,MAAM,YAAY,MAAM,iBAAiB,UAAU,SAAS,SAAS,GAAG,OAAO,WAAW,GAAG,WAAW,CAAC;AAAA,EAC9H,KAAK,YAAY,EAAE,MAAM,eAAe,MAAM,eAAe,UAAU,SAAS,SAAS,GAAG,uBAAuB,MAAM,OAAO,EAAE,GAAG,WAAW,UAAU,GAAG,EAAE,CAAC;AAAA,EAChK,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,MAAM,mBAAmB,UAAU,SAAS,SAAS,GAAG,OAAO,EAAE,GAAG,WAAW,UAAU,GAAG,GAAG,GAAG,WAAW,CAAC;AAAA,EAC9J,KAAK,eAAe,EAAE,MAAM,kBAAkB,MAAM,kBAAkB,UAAU,SAAS,SAAS,GAAG,uBAAuB,MAAM,OAAO,EAAE,GAAG,WAAW,UAAU,GAAG,EAAE,CAAC;AAAA,EACzK,KAAK,cAAc,EAAE,MAAM,iBAAiB,MAAM,iBAAiB,UAAU,SAAS,SAAS,GAAG,OAAO,WAAW,GAAG,WAAW,CAAC;AAAA,EACnI,KAAK,WAAW,EAAE,MAAM,cAAc,MAAM,cAAc,UAAU,SAAS,SAAS,GAAG,uBAAuB,MAAM,OAAO,UAAU,CAAC;AAAA,EACxI,KAAK,OAAO,EAAE,MAAM,SAAS,MAAM,SAAS,UAAU,SAAS,SAAS,GAAG,OAAO,WAAW,GAAG,WAAW,CAAC;AAAA;AAAA,EAG5G,KAAK,WAAW,EAAE,MAAM,aAAa,MAAM,aAAa,UAAU,UAAU,SAAS,GAAG,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA,EACrH,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,MAAM,qBAAqB,UAAU,UAAU,SAAS,GAAG,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA,EAC5I,KAAK,SAAS,EAAE,MAAM,WAAW,MAAM,WAAW,UAAU,UAAU,SAAS,GAAG,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA,EAC/G,KAAK,QAAQ,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,UAAU,SAAS,GAAG,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA,EAC5G,KAAK,UAAU,EAAE,MAAM,YAAY,MAAM,YAAY,UAAU,UAAU,SAAS,GAAG,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA,EAClH,KAAK,KAAK,EAAE,MAAM,OAAO,MAAM,OAAO,UAAU,UAAU,SAAS,GAAG,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA,EACnG,KAAK,OAAO,EAAE,MAAM,SAAS,MAAM,SAAS,UAAU,UAAU,SAAS,GAAG,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA,EACzG,KAAK,aAAa,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,UAAU,UAAU,SAAS,GAAG,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA;AAAA,EAG7H,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,MAAM,oBAAoB,UAAU,YAAY,SAAS,GAAG,OAAO,EAAE,WAAW,GAAG,WAAW,QAAQ,EAAE,CAAC;AAAA,EAC3J,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,MAAM,oBAAoB,UAAU,YAAY,SAAS,GAAG,OAAO,YAAY,SAAS,EAAE,CAAC;AAAA,EAC7I,KAAK,eAAe,EAAE,MAAM,mBAAmB,MAAM,mBAAmB,UAAU,YAAY,SAAS,GAAG,OAAO,YAAY,SAAS,EAAE,CAAC;AAAA,EACzI,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,MAAM,oBAAoB,UAAU,YAAY,SAAS,GAAG,OAAO,YAAY,SAAS,EAAE,CAAC;AAAA;AAAA,EAG7I,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,MAAM,mBAAmB,UAAU,aAAa,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EAC7H,KAAK,cAAc,EAAE,MAAM,iBAAiB,MAAM,6BAA6B,UAAU,aAAa,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EACnI,KAAK,YAAY,EAAE,MAAM,eAAe,MAAM,eAAe,UAAU,aAAa,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EACjH,KAAK,aAAa,EAAE,MAAM,gBAAgB,MAAM,iBAAiB,UAAU,aAAa,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EACrH,KAAK,aAAa,EAAE,MAAM,wBAAwB,MAAM,4BAA4B,UAAU,aAAa,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EACxI,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,MAAM,wBAAwB,UAAU,aAAa,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EACnI,KAAK,YAAY,EAAE,MAAM,eAAe,MAAM,eAAe,UAAU,aAAa,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EACjH,KAAK,WAAW,EAAE,MAAM,cAAc,MAAM,cAAc,UAAU,aAAa,SAAS,GAAG,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,QAAQ,EAAE,CAAC;AAAA,EAChK,KAAK,SAAS,EAAE,MAAM,yBAAyB,MAAM,6BAA6B,UAAU,aAAa,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EACtI,KAAK,UAAU,EAAE,MAAM,aAAa,MAAM,aAAa,UAAU,aAAa,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EAC3G,KAAK,UAAU,EAAE,MAAM,YAAY,MAAM,YAAY,UAAU,aAAa,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA;AAAA,EAGzG,KAAK,WAAW,EAAE,MAAM,aAAa,MAAM,aAAa,UAAU,cAAc,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EAC7G,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,MAAM,oBAAoB,UAAU,cAAc,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EACjI,KAAK,yBAAyB,EAAE,MAAM,6BAA6B,MAAM,6BAA6B,UAAU,cAAc,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EAC3J,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,MAAM,oBAAoB,UAAU,cAAc,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA;AAAA,EAGjI,KAAK,SAAS,EAAE,MAAM,WAAW,MAAM,YAAY,UAAU,QAAQ,SAAS,GAAG,OAAO,EAAE,WAAW,0BAA0B,WAAW,GAAG,WAAW,SAAS,UAAU,GAAG,EAAE,CAAC;AAAA,EACjL,KAAK,YAAY,EAAE,MAAM,kBAAkB,MAAM,eAAe,UAAU,QAAQ,SAAS,GAAG,OAAO,SAAS,CAAC;AAAA,EAC/G,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,MAAM,qBAAqB,UAAU,QAAQ,SAAS,EAAE,CAAC;AAAA,EACxG,KAAK,SAAS,EAAE,MAAM,eAAe,MAAM,YAAY,UAAU,QAAQ,SAAS,EAAE,CAAC;AAAA;AAAA,EAGrF,KAAK,cAAc,EAAE,MAAM,iBAAiB,MAAM,iBAAiB,UAAU,YAAY,SAAS,GAAG,OAAO,YAAY,WAAW,IAAI,EAAE,CAAC;AAAA,EAC1I,KAAK,eAAe,EAAE,MAAM,kBAAkB,MAAM,kBAAkB,UAAU,YAAY,SAAS,GAAG,OAAO,YAAY,WAAW,IAAI,EAAE,CAAC;AAAA,EAC7I,KAAK,aAAa,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,UAAU,YAAY,SAAS,GAAG,OAAO,YAAY,WAAW,KAAK,EAAE,CAAC;AAAA,EACxI,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,MAAM,wBAAwB,UAAU,YAAY,SAAS,GAAG,OAAO,YAAY,WAAW,KAAK,EAAE,CAAC;AAAA,EACvJ,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,MAAM,oBAAoB,UAAU,YAAY,SAAS,GAAG,OAAO,YAAY,WAAW,IAAI,EAAE,CAAC;AAAA,EACnJ,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,MAAM,sBAAsB,UAAU,YAAY,SAAS,GAAG,OAAO,YAAY,WAAW,IAAI,EAAE,CAAC;AAAA;AAAA,EAGxJ,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,MAAM,2BAA2B,UAAU,WAAW,SAAS,GAAG,OAAO,SAAS,SAAS,EAAE,CAAC;AAAA,EACnJ,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,MAAM,4BAA4B,UAAU,WAAW,SAAS,GAAG,OAAO,SAAS,SAAS,EAAE,CAAC;AAAA,EACrJ,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,MAAM,4BAA4B,UAAU,WAAW,SAAS,GAAG,OAAO,SAAS,SAAS,EAAE,CAAC;AAAA,EACtJ,KAAK,oBAAoB,EAAE,MAAM,wBAAwB,MAAM,8BAA8B,UAAU,WAAW,SAAS,GAAG,OAAO,SAAS,SAAS,EAAE,CAAC;AAAA,EAC1J,KAAK,oBAAoB,EAAE,MAAM,wBAAwB,MAAM,gCAAgC,UAAU,WAAW,SAAS,GAAG,OAAO,SAAS,SAAS,EAAE,CAAC;AAAA;AAAA,EAG5J,KAAK,aAAa,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,UAAU,UAAU,SAAS,GAAG,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,QAAQ,EAAE,CAAC;AAAA,EACnK,KAAK,YAAY,EAAE,MAAM,eAAe,MAAM,eAAe,UAAU,UAAU,SAAS,GAAG,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,SAAS,WAAW,WAAW,aAAa,IAAI,EAAE,CAAC;AAAA,EACxM,KAAK,UAAU,EAAE,MAAM,aAAa,MAAM,aAAa,UAAU,UAAU,SAAS,GAAG,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,QAAQ,EAAE,CAAC;AAAA;AAAA,EAG1J,KAAK,cAAc,EAAE,MAAM,iBAAiB,MAAM,iBAAiB,UAAU,eAAe,SAAS,GAAG,WAAW,WAAW,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,SAAS,WAAW,WAAW,UAAU,GAAG,EAAE,CAAC;AAAA,EACrO,KAAK,eAAe,EAAE,MAAM,kBAAkB,MAAM,kBAAkB,UAAU,eAAe,SAAS,GAAG,WAAW,WAAW,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,SAAS,WAAW,WAAW,UAAU,GAAG,EAAE,CAAC;AAAA,EACxO,KAAK,UAAU,EAAE,MAAM,YAAY,MAAM,qBAAqB,UAAU,eAAe,SAAS,GAAG,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,QAAQ,EAAE,CAAC;AAAA,EACtK,KAAK,QAAQ,EAAE,MAAM,UAAU,MAAM,UAAU,UAAU,eAAe,SAAS,GAAG,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,QAAQ,EAAE,CAAC;AAAA,EACvJ,KAAK,aAAa,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,UAAU,eAAe,SAAS,GAAG,cAAc,MAAM,OAAO,EAAE,WAAW,UAAU,EAAE,CAAC;AAAA,EAC1J,KAAK,WAAW,EAAE,MAAM,cAAc,MAAM,cAAc,UAAU,eAAe,SAAS,GAAG,cAAc,KAAK,CAAC;AAAA;AAAA,EAGnH,KAAK,cAAc,EAAE,MAAM,iBAAiB,MAAM,iBAAiB,UAAU,UAAU,SAAS,GAAG,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,SAAS,WAAW,WAAW,aAAa,KAAK,EAAE,CAAC;AAAA,EAC/M,KAAK,yBAAyB,EAAE,MAAM,8BAA8B,MAAM,8BAA8B,UAAU,UAAU,SAAS,EAAE,CAAC;AAAA,EACxI,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,MAAM,2BAA2B,UAAU,UAAU,SAAS,EAAE,CAAC;AAAA;AAAA,EAGhI,KAAK,WAAW,EAAE,MAAM,SAAS,MAAM,SAAS,UAAU,WAAW,SAAS,EAAE,CAAC;AAAA,EACjF,KAAK,WAAW,EAAE,MAAM,SAAS,MAAM,SAAS,UAAU,WAAW,SAAS,EAAE,CAAC;AAAA,EACjF,KAAK,aAAa,EAAE,MAAM,WAAW,MAAM,WAAW,UAAU,WAAW,SAAS,EAAE,CAAC;AAAA,EACvF,KAAK,UAAU,EAAE,MAAM,QAAQ,MAAM,QAAQ,UAAU,WAAW,SAAS,GAAG,OAAO,EAAE,WAAW,UAAU,EAAE,CAAC;AAAA;AAAA,EAG/G,KAAK,WAAW;AAAA,IACd,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY,EAAE,aAAa,MAAM,WAAW,WAAW;AAAA,IACvD,uBAAuB;AAAA,IACvB,OAAO,EAAE,WAAW,WAAW,UAAU,IAAI,WAAW,WAAW,aAAa,MAAM,WAAW,UAAU;AAAA,EAC7G,CAAC;AAAA,EACD,KAAK,MAAM;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY,EAAE,aAAa,MAAM,WAAW,WAAW;AAAA,IACvD,uBAAuB;AAAA,IACvB,OAAO,EAAE,WAAW,WAAW,WAAW,WAAW,UAAU,IAAI,WAAW,WAAW,aAAa,EAAE;AAAA,EAC1G,CAAC;AAAA,EACD,KAAK,SAAS;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY,EAAE,aAAa,MAAM,WAAW,WAAW;AAAA,IACvD,uBAAuB;AAAA,IACvB,OAAO,EAAE,WAAW,WAAW,UAAU,IAAI,WAAW,WAAW,aAAa,GAAG,WAAW,UAAU;AAAA,EAC1G,CAAC;AAAA,EACD,KAAK,SAAS;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY,EAAE,aAAa,MAAM,WAAW,SAAS;AAAA,IACrD,uBAAuB;AAAA,IACvB,OAAO,EAAE,WAAW,WAAW,UAAU,IAAI,WAAW,WAAW,aAAa,KAAK,WAAW,WAAW,WAAW,EAAE;AAAA,EAC1H,CAAC;AAAA,EACD,KAAK,YAAY,EAAE,MAAM,eAAe,MAAM,eAAe,UAAU,cAAc,SAAS,GAAG,uBAAuB,MAAM,OAAO,EAAE,WAAW,WAAW,UAAU,IAAI,MAAM,MAAM,WAAW,WAAW,aAAa,GAAG,WAAW,UAAU,EAAE,CAAC;AAAA,EACrP,KAAK,aAAa,EAAE,MAAM,YAAY,MAAM,iBAAiB,UAAU,cAAc,SAAS,GAAG,uBAAuB,MAAM,OAAO,EAAE,WAAW,WAAW,WAAW,WAAW,UAAU,GAAG,EAAE,CAAC;AAAA,EACnM,KAAK,eAAe,EAAE,MAAM,cAAc,MAAM,mBAAmB,UAAU,cAAc,SAAS,GAAG,uBAAuB,MAAM,OAAO,EAAE,WAAW,WAAW,WAAW,WAAW,UAAU,GAAG,EAAE,CAAC;AAAA,EACzM,KAAK,aAAa,EAAE,MAAM,gBAAgB,MAAM,gBAAgB,UAAU,cAAc,SAAS,GAAG,uBAAuB,MAAM,OAAO,EAAE,WAAW,WAAW,WAAW,WAAW,UAAU,IAAI,MAAM,KAAK,EAAE,CAAC;AAAA,EAClN,KAAK,UAAU,EAAE,MAAM,QAAQ,MAAM,aAAa,UAAU,cAAc,SAAS,GAAG,uBAAuB,MAAM,OAAO,EAAE,WAAW,UAAU,EAAE,CAAC;AAAA,EACpJ,KAAK,WAAW,EAAE,MAAM,cAAc,MAAM,cAAc,UAAU,cAAc,SAAS,GAAG,uBAAuB,MAAM,OAAO,EAAE,WAAW,WAAW,WAAW,WAAW,UAAU,GAAG,EAAE,CAAC;AAAA,EAChM,KAAK,KAAK;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY,EAAE,aAAa,MAAM,WAAW,OAAO;AAAA,IACnD,uBAAuB;AAAA,IACvB,OAAO,EAAE,WAAW,WAAW,WAAW,WAAW,UAAU,IAAI,WAAW,WAAW,aAAa,EAAE;AAAA,EAC1G,CAAC;AAAA,EACD,KAAK,UAAU;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY,EAAE,aAAa,MAAM,WAAW,WAAW;AAAA,IACvD,uBAAuB;AAAA,IACvB,WAAW;AAAA,IACX,OAAO,EAAE,WAAW,WAAW,UAAU,GAAG;AAAA,EAC9C,CAAC;AAAA,EACD,KAAK,WAAW,EAAE,MAAM,SAAS,MAAM,SAAS,UAAU,cAAc,SAAS,GAAG,uBAAuB,MAAM,OAAO,EAAE,WAAW,WAAW,aAAa,GAAG,WAAW,WAAW,WAAW,WAAW,UAAU,GAAG,EAAE,CAAC;AAAA;AAAA,EAG5N,KAAK,OAAO,EAAE,MAAM,SAAS,MAAM,SAAS,UAAU,UAAU,SAAS,GAAG,WAAW,YAAY,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,SAAS,WAAW,WAAW,aAAa,IAAI,EAAE,CAAC;AAAA,EAC9M,KAAK,aAAa,EAAE,MAAM,eAAe,MAAM,eAAe,UAAU,UAAU,SAAS,GAAG,WAAW,YAAY,OAAO,EAAE,WAAW,0BAA0B,WAAW,GAAG,EAAE,CAAC;AAAA,EACpL,KAAK,UAAU,EAAE,MAAM,QAAQ,MAAM,QAAQ,UAAU,UAAU,SAAS,GAAG,WAAW,cAAc,OAAO,EAAE,WAAW,WAAW,WAAW,GAAG,WAAW,QAAQ,EAAE,CAAC;AAAA,EACzK,KAAK,UAAU,EAAE,MAAM,YAAY,MAAM,YAAY,UAAU,UAAU,SAAS,GAAG,WAAW,cAAc,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA;AAAA,EAG3I,KAAK,YAAY,EAAE,MAAM,eAAe,MAAM,eAAe,UAAU,eAAe,SAAS,GAAG,OAAO,UAAU,sBAAsB,EAAE,CAAC;AAAA,EAC5I,KAAK,WAAW,EAAE,MAAM,cAAc,MAAM,cAAc,UAAU,eAAe,SAAS,GAAG,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA,EAC5H,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,MAAM,wBAAwB,UAAU,eAAe,SAAS,GAAG,OAAO,UAAU,SAAS,EAAE,CAAC;AAAA,EACrJ,KAAK,SAAS,EAAE,MAAM,WAAW,MAAM,WAAW,UAAU,eAAe,SAAS,EAAE,CAAC;AACzF;AAMO,IAAM,eAAN,MAAmB;AAAA,EACP,SAAS,oBAAI,IAA4B;AAAA,EAE1D,YAAY,aAAwC;AAClD,eAAW,cAAc,YAAa,MAAK,OAAO,IAAI,WAAW,MAAM,UAAU;AAAA,EACnF;AAAA,EAEA,SAAS,YAAkC;AACzC,SAAK,OAAO,IAAI,WAAW,MAAM,UAAU;AAAA,EAC7C;AAAA,EAEA,IAAI,MAA0C;AAC5C,WAAO,KAAK,OAAO,IAAI,IAAI;AAAA,EAC7B;AAAA,EAEA,IAAI,MAAuB;AACzB,WAAO,KAAK,OAAO,IAAI,IAAI;AAAA,EAC7B;AAAA,EAEA,MAAwB;AACtB,WAAO,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC;AAAA,EACxC;AAAA,EAEA,WAAW,UAA0C;AACnD,WAAO,KAAK,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,QAAQ;AAAA,EACzD;AAAA;AAAA,EAGA,OACE,MACA,IACA,SACA,gBACmB;AACnB,UAAM,aAAa,KAAK,OAAO,IAAI,IAAI;AACvC,QAAI,CAAC,WAAY,QAAO;AACxB,WAAO,WAAW,OAAO,IAAI,SAAS,EAAE,GAAG,WAAW,OAAO,GAAG,eAAe,CAAC;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,MAAkC;AACzC,WAAO,KAAK,OAAO,IAAI,KAAK,IAAI,KAAK,MAAM,QAAQ,KAAK,OAAO,KAAK,KAAK,YAAY;AAAA,EACvF;AAAA;AAAA;AAAA,EAIA,QAAQ,MAA4C;AAClD,QAAI,CAAC,KAAK,SAAS,IAAI,EAAG,QAAO;AACjC,QAAI;AACF,YAAMC,WAAU,KAAK,OAAO,IAAI,KAAK,IAAI,EAAG,OAAO,KAAK,IAAI,KAAK,SAAS,KAAK,OAAO,KAAK,SAAS,KAAK,KAAK;AAC9G,UAAI,EAAE,KAAK,KAAK,gBAAiB,CAAAA,SAAQ,cAAc,IAAI;AAC3D,aAAOA;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEO,IAAM,eAAe,IAAI,aAAa,WAAW;;;AC/ajD,SAAS,mBAAmB,KAAqE;AACtG,MAAI;AACF,UAAM,SAAkB,KAAK,MAAM,OAAO,MAAM;AAChD,QAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC;AAC5E,UAAM,MAA2C,CAAC;AAClD,eAAW,CAAC,KAAK,MAAM,KAAK,OAAO,QAAQ,MAAiC,GAAG;AAC7E,UAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,SAAS,EAAG,KAAI,GAAG,IAAI;AAAA,IAC7D;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAIO,SAAS,uBAAuB,KAA2D;AAChG,QAAM,MAAoD,CAAC;AAC3D,aAAW,CAAC,KAAK,MAAM,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC/C,QAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,SAAS,EAAG,KAAI,GAAG,IAAI;AAAA,EAC7D;AACA,SAAO,KAAK,UAAU,GAAG;AAC3B;AAKO,SAAS,gBAAgB,MAAkD;AAChF,QAAM,MAAoB,CAAC;AAC3B,aAAW,KAAK,MAAM;AACpB,UAAM,MAAM,aAAa,QAAQ,CAAC;AAClC,QAAI,IAAK,KAAI,KAAK,GAAG;AAAA,EACvB;AACA,SAAO;AACT;;;ACRA,IAAM,WAAW,CAAC,eASC,OAAO,OAAO,EAAE,GAAG,WAAW,CAAC;AAmBlD,IAAM,UAA8B;AAAA,EAClC,IAAI,MAAM;AACR,UAAM,aAAa,aAAa,IAAI,IAAI;AACxC,WAAO,aAAa,SAAS,UAAU,IAAI;AAAA,EAC7C;AAAA,EACA,IAAI,MAAM;AACR,WAAO,aAAa,IAAI,IAAI;AAAA,EAC9B;AAAA,EACA,MAAM;AACJ,WAAO,aAAa,IAAI,EAAE,IAAI,QAAQ;AAAA,EACxC;AAAA,EACA,WAAW,UAAU;AACnB,WAAO,aAAa,WAAW,QAAQ,EAAE,IAAI,QAAQ;AAAA,EACvD;AAAA,EACA,OAAO,MAAM,IAAI,SAAS,OAAO;AAC/B,WAAO,aAAa,OAAO,MAAM,IAAI,SAAS,KAAK;AAAA,EACrD;AAAA,EACA,QAAQ,MAAM;AACZ,WAAO,aAAa,QAAQ,IAAI;AAAA,EAClC;AACF;AAIO,IAAM,eAAmC,OAAO,OAAO,OAAO;;;ACrE9D,SAASC,iBAAgB,MAAgD;AAC9E,SAAO,gBAAW,IAAI;AACxB;;;ACXO,IAAM,mBAA0D,CAAC,QAAQ,QAAQ;AAEjF,IAAM,gBAA+E;AAAA,EAC1F,MAAM;AAAA,EACN,QAAQ;AACV;AAIO,SAAS,aAAa,MAAkB,eAA2C,QAAoB;AAC5G,SAAO,SAAS,QAAQ,eAAe;AACzC;AAIO,SAAS,qBAAqB,MAAkB,UAAkD;AACvG,SAAO,SAAS,WAAW,QAAQ;AACrC;AAGO,IAAM,eAAe,CAAC,SAA8B,SAAS;;;ACL7D,IAAM,cAAiC,CAAC,gBAAgB,SAAS,YAAY,YAAY;AAEzF,IAAM,cAAiC,CAAC,SAAS,aAAa;AAE9D,IAAM,cAAiC,CAAC,SAAS,WAAW,MAAM;AAElE,IAAM,aAAgC,CAAC,OAAO;AAyB9C,IAAM,uBAA6C;AAAA,EACxD;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,MACR,EAAE,OAAO,wBAAwB,UAAU,SAAS,SAAS,CAAC,OAAO,EAAE;AAAA,MACvE,EAAE,OAAO,2BAA2B,UAAU,WAAW;AAAA,MACzD,EAAE,OAAO,6BAA6B,UAAU,aAAa;AAAA,IAC/D;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,MACR,EAAE,OAAO,4BAA4B,UAAU,YAAY;AAAA,MAC3D,EAAE,OAAO,uBAAuB,UAAU,OAAO;AAAA,IACnD;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,MACR,EAAE,OAAO,gCAAgC,UAAU,WAAW;AAAA,MAC9D,EAAE,OAAO,0BAA0B,UAAU,UAAU;AAAA,MACvD,EAAE,OAAO,yBAAyB,UAAU,SAAS;AAAA,IACvD;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,MACR,EAAE,OAAO,8BAA8B,UAAU,cAAc;AAAA,MAC/D,EAAE,OAAO,8BAA8B,UAAU,SAAS;AAAA;AAAA,MAE1D,EAAE,OAAO,2BAA2B,UAAU,eAAe,SAAS,CAAC,SAAS,EAAE;AAAA,IACpF;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,MACR,EAAE,OAAO,0BAA0B,OAAO,YAAY;AAAA,MACtD,EAAE,OAAO,yBAAyB,OAAO,YAAY;AAAA,MACrD,EAAE,OAAO,kBAAkB,UAAU,UAAU,SAAS,YAAY;AAAA,IACtE;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,MACR,EAAE,OAAO,qBAAqB,UAAU,cAAc,SAAS,YAAY;AAAA,MAC3E,EAAE,OAAO,0BAA0B,OAAO,WAAW;AAAA,IACvD;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,UAAU,CAAC,EAAE,OAAO,yBAAyB,OAAO,YAAY,CAAC;AAAA,EACnE;AACF;AAEA,IAAM,gBAAgB,CAAC,YAAiD,WAAW;AAI5E,SAAS,0BAA0BC,WAAU,cAAqC;AACvF,QAAM,UAAU,CAAC,YACf,cAAc,OAAO,IACjB,QAAQ,MAAM,IAAI,CAAC,SAASA,SAAQ,IAAI,IAAI,CAAC,EAAE,OAAO,CAACC,UAA8B,CAAC,CAACA,KAAI,IAC3FD,SAAQ,WAAW,QAAQ,QAAQ,EAAE,OAAO,CAACC,UAAS,EAAE,QAAQ,WAAW,CAAC,GAAG,SAASA,MAAK,IAAI,CAAC;AAExG,SAAO,qBAAqB,IAAI,CAAC,WAAW;AAAA,IAC1C,IAAI,MAAM;AAAA,IACV,OAAO,MAAM;AAAA,IACb,UAAU,MAAM,SAAS,IAAI,CAAC,aAAa,EAAE,OAAO,QAAQ,OAAO,OAAO,QAAQ,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,YAAY,QAAQ,MAAM,SAAS,CAAC;AAAA,EAC7I,EAAE,EAAE,OAAO,CAAC,UAAU,MAAM,SAAS,SAAS,CAAC;AACjD;AAIO,SAAS,YAAY,QAAwC,MAAoC;AACtG,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,OAAO,KAAK,CAAC,UAAU,MAAM,SAAS,KAAK,CAAC,YAAY,QAAQ,MAAM,KAAK,CAACA,UAASA,MAAK,SAAS,IAAI,CAAC,CAAC,GAAG,MAAM;AAC3H;AAKO,SAAS,qBAAqB,OAA4B,WAA4D;AAC3H,QAAM,aAAa,UAAU,MAAM,EAAE;AACrC,MAAI,cAAc,MAAM,SAAS,KAAK,CAAC,YAAY,QAAQ,MAAM,KAAK,CAACA,UAASA,MAAK,SAAS,UAAU,CAAC,EAAG,QAAO;AACnH,SAAO,MAAM,SAAS,CAAC,GAAG,MAAM,CAAC,GAAG,QAAQ;AAC9C;AAIO,SAAS,2BACd,QACA,WACA,MACwB;AACxB,QAAM,QAAQ,YAAY,QAAQ,IAAI;AACtC,MAAI,CAAC,MAAO,QAAO,EAAE,GAAG,UAAU;AAClC,SAAO,EAAE,GAAG,WAAW,CAAC,KAAK,GAAG,KAAK;AACvC;;;ACjJO,IAAM,oBAAgD,CAAC,YAAY,YAAY;AAG/E,SAAS,UAAU,cAAiC,CAAC,GAAwB;AAClF,SAAO,CAAC,GAAG,mBAAmB,GAAG,aAAa,KAAK;AACrD;AASO,IAAM,qBAAgC,EAAE,MAAM,YAAY,IAAI,MAAM;AAKpE,IAAM,cAAmG;AAAA,EAC9G,UAAU,EAAE,MAAM,wBAAwB,MAAM,uBAAuB;AAAA,EACvE,YAAY,EAAE,MAAM,0BAA0B,MAAM,yBAAyB;AAAA,EAC7E,KAAK,EAAE,MAAM,mBAAmB,MAAM,kBAAkB;AAC1D;AAEO,SAAS,kBAAkB,MAAyC;AACzE,SAAO,SAAS,cAAc,SAAS,gBAAgB,SAAS;AAClE;AAIO,SAAS,OAAO,OAAkB,OAA0B;AACjE,SAAO,MAAM,OAAO,MAAM,SAAS,SAAS,MAAM,SAAS;AAC7D;AAGO,SAAS,WAAW,OAA6B;AACtD,SAAO,EAAE,MAAM,MAAM,MAAM,IAAI,CAAC,MAAM,GAAG;AAC3C;AAKO,SAAS,eAAe,OAAkB,MAA2B;AAC1E,QAAM,SAAS,MAAM,MAAM,MAAM,SAAS;AAC1C,SAAO,EAAE,MAAM,IAAI,CAAC,OAAO;AAC7B;AAIO,SAAS,cAAc,OAAkB,MAAyB;AACvE,SAAO,MAAM,MAAM,MAAM,SAAS;AACpC;;;AC1DO,IAAM,eAAsC,CAAC,SAAS,OAAO,OAAO;AAEpE,IAAM,gBAA+D;AAAA,EAC1E,OAAO;AAAA,EACP,KAAK;AAAA,EACL,OAAO;AACT;AAMO,IAAM,kBAA4C,CAAC,UAAU,WAAW,MAAM;AAE9E,IAAM,mBAAqE;AAAA,EAChF,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AACR;AAIO,SAAS,gBAAgBC,OAA4C;AAC1E,SAAOA,UAAS,QAAS,gBAAsC,SAASA,KAAI;AAC9E;AAKO,SAAS,kBAAkBA,OAA8B;AAC9D,SAAOA,UAAS,aAAaA,UAAS;AACxC;AAIO,SAAS,mBAAmBA,OAAqB,mBAA2C;AACjG,MAAI,gBAAgBA,KAAI,KAAKA,UAAS,WAAWA,UAAS,cAAe,QAAOA;AAChF,SAAO,oBAAoBA,QAAO;AACpC;AAIO,SAAS,kBAAkBA,OAA8B;AAC9D,SAAOA,UAAS,QAAQA,UAAS;AACnC;;;ACrBA,IAAM,iBAAyC,CAAC,QAAQ,UAAU,YAAY,SAAS,WAAW;AAQ3F,SAAS,YAAY,MAAmB,QAAoC,WAA6B;AAC9G,MAAI,UAAW,QAAO;AACtB,SAAO,CAAC,CAAC,UAAU,OAAO,UAAU,eAAe,SAAS,IAAI;AAClE;AAWO,SAAS,kBAAkB,QAAuB,eAAgC;AACvF,SAAO,gBAAgB,OAAO,QAAQ,OAAO,QAAQ,OAAO;AAC9D;AAcO,SAAS,WAAW,QAAuB,YAAoB,eAAqC;AACzG,QAAM,WAAW,kBAAkB,QAAQ,aAAa;AACxD,QAAM,OAAoB,CAAC;AAC3B,MAAI,WAAW,EAAG,MAAK,KAAK,EAAE,IAAI,YAAY,OAAO,uBAAuB,UAAU,YAAY,EAAE,CAAC;AACrG,MAAI,aAAa,EAAG,MAAK,KAAK,EAAE,IAAI,cAAc,OAAO,uBAAuB,UAAU,GAAG,WAAW,CAAC;AACzG,MAAI,WAAW,KAAK,aAAa,EAAG,MAAK,KAAK,EAAE,IAAI,QAAQ,OAAO,sBAAsB,UAAU,WAAW,CAAC;AAC/G,SAAO;AACT;;;ACpEO,IAAM,qBAAqB;AAgB3B,IAAM,oBAAoC,EAAE,OAAO,CAAC,GAAG,SAAS,MAAM,UAAU,KAAK;AAarF,IAAM,aAAa,CAAC,OAAuB,SAA0B,MAAM,MAAM,SAAS,IAAI;AAI9F,SAAS,eAAe,OAAuB,MAA8B;AAClF,MAAI,WAAW,OAAO,IAAI,EAAG,QAAO,EAAE,GAAG,OAAO,OAAO,MAAM,MAAM,OAAO,CAAC,MAAM,MAAM,IAAI,EAAE;AAC7F,MAAI,MAAM,MAAM,UAAU,mBAAoB,QAAO;AACrD,SAAO,EAAE,GAAG,OAAO,OAAO,CAAC,GAAG,MAAM,OAAO,IAAI,EAAE;AACnD;AAIO,IAAM,oBAAoB,CAAC,UAAmC,MAAM,WAAW,MAAM,MAAM,SAAS;AAIpG,SAAS,eAAe,OAAuB,OAAkD;AACtG,QAAM,QAAQ,MAAM,MAAM,OAAO,KAAK;AACtC,SAAO,MAAM,WAAW,MAAM,MAAM,SAAS,QAAQ,EAAE,GAAG,OAAO,MAAM;AACzE;AAIO,SAAS,uBACd,UACA,KACA,OACmB;AACnB,SAAO;AAAA,IACL,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,SAAS,CAAC,GAAG,KAAK,IAAI,GAAG,MAAM,QAAQ,IAAI,KAAK,CAAC;AAAA,IACzE,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,SAAS,CAAC,GAAG,KAAK,IAAI,GAAG,MAAM,SAAS,IAAI,MAAM,CAAC;AAAA,EAC7E;AACF;;;AC1DO,IAAM,kBAAkB;AAmBxB,SAAS,WAAW,QAAwB,OAA2B;AAC5E,QAAM,OAAO,MAAM,KAAK;AACxB,MAAI,OAAO,KAAM,QAAO,EAAE,MAAM,cAAc,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK,KAAK;AAC/F,MAAI,CAAC,QAAQ,OAAO,MAAO,QAAO,EAAE,MAAM,UAAU;AACpD,SAAO,EAAE,MAAM,SAAS,KAAK;AAC/B;AAIO,SAAS,WAAW,QAA+D;AACxF,SAAO,OAAO,QAAQ,EAAE,MAAM,SAAS,IAAI,EAAE,MAAM,OAAO;AAC5D;AAGO,IAAM,kBAAkB,CAACC,UAAqD,CAAC,CAACA,OAAM;;;AC9B7F,IAAM,MAAM;AACZ,IAAM,aAAa;AAInB,SAAS,QAAQ,OAA8B;AAC7C,QAAM,MAAM,MAAM,SAAS,GAAG;AAC9B,QAAM,IAAI,OAAO,MAAM,MAAM,MAAM,GAAG,EAAE,IAAI,KAAK;AACjD,MAAI,CAAC,OAAO,SAAS,CAAC,EAAG,QAAO;AAChC,SAAO,MAAO,IAAI,MAAO,MAAM;AACjC;AAKO,SAAS,cAAc,OAA4B;AACxD,QAAM,QAAQ,MAAM,KAAK;AAEzB,QAAM,MAAM,IAAI,KAAK,KAAK;AAC1B,MAAI,KAAK;AACP,UAAM,SAAS,IAAI,CAAC;AACpB,UAAM,SAAS,CAAC,MAAsB,SAAS,EAAE,WAAW,IAAI,IAAI,IAAI,GAAG,EAAE;AAC7E,QAAI,OAAO,WAAW,KAAK,OAAO,WAAW,GAAG;AAC9C,YAAM,CAAC,GAAG,GAAG,GAAGC,EAAC,IAAI,CAAC,OAAO,CAAC,GAAI,OAAO,CAAC,GAAI,OAAO,CAAC,GAAI,OAAO,CAAC,CAAC;AACnE,aAAO,EAAE,GAAG,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,GAAGA,OAAM,SAAY,IAAI,OAAOA,EAAC,IAAI,IAAI;AAAA,IAC9F;AACA,QAAI,OAAO,WAAW,KAAK,OAAO,WAAW,GAAG;AAC9C,YAAM,OAAO,CAAC,MAAsB,SAAS,OAAO,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AACvE,aAAO,EAAE,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,GAAG,OAAO,WAAW,IAAI,KAAK,CAAC,IAAI,MAAM,EAAE;AAAA,IAC1F;AACA,WAAO;AAAA,EACT;AAEA,QAAM,KAAK,WAAW,KAAK,KAAK;AAChC,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,OAAO,GAAG,CAAC,EAAG,KAAK;AACzB,QAAM,CAAC,WAAW,SAAS,IAAI,KAAK,SAAS,GAAG,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,MAAS;AACtF,QAAM,QAAQ,UAAW,KAAK,EAAE,MAAM,QAAQ,EAAE,OAAO,OAAO;AAC9D,QAAM,gBAAgB,WAAW,KAAK,MAAM,MAAM,WAAW,IAAI,MAAM,CAAC,IAAI;AAC5E,MAAI,MAAM,WAAW,KAAK,MAAM,WAAW,EAAG,QAAO;AACrD,QAAM,MAAM,CAAC,MAAM,CAAC,GAAI,MAAM,CAAC,GAAI,MAAM,CAAC,CAAE,EAAE,IAAI,OAAO;AACzD,MAAI,IAAI,KAAK,CAAC,MAAM,MAAM,IAAI,EAAG,QAAO;AACxC,MAAI,IAAI;AACR,MAAI,kBAAkB,QAAW;AAC/B,UAAM,MAAM,cAAc,SAAS,GAAG,IAAI,OAAO,cAAc,MAAM,GAAG,EAAE,CAAC,IAAI,MAAM,OAAO,aAAa;AACzG,QAAI,CAAC,OAAO,SAAS,GAAG,EAAG,QAAO;AAClC,QAAI;AAAA,EACN;AACA,QAAM,QAAQ,CAAC,GAAW,OAAuB,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC;AAC5E,SAAO,EAAE,GAAG,MAAM,KAAK,MAAM,IAAI,CAAC,CAAE,GAAG,GAAG,GAAG,GAAG,MAAM,KAAK,MAAM,IAAI,CAAC,CAAE,GAAG,GAAG,GAAG,GAAG,MAAM,KAAK,MAAM,IAAI,CAAC,CAAE,GAAG,GAAG,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE;AACtI;;;AC9CA,IAAM,MAAM,CAAC,MAAsB,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAGlG,IAAM,WAAW,CAAC,GAAW,GAAW,MAAsB,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAO1F,SAAS,YAAY,MAA6B;AACvD,QAAM,SAAS,iCAAiC,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY;AACpF,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,IAAI,OAAO,WAAW,IAAI,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,MAAM;AAClF;AAGO,SAAS,SAAS,KAAkB;AACzC,QAAM,IAAI,SAAS,IAAI,QAAQ,KAAK,EAAE,GAAG,EAAE;AAC3C,QAAM,KAAM,KAAK,KAAM,OAAO;AAC9B,QAAM,KAAM,KAAK,IAAK,OAAO;AAC7B,QAAM,KAAK,IAAI,OAAO;AACtB,QAAM,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC;AAC5B,QAAM,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC;AAC5B,QAAM,IAAI,MAAM;AAChB,MAAI,IAAI;AACR,MAAI,MAAM,GAAG;AACX,QAAI,QAAQ,EAAG,MAAM,IAAI,KAAK,IAAK;AAAA,aAC1B,QAAQ,EAAG,MAAK,IAAI,KAAK,IAAI;AAAA,QACjC,MAAK,IAAI,KAAK,IAAI;AACvB,SAAK;AACL,QAAI,IAAI,EAAG,MAAK;AAAA,EAClB;AACA,SAAO,EAAE,GAAG,GAAG,QAAQ,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI;AACjD;AAGO,SAAS,SAAS,GAAW,GAAW,GAAmB;AAChE,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,KAAK,IAAI,KAAK,IAAM,IAAI,KAAM,IAAK,CAAC;AAC9C,QAAM,IAAI,IAAI;AACd,QAAM,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;AAC1I,SAAO,UAAU,KAAK,KAAK,MAAM,KAAK,KAAK,MAAM,KAAK,KAAK,GAAG;AAChE;AAKO,SAAS,MAAM,OAAuB;AAC3C,QAAM,QAAQ,MAAM,KAAK;AACzB,QAAM,SAAS,cAAc,KAAK;AAClC,MAAI,OAAQ,QAAO,SAAS,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AACxD,SAAO,MAAM,YAAY;AAC3B;AAIO,SAAS,UAAU,OAAkE;AAC1F,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,cAAc,MAAM,KAAK,CAAC;AACzC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,EAAE,KAAK,SAAS,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC,GAAG,OAAO,OAAO,EAAE;AACxE;AAGO,IAAM,YAA+B,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAGlJ,IAAM,YAA+B,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAKlJ,IAAM,YAA4C;AAAA,EACvD,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EAC7G,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EAC7G,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EAC7G,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EAC7G,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EAC7G,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AAC/G;AAGO,IAAM,wBAAwB;AAK9B,IAAM,gBAA6D,CAAC,CAAC,WAAW,SAAS,GAAG,SAAS;;;ACxGrG,SAAS,WAAW,MAAkC;AAC3D,QAAM,QAAQ,KAAK,iBAA8B,qDAAqD;AACtG,SAAO,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,aAAa,UAAU,KAAK,EAAE,YAAY,KAAK,CAAC,aAAa,GAAG,IAAI,KAAK,EAAE,aAAa,aAAa,MAAM,MAAM;AACtJ;AAGA,SAAS,aAAa,MAAmB,MAA4B;AACnE,WAASC,MAAyB,MAAMA,OAAMA,QAAO,MAAMA,MAAKA,IAAG,cAAe,KAAIA,IAAG,OAAQ,QAAO;AACxG,SAAO;AACT;AAIO,SAAS,MAAM,MAAwB;AAC5C,QAAM,MAAM,KAAK,QAAqB,OAAO,GAAG,aAAa,KAAK,MAAM,OAAO,qBAAqB,aAAa,iBAAiB,IAAI,EAAE,YAAY;AACpJ,SAAO,QAAQ;AACjB;;;ACfA,IAAM,QAAkB,CAAC;AAGlB,SAAS,kBAAsD;AACpE,QAAM,QAAQ,CAAC;AACf,QAAM,KAAK,KAAK;AAChB,SAAO;AAAA,IACL;AAAA,IACA,UAAU;AACR,YAAM,KAAK,MAAM,QAAQ,KAAK;AAC9B,UAAI,MAAM,EAAG,OAAM,OAAO,IAAI,CAAC;AAAA,IACjC;AAAA,EACF;AACF;AAGO,SAAS,WAAW,OAAwB;AACjD,SAAO,MAAM,WAAW,KAAK,MAAM,MAAM,SAAS,CAAC,MAAM;AAC3D;;;ACXO,SAAS,GACd,KACA,QAA+F,CAAC,MAC7F,UACuB;AAC1B,QAAM,OAAO,SAAS,cAAc,GAAG;AACvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,UAAU,UAAa,UAAU,MAAO;AAC5C,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,QAAQ,KAAM,YAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ,KAAK,EAAG,MAAK,iBAAiB,MAAM,QAAQ;AAAA,IAC9G,WAAW,QAAQ,QAAS,MAAK,YAAY,OAAO,KAAK;AAAA,aAChD,QAAQ,OAAQ,MAAK,cAAc,OAAO,KAAK;AAAA,aAC/C,QAAQ,OAAQ,MAAK,YAAY,OAAO,KAAK;AAAA,QACjD,MAAK,aAAa,KAAK,UAAU,OAAO,KAAK,OAAO,KAAK,CAAC;AAAA,EACjE;AACA,aAAW,SAAS,UAAU;AAC5B,QAAI,UAAU,QAAQ,UAAU,UAAa,UAAU,MAAO;AAC9D,SAAK,OAAO,KAAK;AAAA,EACnB;AACA,SAAO;AACT;AAGO,SAAS,OAAO,OAAiM;AACtN,QAAM,IAAI,GAAG,UAAU;AAAA,IACrB,MAAM;AAAA,IACN,OAAO,MAAM,SAAS;AAAA,IACtB,cAAc,MAAM;AAAA,IACpB,OAAO,MAAM,SAAS,MAAM;AAAA,IAC5B,GAAI,MAAM,SAAS,SAAY,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,IACvD,GAAI,MAAM,YAAY,SAAY,EAAE,gBAAgB,OAAO,MAAM,OAAO,EAAE,IAAI,CAAC;AAAA,EACjF,CAAC;AACD,MAAI,MAAM,KAAM,GAAE,OAAO,MAAM,IAAI;AACnC,MAAI,MAAM,SAAU,GAAE,WAAW;AACjC,MAAI,MAAM,QAAS,GAAE,iBAAiB,SAAS,MAAM,OAAO;AAC5D,SAAO;AACT;AAMO,SAAS,WAAW,MAAyB;AAClD,aAAW,QAAQ,CAAC,eAAe,aAAa,eAAe,SAAS,aAAa,UAAU,GAAY;AACzG,SAAK,iBAAiB,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC;AAAA,EACxD;AACF;AAMO,SAAS,gBAAgB,UAAoC,KAAkB,MAA6C;AACjI,QAAMC,OAAM,KAAK,sBAAsB;AACvC,MAAI,EAAEA,KAAI,QAAQ,KAAKA,KAAI,SAAS,GAAI,QAAO;AAC/C,SAAO;AAAA,IACL,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,SAAS,CAAC,GAAG,KAAK,IAAI,GAAGA,KAAI,QAAQ,IAAI,WAAW,CAAC;AAAA,IAC7E,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,SAAS,CAAC,GAAG,KAAK,IAAI,GAAGA,KAAI,SAAS,IAAI,YAAY,CAAC;AAAA,EACjF;AACF;AAGO,SAAS,eAAe,MAAmB,OAA+B;AAC/E,MAAI,OAAO,mBAAmB,YAAa,QAAO,MAAM;AACxD,QAAM,WAAW,IAAI,eAAe,MAAM,MAAM,CAAC;AACjD,WAAS,QAAQ,IAAI;AACrB,SAAO,MAAM,SAAS,WAAW;AACnC;AAWO,SAAS,iBAAiB,QAAuC,WAAmC;AACzG,QAAM,QAAQ,CAAC,eAAe,aAAa,eAAe;AAC1D,QAAM,OAAO,MAAY;AACvB,eAAW,QAAQ,MAAO,QAAO,oBAAoB,MAAM,SAAS,IAAI,GAAG,IAAI;AAC/E,WAAO,oBAAoB,QAAQ,GAAG;AAAA,EACxC;AACA,QAAM,MAAM,MAAY;AACtB,SAAK;AACL,cAAU;AAAA,EACZ;AACA,QAAM,WAAW,EAAE,aAAa,QAAQ,WAAW,KAAK,eAAe,IAAI;AAC3E,aAAW,QAAQ,MAAO,QAAO,iBAAiB,MAAM,SAAS,IAAI,GAAG,IAAI;AAC5E,SAAO,iBAAiB,QAAQ,GAAG;AACnC,SAAO;AACT;AAKO,SAAS,YAAY,MAAmB,OAA4B,cAAkD,QAAoB;AAC/I,QAAM,OAAO,CAAC,WAAqC;AACjD,UAAM,OAAO,MAAM;AACnB,eAAW,QAAQ,KAAM,MAAK,WAAW,SAAS,SAAS,IAAI;AAC/D,QAAI,CAAC,UAAU,KAAK,CAAC,EAAG,MAAK,CAAC,EAAE,WAAW;AAAA,EAC7C;AACA,QAAM,QAAQ,CAAC,MAA2B;AACxC,UAAM,OAAO,MAAM;AACnB,QAAI,KAAK,WAAW,EAAG;AACvB,UAAM,KAAK,KAAK,QAAQ,SAAS,aAA4B;AAC7D,UAAM,OAAO,gBAAgB,eAAe,EAAE,QAAQ,gBAAiB,gBAAgB,gBAAgB,EAAE,QAAQ;AACjH,UAAM,OAAO,gBAAgB,eAAe,EAAE,QAAQ,eAAgB,gBAAgB,gBAAgB,EAAE,QAAQ;AAChH,UAAM,OAAO,gBAAgB,gBAAgB,EAAE,QAAQ;AACvD,UAAM,KAAK,gBAAgB,gBAAgB,EAAE,QAAQ;AACrD,QAAI;AACJ,QAAI,QAAQ,KAAM,UAAS,MAAM,KAAK,IAAI,KAAK,UAAU,KAAK,MAAM;AAAA,aAC3D,QAAQ,GAAI,UAAS,MAAM,KAAK,IAAI,KAAK,UAAU,KAAK,MAAM;AAAA,aAC9D,EAAE,QAAQ,OAAQ,UAAS,KAAK,CAAC;AAAA,aACjC,EAAE,QAAQ,MAAO,UAAS,KAAK,KAAK,SAAS,CAAC;AACvD,QAAI,CAAC,OAAQ;AACb,MAAE,eAAe;AACjB,SAAK,MAAM;AACX,WAAO,MAAM;AAAA,EACf;AACA,QAAM,UAAU,CAAC,MAAwB;AACvC,UAAM,SAAS,EAAE;AACjB,QAAI,MAAM,EAAE,SAAS,MAAM,EAAG,MAAK,MAAM;AAAA,EAC3C;AACA,OAAK,iBAAiB,WAAW,KAAK;AACtC,OAAK,iBAAiB,WAAW,OAAO;AACxC,OAAK,IAAI;AACT,SAAO,MAAM;AACX,SAAK,oBAAoB,WAAW,KAAK;AACzC,SAAK,oBAAoB,WAAW,OAAO;AAAA,EAC7C;AACF;AAiCO,SAAS,iBAAiB,OAAoB,QAA4B,OAAmB,QAAgD;AAClJ,QAAM,SAAS,gBAAgB;AAC/B,QAAM,SAAS,CAAC,MAAmB;AACjC,UAAM,SAAS,EAAE;AACjB,QAAI,MAAM,SAAS,MAAM,KAAM,UAAU,OAAO,SAAS,MAAM,KAAM,SAAS,MAAM,EAAG;AACvF,UAAM;AAAA,EACR;AACA,QAAM,QAAQ,CAAC,MAA2B;AACxC,QAAI,EAAE,QAAQ,YAAY,WAAW,OAAO,KAAK,GAAG;AAClD,QAAE,gBAAgB;AAClB,YAAM;AAAA,IACR;AAAA,EACF;AACA,WAAS,iBAAiB,eAAe,QAAQ,IAAI;AACrD,WAAS,iBAAiB,WAAW,OAAO,IAAI;AAChD,SAAO,MAAM;AACX,WAAO,QAAQ;AACf,aAAS,oBAAoB,eAAe,QAAQ,IAAI;AACxD,aAAS,oBAAoB,WAAW,OAAO,IAAI;AAAA,EACrD;AACF;AAeO,SAAS,WAAW,OAAoB,QAAqBC,MAAkB,MAAsB,MAAM,GAAS;AAGzH,QAAM,IAAIA,KAAI,UAAU,SAAS,UAAU,IACvC,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,SAAS,gBAAgB,aAAa,QAAQ,SAAS,gBAAgB,aAAa,IAC9GA,KAAI,sBAAsB;AAC9B,QAAM,IAAI,OAAO,sBAAsB;AACvC,QAAM,IAAI,MAAM;AAChB,QAAM,IAAI,MAAM;AAChB,QAAM,MAAM,MAAMA,IAAG;AACrB,MAAI;AACJ,MAAI;AACJ,MAAI,SAAS,WAAW;AAGtB,UAAM,QAAQ,OAAO,QAAQ,eAAe,KAAK,QAAQ,sBAAsB;AAC/E,WAAO,MAAM,KAAK,OAAO,EAAE,OAAO,IAAI,KAAK,QAAQ,EAAE;AACrD,QAAI,MAAM,OAAO,IAAI,OAAO,IAAI,EAAE,MAAO,QAAO,MAAM,KAAK,QAAQ,EAAE,OAAO,KAAK,OAAO,EAAE,OAAO;AACjG,UAAM,EAAE,MAAM,EAAE;AAAA,EAClB,WAAW,SAAS,QAAQ;AAG1B,WAAO,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,QAAQ,EAAE,OAAO;AAC1D,QAAI,OAAO,IAAI,EAAE,MAAO,QAAO,EAAE,OAAO,EAAE,OAAO,IAAI;AACrD,QAAI,OAAO,EAAG,QAAO,KAAK,IAAI,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC;AAG3D,UAAM,OAAO,OAAO,WAAW,iBAAiB,KAAK,EAAE,UAAU,KAAK;AACtE,UAAM,EAAE,MAAM,EAAE,MAAM;AACtB,QAAI,MAAM,IAAI,EAAE,OAAQ,OAAM,KAAK,IAAI,GAAG,EAAE,SAAS,CAAC;AAAA,EACxD,WAAW,SAAS,SAAS;AAC3B,WAAO,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE;AAC/C,UAAM,EAAE,MAAM,EAAE,MAAM,IAAI;AAC1B,QAAI,MAAM,EAAG,OAAM,EAAE,SAAS,EAAE,MAAM;AAAA,EACxC,OAAO;AACL,UAAM,MAAO,SAAS,gBAAiB;AACvC,WAAO,MAAM,EAAE,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE;AAC/C,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC9C,UAAM,EAAE,SAAS,EAAE,MAAM;AACzB,QAAI,MAAM,IAAI,EAAE,OAAQ,OAAM,KAAK,IAAI,GAAG,EAAE,MAAM,EAAE,MAAM,IAAI,GAAG;AAAA,EACnE;AAGA,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC9C,QAAM,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,EAAE,SAAS,CAAC,CAAC;AAC7C,QAAM,MAAM,OAAO,GAAG,KAAK,MAAM,IAAI,CAAC;AACtC,QAAM,MAAM,MAAM,GAAG,KAAK,MAAM,GAAG,CAAC;AACpC,QAAM,MAAM,YAAY,GAAG,KAAK,IAAI,KAAK,EAAE,SAAS,GAAG,CAAC;AAC1D;AAIO,SAAS,SAAS,MAAmB,MAAuC;AACjF,SAAO,YAAY,MAAM,MAAM,UAAU;AAC3C;AAGO,SAAS,WAAW,MAAyB;AAClD,aAAW,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,eAAe,KAAK,CAAC;AACpD;;;AChQA,IAAM,UAAU,CAAC,MAAsB,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AAI1D,IAAM,qBAAqB;AAGlC,IAAM,UAAU;AAGhB,IAAM,OAAO;AAiBb,IAAM,YAAY,CAAC,UAA0B,KAAK,MAAM,QAAQ,KAAK,IAAI,GAAG;AAG5E,IAAM,QAA0C,EAAE,YAAY,GAAG,SAAS,GAAG,WAAW,IAAI,WAAW,IAAI,QAAQ,IAAI,UAAU,IAAI;AAY9H,SAAS,oBAAoB,GAAmB,OAAe,OAAe,UAA8C;AACjI,MAAI,UAAU,UAAU,KAAK;AAC7B,MAAI,MAAM,MAAM,KAAK;AACrB,QAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,0BAA0B,CAAC;AAC5D,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,EAAE,OAAO,sBAAsB,MAAM,UAAU,UAAU,KAAK,cAAc,EAAE,iBAAiB,GAAG,iBAAiB,KAAK,iBAAiB,MAAM;AAAA,IAC/I,GAAG,QAAQ,EAAE,OAAO,0BAA0B,CAAC;AAAA,IAC/C,GAAG,QAAQ,EAAE,OAAO,4BAA4B,GAAG,IAAI;AAAA,EACzD;AACA,QAAM,SAAS,GAAG,SAAS,EAAE,OAAO,8BAA8B,cAAc,EAAE,iBAAiB,GAAG,WAAW,WAAW,YAAY,SAAS,cAAc,OAAO,WAAW,IAAI,CAAC;AAEtL,QAAM,QAAQ,MAAY;AACxB,UAAM,MAAM,YAAY,gBAAgB,GAAG;AAC3C,SAAK,MAAM,YAAY,sBAAsB,GAAG,OAAO,GAAG;AAC1D,UAAM,aAAa,iBAAiB,OAAO,OAAO,CAAC;AACnD,UAAM,aAAa,kBAAkB,GAAG,OAAO,GAAG;AAClD,QAAI,SAAS,kBAAkB,OAAQ,QAAO,QAAQ,OAAO,OAAO;AAAA,EACtE;AACA,QAAM,MAAM,CAAC,SAAuB;AAClC,UAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;AACrD,QAAI,MAAM,QAAS;AACnB,cAAU;AACV,UAAM;AACN,aAAS,IAAI,GAAG;AAAA,EAClB;AAGA,QAAM,QAAQ,CAAC,UAAgC;AAC7C,UAAM,IAAI,MAAM,sBAAsB;AACtC,UAAM,QAAQ,MAAM,KAAK,IAAI,EAAE,QAAQ,MAAM,UAAU,MAAM,UAAU,EAAE;AACzE,YAAS,QAAQ,OAAO,KAAK,KAAK,IAAI,GAAG,EAAE,QAAQ,IAAI,IAAK;AAAA,EAC9D;AAEA,MAAI,WAAgC;AACpC,QAAM,iBAAiB,eAAe,CAAC,UAAU;AAC/C,QAAI,MAAM,WAAW,EAAG;AACxB,UAAM,eAAe;AACrB,UAAM,MAAM,EAAE,eAAe,KAAK,CAAC;AACnC,eAAW;AACX,UAAM,QAAQ,aAAa;AAC3B,QAAI,MAAM,KAAK,CAAC;AAChB,eAAW;AAAA,MACT,CAAC,SAAS,IAAI,MAAM,IAAI,CAAC;AAAA,MACzB,MAAM;AACJ,mBAAW;AACX,eAAO,MAAM,QAAQ;AAAA,MACvB;AAAA,IACF;AAAA,EACF,CAAC;AACD,QAAM,iBAAiB,WAAW,CAAC,UAAU;AAC3C,UAAM,OAAO,MAAM,MAAM,GAAG;AAG5B,QAAI,SAAS,OAAW,KAAI,YAAY,MAAM,QAAQ,eAAe,MAAM,QAAQ,iBAAiB,MAAM,KAAK,IAAI,CAAC,OAAO,KAAK;AAAA,aACvH,MAAM,QAAQ,OAAQ,KAAI,CAAC;AAAA,aAC3B,MAAM,QAAQ,MAAO,KAAI,GAAG;AAAA,QAChC;AACL,UAAM,eAAe;AAAA,EACvB,CAAC;AAED,SAAO,iBAAiB,SAAS,MAAM;AACrC,UAAM,SAAS,OAAO,MAAM,QAAQ,OAAO,EAAE;AAE7C,QAAI,WAAW,IAAI;AACjB,aAAO,QAAQ;AACf;AAAA,IACF;AACA,UAAM,QAAQ,KAAK,IAAI,KAAK,OAAO,MAAM,CAAC;AAC1C,WAAO,QAAQ,OAAO,KAAK;AAC3B,QAAI,KAAK;AAAA,EACX,CAAC;AACD,SAAO,iBAAiB,WAAW,CAAC,UAAU;AAC5C,QAAI,MAAM,QAAQ,SAAS;AACzB,YAAM,eAAe;AACrB,aAAO,QAAQ,OAAO,OAAO;AAC7B;AAAA,IACF;AACA,UAAM,OAAO,MAAM,QAAQ,YAAY,IAAI,MAAM,QAAQ,cAAc,KAAK;AAC5E,QAAI,CAAC,KAAM;AACX,UAAM,eAAe;AACrB,QAAI,UAAU,QAAQ,MAAM,WAAW,KAAK,EAAE;AAC9C,WAAO,QAAQ,OAAO,OAAO;AAAA,EAC/B,CAAC;AACD,SAAO,iBAAiB,QAAQ,MAAM;AACpC,WAAO,QAAQ,OAAO,OAAO;AAAA,EAC/B,CAAC;AAED,QAAM,UAAU;AAAA,IACd;AAAA,IACA,EAAE,OAAO,yBAAyB;AAAA,IAClC;AAAA,IACA,GAAG,QAAQ,EAAE,OAAO,2BAA2B,GAAG,QAAQ,GAAG,QAAQ,EAAE,OAAO,2BAA2B,eAAe,QAAQ,MAAM,IAAI,CAAC,CAAC;AAAA,EAC9I;AACA,QAAM;AACN,SAAO;AAAA,IACL;AAAA,IACA,OAAO,WAAW,WAAW;AAC3B,YAAM,MAAM,SAAS;AAErB,UAAI,MAAM,QAAQ,eAAe,OAAQ,WAAU,UAAU,SAAS;AACtE,YAAM;AAAA,IACR;AAAA,IACA,UAAU;AACR,iBAAW;AACX,cAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AACF;AAWO,SAAS,wBAAwB,GAAmB,SAAiB,OAAiD;AAC3H,QAAM,UAAU,CAAC,UAA0B,UAAU,KAAK,GAAG,OAAO;AACpE,MAAI,MAAW,SAAS,QAAQ,OAAO,CAAC;AACxC,QAAM,OAAO,MAAc,SAAS,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvD,QAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,2BAA2B,CAAC;AAC7D,QAAM,QAAQ,GAAG,SAAS,EAAE,OAAO,kBAAkB,cAAc,EAAE,kBAAkB,GAAG,YAAY,SAAS,cAAc,OAAO,WAAW,IAAI,CAAC;AACpJ,QAAM,MAAM,OAAO,EAAE,OAAO,+CAA+C,OAAO,EAAE,aAAa,GAAG,MAAM,EAAE,aAAa,GAAG,SAAS,MAAM,OAAO,EAAE,CAAC;AACrJ,QAAM,WAAW,GAAG,QAAQ,EAAE,OAAO,oBAAoB,CAAC;AAC1D,QAAM,OAAO,GAAG,OAAO,EAAE,OAAO,iBAAiB,MAAM,UAAU,UAAU,KAAK,cAAc,EAAE,yBAAyB,EAAE,GAAG,QAAQ;AACtI,QAAM,YAAY,GAAG,QAAQ,EAAE,OAAO,qBAAqB,CAAC;AAC5D,QAAM,cAAc,GAAG,QAAQ,EAAE,OAAO,wBAAwB,GAAG,SAAS;AAC5E,QAAM,QAAQ,GAAG,OAAO,EAAE,OAAO,kBAAkB,MAAM,UAAU,UAAU,KAAK,cAAc,EAAE,aAAa,GAAG,iBAAiB,KAAK,iBAAiB,OAAO,oBAAoB,WAAW,GAAG,WAAW;AAI7M,QAAM,QAAQ,CAAC,QAAQ,UAAgB;AACrC,UAAM,MAAM,KAAK;AACjB,SAAK,MAAM,YAAY,gBAAgB,GAAG;AAC1C,SAAK,MAAM,YAAY,aAAa,SAAS,IAAI,GAAG,GAAG,CAAC,CAAC;AACzD,aAAS,MAAM,YAAY,sBAAsB,GAAG,IAAI,IAAI,GAAG,GAAG;AAClE,aAAS,MAAM,MAAM,IAAI,IAAI,IAAI,KAAK,GAAG;AACzC,cAAU,MAAM,MAAM,GAAI,IAAI,IAAI,MAAO,GAAG;AAC5C,SAAK,aAAa,kBAAkB,GAAG;AACvC,UAAM,aAAa,iBAAiB,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC;AAC7D,QAAI,MAAO;AACX,UAAM,QAAQ,IAAI,MAAM,CAAC;AACzB,UAAM,gBAAgB,cAAc;AAAA,EACtC;AACA,QAAM,SAAS,MAAY;AACzB,UAAM,MAAM,YAAY,MAAM,KAAK;AACnC,QAAI,CAAC,KAAK;AACR,YAAM,aAAa,gBAAgB,MAAM;AACzC,YAAM,MAAM,EAAE,eAAe,KAAK,CAAC;AACnC;AAAA,IACF;AACA,UAAM,GAAG;AAAA,EACX;AACA,QAAM,iBAAiB,SAAS,MAAM;AACpC,UAAM,MAAM,YAAY,MAAM,KAAK;AACnC,QAAI,CAAC,IAAK;AACV,UAAM,gBAAgB,cAAc;AACpC,UAAM,SAAS,GAAG;AAClB,UAAM,IAAI;AAAA,EACZ,CAAC;AACD,QAAM,iBAAiB,WAAW,CAAC,UAAU;AAC3C,QAAI,MAAM,QAAQ,QAAS;AAC3B,UAAM,eAAe;AACrB,WAAO;AAAA,EACT,CAAC;AAGD,MAAI,WAAgC;AAGpC,QAAM,SAAS,CAAC,QAAqB,OAAoB,UAAgD;AACvG,WAAO,iBAAiB,eAAe,CAAC,UAAU;AAChD,UAAI,MAAM,WAAW,EAAG;AACxB,YAAM,eAAe;AACrB,aAAO,MAAM,EAAE,eAAe,KAAK,CAAC;AACpC,YAAM,KAAK,CAAC,MAA0B;AACpC,cAAM,IAAI,MAAM,sBAAsB;AACtC,cAAM,IAAI,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE;AACvD,cAAM,MAAM,MAAM,IAAI,IAAI,IAAI,GAAG,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AAC/E,cAAM;AAAA,MACR;AACA,iBAAW;AACX,aAAO,QAAQ,aAAa;AAC5B,SAAG,KAAK;AACR,iBAAW,iBAAiB,IAAI,MAAM;AACpC,mBAAW;AACX,eAAO,OAAO,QAAQ;AAAA,MACxB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACA,SAAO,MAAM,MAAM,CAAC,GAAG,MAAM;AAC3B,UAAM,EAAE,GAAG,KAAK,GAAG,GAAG,GAAG,IAAI,EAAE;AAAA,EACjC,CAAC;AACD,SAAO,OAAO,aAAa,CAAC,IAAI,MAAM;AACpC,UAAM,EAAE,GAAG,KAAK,GAAG,IAAI,IAAI;AAAA,EAC7B,CAAC;AAID,OAAK,iBAAiB,WAAW,CAAC,UAAU;AAC1C,QAAI,MAAM,QAAQ,SAAS;AACzB,YAAM,eAAe;AACrB,aAAO;AACP;AAAA,IACF;AACA,UAAM,OAAO,MAAM,WAAW,MAAM;AACpC,UAAM,SAAS,MAAM,IAAI,IAAI,CAAC,OAAO;AACrC,QAAI,MAAM,QAAQ,aAAc,OAAM,EAAE,GAAG,KAAK,GAAG,QAAQ,IAAI,IAAI,MAAM,EAAE;AAAA,aAClE,MAAM,QAAQ,YAAa,OAAM,EAAE,GAAG,KAAK,GAAG,QAAQ,IAAI,IAAI,MAAM,EAAE;AAAA,aACtE,MAAM,QAAQ,UAAW,OAAM,EAAE,GAAG,KAAK,GAAG,QAAQ,IAAI,IAAI,IAAI,EAAE;AAAA,aAClE,MAAM,QAAQ,YAAa,OAAM,EAAE,GAAG,KAAK,GAAG,QAAQ,IAAI,IAAI,IAAI,EAAE;AAAA,aACpE,MAAM,QAAQ,OAAQ,OAAM,EAAE,GAAG,KAAK,GAAG,GAAG,GAAG,EAAE;AAAA,aACjD,MAAM,QAAQ,MAAO,OAAM,EAAE,GAAG,KAAK,GAAG,GAAG,GAAG,EAAE;AAAA,QACpD;AACL,UAAM,eAAe;AACrB,UAAM;AAAA,EACR,CAAC;AACD,QAAM,iBAAiB,WAAW,CAAC,UAAU;AAC3C,QAAI,MAAM,QAAQ,SAAS;AACzB,YAAM,eAAe;AACrB,aAAO;AACP;AAAA,IACF;AACA,UAAM,OAAO,MAAM,WAAW,KAAK;AACnC,UAAM,OAAO,CAAC,MAAoB;AAChC,YAAM,EAAE,GAAG,KAAK,GAAG,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,CAAC,EAAE;AAAA,IACnD;AACA,QAAI,MAAM,QAAQ,gBAAgB,MAAM,QAAQ,UAAW,MAAK,IAAI,IAAI,IAAI;AAAA,aACnE,MAAM,QAAQ,eAAe,MAAM,QAAQ,YAAa,MAAK,IAAI,IAAI,IAAI;AAAA,aACzE,MAAM,QAAQ,OAAQ,MAAK,CAAC;AAAA,aAC5B,MAAM,QAAQ,MAAO,MAAK,GAAG;AAAA,QACjC;AACL,UAAM,eAAe;AACrB,UAAM;AAAA,EACR,CAAC;AACD,QAAM;AAEN,QAAM,UAAU;AAAA,IACd;AAAA,IACA,EAAE,OAAO,oBAAoB;AAAA,IAC7B,GAAG,OAAO,EAAE,OAAO,wBAAwB,GAAG,MAAM,GAAG,QAAQ,EAAE,OAAO,sBAAsB,GAAG,GAAG,QAAQ,EAAE,OAAO,uBAAuB,eAAe,QAAQ,MAAM,IAAI,CAAC,GAAG,KAAK,GAAG,GAAG;AAAA,IAC5L,GAAG,OAAO,EAAE,OAAO,2BAA2B,GAAG,MAAM,KAAK;AAAA,EAC9D;AACA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,OAAO;AAEZ,UAAI,SAAS,kBAAkB,MAAO;AACtC,YAAM,SAAS,QAAQ,KAAK,CAAC;AAC7B,YAAM;AAAA,IACR;AAAA,IACA,UAAU;AACR,iBAAW;AACX,cAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AACF;AA8BO,SAAS,mBAAmB,GAAmB,SAAwC;AAC5F,MAAI,QAAQ,QAAQ;AACpB,QAAM,SAAS,QAAQ,WAAW;AAClC,QAAM,OAAO,GAAG,OAAO,EAAE,OAAO,uBAAuB,MAAM,SAAS,cAAc,EAAE,mBAAmB,EAAE,CAAC;AAC5G,QAAM,SAAS,CAAC,MAAiC;AAC/C,UAAM,IAAI,GAAG,UAAU,EAAE,MAAM,UAAU,OAAO,qBAAqB,cAAc,EAAE,uBAAuB,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AACzH,MAAE,iBAAiB,SAAS,MAAM,KAAK,CAAC,CAAC;AACzC,MAAE,MAAM,YAAY,gBAAgB,CAAC;AACrC,MAAE,QAAQ,UAAU;AAEpB,QAAI,MAAM,UAAU,CAAC,EAAG,GAAE,QAAQ,SAAS;AAC3C,WAAO;AAAA,EACT;AAGA,QAAM,UAAU,CAACC,QAA+B,YAAY,8BAA2C;AACrG,UAAM,QAAQ,GAAG,OAAO,EAAE,OAAO,UAAU,CAAC;AAC5C,aAAS,IAAI,GAAG,IAAIA,OAAM,QAAQ,KAAK,QAAS,OAAM,YAAY,GAAG,OAAO,EAAE,OAAO,wBAAwB,GAAG,GAAGA,OAAM,MAAM,GAAG,IAAI,OAAO,CAAC,CAAC;AAC/I,WAAO;AAAA,EACT;AACA,aAAW,QAAQ,cAAe,MAAK,YAAY,QAAQ,KAAK,KAAK,EAAE,IAAI,MAAM,CAAC,CAAC;AACnF,OAAK,YAAY,GAAG,OAAO,EAAE,OAAO,wBAAwB,MAAM,eAAe,CAAC,CAAC;AAInF,QAAM,OAAO,OAAO,EAAE,OAAO,0BAA0B,OAAO,EAAE,wBAAwB,GAAG,SAAS,MAAM,UAAU,EAAE,CAAC;AACvH,MAAI,QAAkC;AACtC,MAAI,aAAa,QAAQ,CAAC,IAAI,GAAG,wDAAwD;AACzF,OAAK,YAAY,UAAU;AAG3B,QAAM,aAAa,MAAY;AAC7B,UAAM,QAAQ,QAAQ,KAAK,KAAK,CAAC,GAAG,MAAM,GAAG,kBAAkB;AAC/D,QAAI,SAAS,KAAK,WAAW,MAAM,UAAU,KAAK,MAAM,CAAC,GAAG,MAAM,MAAM,MAAO,CAAC,CAAC,EAAG;AACpF,YAAQ;AACR,UAAM,OAAO,QAAQ,CAAC,GAAG,KAAK,IAAI,MAAM,GAAG,IAAI,GAAG,wDAAwD;AAC1G,eAAW,YAAY,IAAI;AAC3B,iBAAa;AAAA,EACf;AAEA,QAAM,QAAQ,MAAqB,CAAC,GAAG,KAAK,iBAA8B,6CAA6C,CAAC;AAExH,QAAM,aAAa,MAAY;AAC7B,UAAM,OAAO,MAAM,KAAK;AACxB,QAAI,OAA2B;AAC/B,eAAW,QAAQ,MAAM,GAAG;AAC1B,YAAM,SAAS,KAAK,QAAQ,YAAY;AACxC,UAAI,QAAQ;AACV,aAAK,QAAQ,WAAW;AACxB,iBAAS;AAAA,MACX,MAAO,QAAO,KAAK,QAAQ;AAC3B,UAAI,KAAK,QAAQ,QAAS,MAAK,aAAa,gBAAgB,OAAO,MAAM,CAAC;AAAA,IAC5E;AACA,UAAM,UAAU,MAAM,EAAE,KAAK,CAAC,SAAS,SAAS,SAAS,aAAa;AACtE,SAAK,WAAW,QAAQ,MAAM,EAAE,CAAC,KAAK,IAAI;AAAA,EAC5C;AACA,QAAM,OAAO,CAAC,OAAiC;AAC7C,eAAW,QAAQ,MAAM,EAAG,MAAK,WAAW,SAAS,KAAK,IAAI;AAAA,EAChE;AACA,QAAM,OAAO,CAAC,MAAoB;AAChC,YAAQ;AACR,eAAW;AACX,YAAQ,OAAO,CAAC;AAAA,EAClB;AACA,OAAK,iBAAiB,WAAW,CAAC,UAAU;AAC1C,UAAM,OAAO,MAAM;AACnB,QAAI,MAAM,EAAE,SAAS,IAAI,EAAG,MAAK,IAAI;AAAA,EACvC,CAAC;AACD,OAAK,iBAAiB,WAAW,CAAC,UAAU;AAC1C,UAAM,OAAO,MAAM;AACnB,UAAM,KAAK,KAAK,QAAQ,SAAS,aAA4B;AAC7D,QAAI,KAAK,EAAG;AACZ,UAAM,MAAM,MAAM,IAAI;AACtB,QAAI,KAAK;AACT,QAAI,MAAM,QAAQ,aAAc,MAAK,MAAM,MAAM,KAAK;AAAA,aAC7C,MAAM,QAAQ,YAAa,MAAK,MAAM,MAAM,IAAI;AAAA,aAChD,MAAM,QAAQ,YAAa,MAAK,KAAK,UAAU,KAAK,SAAS,KAAK,UAAU,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK,OAAO,KAAK,SAAS,KAAK,OAAO,IAAI,KAAK,SAAS,IAAI;AAAA,aACnK,MAAM,QAAQ,UAAW,MAAK,KAAK,WAAW,IAAI,KAAK,UAAU;AAAA,aACjE,MAAM,QAAQ,OAAQ,MAAK;AAAA,aAC3B,MAAM,QAAQ,MAAO,MAAK,KAAK,SAAS;AAAA,QAC5C;AACL,UAAM,eAAe;AACrB,UAAM,SAAS,KAAK,KAAK,IAAI,KAAK,SAAS,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AAC9D,SAAK,MAAM;AACX,WAAO,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,EACtC,CAAC;AAED,QAAM,UAAU,GAAG,OAAO,EAAE,OAAO,qBAAqB,GAAG,IAAI;AAE/D,MAAI,UAAgC;AACpC,MAAI,eAAmC;AACvC,MAAI,QAAQ,YAAY,UAAa,QAAQ,WAAW;AACtD,cAAU,oBAAoB,GAAG,MAAM,KAAK,GAAG,QAAQ,SAAS,QAAQ,SAAS;AACjF,mBAAe,GAAG,OAAO,EAAE,OAAO,6BAA6B,GAAG,GAAG,OAAO,EAAE,OAAO,4BAA4B,MAAM,EAAE,iBAAiB,EAAE,CAAC,GAAG,QAAQ,OAAO;AAC/J,YAAQ,YAAY,YAAY;AAAA,EAClC;AAKA,MAAI,QAAkC;AACtC,QAAM,aAAa,MAAY;AAC7B,QAAI,CAAC,MAAO;AACZ,UAAM,QAAQ;AACd,YAAQ;AACR,SAAK,SAAS;AACd,QAAI,aAAc,cAAa,SAAS;AACxC,YAAQ,WAAW,KAAK;AAAA,EAC1B;AACA,QAAM,YAAY,MAAY;AAC5B,QAAI,MAAO;AACX,YAAQ,wBAAwB,GAAG,OAAO,CAAC,QAAQ;AACjD,cAAQ,IAAI,GAAG;AACf,iBAAW;AACX,iBAAW;AACX,WAAK,GAAG;AACP,OAAC,WAAW,cAA2B,mBAAmB,GAAG,IAAI,KAAK,KAAK,cAA2B,yBAAyB,KAAK,MAAM,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,IAC1K,CAAC;AACD,SAAK,SAAS;AACd,QAAI,aAAc,cAAa,SAAS;AACxC,YAAQ,YAAY,MAAM,OAAO;AACjC,YAAQ,WAAW,IAAI;AACvB,eAAW,MAAM,OAAO;AAAA,EAC1B;AAEA,aAAW;AACX,aAAW;AACX,SAAO;AAAA,IACL;AAAA,IACA,OAAO,MAAM,aAAa;AACxB,cAAQ;AACR,iBAAW;AACX,iBAAW;AACX,aAAO,OAAO,IAAI;AAClB,UAAI,WAAW,gBAAgB,OAAW,SAAQ,OAAO,MAAM,IAAI,GAAG,WAAW;AAAA,IACnF;AAAA,IACA,UAAU;AACR,iBAAW;AACX,eAAS,QAAQ;AACjB,cAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AACF;AA0BO,SAAS,mBAAmB,GAAmB,SAAkD;AACtG,MAAI,QAAQ,QAAQ;AACpB,MAAI,UAAU,QAAQ;AACtB,QAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,uBAAuB,CAAC;AACzD,QAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,kBAAkB,GAAG,IAAI;AAC1D,QAAM,OAAO,MAAY;AACvB,SAAK,MAAM,YAAY,gBAAgB,KAAK;AAC5C,SAAK,MAAM,UAAU,OAAO,WAAW,CAAC;AAAA,EAC1C;AACA,OAAK;AACL,QAAM,UAAU,OAAO,EAAE,OAAO,qCAAqC,OAAO,QAAQ,OAAO,UAAU,QAAQ,SAAS,CAAC;AACvH,UAAQ,aAAa,iBAAiB,QAAQ;AAC9C,UAAQ,aAAa,iBAAiB,OAAO;AAC7C,UAAQ,YAAY,IAAI;AAExB,MAAI,UAAgC;AACpC,MAAI,QAA6B;AACjC,UAAQ,iBAAiB,SAAS,MAAM;AACtC,QAAI,OAAO;AACT,YAAM;AACN;AAAA,IACF;AACA,UAAM,QAAQ,GAAG,OAAO,EAAE,OAAO,0BAA0B,CAAC;AAC5D,cAAU,mBAAmB,GAAG;AAAA,MAC9B;AAAA,MACA,QAAQ,CAAC,MAAM;AACb,gBAAQ,OAAO,CAAC;AAChB,YAAI,QAAQ,YAAa,SAAQ;AAAA,MACnC;AAAA,MACA,SAAS,QAAQ,WAAW;AAAA,MAC5B,GAAI,YAAY,UAAa,QAAQ,YAAY,EAAE,SAAS,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,IAChG,CAAC;AACD,UAAM,YAAY,QAAQ,OAAO;AACjC,YAAQ,QAAQ,UAAU,SAAS,OAAO,MAAM;AAC9C,eAAS,QAAQ;AACjB,gBAAU;AACV,cAAQ;AAAA,IACV,CAAC;AACD,eAAW,KAAK;AAAA,EAClB,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,OAAO,MAAM,aAAa;AACxB,cAAQ;AACR,UAAI,gBAAgB,OAAW,WAAU;AACzC,WAAK;AACL,eAAS,OAAO,MAAM,WAAW;AAAA,IACnC;AAAA,IACA,UAAU;AACR,cAAQ;AACR,cAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AACF;;;ACziBA,IAAM,oBAAoB;AA2BnB,IAAM,8BAAkD;AAAA,EAC7D,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,qBAAqB,CAAC;AAAA,EACtB,WAAW;AAAA,EACX,qBAAqB;AAAA,EACrB,cAAc,CAAC;AAAA,EACf,cAAc,CAAC;AACjB;AAEA,IAAM,aAAa,CAAC,UAA6C;AAC/D,QAAM,IAAI;AACV,SAAO,KAAK,OAAO,EAAE,MAAM,YAAY,OAAO,EAAE,MAAM,WAAW,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,IAAI;AACxF;AAEA,IAAM,QAAQ,CAAmB,OAAgB,SAAuB,aACtE,OAAO,UAAU,YAAa,QAA8B,SAAS,KAAK,IAAK,QAAc;AAE/F,IAAM,OAAO,CAAC,OAAgB,aAAgC,OAAO,UAAU,YAAY,QAAQ;AAEnG,IAAM,eAAe,CAAC,UAA2C;AAC/D,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACzE,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAgC,EAAG,KAAI,OAAO,UAAU,SAAU,KAAI,GAAG,IAAI;AACvH,SAAO;AACT;AAEA,IAAM,cAAc,CAAC,UAAmC;AACtD,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AACxE,QAAM,MAAM;AACZ,QAAM,QAAQ,MAAM,QAAQ,IAAI,KAAK,IAAI,IAAI,MAAM,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,EAAE,MAAM,GAAG,kBAAkB,IAAI,CAAC;AACrI,QAAM,IAAI,IAAI;AACd,QAAM,WAAW,KAAK,OAAO,EAAE,MAAM,YAAY,OAAO,EAAE,MAAM,WAAW,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,IAAI;AAChG,SAAO,EAAE,OAAO,SAAS,KAAK,IAAI,SAAS,kBAAkB,OAAO,GAAG,SAAS;AAClF;AAKO,SAAS,wBAAwB,KAAoD;AAC1F,MAAI,SAAkB;AACtB,MAAI;AACF,aAAS,KAAK,MAAM,OAAO,MAAM;AAAA,EACnC,QAAQ;AACN,aAAS;AAAA,EACX;AACA,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,EAAG,QAAO;AAC3E,QAAM,QAAQ;AACd,SAAO;AAAA,IACL,QAAQ,MAAM,MAAM,QAAQ,cAAc,4BAA4B,MAAM;AAAA,IAC5E,QAAQ,MAAM,MAAM,QAAQ,CAAC,OAAO,QAAQ,QAAQ,GAAY,4BAA4B,MAAM;AAAA,IAClG,gBAAgB,MAAM,MAAM,gBAAgB,CAAC,QAAQ,QAAQ,GAAY,4BAA4B,cAAc;AAAA,IACnH,mBAAmB,KAAK,MAAM,mBAAmB,4BAA4B,iBAAiB;AAAA,IAC9F,cAAc,KAAK,MAAM,cAAc,4BAA4B,YAAY;AAAA,IAC/E,iBAAiB,KAAK,MAAM,iBAAiB,4BAA4B,eAAe;AAAA,IACxF,qBAAqB,aAAa,MAAM,mBAAmB;AAAA,IAC3D,WAAW,YAAY,MAAM,SAAS;AAAA,IACtC,qBAAqB,WAAW,MAAM,mBAAmB;AAAA,IACzD,cAAc,MAAM,QAAQ,MAAM,YAAY,IAAI,MAAM,aAAa,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,EAAE,MAAM,GAAG,iBAAiB,IAAI,CAAC;AAAA,IACtJ,cAAc,MAAM,QAAQ,MAAM,YAAY,IAAI,MAAM,aAAa,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,kBAAkB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,kBAAkB,IAAI,CAAC;AAAA,EACtL;AACF;AAGO,SAAS,4BAA4B,aAAyC;AACnF,SAAO,KAAK,UAAU,WAAW;AACnC;AAIO,IAAM,0BAA0B;;;ACvFhC,IAAM,sBAAsB;AAEnC,IAAM,SAAS,CAAC,WAA+B,KAAK,UAAU,MAAM;AAI7D,SAAS,aAAa,SAA6B;AACxD,MAAI;AACF,UAAM,SAAkB,KAAK,MAAM,OAAO;AAC1C,QAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC;AAC5E,UAAM,MAAM;AACZ,UAAM,SAAqB,CAAC;AAC5B,QAAI,IAAI,SAAS,OAAO,IAAI,UAAU,YAAY,CAAC,MAAM,QAAQ,IAAI,KAAK,EAAG,QAAO,QAAQ,IAAI;AAChG,QAAI,IAAI,SAAS,OAAO,IAAI,UAAU,YAAY,CAAC,MAAM,QAAQ,IAAI,KAAK,EAAG,QAAO,QAAQ,IAAI;AAChG,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAGA,IAAM,eAAe,CAAC,QAA+B,IAAI,SAAS;AAGlE,IAAM,aAAa;AAKZ,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,OAAkD;AAAlD;AAAA,EAAmD;AAAA,EAAnD;AAAA;AAAA;AAAA,EAI7B,MAAM,KAAKC,OAAc,QAA+C;AACtE,UAAM,OAAO,MAAM,KAAK,MAAM,KAAK,MAAM;AACzC,WAAO,KAAK,OAAO,CAAC,QAAQ,IAAI,SAASA,SAAQ,CAAC,aAAa,GAAG,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,QAA+C;AAC3D,UAAM,OAAO,MAAM,KAAK,MAAM,KAAK,MAAM;AACzC,UAAM,QAAgG,IAAI,MAAM,KAAK,MAAM;AAC3H,QAAI,OAAO;AACX,UAAM,SAAS,YAA2B;AACxC,aAAO,OAAO,KAAK,QAAQ;AACzB,cAAM,KAAK;AACX,cAAM,EAAE,IAAI,MAAM,KAAK,MAAM,KAAK,KAAK,EAAE,EAAG,IAAI,MAAM;AAAA,MACxD;AAAA,IACF;AACA,UAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,YAAY,KAAK,MAAM,EAAE,GAAG,MAAM,CAAC;AACnF,UAAM,MAAsB,CAAC;AAC7B,eAAW,OAAO,OAAO;AACvB,UAAI,IAAK,KAAI,KAAK,EAAE,GAAG,aAAa,IAAI,KAAK,OAAO,GAAG,KAAK,IAAI,KAAK,MAAM,IAAI,KAAK,MAAM,MAAM,IAAI,KAAK,QAAQ,GAAG,CAAC;AAAA,IACvH;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,MAAM,KAAK,IAAY,QAAoF;AACzG,UAAM,QAAQ,MAAM,KAAK,MAAM,KAAK,IAAI,MAAM;AAC9C,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,SAAS,aAAa,MAAM,KAAK,OAAO;AAC9C,WAAO,EAAE,KAAK,MAAM,KAAK,UAAU,EAAE,GAAG,QAAQ,KAAK,MAAM,KAAK,MAAM,MAAM,KAAK,MAAM,MAAM,MAAM,KAAK,QAAQ,GAAG,EAAE;AAAA,EACvH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAKA,OAAc,MAAc,QAAoB,QAA2D;AACpH,UAAM,OAAqB,EAAE,MAAM,MAAAA,OAAM,SAAS,OAAO,MAAM,EAAE;AACjE,UAAM,OAAO,MAAM,KAAK,MAAM,KAAK,MAAM;AACzC,UAAM,WAAW,KAAK,KAAK,CAAC,QAAQ,IAAI,SAASA,SAAQ,IAAI,SAAS,IAAI;AAC1E,QAAI,CAAC,SAAU,QAAO,KAAK,MAAM,OAAO,MAAM,MAAM;AACpD,UAAM,QAAQ,MAAM,KAAK,MAAM,KAAK,SAAS,IAAI,MAAM;AACvD,QAAI,CAAC,MAAO,QAAO,KAAK,MAAM,OAAO,MAAM,MAAM;AACjD,WAAO,KAAK,MAAM,OAAO,MAAM,KAAK,MAAM,MAAM;AAAA,EAClD;AAAA,EAEA,MAAM,OAAO,KAAkB,QAAmD;AAChF,WAAO,KAAK,MAAM,OAAO,KAAK,MAAM;AAAA,EACtC;AAAA;AAAA,EAGA,MAAM,WAAWA,OAAc,QAA2C;AACxE,UAAM,OAAO,MAAM,KAAK,MAAM,KAAK,MAAM;AACzC,UAAM,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,SAASA,SAAQ,aAAa,CAAC,CAAC;AAC/D,QAAI,CAAC,IAAK,QAAO,CAAC;AAClB,UAAM,QAAQ,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,MAAM;AAClD,WAAO,QAAQ,aAAa,MAAM,KAAK,OAAO,IAAI,CAAC;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAgBA,OAAc,QAAoB,QAA2D;AACjH,WAAO,KAAK,KAAKA,OAAM,qBAAqB,QAAQ,MAAM;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,aAAaA,OAAc,QAA0D;AACzF,UAAM,OAAO,MAAM,KAAK,MAAM,KAAK,MAAM;AACzC,UAAM,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,SAASA,SAAQ,aAAa,CAAC,CAAC;AAC/D,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,QAAQ,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,MAAM;AAClD,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,KAAK,MAAM,OAAO,MAAM,KAAK,MAAM;AAAA,EAC5C;AACF;;;AC3IO,IAAM,kBAAkB,IAAI,OAAO;AAEnC,IAAM,iBAAiB;AAGvB,IAAM,cAAiC,CAAC,cAAc,aAAa,YAAY;AAE/E,IAAM,eAAe;AAOrB,IAAM,uBAA4E;AAAA,EACvF,cAAc;AAAA,EACd,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,aAAa;AACf;AA6BO,SAAS,eAAe,MAA0F;AACvH,MAAI,CAAC,YAAY,SAAS,KAAK,IAAI,EAAG,QAAO,EAAE,OAAO,aAAa;AACnE,MAAI,KAAK,OAAO,gBAAiB,QAAO,EAAE,OAAO,aAAa,OAAO,KAAK,KAAK;AAC/E,SAAO;AACT;AAIO,SAAS,SAAS,OAAe,QAAgB,UAAU,gBAAwB;AACxF,QAAM,UAAU,KAAK,IAAI,OAAO,MAAM;AACtC,SAAO,UAAU,UAAU,UAAU,UAAU;AACjD;AAGO,SAAS,WAAW,OAAe,QAAgB,UAAU,gBAAmD;AACrH,QAAM,QAAQ,SAAS,OAAO,QAAQ,OAAO;AAC7C,SAAO,EAAE,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,KAAK,CAAC,GAAG,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,KAAK,CAAC,EAAE;AAC1G;;;AC7DO,IAAM,WAAgC,oBAAI,IAAI;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKM,IAAM,YAAiC,oBAAI,IAAI;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAIM,IAAM,gBAAqC,oBAAI,IAAI;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKM,IAAM,eAAoC,oBAAI,IAAI,CAAC,QAAQ,WAAW,WAAW,SAAS,SAAS,CAAC;AAKpG,IAAM,kBAAuC,oBAAI,IAAI,CAAC,iBAAiB,gBAAgB,CAAC;AAGxF,IAAM,aAAkC,oBAAI,IAAI,CAAC,QAAQ,QAAQ,WAAW,WAAW,SAAS,eAAe,UAAU,CAAC;AAI1H,IAAM,mBAAwC,oBAAI,IAAI,CAAC,iBAAiB,kBAAkB,gBAAgB,oBAAoB,sBAAsB,cAAc,CAAC;AAE1K,IAAM,aAAa,CAAC,WAAW;AAC/B,IAAM,aAAa,CAAC,eAAe,iBAAiB,eAAe;AACnE,IAAM,OAAO,CAAC,aAAa;AAC3B,IAAM,UAAU,CAAC,aAAa;AAC9B,IAAM,UAAU,CAAC,YAAY;AAC7B,IAAM,OAAO,CAAC,cAAc,YAAY;AACxC,IAAM,UAAU,CAAC,SAAS;AAC1B,IAAM,QAAQ,CAAC,gBAAgB;AAKxB,IAAM,mBAAsD;AAAA,EACjE,kBAAkB,CAAC,WAAW;AAAA,EAC9B,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,aAAa;AAAA,EACb,aAAa,CAAC,eAAe;AAAA,EAC7B,sBAAsB;AAAA,EACtB,UAAU;AAAA,EACV,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,2BAA2B;AAAA,EAC3B,kBAAkB;AAAA,EAClB,SAAS,CAAC,MAAM;AAAA,EAChB,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,cAAc,CAAC,SAAS;AAAA,EACxB,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,OAAO;AAAA,EACP,SAAS,CAAC,eAAe,GAAG,UAAU;AAAA,EACtC,aAAa;AAAA,EACb,KAAK;AAAA,EACL,MAAM;AAAA,EACN,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,sBAAsB,CAAC,cAAc,eAAe,GAAG,KAAK;AAC9D;AAKO,IAAM,cAAiD;AAAA,EAC5D,GAAG;AAAA,EACH,aAAa,CAAC,QAAQ,WAAW,YAAY,qBAAqB,gBAAgB,aAAa,GAAG,UAAU;AAAA,EAC5G,OAAO,CAAC,SAAS,aAAa,GAAG,UAAU;AAC7C;AAOO,IAAM,qBAA0C,oBAAI,IAAI,CAAC,qBAAqB,OAAO,YAAY,WAAW,aAAa,mBAAmB,oBAAoB,UAAU,gBAAgB,iBAAiB,kBAAkB,iBAAiB,QAAQ,SAAS,SAAS,eAAe,QAAQ,SAAS,WAAW,QAAQ,OAAO,CAAC;AAGnU,IAAM,oBAAyC,oBAAI,IAAI,CAAC,iBAAiB,CAAC;AAG1E,IAAM,kBAAuC,oBAAI,IAAI;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAiBM,IAAM,sBAAmE;AAAA,EAC9E,eAAe;AAAA,IACb,EAAE,MAAM,eAAe,MAAM,UAAU,OAAO,sBAAsB;AAAA,IACpE,EAAE,MAAM,aAAa,MAAM,UAAU,OAAO,oBAAoB;AAAA,EAClE;AAAA,EACA,gBAAgB;AAAA,IACd,EAAE,MAAM,eAAe,MAAM,UAAU,OAAO,sBAAsB;AAAA,IACpE,EAAE,MAAM,aAAa,MAAM,UAAU,OAAO,oBAAoB;AAAA,EAClE;AACF;AAEO,IAAM,UAA+B,oBAAI,IAAI,CAAC,eAAe,SAAS,eAAe,cAAc,wBAAwB,SAAS,CAAC;AAKrI,IAAM,cAAiD;AAAA,EAC5D,4BAA4B,CAAC,cAAc,WAAW,UAAU,mBAAmB,aAAa;AAAA,EAChG,yBAAyB,CAAC,cAAc,WAAW,UAAU,iBAAiB;AAAA,EAC9E,YAAY,CAAC,aAAa,UAAU;AAAA,EACpC,eAAe,CAAC,eAAe,QAAQ,eAAe,WAAW,YAAY,cAAc;AAAA,EAC3F,gBAAgB,CAAC,eAAe,QAAQ,eAAe,WAAW,YAAY,cAAc;AAAA,EAC5F,kBAAkB,CAAC,kBAAkB,kBAAkB,YAAY,YAAY,QAAQ;AAAA,EACvF,eAAe,CAAC,UAAU,aAAa,mBAAmB,SAAS;AACrE;","names":["line","box","drawing","box","drawing","box","box","box","drawing","y","at","drawing","hitTolerance","box","lineHeight","width","height","ACROSS","p","inBox","spanText","line2","box","hitTolerance","drawing","line","box","hitTolerance","line","drawing","FORK_LEVELS","levelStroke","line","hitTolerance","box","line","ratio","box","hitTolerance","line","xs","ys","hitTolerance","hitTolerance","hitTolerance","line","hitTolerance","line","inBox","box","ratio","line","drawing","restoreDrawings","catalog","tool","tool","tool","a","el","box","box","cells","tool"]}