@foxeltech/angular-ui 0.7.103 → 0.7.106

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.
@@ -22,10 +22,26 @@ class ChartComponent {
22
22
  showPieLegend = input(true, ...(ngDevMode ? [{ debugName: "showPieLegend" }] : /* istanbul ignore next */ []));
23
23
  /** Caption under the donut's centre total (design: "42 / confirmed"). */
24
24
  pieCenterLabel = input('', ...(ngDevMode ? [{ debugName: "pieCenterLabel" }] : /* istanbul ignore next */ []));
25
+ /**
26
+ * Type size of the donut's centre TOTAL, in px. The default matches what the
27
+ * figure has always been; raise it where the total is the panel's headline
28
+ * rather than an annotation.
29
+ */
30
+ pieCenterValueSize = input(24, ...(ngDevMode ? [{ debugName: "pieCenterValueSize" }] : /* istanbul ignore next */ []));
25
31
  mobileWidth = input(350, ...(ngDevMode ? [{ debugName: "mobileWidth" }] : /* istanbul ignore next */ []));
26
32
  /** Override font for canvas text; empty = follow the theme's --og-font-figure. */
27
33
  labelFontFamily = input('', ...(ngDevMode ? [{ debugName: "labelFontFamily" }] : /* istanbul ignore next */ []));
28
34
  emptyText = input('No data available', ...(ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []));
35
+ // line / area-trend controls
36
+ /**
37
+ * Print each point's value beside a marker on the line.
38
+ *
39
+ * Off by default: on a dense series the labels collide and the line becomes
40
+ * unreadable. Turn it on for the sparse, weekly kind of series where the
41
+ * number at each step IS the content — a reader should not have to hover to
42
+ * learn what a step was.
43
+ */
44
+ showPointLabels = input(false, ...(ngDevMode ? [{ debugName: "showPointLabels" }] : /* istanbul ignore next */ []));
29
45
  /* ================= OUTPUTS ================= */
30
46
  chartClick = output();
31
47
  chartInit = output();
@@ -247,7 +263,14 @@ class ChartComponent {
247
263
  * lại cùng cỡ thì coi như không đổi (không resize, không cắt animation).
248
264
  */
249
265
  measure() {
250
- const { width, height } = this.ref.nativeElement.getBoundingClientRect();
266
+ const rect = this.ref.nativeElement.getBoundingClientRect();
267
+ // Whole pixels only. getBoundingClientRect() follows transforms, so a host
268
+ // riding an fxReveal translateY reports 200.00003 then 199.99997 — the
269
+ // old strict compare took that jitter for a resize, and after the appear
270
+ // window a pie was resized + rebuilt = drawn twice (đo 07/09, Overview
271
+ // "Open findings by severity" 2 × 60 frames 1.1 s apart).
272
+ const width = Math.round(rect.width);
273
+ const height = Math.round(rect.height);
251
274
  if (width <= 0 || height <= 0)
252
275
  return { size: false, mobile: false };
253
276
  const isMobile = width < this.mobileWidth();
@@ -493,15 +516,15 @@ class ChartComponent {
493
516
  const cx = (this.containerWidth || 400) * (parseFloat(layout.pieCenter[0]) / 100);
494
517
  const ch = this.ref.nativeElement.clientHeight || 300;
495
518
  const cy = ch * (parseFloat(layout.pieCenter[1]) / 100);
519
+ const centre = this.pieCentreAnchors();
496
520
  return [
497
521
  {
498
522
  type: 'text',
499
- // Shift the total up when a caption sits under it.
500
523
  x: cx,
501
- y: cy + (this.pieCenterLabel() ? -9 : 0),
524
+ y: cy + centre.total,
502
525
  style: {
503
526
  text: total.toString(),
504
- fontSize: 24,
527
+ fontSize: this.pieCenterValueSize(),
505
528
  fontWeight: 600,
506
529
  fontFamily: this.resolvedFontFamily(),
507
530
  fill: FxUtils.convertColorFromVariable('--text-primary'),
@@ -514,7 +537,7 @@ class ChartComponent {
514
537
  {
515
538
  type: 'text',
516
539
  x: cx,
517
- y: cy + 12,
540
+ y: cy + centre.caption,
518
541
  style: {
519
542
  text: this.pieCenterLabel(),
520
543
  fontSize: 11,
@@ -568,7 +591,7 @@ class ChartComponent {
568
591
  name: data?.currentLabel || 'Current',
569
592
  data: data?.current || [],
570
593
  smooth: true,
571
- symbol: 'none',
594
+ ...this.pointMarks('top', accent),
572
595
  lineStyle: { width: 2, color: accent },
573
596
  itemStyle: { color: accent },
574
597
  areaStyle: {
@@ -589,7 +612,9 @@ class ChartComponent {
589
612
  name: data?.previousLabel || 'Previous',
590
613
  data: data.previous,
591
614
  smooth: true,
592
- symbol: 'none',
615
+ // Labels below this line, above the other one: two series sharing an
616
+ // x tick would otherwise print their numbers on top of each other.
617
+ ...this.pointMarks('bottom', FxUtils.convertColorFromVariable('--text-placeholder', 1, { legacyCommaSyntax: true })),
593
618
  lineStyle: {
594
619
  width: 1.5,
595
620
  type: 'dashed',
@@ -696,14 +721,77 @@ class ChartComponent {
696
721
  return 'pie';
697
722
  return 'bar';
698
723
  }
724
+ /**
725
+ * Marker and value label for one line series, per `showPointLabels`.
726
+ *
727
+ * Returns the OFF state explicitly (`symbol: 'none'`) rather than nothing, so
728
+ * the caller spreads one object either way and the default stays exactly what
729
+ * it was before this input existed.
730
+ */
731
+ pointMarks(position, color) {
732
+ if (!this.showPointLabels())
733
+ return { symbol: 'none' };
734
+ return {
735
+ symbol: 'circle',
736
+ symbolSize: 6,
737
+ showSymbol: true,
738
+ label: {
739
+ show: true,
740
+ position,
741
+ distance: 7,
742
+ fontSize: this.labelFontSize,
743
+ fontFamily: this.resolvedFontFamily(),
744
+ color,
745
+ },
746
+ };
747
+ }
748
+ /**
749
+ * Where the donut's centre total and its caption sit, relative to the ring's
750
+ * centre.
751
+ *
752
+ * MEASURED, not guessed. Both numbers below were read off a render at two
753
+ * sizes (glyph ink bounding boxes against the ring's own bounding box):
754
+ * neutral-figure ink is ~0.73 of the font size tall, and an ECharts text with
755
+ * `verticalAlign: 'middle'` places its ANCHOR ~0.095 of the font size BELOW
756
+ * the ink's optical centre — digits have no descender, so the ink rides high
757
+ * in the line box.
758
+ *
759
+ * The line gap is a CONSTANT. That is the whole point of this function: the
760
+ * gap between two lines is typographic and does not scale with the size of
761
+ * the number above it. Deriving it from the font size instead — which the
762
+ * first cut of `pieCenterValueSize` did — inflated a 9.6px gap to 18.2px at
763
+ * 38px type and pushed the pair 4.8px above the ring's centre. The hand-tuned
764
+ * constants it replaced were already 2.5px high at the default size; this
765
+ * lands the block dead centre at every size (verified 24/30/38/48).
766
+ */
767
+ pieCentreAnchors() {
768
+ const FIGURE_INK = 0.73;
769
+ const MIDDLE_ANCHOR_DROP = 0.095;
770
+ const LINE_GAP = 10;
771
+ const CAPTION_SIZE = 11;
772
+ const value = this.pieCenterValueSize();
773
+ // No caption: one line, its ink centred on the ring.
774
+ if (!this.pieCenterLabel()) {
775
+ return { total: MIDDLE_ANCHOR_DROP * value, caption: 0 };
776
+ }
777
+ const valueInk = FIGURE_INK * value;
778
+ const captionInk = FIGURE_INK * CAPTION_SIZE;
779
+ const blockHeight = valueInk + LINE_GAP + captionInk;
780
+ return {
781
+ total: -blockHeight / 2 + valueInk / 2 + MIDDLE_ANCHOR_DROP * value,
782
+ caption: blockHeight / 2 - captionInk / 2 + MIDDLE_ANCHOR_DROP * CAPTION_SIZE,
783
+ };
784
+ }
699
785
  buildOptions() {
700
786
  const type = this.detectType();
701
787
  const palette = this.resolvePalette();
702
788
  const base = this.registry[type]?.(this.data(), palette) || {};
703
- return {
704
- ...base,
705
- ...this.options(),
706
- };
789
+ // DEEP merge, not a spread. A shallow one replaced whole branches, so
790
+ // `[options]="{series:[{label:…}]}"` threw away the recipe's own series —
791
+ // data included — and there was no way to adjust one nested detail from
792
+ // outside. Arrays merge BY INDEX for the same reason: a caller tweaking
793
+ // series 0 must not have to restate series 1.
794
+ return deepMergeOptions(base, this.options());
707
795
  }
708
796
  categoryAxis(categories) {
709
797
  return {
@@ -770,15 +858,49 @@ class ChartComponent {
770
858
  });
771
859
  }
772
860
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ChartComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
773
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: ChartComponent, isStandalone: true, selector: "fx-ui-chart", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, palette: { classPropertyName: "palette", publicName: "palette", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, pieLegendAlign: { classPropertyName: "pieLegendAlign", publicName: "pieLegendAlign", isSignal: true, isRequired: false, transformFunction: null }, pieLegendPosition: { classPropertyName: "pieLegendPosition", publicName: "pieLegendPosition", isSignal: true, isRequired: false, transformFunction: null }, showPieLabel: { classPropertyName: "showPieLabel", publicName: "showPieLabel", isSignal: true, isRequired: false, transformFunction: null }, showPieLegend: { classPropertyName: "showPieLegend", publicName: "showPieLegend", isSignal: true, isRequired: false, transformFunction: null }, pieCenterLabel: { classPropertyName: "pieCenterLabel", publicName: "pieCenterLabel", isSignal: true, isRequired: false, transformFunction: null }, mobileWidth: { classPropertyName: "mobileWidth", publicName: "mobileWidth", isSignal: true, isRequired: false, transformFunction: null }, labelFontFamily: { classPropertyName: "labelFontFamily", publicName: "labelFontFamily", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { chartClick: "chartClick", chartInit: "chartInit" }, host: { listeners: { "window:theme-changed": "onThemeChange()" } }, providers: [provideEchartsCore({ echarts: () => import('echarts') })], usesOnChanges: true, ngImport: i0, template: "<div class=\"chart-wrapper\" [style.height]=\"height()\">\n @if (isEmpty) {\n <div class=\"chart-empty\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"chart-empty-icon\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n <span class=\"chart-empty-text\">{{ emptyText() }}</span>\n </div>\n } @else if (hasOptions) {\n <div\n echarts\n [options]=\"chartOptions\"\n [autoResize]=\"false\"\n [loading]=\"loading()\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height()\"\n ></div>\n } @else {\n <!-- Until echarts is loaded + initialised (or the element scrolls into view)\n the panel keeps the chart's footprint with a quiet pulsing sketch\n instead of an empty box (anh T\u00FA 04/09: \"the page is too blank\"). -->\n <div class=\"chart-placeholder\" aria-hidden=\"true\">\n @for (h of placeholderBars; track $index) {\n <span class=\"chart-placeholder__bar\" [style.height.%]=\"h\"></span>\n }\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.chart-wrapper{position:relative;width:100%;height:100%}.chart-container{width:100%;height:100%}.chart-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--bg-primary-hover)/.6);font-weight:500;font-size:1.1rem;z-index:2;border-radius:4px}.chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:rgba(var(--text-secondary)/1)}.chart-empty-icon{width:48px;height:48px;opacity:.4}.chart-empty-text{font-size:14px;font-weight:500}.chart-placeholder{position:absolute;inset:0;display:flex;align-items:flex-end;gap:6px;padding:12px 8px 22px;animation:chart-placeholder-pulse 1.6s ease-in-out infinite}.chart-placeholder__bar{flex:1;border-radius:3px 3px 0 0;background:rgb(var(--og-track))}@keyframes chart-placeholder-pulse{0%,to{opacity:1}50%{opacity:.45}}@media(prefers-reduced-motion:reduce){.chart-placeholder{animation:none}}\n"], dependencies: [{ kind: "directive", type: NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
861
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: ChartComponent, isStandalone: true, selector: "fx-ui-chart", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, palette: { classPropertyName: "palette", publicName: "palette", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, pieLegendAlign: { classPropertyName: "pieLegendAlign", publicName: "pieLegendAlign", isSignal: true, isRequired: false, transformFunction: null }, pieLegendPosition: { classPropertyName: "pieLegendPosition", publicName: "pieLegendPosition", isSignal: true, isRequired: false, transformFunction: null }, showPieLabel: { classPropertyName: "showPieLabel", publicName: "showPieLabel", isSignal: true, isRequired: false, transformFunction: null }, showPieLegend: { classPropertyName: "showPieLegend", publicName: "showPieLegend", isSignal: true, isRequired: false, transformFunction: null }, pieCenterLabel: { classPropertyName: "pieCenterLabel", publicName: "pieCenterLabel", isSignal: true, isRequired: false, transformFunction: null }, pieCenterValueSize: { classPropertyName: "pieCenterValueSize", publicName: "pieCenterValueSize", isSignal: true, isRequired: false, transformFunction: null }, mobileWidth: { classPropertyName: "mobileWidth", publicName: "mobileWidth", isSignal: true, isRequired: false, transformFunction: null }, labelFontFamily: { classPropertyName: "labelFontFamily", publicName: "labelFontFamily", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, showPointLabels: { classPropertyName: "showPointLabels", publicName: "showPointLabels", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { chartClick: "chartClick", chartInit: "chartInit" }, host: { listeners: { "window:theme-changed": "onThemeChange()" } }, providers: [provideEchartsCore({ echarts: () => import('echarts') })], usesOnChanges: true, ngImport: i0, template: "<div class=\"chart-wrapper\" [style.height]=\"height()\">\n @if (isEmpty) {\n <div class=\"chart-empty\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"chart-empty-icon\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n <span class=\"chart-empty-text\">{{ emptyText() }}</span>\n </div>\n } @else if (hasOptions) {\n <div\n echarts\n [options]=\"chartOptions\"\n [autoResize]=\"false\"\n [loading]=\"loading()\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height()\"\n ></div>\n } @else {\n <!-- Until echarts is loaded + initialised (or the element scrolls into view)\n the panel keeps the chart's footprint with a quiet pulsing sketch\n instead of an empty box (anh T\u00FA 04/09: \"the page is too blank\"). -->\n <div class=\"chart-placeholder\" aria-hidden=\"true\">\n @for (h of placeholderBars; track $index) {\n <span class=\"chart-placeholder__bar\" [style.height.%]=\"h\"></span>\n }\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.chart-wrapper{position:relative;width:100%;height:100%}.chart-container{width:100%;height:100%}.chart-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--bg-primary-hover)/.6);font-weight:500;font-size:1.1rem;z-index:2;border-radius:4px}.chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:rgba(var(--text-secondary)/1)}.chart-empty-icon{width:48px;height:48px;opacity:.4}.chart-empty-text{font-size:14px;font-weight:500}.chart-placeholder{position:absolute;inset:0;display:flex;align-items:flex-end;gap:6px;padding:12px 8px 22px;animation:chart-placeholder-pulse 1.6s ease-in-out infinite}.chart-placeholder__bar{flex:1;border-radius:3px 3px 0 0;background:rgb(var(--og-track))}@keyframes chart-placeholder-pulse{0%,to{opacity:1}50%{opacity:.45}}@media(prefers-reduced-motion:reduce){.chart-placeholder{animation:none}}\n"], dependencies: [{ kind: "directive", type: NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
774
862
  }
775
863
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ChartComponent, decorators: [{
776
864
  type: Component,
777
865
  args: [{ selector: 'fx-ui-chart', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgxEchartsDirective, InputComponent], providers: [provideEchartsCore({ echarts: () => import('echarts') })], template: "<div class=\"chart-wrapper\" [style.height]=\"height()\">\n @if (isEmpty) {\n <div class=\"chart-empty\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"chart-empty-icon\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n <span class=\"chart-empty-text\">{{ emptyText() }}</span>\n </div>\n } @else if (hasOptions) {\n <div\n echarts\n [options]=\"chartOptions\"\n [autoResize]=\"false\"\n [loading]=\"loading()\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height()\"\n ></div>\n } @else {\n <!-- Until echarts is loaded + initialised (or the element scrolls into view)\n the panel keeps the chart's footprint with a quiet pulsing sketch\n instead of an empty box (anh T\u00FA 04/09: \"the page is too blank\"). -->\n <div class=\"chart-placeholder\" aria-hidden=\"true\">\n @for (h of placeholderBars; track $index) {\n <span class=\"chart-placeholder__bar\" [style.height.%]=\"h\"></span>\n }\n </div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:block;width:100%}.chart-wrapper{position:relative;width:100%;height:100%}.chart-container{width:100%;height:100%}.chart-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--bg-primary-hover)/.6);font-weight:500;font-size:1.1rem;z-index:2;border-radius:4px}.chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:rgba(var(--text-secondary)/1)}.chart-empty-icon{width:48px;height:48px;opacity:.4}.chart-empty-text{font-size:14px;font-weight:500}.chart-placeholder{position:absolute;inset:0;display:flex;align-items:flex-end;gap:6px;padding:12px 8px 22px;animation:chart-placeholder-pulse 1.6s ease-in-out infinite}.chart-placeholder__bar{flex:1;border-radius:3px 3px 0 0;background:rgb(var(--og-track))}@keyframes chart-placeholder-pulse{0%,to{opacity:1}50%{opacity:.45}}@media(prefers-reduced-motion:reduce){.chart-placeholder{animation:none}}\n"] }]
778
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], palette: [{ type: i0.Input, args: [{ isSignal: true, alias: "palette", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], pieLegendAlign: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieLegendAlign", required: false }] }], pieLegendPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieLegendPosition", required: false }] }], showPieLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPieLabel", required: false }] }], showPieLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPieLegend", required: false }] }], pieCenterLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieCenterLabel", required: false }] }], mobileWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileWidth", required: false }] }], labelFontFamily: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelFontFamily", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], chartClick: [{ type: i0.Output, args: ["chartClick"] }], chartInit: [{ type: i0.Output, args: ["chartInit"] }], onThemeChange: [{
866
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], palette: [{ type: i0.Input, args: [{ isSignal: true, alias: "palette", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], pieLegendAlign: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieLegendAlign", required: false }] }], pieLegendPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieLegendPosition", required: false }] }], showPieLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPieLabel", required: false }] }], showPieLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPieLegend", required: false }] }], pieCenterLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieCenterLabel", required: false }] }], pieCenterValueSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieCenterValueSize", required: false }] }], mobileWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileWidth", required: false }] }], labelFontFamily: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelFontFamily", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], showPointLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPointLabels", required: false }] }], chartClick: [{ type: i0.Output, args: ["chartClick"] }], chartInit: [{ type: i0.Output, args: ["chartInit"] }], onThemeChange: [{
779
867
  type: HostListener,
780
868
  args: ['window:theme-changed']
781
869
  }] } });
870
+ /**
871
+ * Recursively merges an override onto a base ECharts option tree.
872
+ *
873
+ * Plain objects merge key by key; arrays merge BY INDEX, so overriding one
874
+ * series does not delete its siblings; anything else — a scalar, a Date, a
875
+ * colour-stop function — is replaced whole, because a half-merged value of
876
+ * those types has no meaning. `undefined` in the override is skipped so an
877
+ * unset field cannot erase a built-in.
878
+ */
879
+ function deepMergeOptions(base, override) {
880
+ if (override === undefined)
881
+ return base;
882
+ if (Array.isArray(base) && Array.isArray(override)) {
883
+ const out = [...base];
884
+ override.forEach((value, i) => {
885
+ out[i] = i < base.length ? deepMergeOptions(base[i], value) : value;
886
+ });
887
+ return out;
888
+ }
889
+ if (isPlainObject(base) && isPlainObject(override)) {
890
+ const out = { ...base };
891
+ for (const [key, value] of Object.entries(override)) {
892
+ out[key] = key in base ? deepMergeOptions(base[key], value) : value;
893
+ }
894
+ return out;
895
+ }
896
+ return override;
897
+ }
898
+ function isPlainObject(value) {
899
+ return (typeof value === 'object' &&
900
+ value !== null &&
901
+ !Array.isArray(value) &&
902
+ (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null));
903
+ }
782
904
 
783
905
  let pending;
784
906
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"foxeltech-angular-ui-chart.mjs","sources":["../../../projects/ui/chart/src/chart/chart.component.ts","../../../projects/ui/chart/src/chart/chart.component.html","../../../projects/ui/chart/src/preload-echarts.ts","../../../projects/ui/chart/src/foxeltech-angular-ui-chart.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectorRef,\n Component,\n ElementRef,\n HostListener,\n OnChanges,\n OnDestroy,\n ChangeDetectionStrategy,\n input,\n output\n} from '@angular/core';\nimport { ECharts, EChartsOption } from 'echarts';\nimport { FxUtils, InputComponent } from '@foxeltech/angular-ui';\nimport { NgxEchartsDirective, provideEchartsCore } from 'ngx-echarts';\n\n\n// 'radar' was advertised here but has no builder in the registry — it\n// silently rendered an empty chart. Re-add when implemented.\n// V2 presets: 'line' (risk score by release), 'area-trend' (weekly trend with\n// accent fill + gray comparison line). Both need an explicit [type] — 'auto'\n// cannot tell them apart from 'bar'.\nexport type IChartType = 'bar' | 'pie' | 'sunburst' | 'line' | 'area-trend' | 'auto';\n\n@Component({\n selector: 'fx-ui-chart',\n templateUrl: './chart.component.html',\n styleUrl: './chart.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgxEchartsDirective, InputComponent],\n // Self-contained: echarts is provided (and lazy-loaded) right here, so\n // consumers just import ChartComponent — no forRoot wiring in the app.\n providers: [provideEchartsCore({ echarts: () => import('echarts') })],\n})\nexport class ChartComponent implements OnChanges, AfterViewInit, OnDestroy {\n /* ================= INPUTS ================= */\n\n readonly type = input<IChartType>('auto');\n readonly data = input<any>();\n readonly options = input<EChartsOption>();\n readonly palette = input<string[]>();\n readonly height = input('400px');\n readonly loading = input(false);\n\n // pie controls\n readonly pieLegendAlign = input<string | number>('10%');\n readonly pieLegendPosition = input<string | number>('middle');\n readonly showPieLabel = input(true);\n /** Hide the built-in legend (panels that render their own legend beside the\n donut); the donut then centres in the container. */\n readonly showPieLegend = input(true);\n /** Caption under the donut's centre total (design: \"42 / confirmed\"). */\n readonly pieCenterLabel = input('');\n readonly mobileWidth = input(350);\n /** Override font for canvas text; empty = follow the theme's --og-font-figure. */\n readonly labelFontFamily = input('');\n readonly emptyText = input('No data available');\n\n /* ================= OUTPUTS ================= */\n\n readonly chartClick = output<any>();\n readonly chartInit = output<ECharts>();\n\n /* ================= INTERNAL ================= */\n\n chartOptions: EChartsOption = {};\n isEmpty = false;\n /**\n * ⚠️ Cổng cho `<div echarts>` trong template. Trước đây div render NGAY với\n * `chartOptions = {}`, nên NgxEchartsDirective khởi tạo chart bằng options\n * RỖNG; options thật gán vào giữa lúc `await createChart()` của lần đó ⇒\n * onOptionsChange() thấy `chart == null` và createChart() LẦN HAI trên cùng\n * DOM node ⇒ \"[ECharts] There is a chart instance already initialized on the\n * dom.\". Chỉ dựng directive khi đã có options thật ⇒ đúng một lần init.\n */\n hasOptions = false;\n /** Heights (%) of the pre-init placeholder bars — a fixed, calm silhouette. */\n readonly placeholderBars = [34, 52, 44, 66, 58, 78, 70, 88, 62, 74];\n labelFontSize = 12;\n\n private chartInstance?: ECharts;\n private resizeObserver?: ResizeObserver;\n private intersectionObserver?: IntersectionObserver;\n\n private canInit = false;\n private destroyed = false;\n /**\n * ⚠️ Đang chờ init đầu tiên của directive hoàn tất?\n *\n * NgxEchartsDirective đăng ký `changeFilter.notFirstAndEmpty('options', …)`:\n * lần gán `options` ĐẦU bị bỏ qua (ngAfterViewInit lo), lần gán THỨ HAI gọi\n * onOptionsChange(). Mà onOptionsChange() chỉ createChart() khi `this.chart`\n * còn null — và nó null suốt thời gian `await createChart()` của lần đầu.\n * Nên nếu ta gán `chartOptions` (object mới) trong khoảng await đó thì\n * init() chạy HAI LẦN trên cùng DOM node ⇒\n * \"[ECharts] There is a chart instance already initialized on the dom.\"\n *\n * Cách chặn: trong khoảng chờ, giữ options ở `deferredOptions` chứ không đụng\n * vào property đang bind; init xong thì áp một lần qua instance.\n */\n private awaitingFirstInit = false;\n private deferredOptions?: EChartsOption;\n private pendingFrames = new Set<number>();\n private isMobile = false;\n private containerWidth = 0;\n private containerHeight = 0;\n /**\n * Mốc (performance.now) mà animation \"xuất hiện\" của lần setOption gần nhất\n * chắc chắn đã xong. ECharts mặc định animationDuration 1000ms; trong khoảng\n * này KHÔNG được `resize()` — resize nhảy thẳng tới trạng thái cuối và giết\n * animation (đo 05/09: chart PM bị cắt ở ~800ms khi thanh cuộn xuất hiện\n * lúc lưới card nạp xong làm bề rộng đổi 720→710).\n */\n private appearUntil = 0;\n private static readonly APPEAR_MS = 1100;\n private deferTimer?: ReturnType<typeof setTimeout>;\n /**\n * Thay đổi kích thước ghi nhận TRONG cửa sổ appear, chờ áp sau. `measure()`\n * đã cập nhật containerWidth/Height ngay lúc đo, nên lần gọi hoãn không thể\n * dựa vào \"có đổi không\" nữa — phải nhớ bằng cờ.\n */\n private pendingResize = false;\n private pendingMobile = false;\n\n constructor(\n private ref: ElementRef<HTMLElement>,\n private cdr: ChangeDetectorRef,\n ) {}\n\n /* ================= LIFECYCLE ================= */\n\n ngAfterViewInit(): void {\n // Only initialize when visible (tab-safe)\n this.intersectionObserver = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting && !this.canInit && !this.destroyed) {\n this.canInit = true;\n this.measure();\n this.rebuildChart();\n this.cdr.detectChanges();\n }\n },\n { threshold: 0.1 },\n );\n\n this.intersectionObserver.observe(this.ref.nativeElement);\n\n // Resize-safe (tabs, flex, async layout). Đây là ĐƯỜNG RESIZE DUY NHẤT:\n // `autoResize` của NgxEchartsDirective đã tắt trong template — nó\n // resize() mù sau throttle 100ms, kể cả về 0×H khi phần tử display:none\n // (skeleton route ẩn nội dung cũ) rồi resize lại khi hiện → animation\n // xuất hiện bị giết (đo 05/09 khi đổi project trên chip breadcrumb).\n this.resizeObserver = new ResizeObserver(() => {\n if (!this.canInit || this.destroyed) return;\n this.forceMediaRecalc();\n });\n\n this.resizeObserver.observe(this.ref.nativeElement);\n }\n\n ngOnChanges(): void {\n if (this.canInit && !this.destroyed) {\n this.measure();\n this.rebuildChart();\n }\n }\n\n ngOnDestroy(): void {\n // NgxEchartsDirective tự dispose instance của nó, nên KHÔNG dispose ở đây\n // (sẽ dispose trùng). Việc phải làm là ngắt mọi đường còn chạm được vào\n // instance sau khi nó đã bị dispose: callback rAF đang chờ + tham chiếu\n // `chartInstance` mà forceMediaRecalc/rebuildChart vẫn dùng.\n this.destroyed = true;\n\n for (const id of this.pendingFrames) cancelAnimationFrame(id);\n this.pendingFrames.clear();\n if (this.deferTimer !== undefined) clearTimeout(this.deferTimer);\n this.deferTimer = undefined;\n\n this.resizeObserver?.disconnect();\n this.intersectionObserver?.disconnect();\n this.resizeObserver = undefined;\n this.intersectionObserver = undefined;\n\n this.chartInstance = undefined;\n this.awaitingFirstInit = false;\n this.deferredOptions = undefined;\n this.sweepOrphanInstance();\n }\n\n /**\n * ⚠️ RACE TRONG NGX-ECHARTS v20 — nguồn của\n * \"[ECharts] There is a chart instance already initialized on the dom.\"\n *\n * NgxEchartsDirective.onOptionsChange() làm:\n * this.chart = await this.createChart(); // ← destroy có thể rơi vào đây\n * this.chart$.next(this.chart);\n * this.chartInit.emit(this.chart);\n *\n * Destroy đúng lúc đang await thì ngOnDestroy → dispose() thấy `this.chart == null`\n * nên KHÔNG dispose gì. Sau đó await resolve, gán một instance ECharts còn sống cho\n * directive đã chết → instance MỒ CÔI, vẫn nằm trong registry của echarts gắn với\n * DOM node đó. Angular tái dùng node ⇒ init() lần sau báo \"already initialized\".\n *\n * Không thể bắt qua (chartInit): Angular v20 TỪ CHỐI emit trên OutputRef đã destroy\n * (chỉ log NG0953, listener không hề được gọi). Nên đường duy nhất là hỏi thẳng\n * echarts xem node còn instance nào không, ở các macrotask SAU destroy.\n */\n private sweepOrphanInstance(): void {\n const host = this.ref.nativeElement.querySelector<HTMLElement>('.fx-chart');\n if (!host) return;\n\n // Chỉ nạp echarts nếu nó đã ở trong module cache — không tự kéo bundle về\n // chỉ để đi dọn.\n let attempt = 0;\n const sweep = () => {\n import('echarts').then(({ getInstanceByDom }) => {\n const orphan = getInstanceByDom(host);\n if (orphan) {\n if (!orphan.isDisposed()) orphan.dispose();\n return;\n }\n // createChart() phải chờ dynamic import nên instance mồ côi có thể xuất\n // hiện muộn hơn một macrotask; thử lại vài nhịp rồi dừng.\n if (++attempt < 5) setTimeout(sweep, 50 * attempt);\n });\n };\n\n setTimeout(sweep);\n }\n\n /** rAF có thể huỷ được khi destroy — tránh chạm instance đã dispose. */\n private schedule(fn: () => void): void {\n if (this.destroyed) return;\n const id = requestAnimationFrame(() => {\n this.pendingFrames.delete(id);\n if (this.destroyed) return;\n fn();\n });\n this.pendingFrames.add(id);\n }\n\n /** Instance còn dùng được? (đã dispose thì mọi API echarts đều ném lỗi) */\n private get liveChart(): ECharts | undefined {\n const chart = this.chartInstance;\n if (!chart || this.destroyed || chart.isDisposed()) return undefined;\n return chart;\n }\n\n @HostListener('window:theme-changed')\n onThemeChange(): void {\n if (!this.canInit || this.destroyed) return;\n this.schedule(() => this.rebuildChart());\n }\n\n /* ================= EVENTS ================= */\n\n onChartClick(event: any) {\n this.chartClick.emit(event);\n }\n\n // ⚠️ Phải để `any`: NgxEchartsDirective emit `EChartsType` từ\n // 'echarts/types/dist/shared', TS coi nó KHÔNG tương thích với `ECharts`\n // của 'echarts' (private `_ssr` khai báo riêng) → template typecheck fail.\n onChartInit(raw: any) {\n const chart = raw as ECharts;\n // Phòng thân: bình thường Angular đã chặn emit sau destroy (NG0953) nên\n // nhánh này không tới; nhưng nếu tới thì tuyệt đối không được gán lại\n // `chartInstance` sau ngOnDestroy. Việc thu dọn instance mồ côi do\n // sweepOrphanInstance() lo — xem ghi chú ở đó.\n if (this.destroyed) {\n if (!chart.isDisposed()) chart.dispose();\n return;\n }\n\n this.chartInstance = chart;\n this.awaitingFirstInit = false;\n\n if (this.deferredOptions) {\n const options = this.deferredOptions;\n this.deferredOptions = undefined;\n this.chartOptions = options;\n if (!chart.isDisposed()) {\n chart.clear();\n chart.setOption(options, true);\n }\n }\n // Lần vẽ đầu (directive setOption lúc init) cũng có animation xuất hiện.\n this.markAppear();\n\n this.chartInit.emit(chart);\n\n this.schedule(() => this.forceMediaRecalc());\n }\n\n /* ================= CORE FIX ================= */\n\n /**\n * Đo host và ghi lại; trả về CÁI GÌ đổi so với lần đo trước.\n * Khi bị ẩn (0×0) thì KHÔNG ghi — giữ kích thước hiển thị cuối, để lúc hiện\n * lại cùng cỡ thì coi như không đổi (không resize, không cắt animation).\n */\n private measure(): { size: boolean; mobile: boolean } {\n const { width, height } = this.ref.nativeElement.getBoundingClientRect();\n if (width <= 0 || height <= 0) return { size: false, mobile: false };\n\n const isMobile = width < this.mobileWidth();\n const size = width !== this.containerWidth || height !== this.containerHeight;\n const mobile = isMobile !== this.isMobile;\n this.containerWidth = width;\n this.containerHeight = height;\n this.isMobile = isMobile;\n return { size, mobile };\n }\n\n /** Animation xuất hiện vừa bắt đầu — khoá resize tới khi nó xong. */\n private markAppear(): void {\n this.appearUntil = performance.now() + ChartComponent.APPEAR_MS;\n }\n\n /** Pie/sunburst đặt legend + số giữa theo px của containerWidth → phải dựng lại. */\n private needsLayoutRebuild(): boolean {\n const type = this.detectType();\n return type === 'pie' || type === 'sunburst';\n }\n\n private deferResize(ms: number): void {\n if (this.deferTimer !== undefined) clearTimeout(this.deferTimer);\n this.deferTimer = setTimeout(() => {\n this.deferTimer = undefined;\n if (!this.destroyed) this.forceMediaRecalc();\n }, ms);\n }\n\n /**\n * Phản ứng với kích thước host (RO, sau init, sau khi hiện lại).\n *\n * Ba quy tắc, đều đo được (0.7.75 và 05/09):\n * 1. **Ẩn (0×H) thì không làm gì** — không resize canvas về 0. Chart hiện\n * lại cùng cỡ thì animation đã bắt đầu lúc ẩn (setOption khi resolver về,\n * ngay trước NavigationEnd) chạy tiếp bình thường.\n * 2. **`resize()` nhảy thẳng tới trạng thái cuối** ⇒ trong cửa sổ appear\n * (`appearUntil`) thì HOÃN, đo lại và xử lý sau khi animation xong. Không\n * dựng lại (clear + setOption) lúc đó vì đó là \"vẽ 2 lần\" theo cách khác.\n * 3. Ngoài cửa sổ: `resize()` trước, rồi chỉ dựng lại khi preset đổi (mobile)\n * hoặc loại chart đặt layout theo px (pie/sunburst). Thứ tự này quan\n * trọng: resize SAU rebuild sẽ cắt ngay animation vừa bắt đầu.\n */\n private forceMediaRecalc(retry = 0) {\n if (!this.liveChart) return;\n\n const { width, height } = this.ref.nativeElement.getBoundingClientRect();\n\n if (width === 0 || height === 0) {\n // Chưa layout xong (ngay sau init) thì thử lại vài frame; đang ẩn thì thôi.\n if (retry < 10) this.schedule(() => this.forceMediaRecalc(retry + 1));\n return;\n }\n\n const change = this.measure();\n const size = change.size || this.pendingResize;\n const mobile = change.mobile || this.pendingMobile;\n if (!size && !mobile) return;\n\n const remaining = this.appearUntil - performance.now();\n if (remaining > 0) {\n this.pendingResize = size;\n this.pendingMobile = mobile;\n this.deferResize(remaining + 30);\n return;\n }\n this.pendingResize = false;\n this.pendingMobile = false;\n\n const chart = this.liveChart;\n if (!chart) return;\n chart.resize();\n if (mobile || this.needsLayoutRebuild()) this.rebuildChart();\n }\n\n private rebuildChart(): void {\n if (this.destroyed) return;\n\n this.isEmpty = this.checkEmpty();\n\n if (this.isEmpty) {\n this.liveChart?.clear();\n return;\n }\n\n const options = this.buildOptions();\n const chart = this.liveChart;\n\n if (!chart) {\n if (this.awaitingFirstInit) {\n // Đang trong khoảng await của lần init đầu — KHÔNG gán vào property\n // đang bind, xem ghi chú ở `awaitingFirstInit`.\n this.deferredOptions = options;\n return;\n }\n this.awaitingFirstInit = true;\n this.chartOptions = options;\n this.hasOptions = true;\n return;\n }\n\n this.chartOptions = options;\n this.hasOptions = true;\n chart.clear();\n chart.setOption(options, true);\n this.markAppear();\n }\n\n private checkEmpty(): boolean {\n const type = this.detectType();\n\n if (type === 'bar') {\n const data = this.data();\n const categories = data?.categories;\n const values = data?.values;\n return !categories?.length || !values?.length;\n }\n\n if (type === 'line') {\n const data = this.data();\n return !data?.categories?.length || !data?.values?.length;\n }\n\n if (type === 'area-trend') {\n const data = this.data();\n return !data?.categories?.length || !data?.current?.length;\n }\n\n if (type === 'pie') {\n const data = this.data();\n if (!Array.isArray(data) || data.length === 0) return true;\n const total = data.reduce((sum: number, d: any) => sum + (d.value || 0), 0);\n return total === 0;\n }\n\n return false;\n }\n\n /* ================= REGISTRY ================= */\n\n private registry: Record<string, (data: any, palette: string[]) => EChartsOption> = {\n bar: (data, colors) => ({\n color: colors,\n tooltip: { trigger: 'axis' },\n grid: { left: '5%', right: '5%', bottom: '10%', containLabel: true },\n xAxis: {\n type: 'category',\n data: data?.categories || [],\n axisLabel: {\n interval: 0,\n width: 80,\n overflow: 'truncate',\n ellipsis: '…',\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-secondary'),\n },\n axisLine: {\n lineStyle: {\n color: FxUtils.convertColorFromVariable('--border-strong'),\n },\n },\n },\n yAxis: {\n type: 'value',\n axisLabel: {\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-secondary'),\n },\n axisLine: {\n lineStyle: {\n color: FxUtils.convertColorFromVariable('--border-strong'),\n },\n },\n splitLine: {\n lineStyle: {\n color: FxUtils.convertColorFromVariable('--border-default'),\n },\n },\n },\n series: [\n {\n type: 'bar',\n data: data?.values || [],\n barMaxWidth: 70,\n itemStyle: {\n color: (p: any) => colors[p.dataIndex % colors.length],\n },\n label: {\n show: true,\n position: 'top',\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-primary'),\n },\n },\n ],\n }),\n\n pie: (data, colors) => {\n const total = data.reduce((sum: number, d: any) => sum + d.value, 0);\n const layout = this.calcPieLayout(data);\n\n return {\n color: colors,\n tooltip: { trigger: 'item' },\n\n legend: {\n show: this.showPieLegend(),\n type: 'scroll' as const,\n orient: layout.legendOrient,\n icon: 'circle',\n itemGap: 12,\n\n right: layout.legendRight,\n top: layout.legendTop,\n left: layout.legendLeft,\n bottom: layout.legendBottom,\n width: layout.legendWidth,\n\n formatter: (name: string) => {\n const item = data.find((d: any) => d.name === name);\n return item ? `${name}: ${item.value}` : name;\n },\n\n textStyle: {\n fontFamily: this.resolvedFontFamily(),\n fontSize: 13,\n fontWeight: 500,\n color: FxUtils.convertColorFromVariable('--text-primary'),\n overflow: 'truncate',\n },\n },\n\n series: [\n {\n type: 'pie',\n radius: ['40%', '70%'],\n center: layout.pieCenter,\n data,\n\n label: {\n show: this.showPieLabel(),\n position: 'outside',\n formatter: '{d}%',\n fontSize: this.labelFontSize,\n fontFamily: this.resolvedFontFamily(),\n color: FxUtils.convertColorFromVariable('--text-primary'),\n textBorderWidth: 0,\n textBorderColor: 'transparent',\n },\n\n labelLine: {\n show: this.showPieLabel(),\n length: 7,\n length2: 7,\n },\n },\n ],\n\n // Centre figure: positioned by x/y in pixels — graphic left/top\n // percentages place the element's bounding-box EDGE, which shifted the\n // total right/down by half its own size (mis-centred, caption clipped).\n graphic: (() => {\n const cx = (this.containerWidth || 400) * (parseFloat(layout.pieCenter[0]) / 100);\n const ch = this.ref.nativeElement.clientHeight || 300;\n const cy = ch * (parseFloat(layout.pieCenter[1]) / 100);\n return [\n {\n type: 'text' as const,\n // Shift the total up when a caption sits under it.\n x: cx,\n y: cy + (this.pieCenterLabel() ? -9 : 0),\n style: {\n text: total.toString(),\n fontSize: 24,\n fontWeight: 600,\n fontFamily: this.resolvedFontFamily(),\n fill: FxUtils.convertColorFromVariable('--text-primary'),\n align: 'center' as const,\n verticalAlign: 'middle' as const,\n },\n },\n ...(this.pieCenterLabel()\n ? [\n {\n type: 'text' as const,\n x: cx,\n y: cy + 12,\n style: {\n text: this.pieCenterLabel(),\n fontSize: 11,\n fontFamily: this.resolvedFontFamily(),\n fill: FxUtils.convertColorFromVariable('--text-secondary'),\n align: 'center' as const,\n verticalAlign: 'middle' as const,\n },\n },\n ]\n : []),\n ];\n })(),\n };\n },\n // V2 preset: single line, accent-coloured — \"risk score by release\".\n line: (data) => ({\n tooltip: { trigger: 'axis' },\n grid: { left: '3%', right: '4%', bottom: '8%', top: '8%', containLabel: true },\n xAxis: this.categoryAxis(data?.categories || []),\n yAxis: this.valueAxis(),\n series: [\n {\n type: 'line',\n data: data?.values || [],\n smooth: false,\n symbol: 'circle',\n symbolSize: 7,\n lineStyle: { width: 2, color: FxUtils.convertColorFromVariable('--og-accent', 1, { legacyCommaSyntax: true }) },\n itemStyle: { color: FxUtils.convertColorFromVariable('--og-accent', 1, { legacyCommaSyntax: true }) },\n label: {\n show: true,\n position: 'top',\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-primary'),\n },\n },\n ],\n }),\n\n // V2 preset: weekly trend — accent gradient fill + gray comparison line.\n // data: { categories: string[], current: number[], previous?: number[] }\n 'area-trend': (data) => {\n // legacyCommaSyntax: zrender's colour parser chokes on CSS4 space syntax.\n const accent = FxUtils.convertColorFromVariable('--og-accent', 1, { legacyCommaSyntax: true });\n const accentSoft = FxUtils.convertColorFromVariable('--og-accent', 0.25, { legacyCommaSyntax: true });\n const accentFade = FxUtils.convertColorFromVariable('--og-accent', 0.02, { legacyCommaSyntax: true });\n const series: any[] = [\n {\n type: 'line',\n name: data?.currentLabel || 'Current',\n data: data?.current || [],\n smooth: true,\n symbol: 'none',\n lineStyle: { width: 2, color: accent },\n itemStyle: { color: accent },\n areaStyle: {\n color: {\n type: 'linear',\n x: 0, y: 0, x2: 0, y2: 1,\n colorStops: [\n { offset: 0, color: accentSoft },\n { offset: 1, color: accentFade },\n ],\n },\n },\n },\n ];\n if (data?.previous?.length) {\n series.push({\n type: 'line',\n name: data?.previousLabel || 'Previous',\n data: data.previous,\n smooth: true,\n symbol: 'none',\n lineStyle: {\n width: 1.5,\n type: 'dashed',\n color: FxUtils.convertColorFromVariable('--text-placeholder', 1, { legacyCommaSyntax: true }),\n },\n itemStyle: { color: FxUtils.convertColorFromVariable('--text-placeholder', 1, { legacyCommaSyntax: true }) },\n });\n }\n return {\n tooltip: { trigger: 'axis' },\n grid: { left: '3%', right: '4%', bottom: '8%', top: '10%', containLabel: true },\n xAxis: { ...this.categoryAxis(data?.categories || []), boundaryGap: false },\n yAxis: this.valueAxis(),\n series,\n };\n },\n\n sunburst: (data, colors) => ({\n color: colors,\n series: [\n {\n type: 'sunburst',\n data,\n radius: ['15%', '90%'],\n itemStyle: {\n borderWidth: 1,\n borderColor: FxUtils.convertColorFromVariable('--border-default'),\n },\n label: {\n rotate: 'tangential',\n fontSize: this.labelFontSize,\n fontFamily: this.resolvedFontFamily(),\n color: FxUtils.convertColorFromVariable('--text-primary'),\n textBorderWidth: 0,\n textBorderColor: 'transparent',\n },\n },\n ],\n }),\n };\n\n /* ================= PIE LAYOUT ================= */\n\n private calcPieLayout(data: any[]) {\n const cw = this.containerWidth || 400;\n\n if (!this.showPieLegend()) {\n return {\n legendOrient: 'vertical' as const,\n legendLeft: undefined as string | undefined,\n legendRight: undefined as string | undefined,\n legendTop: undefined as string | undefined,\n legendBottom: undefined as number | undefined,\n legendWidth: undefined as number | undefined,\n pieCenter: ['50%', '50%'],\n graphicLeft: '50%',\n graphicTop: '50%',\n };\n }\n\n if (this.isMobile) {\n return {\n legendOrient: 'horizontal' as const,\n legendLeft: 'center' as string | undefined,\n legendRight: undefined as string | undefined,\n legendTop: undefined as string | undefined,\n legendBottom: 0 as number | undefined,\n legendWidth: undefined as number | undefined,\n pieCenter: ['50%', '40%'],\n graphicLeft: '50%',\n graphicTop: '40%',\n };\n }\n\n // Estimate legend pixel width from longest formatted label\n const CHAR_WIDTH = 7.5; // approx px per char at fontSize 13\n const ICON_GAP = 30; // legend icon + padding\n const longestLabel = data.reduce((max: number, d: any) => {\n return Math.max(max, `${d.name}: ${d.value}`.length);\n }, 0);\n const rawLegendPx = longestLabel * CHAR_WIDTH + ICON_GAP;\n\n // Clamp: min 100px, max 45% of container\n const legendPx = Math.max(100, Math.min(rawLegendPx, cw * 0.45));\n const legendPct = (legendPx / cw) * 100;\n\n // Pie center: middle of the remaining space after legend\n const pieCenterX = Math.round((100 - legendPct) / 2);\n\n return {\n legendOrient: 'vertical' as const,\n legendLeft: undefined,\n legendRight: '2%',\n legendTop: 'middle' as string | undefined,\n legendBottom: undefined,\n legendWidth: Math.round(legendPx),\n pieCenter: [`${pieCenterX}%`, '50%'],\n graphicLeft: `${pieCenterX}%`,\n graphicTop: '50%',\n };\n }\n\n /* ================= BUILD ================= */\n\n private detectType(): string {\n const type = this.type();\n if (type !== 'auto') return type;\n const data = this.data();\n if (data?.children) return 'sunburst';\n if (data?.categories && data?.values) return 'bar';\n if (Array.isArray(data)) return 'pie';\n return 'bar';\n }\n\n private buildOptions(): EChartsOption {\n const type = this.detectType();\n const palette = this.resolvePalette();\n const base = this.registry[type]?.(this.data(), palette) || {};\n\n return {\n ...base,\n ...this.options(),\n };\n }\n\n private categoryAxis(categories: string[]) {\n return {\n type: 'category' as const,\n data: categories,\n axisLabel: {\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-secondary'),\n },\n axisLine: {\n lineStyle: { color: FxUtils.convertColorFromVariable('--border-strong') },\n },\n };\n }\n\n private valueAxis() {\n return {\n type: 'value' as const,\n axisLabel: {\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-secondary'),\n },\n splitLine: {\n lineStyle: { color: FxUtils.convertColorFromVariable('--border-default') },\n },\n };\n }\n\n /** Canvas không ăn var() — resolve font stack thật tại render; chart đã\n rebuild theo event theme-changed nên tự đổi font khi đổi theme\n (blueprint/terminal dùng mono qua --og-font-figure). */\n private resolvedFontFamily(): string {\n const override = this.labelFontFamily();\n if (override) return override;\n // Dev-mode CSS pretty-printer bẻ dòng giá trị dài — normalize whitespace\n // trước khi chuỗi này vào ctx.font của canvas.\n const figure = getComputedStyle(document.body)\n .getPropertyValue('--og-font-figure')\n .replace(/\\s+/g, ' ')\n .trim();\n return figure || 'Archivo, system-ui, sans-serif';\n }\n\n private resolvePalette(): string[] {\n const defaults = [\n 'rgba(var(--success) / 1)',\n 'rgba(var(--information) / 1)',\n 'rgba(var(--critical) / 1)',\n 'rgba(var(--danger) / 1)',\n 'rgba(var(--warning) / 1)',\n 'rgba(var(--discovery) / 1)',\n ];\n\n const paletteValue = this.palette();\n const palette = paletteValue?.length ? paletteValue : defaults;\n\n return palette.map((raw) => {\n if (!raw.includes('var(')) return raw;\n\n const cssVar = raw.match(/var\\((.*?)\\)/)?.[1];\n const rgb = getComputedStyle(document.body)\n .getPropertyValue(cssVar || '')\n .trim()\n .replace(/\\s+/g, ',');\n return `rgba(${rgb},1)`;\n });\n }\n}\n","<div class=\"chart-wrapper\" [style.height]=\"height()\">\n @if (isEmpty) {\n <div class=\"chart-empty\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"chart-empty-icon\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n <span class=\"chart-empty-text\">{{ emptyText() }}</span>\n </div>\n } @else if (hasOptions) {\n <div\n echarts\n [options]=\"chartOptions\"\n [autoResize]=\"false\"\n [loading]=\"loading()\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height()\"\n ></div>\n } @else {\n <!-- Until echarts is loaded + initialised (or the element scrolls into view)\n the panel keeps the chart's footprint with a quiet pulsing sketch\n instead of an empty box (anh Tú 04/09: \"the page is too blank\"). -->\n <div class=\"chart-placeholder\" aria-hidden=\"true\">\n @for (h of placeholderBars; track $index) {\n <span class=\"chart-placeholder__bar\" [style.height.%]=\"h\"></span>\n }\n </div>\n }\n</div>\n","let pending: Promise<unknown> | undefined;\n\n/**\n * Warm the echarts chunk before any chart is on screen.\n *\n * `fx-ui-chart` loads echarts lazily (`provideEchartsCore({ echarts: () =>\n * import('echarts') })`), so the FIRST chart of a session pays the chunk\n * download right when the user is looking at an empty panel. Call this once\n * from an idle callback when the app's env injector is created (e.g. a\n * `provideEnvironmentInitializer` in the remote's root route) and the dashboard\n * charts appear on the frame they mount. Same module URL as the directive's\n * import ⇒ one shared instance, no double load.\n */\nexport function preloadEcharts(): Promise<unknown> {\n return (pending ??= import('echarts'));\n}\n\n/** Schedule `preloadEcharts()` when the main thread is idle (SSR/tests: no-op). */\nexport function preloadEchartsWhenIdle(timeoutMs = 3000): void {\n if (typeof window === 'undefined') return;\n const w = window as Window & { requestIdleCallback?: (cb: () => void, o?: { timeout: number }) => number };\n if (typeof w.requestIdleCallback === 'function') {\n w.requestIdleCallback(() => void preloadEcharts(), { timeout: timeoutMs });\n } else {\n setTimeout(() => void preloadEcharts(), 1500);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;MAkCa,cAAc,CAAA;AA2Ff,IAAA,GAAA;AACA,IAAA,GAAA;;AAzFD,IAAA,IAAI,GAAG,KAAK,CAAa,MAAM,2EAAC;IAChC,IAAI,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAO;IACnB,OAAO,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAiB;IAChC,OAAO,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAY;AAC3B,IAAA,MAAM,GAAG,KAAK,CAAC,OAAO,6EAAC;AACvB,IAAA,OAAO,GAAG,KAAK,CAAC,KAAK,8EAAC;;AAGtB,IAAA,cAAc,GAAG,KAAK,CAAkB,KAAK,qFAAC;AAC9C,IAAA,iBAAiB,GAAG,KAAK,CAAkB,QAAQ,wFAAC;AACpD,IAAA,YAAY,GAAG,KAAK,CAAC,IAAI,mFAAC;AACnC;AACuD;AAC9C,IAAA,aAAa,GAAG,KAAK,CAAC,IAAI,oFAAC;;AAE3B,IAAA,cAAc,GAAG,KAAK,CAAC,EAAE,qFAAC;AAC1B,IAAA,WAAW,GAAG,KAAK,CAAC,GAAG,kFAAC;;AAExB,IAAA,eAAe,GAAG,KAAK,CAAC,EAAE,sFAAC;AAC3B,IAAA,SAAS,GAAG,KAAK,CAAC,mBAAmB,gFAAC;;IAItC,UAAU,GAAG,MAAM,EAAO;IAC1B,SAAS,GAAG,MAAM,EAAW;;IAItC,YAAY,GAAkB,EAAE;IAChC,OAAO,GAAG,KAAK;AACf;;;;;;;AAOG;IACH,UAAU,GAAG,KAAK;;IAET,eAAe,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IACnE,aAAa,GAAG,EAAE;AAEV,IAAA,aAAa;AACb,IAAA,cAAc;AACd,IAAA,oBAAoB;IAEpB,OAAO,GAAG,KAAK;IACf,SAAS,GAAG,KAAK;AACzB;;;;;;;;;;;;;AAaG;IACK,iBAAiB,GAAG,KAAK;AACzB,IAAA,eAAe;AACf,IAAA,aAAa,GAAG,IAAI,GAAG,EAAU;IACjC,QAAQ,GAAG,KAAK;IAChB,cAAc,GAAG,CAAC;IAClB,eAAe,GAAG,CAAC;AAC3B;;;;;;AAMG;IACK,WAAW,GAAG,CAAC;AACf,IAAA,OAAgB,SAAS,GAAG,IAAI;AAChC,IAAA,UAAU;AAClB;;;;AAIG;IACK,aAAa,GAAG,KAAK;IACrB,aAAa,GAAG,KAAK;IAE7B,WAAA,CACU,GAA4B,EAC5B,GAAsB,EAAA;QADtB,IAAA,CAAA,GAAG,GAAH,GAAG;QACH,IAAA,CAAA,GAAG,GAAH,GAAG;IACV;;IAIH,eAAe,GAAA;;QAEb,IAAI,CAAC,oBAAoB,GAAG,IAAI,oBAAoB,CAClD,CAAC,CAAC,KAAK,CAAC,KAAI;AACV,YAAA,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;AAC5D,gBAAA,IAAI,CAAC,OAAO,GAAG,IAAI;gBACnB,IAAI,CAAC,OAAO,EAAE;gBACd,IAAI,CAAC,YAAY,EAAE;AACnB,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;YAC1B;AACF,QAAA,CAAC,EACD,EAAE,SAAS,EAAE,GAAG,EAAE,CACnB;QAED,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC;;;;;;AAOzD,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAC,MAAK;AAC5C,YAAA,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS;gBAAE;YACrC,IAAI,CAAC,gBAAgB,EAAE;AACzB,QAAA,CAAC,CAAC;QAEF,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC;IACrD;IAEA,WAAW,GAAA;QACT,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnC,IAAI,CAAC,OAAO,EAAE;YACd,IAAI,CAAC,YAAY,EAAE;QACrB;IACF;IAEA,WAAW,GAAA;;;;;AAKT,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AAErB,QAAA,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,aAAa;YAAE,oBAAoB,CAAC,EAAE,CAAC;AAC7D,QAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;AAC1B,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;AAAE,YAAA,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC;AAChE,QAAA,IAAI,CAAC,UAAU,GAAG,SAAS;AAE3B,QAAA,IAAI,CAAC,cAAc,EAAE,UAAU,EAAE;AACjC,QAAA,IAAI,CAAC,oBAAoB,EAAE,UAAU,EAAE;AACvC,QAAA,IAAI,CAAC,cAAc,GAAG,SAAS;AAC/B,QAAA,IAAI,CAAC,oBAAoB,GAAG,SAAS;AAErC,QAAA,IAAI,CAAC,aAAa,GAAG,SAAS;AAC9B,QAAA,IAAI,CAAC,iBAAiB,GAAG,KAAK;AAC9B,QAAA,IAAI,CAAC,eAAe,GAAG,SAAS;QAChC,IAAI,CAAC,mBAAmB,EAAE;IAC5B;AAEA;;;;;;;;;;;;;;;;;AAiBG;IACK,mBAAmB,GAAA;AACzB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,aAAa,CAAc,WAAW,CAAC;AAC3E,QAAA,IAAI,CAAC,IAAI;YAAE;;;QAIX,IAAI,OAAO,GAAG,CAAC;QACf,MAAM,KAAK,GAAG,MAAK;YACjB,OAAO,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAI;AAC9C,gBAAA,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC;gBACrC,IAAI,MAAM,EAAE;AACV,oBAAA,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;wBAAE,MAAM,CAAC,OAAO,EAAE;oBAC1C;gBACF;;;gBAGA,IAAI,EAAE,OAAO,GAAG,CAAC;AAAE,oBAAA,UAAU,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC;AACpD,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC;QAED,UAAU,CAAC,KAAK,CAAC;IACnB;;AAGQ,IAAA,QAAQ,CAAC,EAAc,EAAA;QAC7B,IAAI,IAAI,CAAC,SAAS;YAAE;AACpB,QAAA,MAAM,EAAE,GAAG,qBAAqB,CAAC,MAAK;AACpC,YAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,SAAS;gBAAE;AACpB,YAAA,EAAE,EAAE;AACN,QAAA,CAAC,CAAC;AACF,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5B;;AAGA,IAAA,IAAY,SAAS,GAAA;AACnB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa;QAChC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU,EAAE;AAAE,YAAA,OAAO,SAAS;AACpE,QAAA,OAAO,KAAK;IACd;IAGA,aAAa,GAAA;AACX,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS;YAAE;QACrC,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAC1C;;AAIA,IAAA,YAAY,CAAC,KAAU,EAAA;AACrB,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;IAC7B;;;;AAKA,IAAA,WAAW,CAAC,GAAQ,EAAA;QAClB,MAAM,KAAK,GAAG,GAAc;;;;;AAK5B,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,YAAA,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE;gBAAE,KAAK,CAAC,OAAO,EAAE;YACxC;QACF;AAEA,QAAA,IAAI,CAAC,aAAa,GAAG,KAAK;AAC1B,QAAA,IAAI,CAAC,iBAAiB,GAAG,KAAK;AAE9B,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE;AACxB,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe;AACpC,YAAA,IAAI,CAAC,eAAe,GAAG,SAAS;AAChC,YAAA,IAAI,CAAC,YAAY,GAAG,OAAO;AAC3B,YAAA,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE;gBACvB,KAAK,CAAC,KAAK,EAAE;AACb,gBAAA,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC;YAChC;QACF;;QAEA,IAAI,CAAC,UAAU,EAAE;AAEjB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;QAE1B,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC9C;;AAIA;;;;AAIG;IACK,OAAO,GAAA;AACb,QAAA,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,qBAAqB,EAAE;AACxE,QAAA,IAAI,KAAK,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;QAEpE,MAAM,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE;AAC3C,QAAA,MAAM,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,cAAc,IAAI,MAAM,KAAK,IAAI,CAAC,eAAe;AAC7E,QAAA,MAAM,MAAM,GAAG,QAAQ,KAAK,IAAI,CAAC,QAAQ;AACzC,QAAA,IAAI,CAAC,cAAc,GAAG,KAAK;AAC3B,QAAA,IAAI,CAAC,eAAe,GAAG,MAAM;AAC7B,QAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;AACxB,QAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;IACzB;;IAGQ,UAAU,GAAA;QAChB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,SAAS;IACjE;;IAGQ,kBAAkB,GAAA;AACxB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE;AAC9B,QAAA,OAAO,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,UAAU;IAC9C;AAEQ,IAAA,WAAW,CAAC,EAAU,EAAA;AAC5B,QAAA,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;AAAE,YAAA,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC;AAChE,QAAA,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,MAAK;AAChC,YAAA,IAAI,CAAC,UAAU,GAAG,SAAS;YAC3B,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE,IAAI,CAAC,gBAAgB,EAAE;QAC9C,CAAC,EAAE,EAAE,CAAC;IACR;AAEA;;;;;;;;;;;;;AAaG;IACK,gBAAgB,CAAC,KAAK,GAAG,CAAC,EAAA;QAChC,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;AAErB,QAAA,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,qBAAqB,EAAE;QAExE,IAAI,KAAK,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,EAAE;;YAE/B,IAAI,KAAK,GAAG,EAAE;AAAE,gBAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACrE;QACF;AAEA,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,aAAa;QAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa;AAClD,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM;YAAE;QAEtB,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;AACtD,QAAA,IAAI,SAAS,GAAG,CAAC,EAAE;AACjB,YAAA,IAAI,CAAC,aAAa,GAAG,IAAI;AACzB,YAAA,IAAI,CAAC,aAAa,GAAG,MAAM;AAC3B,YAAA,IAAI,CAAC,WAAW,CAAC,SAAS,GAAG,EAAE,CAAC;YAChC;QACF;AACA,QAAA,IAAI,CAAC,aAAa,GAAG,KAAK;AAC1B,QAAA,IAAI,CAAC,aAAa,GAAG,KAAK;AAE1B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS;AAC5B,QAAA,IAAI,CAAC,KAAK;YAAE;QACZ,KAAK,CAAC,MAAM,EAAE;AACd,QAAA,IAAI,MAAM,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAAE,IAAI,CAAC,YAAY,EAAE;IAC9D;IAEQ,YAAY,GAAA;QAClB,IAAI,IAAI,CAAC,SAAS;YAAE;AAEpB,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;AAEhC,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,YAAA,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE;YACvB;QACF;AAEA,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE;AACnC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS;QAE5B,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,IAAI,IAAI,CAAC,iBAAiB,EAAE;;;AAG1B,gBAAA,IAAI,CAAC,eAAe,GAAG,OAAO;gBAC9B;YACF;AACA,YAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;AAC7B,YAAA,IAAI,CAAC,YAAY,GAAG,OAAO;AAC3B,YAAA,IAAI,CAAC,UAAU,GAAG,IAAI;YACtB;QACF;AAEA,QAAA,IAAI,CAAC,YAAY,GAAG,OAAO;AAC3B,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;QACtB,KAAK,CAAC,KAAK,EAAE;AACb,QAAA,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC;QAC9B,IAAI,CAAC,UAAU,EAAE;IACnB;IAEQ,UAAU,GAAA;AAChB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE;AAE9B,QAAA,IAAI,IAAI,KAAK,KAAK,EAAE;AAClB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE;AACxB,YAAA,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU;AACnC,YAAA,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM;YAC3B,OAAO,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM;QAC/C;AAEA,QAAA,IAAI,IAAI,KAAK,MAAM,EAAE;AACnB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE;AACxB,YAAA,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM;QAC3D;AAEA,QAAA,IAAI,IAAI,KAAK,YAAY,EAAE;AACzB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE;AACxB,YAAA,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM;QAC5D;AAEA,QAAA,IAAI,IAAI,KAAK,KAAK,EAAE;AAClB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE;AACxB,YAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;AAAE,gBAAA,OAAO,IAAI;YAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAW,EAAE,CAAM,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3E,OAAO,KAAK,KAAK,CAAC;QACpB;AAEA,QAAA,OAAO,KAAK;IACd;;AAIQ,IAAA,QAAQ,GAAoE;QAClF,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,MAAM;AACtB,YAAA,KAAK,EAAE,MAAM;AACb,YAAA,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;AAC5B,YAAA,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE;AACpE,YAAA,KAAK,EAAE;AACL,gBAAA,IAAI,EAAE,UAAU;AAChB,gBAAA,IAAI,EAAE,IAAI,EAAE,UAAU,IAAI,EAAE;AAC5B,gBAAA,SAAS,EAAE;AACT,oBAAA,QAAQ,EAAE,CAAC;AACX,oBAAA,KAAK,EAAE,EAAE;AACT,oBAAA,QAAQ,EAAE,UAAU;AACpB,oBAAA,QAAQ,EAAE,GAAG;AACb,oBAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;oBACrC,QAAQ,EAAE,IAAI,CAAC,aAAa;AAC5B,oBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC;AAC5D,iBAAA;AACD,gBAAA,QAAQ,EAAE;AACR,oBAAA,SAAS,EAAE;AACT,wBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,iBAAiB,CAAC;AAC3D,qBAAA;AACF,iBAAA;AACF,aAAA;AACD,YAAA,KAAK,EAAE;AACL,gBAAA,IAAI,EAAE,OAAO;AACb,gBAAA,SAAS,EAAE;AACT,oBAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;oBACrC,QAAQ,EAAE,IAAI,CAAC,aAAa;AAC5B,oBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC;AAC5D,iBAAA;AACD,gBAAA,QAAQ,EAAE;AACR,oBAAA,SAAS,EAAE;AACT,wBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,iBAAiB,CAAC;AAC3D,qBAAA;AACF,iBAAA;AACD,gBAAA,SAAS,EAAE;AACT,oBAAA,SAAS,EAAE;AACT,wBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC;AAC5D,qBAAA;AACF,iBAAA;AACF,aAAA;AACD,YAAA,MAAM,EAAE;AACN,gBAAA;AACE,oBAAA,IAAI,EAAE,KAAK;AACX,oBAAA,IAAI,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE;AACxB,oBAAA,WAAW,EAAE,EAAE;AACf,oBAAA,SAAS,EAAE;AACT,wBAAA,KAAK,EAAE,CAAC,CAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;AACvD,qBAAA;AACD,oBAAA,KAAK,EAAE;AACL,wBAAA,IAAI,EAAE,IAAI;AACV,wBAAA,QAAQ,EAAE,KAAK;AACf,wBAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;wBACrC,QAAQ,EAAE,IAAI,CAAC,aAAa;AAC5B,wBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,gBAAgB,CAAC;AAC1D,qBAAA;AACF,iBAAA;AACF,aAAA;SACF,CAAC;AAEF,QAAA,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAI;YACpB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAW,EAAE,CAAM,KAAK,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACpE,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;YAEvC,OAAO;AACL,gBAAA,KAAK,EAAE,MAAM;AACb,gBAAA,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;AAE5B,gBAAA,MAAM,EAAE;AACN,oBAAA,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE;AAC1B,oBAAA,IAAI,EAAE,QAAiB;oBACvB,MAAM,EAAE,MAAM,CAAC,YAAY;AAC3B,oBAAA,IAAI,EAAE,QAAQ;AACd,oBAAA,OAAO,EAAE,EAAE;oBAEX,KAAK,EAAE,MAAM,CAAC,WAAW;oBACzB,GAAG,EAAE,MAAM,CAAC,SAAS;oBACrB,IAAI,EAAE,MAAM,CAAC,UAAU;oBACvB,MAAM,EAAE,MAAM,CAAC,YAAY;oBAC3B,KAAK,EAAE,MAAM,CAAC,WAAW;AAEzB,oBAAA,SAAS,EAAE,CAAC,IAAY,KAAI;AAC1B,wBAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAM,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;AACnD,wBAAA,OAAO,IAAI,GAAG,GAAG,IAAI,CAAA,EAAA,EAAK,IAAI,CAAC,KAAK,CAAA,CAAE,GAAG,IAAI;oBAC/C,CAAC;AAED,oBAAA,SAAS,EAAE;AACT,wBAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;AACrC,wBAAA,QAAQ,EAAE,EAAE;AACZ,wBAAA,UAAU,EAAE,GAAG;AACf,wBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,gBAAgB,CAAC;AACzD,wBAAA,QAAQ,EAAE,UAAU;AACrB,qBAAA;AACF,iBAAA;AAED,gBAAA,MAAM,EAAE;AACN,oBAAA;AACE,wBAAA,IAAI,EAAE,KAAK;AACX,wBAAA,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;wBACtB,MAAM,EAAE,MAAM,CAAC,SAAS;wBACxB,IAAI;AAEJ,wBAAA,KAAK,EAAE;AACL,4BAAA,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;AACzB,4BAAA,QAAQ,EAAE,SAAS;AACnB,4BAAA,SAAS,EAAE,MAAM;4BACjB,QAAQ,EAAE,IAAI,CAAC,aAAa;AAC5B,4BAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;AACrC,4BAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,gBAAgB,CAAC;AACzD,4BAAA,eAAe,EAAE,CAAC;AAClB,4BAAA,eAAe,EAAE,aAAa;AAC/B,yBAAA;AAED,wBAAA,SAAS,EAAE;AACT,4BAAA,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;AACzB,4BAAA,MAAM,EAAE,CAAC;AACT,4BAAA,OAAO,EAAE,CAAC;AACX,yBAAA;AACF,qBAAA;AACF,iBAAA;;;;gBAKD,OAAO,EAAE,CAAC,MAAK;oBACb,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,GAAG,KAAK,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;oBACjF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,IAAI,GAAG;AACrD,oBAAA,MAAM,EAAE,GAAG,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;oBACvD,OAAO;AACL,wBAAA;AACE,4BAAA,IAAI,EAAE,MAAe;;AAErB,4BAAA,CAAC,EAAE,EAAE;AACL,4BAAA,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACxC,4BAAA,KAAK,EAAE;AACL,gCAAA,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE;AACtB,gCAAA,QAAQ,EAAE,EAAE;AACZ,gCAAA,UAAU,EAAE,GAAG;AACf,gCAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;AACrC,gCAAA,IAAI,EAAE,OAAO,CAAC,wBAAwB,CAAC,gBAAgB,CAAC;AACxD,gCAAA,KAAK,EAAE,QAAiB;AACxB,gCAAA,aAAa,EAAE,QAAiB;AACjC,6BAAA;AACF,yBAAA;AACD,wBAAA,IAAI,IAAI,CAAC,cAAc;AACrB,8BAAE;AACE,gCAAA;AACE,oCAAA,IAAI,EAAE,MAAe;AACrB,oCAAA,CAAC,EAAE,EAAE;oCACL,CAAC,EAAE,EAAE,GAAG,EAAE;AACV,oCAAA,KAAK,EAAE;AACL,wCAAA,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE;AAC3B,wCAAA,QAAQ,EAAE,EAAE;AACZ,wCAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;AACrC,wCAAA,IAAI,EAAE,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC;AAC1D,wCAAA,KAAK,EAAE,QAAiB;AACxB,wCAAA,aAAa,EAAE,QAAiB;AACjC,qCAAA;AACF,iCAAA;AACF;8BACD,EAAE,CAAC;qBACR;AACH,gBAAA,CAAC,GAAG;aACL;QACH,CAAC;;AAED,QAAA,IAAI,EAAE,CAAC,IAAI,MAAM;AACf,YAAA,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;YAC5B,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE;YAC9E,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,IAAI,EAAE,CAAC;AAChD,YAAA,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE;AACvB,YAAA,MAAM,EAAE;AACN,gBAAA;AACE,oBAAA,IAAI,EAAE,MAAM;AACZ,oBAAA,IAAI,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE;AACxB,oBAAA,MAAM,EAAE,KAAK;AACb,oBAAA,MAAM,EAAE,QAAQ;AAChB,oBAAA,UAAU,EAAE,CAAC;oBACb,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,aAAa,EAAE,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE;AAC/G,oBAAA,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,aAAa,EAAE,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE;AACrG,oBAAA,KAAK,EAAE;AACL,wBAAA,IAAI,EAAE,IAAI;AACV,wBAAA,QAAQ,EAAE,KAAK;AACf,wBAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;wBACrC,QAAQ,EAAE,IAAI,CAAC,aAAa;AAC5B,wBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,gBAAgB,CAAC;AAC1D,qBAAA;AACF,iBAAA;AACF,aAAA;SACF,CAAC;;;AAIF,QAAA,YAAY,EAAE,CAAC,IAAI,KAAI;;AAErB,YAAA,MAAM,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,aAAa,EAAE,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;AAC9F,YAAA,MAAM,UAAU,GAAG,OAAO,CAAC,wBAAwB,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;AACrG,YAAA,MAAM,UAAU,GAAG,OAAO,CAAC,wBAAwB,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;AACrG,YAAA,MAAM,MAAM,GAAU;AACpB,gBAAA;AACE,oBAAA,IAAI,EAAE,MAAM;AACZ,oBAAA,IAAI,EAAE,IAAI,EAAE,YAAY,IAAI,SAAS;AACrC,oBAAA,IAAI,EAAE,IAAI,EAAE,OAAO,IAAI,EAAE;AACzB,oBAAA,MAAM,EAAE,IAAI;AACZ,oBAAA,MAAM,EAAE,MAAM;oBACd,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;AACtC,oBAAA,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;AAC5B,oBAAA,SAAS,EAAE;AACT,wBAAA,KAAK,EAAE;AACL,4BAAA,IAAI,EAAE,QAAQ;AACd,4BAAA,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;AACxB,4BAAA,UAAU,EAAE;AACV,gCAAA,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE;AAChC,gCAAA,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE;AACjC,6BAAA;AACF,yBAAA;AACF,qBAAA;AACF,iBAAA;aACF;AACD,YAAA,IAAI,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE;gBAC1B,MAAM,CAAC,IAAI,CAAC;AACV,oBAAA,IAAI,EAAE,MAAM;AACZ,oBAAA,IAAI,EAAE,IAAI,EAAE,aAAa,IAAI,UAAU;oBACvC,IAAI,EAAE,IAAI,CAAC,QAAQ;AACnB,oBAAA,MAAM,EAAE,IAAI;AACZ,oBAAA,MAAM,EAAE,MAAM;AACd,oBAAA,SAAS,EAAE;AACT,wBAAA,KAAK,EAAE,GAAG;AACV,wBAAA,IAAI,EAAE,QAAQ;AACd,wBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,oBAAoB,EAAE,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;AAC9F,qBAAA;AACD,oBAAA,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,oBAAoB,EAAE,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE;AAC7G,iBAAA,CAAC;YACJ;YACA,OAAO;AACL,gBAAA,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;gBAC5B,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE;AAC/E,gBAAA,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE;AAC3E,gBAAA,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE;gBACvB,MAAM;aACP;QACH,CAAC;QAED,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,MAAM;AAC3B,YAAA,KAAK,EAAE,MAAM;AACb,YAAA,MAAM,EAAE;AACN,gBAAA;AACE,oBAAA,IAAI,EAAE,UAAU;oBAChB,IAAI;AACJ,oBAAA,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;AACtB,oBAAA,SAAS,EAAE;AACT,wBAAA,WAAW,EAAE,CAAC;AACd,wBAAA,WAAW,EAAE,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC;AAClE,qBAAA;AACD,oBAAA,KAAK,EAAE;AACL,wBAAA,MAAM,EAAE,YAAY;wBACpB,QAAQ,EAAE,IAAI,CAAC,aAAa;AAC5B,wBAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;AACrC,wBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,gBAAgB,CAAC;AACzD,wBAAA,eAAe,EAAE,CAAC;AAClB,wBAAA,eAAe,EAAE,aAAa;AAC/B,qBAAA;AACF,iBAAA;AACF,aAAA;SACF,CAAC;KACH;;AAIO,IAAA,aAAa,CAAC,IAAW,EAAA;AAC/B,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,IAAI,GAAG;AAErC,QAAA,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE;YACzB,OAAO;AACL,gBAAA,YAAY,EAAE,UAAmB;AACjC,gBAAA,UAAU,EAAE,SAA+B;AAC3C,gBAAA,WAAW,EAAE,SAA+B;AAC5C,gBAAA,SAAS,EAAE,SAA+B;AAC1C,gBAAA,YAAY,EAAE,SAA+B;AAC7C,gBAAA,WAAW,EAAE,SAA+B;AAC5C,gBAAA,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;AACzB,gBAAA,WAAW,EAAE,KAAK;AAClB,gBAAA,UAAU,EAAE,KAAK;aAClB;QACH;AAEA,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,OAAO;AACL,gBAAA,YAAY,EAAE,YAAqB;AACnC,gBAAA,UAAU,EAAE,QAA8B;AAC1C,gBAAA,WAAW,EAAE,SAA+B;AAC5C,gBAAA,SAAS,EAAE,SAA+B;AAC1C,gBAAA,YAAY,EAAE,CAAuB;AACrC,gBAAA,WAAW,EAAE,SAA+B;AAC5C,gBAAA,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;AACzB,gBAAA,WAAW,EAAE,KAAK;AAClB,gBAAA,UAAU,EAAE,KAAK;aAClB;QACH;;AAGA,QAAA,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,QAAA,MAAM,QAAQ,GAAG,EAAE,CAAC;QACpB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAW,EAAE,CAAM,KAAI;AACvD,YAAA,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,CAAA,EAAA,EAAK,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC;QACtD,CAAC,EAAE,CAAC,CAAC;AACL,QAAA,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ;;AAGxD,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,CAAC,QAAQ,GAAG,EAAE,IAAI,GAAG;;AAGvC,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,SAAS,IAAI,CAAC,CAAC;QAEpD,OAAO;AACL,YAAA,YAAY,EAAE,UAAmB;AACjC,YAAA,UAAU,EAAE,SAAS;AACrB,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,SAAS,EAAE,QAA8B;AACzC,YAAA,YAAY,EAAE,SAAS;AACvB,YAAA,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;AACjC,YAAA,SAAS,EAAE,CAAC,CAAA,EAAG,UAAU,CAAA,CAAA,CAAG,EAAE,KAAK,CAAC;YACpC,WAAW,EAAE,CAAA,EAAG,UAAU,CAAA,CAAA,CAAG;AAC7B,YAAA,UAAU,EAAE,KAAK;SAClB;IACH;;IAIQ,UAAU,GAAA;AAChB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE;QACxB,IAAI,IAAI,KAAK,MAAM;AAAE,YAAA,OAAO,IAAI;AAChC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE;QACxB,IAAI,IAAI,EAAE,QAAQ;AAAE,YAAA,OAAO,UAAU;AACrC,QAAA,IAAI,IAAI,EAAE,UAAU,IAAI,IAAI,EAAE,MAAM;AAAE,YAAA,OAAO,KAAK;AAClD,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;AAAE,YAAA,OAAO,KAAK;AACrC,QAAA,OAAO,KAAK;IACd;IAEQ,YAAY,GAAA;AAClB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE;AAC9B,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,EAAE;AACrC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE;QAE9D,OAAO;AACL,YAAA,GAAG,IAAI;YACP,GAAG,IAAI,CAAC,OAAO,EAAE;SAClB;IACH;AAEQ,IAAA,YAAY,CAAC,UAAoB,EAAA;QACvC,OAAO;AACL,YAAA,IAAI,EAAE,UAAmB;AACzB,YAAA,IAAI,EAAE,UAAU;AAChB,YAAA,SAAS,EAAE;AACT,gBAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;gBACrC,QAAQ,EAAE,IAAI,CAAC,aAAa;AAC5B,gBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC;AAC5D,aAAA;AACD,YAAA,QAAQ,EAAE;gBACR,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,iBAAiB,CAAC,EAAE;AAC1E,aAAA;SACF;IACH;IAEQ,SAAS,GAAA;QACf,OAAO;AACL,YAAA,IAAI,EAAE,OAAgB;AACtB,YAAA,SAAS,EAAE;AACT,gBAAA,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE;gBACrC,QAAQ,EAAE,IAAI,CAAC,aAAa;AAC5B,gBAAA,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC;AAC5D,aAAA;AACD,YAAA,SAAS,EAAE;gBACT,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,EAAE;AAC3E,aAAA;SACF;IACH;AAEA;;AAE2D;IACnD,kBAAkB,GAAA;AACxB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,EAAE;AACvC,QAAA,IAAI,QAAQ;AAAE,YAAA,OAAO,QAAQ;;;AAG7B,QAAA,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,IAAI;aAC1C,gBAAgB,CAAC,kBAAkB;AACnC,aAAA,OAAO,CAAC,MAAM,EAAE,GAAG;AACnB,aAAA,IAAI,EAAE;QACT,OAAO,MAAM,IAAI,gCAAgC;IACnD;IAEQ,cAAc,GAAA;AACpB,QAAA,MAAM,QAAQ,GAAG;YACf,0BAA0B;YAC1B,8BAA8B;YAC9B,2BAA2B;YAC3B,yBAAyB;YACzB,0BAA0B;YAC1B,4BAA4B;SAC7B;AAED,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE;AACnC,QAAA,MAAM,OAAO,GAAG,YAAY,EAAE,MAAM,GAAG,YAAY,GAAG,QAAQ;AAE9D,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,KAAI;AACzB,YAAA,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;AAAE,gBAAA,OAAO,GAAG;AAErC,YAAA,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;AAC7C,YAAA,MAAM,GAAG,GAAG,gBAAgB,CAAC,QAAQ,CAAC,IAAI;AACvC,iBAAA,gBAAgB,CAAC,MAAM,IAAI,EAAE;AAC7B,iBAAA,IAAI;AACJ,iBAAA,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;YACvB,OAAO,CAAA,KAAA,EAAQ,GAAG,CAAA,GAAA,CAAK;AACzB,QAAA,CAAC,CAAC;IACJ;wGA7zBW,cAAc,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAd,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,eAAA,EAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,sBAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,SAAA,EAFZ,CAAC,kBAAkB,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,SAAS,CAAC,EAAE,CAAC,CAAC,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EChCzE,+oDA8BA,6hCDDc,mBAAmB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,YAAA,EAAA,SAAA,EAAA,aAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,WAAA,EAAA,cAAA,EAAA,YAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,oBAAA,EAAA,0BAAA,EAAA,qBAAA,EAAA,uBAAA,EAAA,4BAAA,EAAA,gCAAA,EAAA,mBAAA,EAAA,eAAA,EAAA,wBAAA,EAAA,gBAAA,EAAA,cAAA,EAAA,eAAA,EAAA,sBAAA,EAAA,0BAAA,EAAA,cAAA,EAAA,sBAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,uBAAA,EAAA,YAAA,EAAA,eAAA,EAAA,oBAAA,EAAA,wBAAA,EAAA,eAAA,EAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;4FAKpB,cAAc,EAAA,UAAA,EAAA,CAAA;kBAV1B,SAAS;+BACI,aAAa,EAAA,eAAA,EAGN,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC,CAAC,mBAAmB,EAAE,cAAc,CAAC,EAAA,SAAA,EAGnC,CAAC,kBAAkB,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,SAAS,CAAC,EAAE,CAAC,CAAC,EAAA,QAAA,EAAA,+oDAAA,EAAA,MAAA,EAAA,CAAA,q+BAAA,CAAA,EAAA;;sBAyNtE,YAAY;uBAAC,sBAAsB;;;AEzPtC,IAAI,OAAqC;AAEzC;;;;;;;;;;AAUG;SACa,cAAc,GAAA;IAC5B,QAAQ,OAAO,KAAK,OAAO,SAAS,CAAC;AACvC;AAEA;AACM,SAAU,sBAAsB,CAAC,SAAS,GAAG,IAAI,EAAA;IACrD,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE;IACnC,MAAM,CAAC,GAAG,MAAgG;AAC1G,IAAA,IAAI,OAAO,CAAC,CAAC,mBAAmB,KAAK,UAAU,EAAE;AAC/C,QAAA,CAAC,CAAC,mBAAmB,CAAC,MAAM,KAAK,cAAc,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAC5E;SAAO;QACL,UAAU,CAAC,MAAM,KAAK,cAAc,EAAE,EAAE,IAAI,CAAC;IAC/C;AACF;;AC1BA;;AAEG;;;;"}
1
+ {"version":3,"file":"foxeltech-angular-ui-chart.mjs","sources":["../../../projects/ui/chart/src/chart/chart.component.ts","../../../projects/ui/chart/src/chart/chart.component.html","../../../projects/ui/chart/src/preload-echarts.ts","../../../projects/ui/chart/src/foxeltech-angular-ui-chart.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectorRef,\n Component,\n ElementRef,\n HostListener,\n OnChanges,\n OnDestroy,\n ChangeDetectionStrategy,\n input,\n output\n} from '@angular/core';\nimport { ECharts, EChartsOption } from 'echarts';\nimport { FxUtils, InputComponent } from '@foxeltech/angular-ui';\nimport { NgxEchartsDirective, provideEchartsCore } from 'ngx-echarts';\n\n\n// 'radar' was advertised here but has no builder in the registry — it\n// silently rendered an empty chart. Re-add when implemented.\n// V2 presets: 'line' (risk score by release), 'area-trend' (weekly trend with\n// accent fill + gray comparison line). Both need an explicit [type] — 'auto'\n// cannot tell them apart from 'bar'.\nexport type IChartType = 'bar' | 'pie' | 'sunburst' | 'line' | 'area-trend' | 'auto';\n\n@Component({\n selector: 'fx-ui-chart',\n templateUrl: './chart.component.html',\n styleUrl: './chart.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgxEchartsDirective, InputComponent],\n // Self-contained: echarts is provided (and lazy-loaded) right here, so\n // consumers just import ChartComponent — no forRoot wiring in the app.\n providers: [provideEchartsCore({ echarts: () => import('echarts') })],\n})\nexport class ChartComponent implements OnChanges, AfterViewInit, OnDestroy {\n /* ================= INPUTS ================= */\n\n readonly type = input<IChartType>('auto');\n readonly data = input<any>();\n readonly options = input<EChartsOption>();\n readonly palette = input<string[]>();\n readonly height = input('400px');\n readonly loading = input(false);\n\n // pie controls\n readonly pieLegendAlign = input<string | number>('10%');\n readonly pieLegendPosition = input<string | number>('middle');\n readonly showPieLabel = input(true);\n /** Hide the built-in legend (panels that render their own legend beside the\n donut); the donut then centres in the container. */\n readonly showPieLegend = input(true);\n /** Caption under the donut's centre total (design: \"42 / confirmed\"). */\n readonly pieCenterLabel = input('');\n /**\n * Type size of the donut's centre TOTAL, in px. The default matches what the\n * figure has always been; raise it where the total is the panel's headline\n * rather than an annotation.\n */\n readonly pieCenterValueSize = input(24);\n readonly mobileWidth = input(350);\n /** Override font for canvas text; empty = follow the theme's --og-font-figure. */\n readonly labelFontFamily = input('');\n readonly emptyText = input('No data available');\n\n // line / area-trend controls\n /**\n * Print each point's value beside a marker on the line.\n *\n * Off by default: on a dense series the labels collide and the line becomes\n * unreadable. Turn it on for the sparse, weekly kind of series where the\n * number at each step IS the content — a reader should not have to hover to\n * learn what a step was.\n */\n readonly showPointLabels = input(false);\n\n /* ================= OUTPUTS ================= */\n\n readonly chartClick = output<any>();\n readonly chartInit = output<ECharts>();\n\n /* ================= INTERNAL ================= */\n\n chartOptions: EChartsOption = {};\n isEmpty = false;\n /**\n * ⚠️ Cổng cho `<div echarts>` trong template. Trước đây div render NGAY với\n * `chartOptions = {}`, nên NgxEchartsDirective khởi tạo chart bằng options\n * RỖNG; options thật gán vào giữa lúc `await createChart()` của lần đó ⇒\n * onOptionsChange() thấy `chart == null` và createChart() LẦN HAI trên cùng\n * DOM node ⇒ \"[ECharts] There is a chart instance already initialized on the\n * dom.\". Chỉ dựng directive khi đã có options thật ⇒ đúng một lần init.\n */\n hasOptions = false;\n /** Heights (%) of the pre-init placeholder bars — a fixed, calm silhouette. */\n readonly placeholderBars = [34, 52, 44, 66, 58, 78, 70, 88, 62, 74];\n labelFontSize = 12;\n\n private chartInstance?: ECharts;\n private resizeObserver?: ResizeObserver;\n private intersectionObserver?: IntersectionObserver;\n\n private canInit = false;\n private destroyed = false;\n /**\n * ⚠️ Đang chờ init đầu tiên của directive hoàn tất?\n *\n * NgxEchartsDirective đăng ký `changeFilter.notFirstAndEmpty('options', …)`:\n * lần gán `options` ĐẦU bị bỏ qua (ngAfterViewInit lo), lần gán THỨ HAI gọi\n * onOptionsChange(). Mà onOptionsChange() chỉ createChart() khi `this.chart`\n * còn null — và nó null suốt thời gian `await createChart()` của lần đầu.\n * Nên nếu ta gán `chartOptions` (object mới) trong khoảng await đó thì\n * init() chạy HAI LẦN trên cùng DOM node ⇒\n * \"[ECharts] There is a chart instance already initialized on the dom.\"\n *\n * Cách chặn: trong khoảng chờ, giữ options ở `deferredOptions` chứ không đụng\n * vào property đang bind; init xong thì áp một lần qua instance.\n */\n private awaitingFirstInit = false;\n private deferredOptions?: EChartsOption;\n private pendingFrames = new Set<number>();\n private isMobile = false;\n private containerWidth = 0;\n private containerHeight = 0;\n /**\n * Mốc (performance.now) mà animation \"xuất hiện\" của lần setOption gần nhất\n * chắc chắn đã xong. ECharts mặc định animationDuration 1000ms; trong khoảng\n * này KHÔNG được `resize()` — resize nhảy thẳng tới trạng thái cuối và giết\n * animation (đo 05/09: chart PM bị cắt ở ~800ms khi thanh cuộn xuất hiện\n * lúc lưới card nạp xong làm bề rộng đổi 720→710).\n */\n private appearUntil = 0;\n private static readonly APPEAR_MS = 1100;\n private deferTimer?: ReturnType<typeof setTimeout>;\n /**\n * Thay đổi kích thước ghi nhận TRONG cửa sổ appear, chờ áp sau. `measure()`\n * đã cập nhật containerWidth/Height ngay lúc đo, nên lần gọi hoãn không thể\n * dựa vào \"có đổi không\" nữa — phải nhớ bằng cờ.\n */\n private pendingResize = false;\n private pendingMobile = false;\n\n constructor(\n private ref: ElementRef<HTMLElement>,\n private cdr: ChangeDetectorRef,\n ) {}\n\n /* ================= LIFECYCLE ================= */\n\n ngAfterViewInit(): void {\n // Only initialize when visible (tab-safe)\n this.intersectionObserver = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting && !this.canInit && !this.destroyed) {\n this.canInit = true;\n this.measure();\n this.rebuildChart();\n this.cdr.detectChanges();\n }\n },\n { threshold: 0.1 },\n );\n\n this.intersectionObserver.observe(this.ref.nativeElement);\n\n // Resize-safe (tabs, flex, async layout). Đây là ĐƯỜNG RESIZE DUY NHẤT:\n // `autoResize` của NgxEchartsDirective đã tắt trong template — nó\n // resize() mù sau throttle 100ms, kể cả về 0×H khi phần tử display:none\n // (skeleton route ẩn nội dung cũ) rồi resize lại khi hiện → animation\n // xuất hiện bị giết (đo 05/09 khi đổi project trên chip breadcrumb).\n this.resizeObserver = new ResizeObserver(() => {\n if (!this.canInit || this.destroyed) return;\n this.forceMediaRecalc();\n });\n\n this.resizeObserver.observe(this.ref.nativeElement);\n }\n\n ngOnChanges(): void {\n if (this.canInit && !this.destroyed) {\n this.measure();\n this.rebuildChart();\n }\n }\n\n ngOnDestroy(): void {\n // NgxEchartsDirective tự dispose instance của nó, nên KHÔNG dispose ở đây\n // (sẽ dispose trùng). Việc phải làm là ngắt mọi đường còn chạm được vào\n // instance sau khi nó đã bị dispose: callback rAF đang chờ + tham chiếu\n // `chartInstance` mà forceMediaRecalc/rebuildChart vẫn dùng.\n this.destroyed = true;\n\n for (const id of this.pendingFrames) cancelAnimationFrame(id);\n this.pendingFrames.clear();\n if (this.deferTimer !== undefined) clearTimeout(this.deferTimer);\n this.deferTimer = undefined;\n\n this.resizeObserver?.disconnect();\n this.intersectionObserver?.disconnect();\n this.resizeObserver = undefined;\n this.intersectionObserver = undefined;\n\n this.chartInstance = undefined;\n this.awaitingFirstInit = false;\n this.deferredOptions = undefined;\n this.sweepOrphanInstance();\n }\n\n /**\n * ⚠️ RACE TRONG NGX-ECHARTS v20 — nguồn của\n * \"[ECharts] There is a chart instance already initialized on the dom.\"\n *\n * NgxEchartsDirective.onOptionsChange() làm:\n * this.chart = await this.createChart(); // ← destroy có thể rơi vào đây\n * this.chart$.next(this.chart);\n * this.chartInit.emit(this.chart);\n *\n * Destroy đúng lúc đang await thì ngOnDestroy → dispose() thấy `this.chart == null`\n * nên KHÔNG dispose gì. Sau đó await resolve, gán một instance ECharts còn sống cho\n * directive đã chết → instance MỒ CÔI, vẫn nằm trong registry của echarts gắn với\n * DOM node đó. Angular tái dùng node ⇒ init() lần sau báo \"already initialized\".\n *\n * Không thể bắt qua (chartInit): Angular v20 TỪ CHỐI emit trên OutputRef đã destroy\n * (chỉ log NG0953, listener không hề được gọi). Nên đường duy nhất là hỏi thẳng\n * echarts xem node còn instance nào không, ở các macrotask SAU destroy.\n */\n private sweepOrphanInstance(): void {\n const host = this.ref.nativeElement.querySelector<HTMLElement>('.fx-chart');\n if (!host) return;\n\n // Chỉ nạp echarts nếu nó đã ở trong module cache — không tự kéo bundle về\n // chỉ để đi dọn.\n let attempt = 0;\n const sweep = () => {\n import('echarts').then(({ getInstanceByDom }) => {\n const orphan = getInstanceByDom(host);\n if (orphan) {\n if (!orphan.isDisposed()) orphan.dispose();\n return;\n }\n // createChart() phải chờ dynamic import nên instance mồ côi có thể xuất\n // hiện muộn hơn một macrotask; thử lại vài nhịp rồi dừng.\n if (++attempt < 5) setTimeout(sweep, 50 * attempt);\n });\n };\n\n setTimeout(sweep);\n }\n\n /** rAF có thể huỷ được khi destroy — tránh chạm instance đã dispose. */\n private schedule(fn: () => void): void {\n if (this.destroyed) return;\n const id = requestAnimationFrame(() => {\n this.pendingFrames.delete(id);\n if (this.destroyed) return;\n fn();\n });\n this.pendingFrames.add(id);\n }\n\n /** Instance còn dùng được? (đã dispose thì mọi API echarts đều ném lỗi) */\n private get liveChart(): ECharts | undefined {\n const chart = this.chartInstance;\n if (!chart || this.destroyed || chart.isDisposed()) return undefined;\n return chart;\n }\n\n @HostListener('window:theme-changed')\n onThemeChange(): void {\n if (!this.canInit || this.destroyed) return;\n this.schedule(() => this.rebuildChart());\n }\n\n /* ================= EVENTS ================= */\n\n onChartClick(event: any) {\n this.chartClick.emit(event);\n }\n\n // ⚠️ Phải để `any`: NgxEchartsDirective emit `EChartsType` từ\n // 'echarts/types/dist/shared', TS coi nó KHÔNG tương thích với `ECharts`\n // của 'echarts' (private `_ssr` khai báo riêng) → template typecheck fail.\n onChartInit(raw: any) {\n const chart = raw as ECharts;\n // Phòng thân: bình thường Angular đã chặn emit sau destroy (NG0953) nên\n // nhánh này không tới; nhưng nếu tới thì tuyệt đối không được gán lại\n // `chartInstance` sau ngOnDestroy. Việc thu dọn instance mồ côi do\n // sweepOrphanInstance() lo — xem ghi chú ở đó.\n if (this.destroyed) {\n if (!chart.isDisposed()) chart.dispose();\n return;\n }\n\n this.chartInstance = chart;\n this.awaitingFirstInit = false;\n\n if (this.deferredOptions) {\n const options = this.deferredOptions;\n this.deferredOptions = undefined;\n this.chartOptions = options;\n if (!chart.isDisposed()) {\n chart.clear();\n chart.setOption(options, true);\n }\n }\n // Lần vẽ đầu (directive setOption lúc init) cũng có animation xuất hiện.\n this.markAppear();\n\n this.chartInit.emit(chart);\n\n this.schedule(() => this.forceMediaRecalc());\n }\n\n /* ================= CORE FIX ================= */\n\n /**\n * Đo host và ghi lại; trả về CÁI GÌ đổi so với lần đo trước.\n * Khi bị ẩn (0×0) thì KHÔNG ghi — giữ kích thước hiển thị cuối, để lúc hiện\n * lại cùng cỡ thì coi như không đổi (không resize, không cắt animation).\n */\n private measure(): { size: boolean; mobile: boolean } {\n const rect = this.ref.nativeElement.getBoundingClientRect();\n // Whole pixels only. getBoundingClientRect() follows transforms, so a host\n // riding an fxReveal translateY reports 200.00003 then 199.99997 — the\n // old strict compare took that jitter for a resize, and after the appear\n // window a pie was resized + rebuilt = drawn twice (đo 07/09, Overview\n // \"Open findings by severity\" 2 × 60 frames 1.1 s apart).\n const width = Math.round(rect.width);\n const height = Math.round(rect.height);\n if (width <= 0 || height <= 0) return { size: false, mobile: false };\n\n const isMobile = width < this.mobileWidth();\n const size = width !== this.containerWidth || height !== this.containerHeight;\n const mobile = isMobile !== this.isMobile;\n this.containerWidth = width;\n this.containerHeight = height;\n this.isMobile = isMobile;\n return { size, mobile };\n }\n\n /** Animation xuất hiện vừa bắt đầu — khoá resize tới khi nó xong. */\n private markAppear(): void {\n this.appearUntil = performance.now() + ChartComponent.APPEAR_MS;\n }\n\n /** Pie/sunburst đặt legend + số giữa theo px của containerWidth → phải dựng lại. */\n private needsLayoutRebuild(): boolean {\n const type = this.detectType();\n return type === 'pie' || type === 'sunburst';\n }\n\n private deferResize(ms: number): void {\n if (this.deferTimer !== undefined) clearTimeout(this.deferTimer);\n this.deferTimer = setTimeout(() => {\n this.deferTimer = undefined;\n if (!this.destroyed) this.forceMediaRecalc();\n }, ms);\n }\n\n /**\n * Phản ứng với kích thước host (RO, sau init, sau khi hiện lại).\n *\n * Ba quy tắc, đều đo được (0.7.75 và 05/09):\n * 1. **Ẩn (0×H) thì không làm gì** — không resize canvas về 0. Chart hiện\n * lại cùng cỡ thì animation đã bắt đầu lúc ẩn (setOption khi resolver về,\n * ngay trước NavigationEnd) chạy tiếp bình thường.\n * 2. **`resize()` nhảy thẳng tới trạng thái cuối** ⇒ trong cửa sổ appear\n * (`appearUntil`) thì HOÃN, đo lại và xử lý sau khi animation xong. Không\n * dựng lại (clear + setOption) lúc đó vì đó là \"vẽ 2 lần\" theo cách khác.\n * 3. Ngoài cửa sổ: `resize()` trước, rồi chỉ dựng lại khi preset đổi (mobile)\n * hoặc loại chart đặt layout theo px (pie/sunburst). Thứ tự này quan\n * trọng: resize SAU rebuild sẽ cắt ngay animation vừa bắt đầu.\n */\n private forceMediaRecalc(retry = 0) {\n if (!this.liveChart) return;\n\n const { width, height } = this.ref.nativeElement.getBoundingClientRect();\n\n if (width === 0 || height === 0) {\n // Chưa layout xong (ngay sau init) thì thử lại vài frame; đang ẩn thì thôi.\n if (retry < 10) this.schedule(() => this.forceMediaRecalc(retry + 1));\n return;\n }\n\n const change = this.measure();\n const size = change.size || this.pendingResize;\n const mobile = change.mobile || this.pendingMobile;\n if (!size && !mobile) return;\n\n const remaining = this.appearUntil - performance.now();\n if (remaining > 0) {\n this.pendingResize = size;\n this.pendingMobile = mobile;\n this.deferResize(remaining + 30);\n return;\n }\n this.pendingResize = false;\n this.pendingMobile = false;\n\n const chart = this.liveChart;\n if (!chart) return;\n chart.resize();\n if (mobile || this.needsLayoutRebuild()) this.rebuildChart();\n }\n\n private rebuildChart(): void {\n if (this.destroyed) return;\n\n this.isEmpty = this.checkEmpty();\n\n if (this.isEmpty) {\n this.liveChart?.clear();\n return;\n }\n\n const options = this.buildOptions();\n const chart = this.liveChart;\n\n if (!chart) {\n if (this.awaitingFirstInit) {\n // Đang trong khoảng await của lần init đầu — KHÔNG gán vào property\n // đang bind, xem ghi chú ở `awaitingFirstInit`.\n this.deferredOptions = options;\n return;\n }\n this.awaitingFirstInit = true;\n this.chartOptions = options;\n this.hasOptions = true;\n return;\n }\n\n this.chartOptions = options;\n this.hasOptions = true;\n chart.clear();\n chart.setOption(options, true);\n this.markAppear();\n }\n\n private checkEmpty(): boolean {\n const type = this.detectType();\n\n if (type === 'bar') {\n const data = this.data();\n const categories = data?.categories;\n const values = data?.values;\n return !categories?.length || !values?.length;\n }\n\n if (type === 'line') {\n const data = this.data();\n return !data?.categories?.length || !data?.values?.length;\n }\n\n if (type === 'area-trend') {\n const data = this.data();\n return !data?.categories?.length || !data?.current?.length;\n }\n\n if (type === 'pie') {\n const data = this.data();\n if (!Array.isArray(data) || data.length === 0) return true;\n const total = data.reduce((sum: number, d: any) => sum + (d.value || 0), 0);\n return total === 0;\n }\n\n return false;\n }\n\n /* ================= REGISTRY ================= */\n\n private registry: Record<string, (data: any, palette: string[]) => EChartsOption> = {\n bar: (data, colors) => ({\n color: colors,\n tooltip: { trigger: 'axis' },\n grid: { left: '5%', right: '5%', bottom: '10%', containLabel: true },\n xAxis: {\n type: 'category',\n data: data?.categories || [],\n axisLabel: {\n interval: 0,\n width: 80,\n overflow: 'truncate',\n ellipsis: '…',\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-secondary'),\n },\n axisLine: {\n lineStyle: {\n color: FxUtils.convertColorFromVariable('--border-strong'),\n },\n },\n },\n yAxis: {\n type: 'value',\n axisLabel: {\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-secondary'),\n },\n axisLine: {\n lineStyle: {\n color: FxUtils.convertColorFromVariable('--border-strong'),\n },\n },\n splitLine: {\n lineStyle: {\n color: FxUtils.convertColorFromVariable('--border-default'),\n },\n },\n },\n series: [\n {\n type: 'bar',\n data: data?.values || [],\n barMaxWidth: 70,\n itemStyle: {\n color: (p: any) => colors[p.dataIndex % colors.length],\n },\n label: {\n show: true,\n position: 'top',\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-primary'),\n },\n },\n ],\n }),\n\n pie: (data, colors) => {\n const total = data.reduce((sum: number, d: any) => sum + d.value, 0);\n const layout = this.calcPieLayout(data);\n\n return {\n color: colors,\n tooltip: { trigger: 'item' },\n\n legend: {\n show: this.showPieLegend(),\n type: 'scroll' as const,\n orient: layout.legendOrient,\n icon: 'circle',\n itemGap: 12,\n\n right: layout.legendRight,\n top: layout.legendTop,\n left: layout.legendLeft,\n bottom: layout.legendBottom,\n width: layout.legendWidth,\n\n formatter: (name: string) => {\n const item = data.find((d: any) => d.name === name);\n return item ? `${name}: ${item.value}` : name;\n },\n\n textStyle: {\n fontFamily: this.resolvedFontFamily(),\n fontSize: 13,\n fontWeight: 500,\n color: FxUtils.convertColorFromVariable('--text-primary'),\n overflow: 'truncate',\n },\n },\n\n series: [\n {\n type: 'pie',\n radius: ['40%', '70%'],\n center: layout.pieCenter,\n data,\n\n label: {\n show: this.showPieLabel(),\n position: 'outside',\n formatter: '{d}%',\n fontSize: this.labelFontSize,\n fontFamily: this.resolvedFontFamily(),\n color: FxUtils.convertColorFromVariable('--text-primary'),\n textBorderWidth: 0,\n textBorderColor: 'transparent',\n },\n\n labelLine: {\n show: this.showPieLabel(),\n length: 7,\n length2: 7,\n },\n },\n ],\n\n // Centre figure: positioned by x/y in pixels — graphic left/top\n // percentages place the element's bounding-box EDGE, which shifted the\n // total right/down by half its own size (mis-centred, caption clipped).\n graphic: (() => {\n const cx = (this.containerWidth || 400) * (parseFloat(layout.pieCenter[0]) / 100);\n const ch = this.ref.nativeElement.clientHeight || 300;\n const cy = ch * (parseFloat(layout.pieCenter[1]) / 100);\n const centre = this.pieCentreAnchors();\n return [\n {\n type: 'text' as const,\n x: cx,\n y: cy + centre.total,\n style: {\n text: total.toString(),\n fontSize: this.pieCenterValueSize(),\n fontWeight: 600,\n fontFamily: this.resolvedFontFamily(),\n fill: FxUtils.convertColorFromVariable('--text-primary'),\n align: 'center' as const,\n verticalAlign: 'middle' as const,\n },\n },\n ...(this.pieCenterLabel()\n ? [\n {\n type: 'text' as const,\n x: cx,\n y: cy + centre.caption,\n style: {\n text: this.pieCenterLabel(),\n fontSize: 11,\n fontFamily: this.resolvedFontFamily(),\n fill: FxUtils.convertColorFromVariable('--text-secondary'),\n align: 'center' as const,\n verticalAlign: 'middle' as const,\n },\n },\n ]\n : []),\n ];\n })(),\n };\n },\n // V2 preset: single line, accent-coloured — \"risk score by release\".\n line: (data) => ({\n tooltip: { trigger: 'axis' },\n grid: { left: '3%', right: '4%', bottom: '8%', top: '8%', containLabel: true },\n xAxis: this.categoryAxis(data?.categories || []),\n yAxis: this.valueAxis(),\n series: [\n {\n type: 'line',\n data: data?.values || [],\n smooth: false,\n symbol: 'circle',\n symbolSize: 7,\n lineStyle: { width: 2, color: FxUtils.convertColorFromVariable('--og-accent', 1, { legacyCommaSyntax: true }) },\n itemStyle: { color: FxUtils.convertColorFromVariable('--og-accent', 1, { legacyCommaSyntax: true }) },\n label: {\n show: true,\n position: 'top',\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-primary'),\n },\n },\n ],\n }),\n\n // V2 preset: weekly trend — accent gradient fill + gray comparison line.\n // data: { categories: string[], current: number[], previous?: number[] }\n 'area-trend': (data) => {\n // legacyCommaSyntax: zrender's colour parser chokes on CSS4 space syntax.\n const accent = FxUtils.convertColorFromVariable('--og-accent', 1, { legacyCommaSyntax: true });\n const accentSoft = FxUtils.convertColorFromVariable('--og-accent', 0.25, { legacyCommaSyntax: true });\n const accentFade = FxUtils.convertColorFromVariable('--og-accent', 0.02, { legacyCommaSyntax: true });\n const series: any[] = [\n {\n type: 'line',\n name: data?.currentLabel || 'Current',\n data: data?.current || [],\n smooth: true,\n ...this.pointMarks('top', accent),\n lineStyle: { width: 2, color: accent },\n itemStyle: { color: accent },\n areaStyle: {\n color: {\n type: 'linear',\n x: 0, y: 0, x2: 0, y2: 1,\n colorStops: [\n { offset: 0, color: accentSoft },\n { offset: 1, color: accentFade },\n ],\n },\n },\n },\n ];\n if (data?.previous?.length) {\n series.push({\n type: 'line',\n name: data?.previousLabel || 'Previous',\n data: data.previous,\n smooth: true,\n // Labels below this line, above the other one: two series sharing an\n // x tick would otherwise print their numbers on top of each other.\n ...this.pointMarks('bottom', FxUtils.convertColorFromVariable('--text-placeholder', 1, { legacyCommaSyntax: true })),\n lineStyle: {\n width: 1.5,\n type: 'dashed',\n color: FxUtils.convertColorFromVariable('--text-placeholder', 1, { legacyCommaSyntax: true }),\n },\n itemStyle: { color: FxUtils.convertColorFromVariable('--text-placeholder', 1, { legacyCommaSyntax: true }) },\n });\n }\n return {\n tooltip: { trigger: 'axis' },\n grid: { left: '3%', right: '4%', bottom: '8%', top: '10%', containLabel: true },\n xAxis: { ...this.categoryAxis(data?.categories || []), boundaryGap: false },\n yAxis: this.valueAxis(),\n series,\n };\n },\n\n sunburst: (data, colors) => ({\n color: colors,\n series: [\n {\n type: 'sunburst',\n data,\n radius: ['15%', '90%'],\n itemStyle: {\n borderWidth: 1,\n borderColor: FxUtils.convertColorFromVariable('--border-default'),\n },\n label: {\n rotate: 'tangential',\n fontSize: this.labelFontSize,\n fontFamily: this.resolvedFontFamily(),\n color: FxUtils.convertColorFromVariable('--text-primary'),\n textBorderWidth: 0,\n textBorderColor: 'transparent',\n },\n },\n ],\n }),\n };\n\n /* ================= PIE LAYOUT ================= */\n\n private calcPieLayout(data: any[]) {\n const cw = this.containerWidth || 400;\n\n if (!this.showPieLegend()) {\n return {\n legendOrient: 'vertical' as const,\n legendLeft: undefined as string | undefined,\n legendRight: undefined as string | undefined,\n legendTop: undefined as string | undefined,\n legendBottom: undefined as number | undefined,\n legendWidth: undefined as number | undefined,\n pieCenter: ['50%', '50%'],\n graphicLeft: '50%',\n graphicTop: '50%',\n };\n }\n\n if (this.isMobile) {\n return {\n legendOrient: 'horizontal' as const,\n legendLeft: 'center' as string | undefined,\n legendRight: undefined as string | undefined,\n legendTop: undefined as string | undefined,\n legendBottom: 0 as number | undefined,\n legendWidth: undefined as number | undefined,\n pieCenter: ['50%', '40%'],\n graphicLeft: '50%',\n graphicTop: '40%',\n };\n }\n\n // Estimate legend pixel width from longest formatted label\n const CHAR_WIDTH = 7.5; // approx px per char at fontSize 13\n const ICON_GAP = 30; // legend icon + padding\n const longestLabel = data.reduce((max: number, d: any) => {\n return Math.max(max, `${d.name}: ${d.value}`.length);\n }, 0);\n const rawLegendPx = longestLabel * CHAR_WIDTH + ICON_GAP;\n\n // Clamp: min 100px, max 45% of container\n const legendPx = Math.max(100, Math.min(rawLegendPx, cw * 0.45));\n const legendPct = (legendPx / cw) * 100;\n\n // Pie center: middle of the remaining space after legend\n const pieCenterX = Math.round((100 - legendPct) / 2);\n\n return {\n legendOrient: 'vertical' as const,\n legendLeft: undefined,\n legendRight: '2%',\n legendTop: 'middle' as string | undefined,\n legendBottom: undefined,\n legendWidth: Math.round(legendPx),\n pieCenter: [`${pieCenterX}%`, '50%'],\n graphicLeft: `${pieCenterX}%`,\n graphicTop: '50%',\n };\n }\n\n /* ================= BUILD ================= */\n\n private detectType(): string {\n const type = this.type();\n if (type !== 'auto') return type;\n const data = this.data();\n if (data?.children) return 'sunburst';\n if (data?.categories && data?.values) return 'bar';\n if (Array.isArray(data)) return 'pie';\n return 'bar';\n }\n\n /**\n * Marker and value label for one line series, per `showPointLabels`.\n *\n * Returns the OFF state explicitly (`symbol: 'none'`) rather than nothing, so\n * the caller spreads one object either way and the default stays exactly what\n * it was before this input existed.\n */\n private pointMarks(position: 'top' | 'bottom', color: string) {\n if (!this.showPointLabels()) return { symbol: 'none' as const };\n return {\n symbol: 'circle' as const,\n symbolSize: 6,\n showSymbol: true,\n label: {\n show: true,\n position,\n distance: 7,\n fontSize: this.labelFontSize,\n fontFamily: this.resolvedFontFamily(),\n color,\n },\n };\n }\n\n /**\n * Where the donut's centre total and its caption sit, relative to the ring's\n * centre.\n *\n * MEASURED, not guessed. Both numbers below were read off a render at two\n * sizes (glyph ink bounding boxes against the ring's own bounding box):\n * neutral-figure ink is ~0.73 of the font size tall, and an ECharts text with\n * `verticalAlign: 'middle'` places its ANCHOR ~0.095 of the font size BELOW\n * the ink's optical centre — digits have no descender, so the ink rides high\n * in the line box.\n *\n * The line gap is a CONSTANT. That is the whole point of this function: the\n * gap between two lines is typographic and does not scale with the size of\n * the number above it. Deriving it from the font size instead — which the\n * first cut of `pieCenterValueSize` did — inflated a 9.6px gap to 18.2px at\n * 38px type and pushed the pair 4.8px above the ring's centre. The hand-tuned\n * constants it replaced were already 2.5px high at the default size; this\n * lands the block dead centre at every size (verified 24/30/38/48).\n */\n private pieCentreAnchors(): { total: number; caption: number } {\n const FIGURE_INK = 0.73;\n const MIDDLE_ANCHOR_DROP = 0.095;\n const LINE_GAP = 10;\n const CAPTION_SIZE = 11;\n\n const value = this.pieCenterValueSize();\n // No caption: one line, its ink centred on the ring.\n if (!this.pieCenterLabel()) {\n return { total: MIDDLE_ANCHOR_DROP * value, caption: 0 };\n }\n const valueInk = FIGURE_INK * value;\n const captionInk = FIGURE_INK * CAPTION_SIZE;\n const blockHeight = valueInk + LINE_GAP + captionInk;\n return {\n total: -blockHeight / 2 + valueInk / 2 + MIDDLE_ANCHOR_DROP * value,\n caption: blockHeight / 2 - captionInk / 2 + MIDDLE_ANCHOR_DROP * CAPTION_SIZE,\n };\n }\n\n private buildOptions(): EChartsOption {\n const type = this.detectType();\n const palette = this.resolvePalette();\n const base = this.registry[type]?.(this.data(), palette) || {};\n\n // DEEP merge, not a spread. A shallow one replaced whole branches, so\n // `[options]=\"{series:[{label:…}]}\"` threw away the recipe's own series —\n // data included — and there was no way to adjust one nested detail from\n // outside. Arrays merge BY INDEX for the same reason: a caller tweaking\n // series 0 must not have to restate series 1.\n return deepMergeOptions(base, this.options()) as EChartsOption;\n }\n\n private categoryAxis(categories: string[]) {\n return {\n type: 'category' as const,\n data: categories,\n axisLabel: {\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-secondary'),\n },\n axisLine: {\n lineStyle: { color: FxUtils.convertColorFromVariable('--border-strong') },\n },\n };\n }\n\n private valueAxis() {\n return {\n type: 'value' as const,\n axisLabel: {\n fontFamily: this.resolvedFontFamily(),\n fontSize: this.labelFontSize,\n color: FxUtils.convertColorFromVariable('--text-secondary'),\n },\n splitLine: {\n lineStyle: { color: FxUtils.convertColorFromVariable('--border-default') },\n },\n };\n }\n\n /** Canvas không ăn var() — resolve font stack thật tại render; chart đã\n rebuild theo event theme-changed nên tự đổi font khi đổi theme\n (blueprint/terminal dùng mono qua --og-font-figure). */\n private resolvedFontFamily(): string {\n const override = this.labelFontFamily();\n if (override) return override;\n // Dev-mode CSS pretty-printer bẻ dòng giá trị dài — normalize whitespace\n // trước khi chuỗi này vào ctx.font của canvas.\n const figure = getComputedStyle(document.body)\n .getPropertyValue('--og-font-figure')\n .replace(/\\s+/g, ' ')\n .trim();\n return figure || 'Archivo, system-ui, sans-serif';\n }\n\n private resolvePalette(): string[] {\n const defaults = [\n 'rgba(var(--success) / 1)',\n 'rgba(var(--information) / 1)',\n 'rgba(var(--critical) / 1)',\n 'rgba(var(--danger) / 1)',\n 'rgba(var(--warning) / 1)',\n 'rgba(var(--discovery) / 1)',\n ];\n\n const paletteValue = this.palette();\n const palette = paletteValue?.length ? paletteValue : defaults;\n\n return palette.map((raw) => {\n if (!raw.includes('var(')) return raw;\n\n const cssVar = raw.match(/var\\((.*?)\\)/)?.[1];\n const rgb = getComputedStyle(document.body)\n .getPropertyValue(cssVar || '')\n .trim()\n .replace(/\\s+/g, ',');\n return `rgba(${rgb},1)`;\n });\n }\n}\n\n/**\n * Recursively merges an override onto a base ECharts option tree.\n *\n * Plain objects merge key by key; arrays merge BY INDEX, so overriding one\n * series does not delete its siblings; anything else — a scalar, a Date, a\n * colour-stop function — is replaced whole, because a half-merged value of\n * those types has no meaning. `undefined` in the override is skipped so an\n * unset field cannot erase a built-in.\n */\nfunction deepMergeOptions(base: unknown, override: unknown): unknown {\n if (override === undefined) return base;\n if (Array.isArray(base) && Array.isArray(override)) {\n const out = [...base];\n override.forEach((value, i) => {\n out[i] = i < base.length ? deepMergeOptions(base[i], value) : value;\n });\n return out;\n }\n if (isPlainObject(base) && isPlainObject(override)) {\n const out: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n out[key] = key in base ? deepMergeOptions(base[key], value) : value;\n }\n return out;\n }\n return override;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)\n );\n}\n","<div class=\"chart-wrapper\" [style.height]=\"height()\">\n @if (isEmpty) {\n <div class=\"chart-empty\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"chart-empty-icon\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n <span class=\"chart-empty-text\">{{ emptyText() }}</span>\n </div>\n } @else if (hasOptions) {\n <div\n echarts\n [options]=\"chartOptions\"\n [autoResize]=\"false\"\n [loading]=\"loading()\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height()\"\n ></div>\n } @else {\n <!-- Until echarts is loaded + initialised (or the element scrolls into view)\n the panel keeps the chart's footprint with a quiet pulsing sketch\n instead of an empty box (anh Tú 04/09: \"the page is too blank\"). -->\n <div class=\"chart-placeholder\" aria-hidden=\"true\">\n @for (h of placeholderBars; track $index) {\n <span class=\"chart-placeholder__bar\" [style.height.%]=\"h\"></span>\n }\n </div>\n }\n</div>\n","let pending: Promise<unknown> | undefined;\n\n/**\n * Warm the echarts chunk before any chart is on screen.\n *\n * `fx-ui-chart` loads echarts lazily (`provideEchartsCore({ echarts: () =>\n * import('echarts') })`), so the FIRST chart of a session pays the chunk\n * download right when the user is looking at an empty panel. Call this once\n * from an idle callback when the app's env injector is created (e.g. a\n * `provideEnvironmentInitializer` in the remote's root route) and the dashboard\n * charts appear on the frame they mount. Same module URL as the directive's\n * import ⇒ one shared instance, no double load.\n */\nexport function preloadEcharts(): Promise<unknown> {\n return (pending ??= import('echarts'));\n}\n\n/** Schedule `preloadEcharts()` when the main thread is idle (SSR/tests: no-op). */\nexport function preloadEchartsWhenIdle(timeoutMs = 3000): void {\n if (typeof window === 'undefined') return;\n const w = window as Window & { requestIdleCallback?: (cb: () => void, o?: { timeout: number }) => number };\n if (typeof w.requestIdleCallback === 'function') {\n w.requestIdleCallback(() => void preloadEcharts(), { timeout: timeoutMs });\n } else {\n setTimeout(() => void preloadEcharts(), 1500);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foxeltech/angular-ui",
3
- "version": "0.7.103",
3
+ "version": "0.7.106",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -504,143 +504,3 @@
504
504
  --border-secondary-hover: var(--og-accent);
505
505
  --bg-secondary-hover: var(--og-neutral-soft-bg);
506
506
  }
507
-
508
- /* ---- STALE-HOST FALLBACK (transitional) -----------------------------
509
- Host CŨ không set data-og-theme, chỉ toggle .light_theme trên body.
510
- Map light→porcelain (đã là :root default), dark→charcoal — cả hai kèm
511
- alias ở body-level để đè literal của stylesheet host cũ. Remote chạy
512
- standalone không set theme cũng rơi vào nhánh charcoal (khớp hành vi
513
- dark-default cũ). */
514
- html:not([data-og-theme]) body:not(.light_theme) {
515
- --og-page-bg: 26 24 17; /* #1a1811 */
516
- --og-surface: 34 31 22; /* #221f16 */
517
- --og-surface-raised: 42 38 25; /* #2a2619 */
518
- --og-surface-sunken: 23 21 9; /* #171509 */
519
- --og-border: 58 54 38; /* #3a3626 */
520
- --og-border-subtle: 44 41 25; /* #2c2919 */
521
- --og-border-strong: 76 71 50; /* #4c4732 */
522
- --og-text: 226 221 203; /* #e2ddcb */
523
- --og-text-body: 193 188 166; /* #c1bca6 */
524
- --og-text-muted: 147 141 118; /* #938d76 */
525
- --og-text-faint: 107 102 83; /* #6b6653 */
526
- --og-accent: 143 200 102; /* #8fc866 */
527
- --og-accent-fg: 164 217 126; /* #a4d97e */
528
- --og-accent-contrast: 23 21 9; /* #171509 */
529
- --og-accent-soft-bg: 38 48 26; /* #26301a */
530
- --og-accent-soft-fg: 164 217 126; /* #a4d97e */
531
- --og-positive: 132 200 98; /* #84c862 */
532
- --og-positive-soft-bg: 34 48 15; /* #22300f */
533
- --og-negative: 229 130 142; /* #e5828e */
534
- --og-negative-soft-bg: 63 30 36; /* #3f1e24 */
535
- --og-warning: 214 178 90; /* #d6b25a */
536
- --og-warning-soft-bg: 51 42 18; /* #332a12 */
537
- --og-neutral-soft-bg: 42 39 25; /* #2a2719 */
538
- --og-neutral-soft-fg: 164 158 134; /* #a49e86 */
539
- --og-track: 48 44 30; /* #302c1e */
540
- --og-radius-frame: 10px;
541
- --og-radius-card: 9px;
542
- --og-radius-control: 7px;
543
- --og-radius-pill: 999px;
544
- --og-font-body: 'Familjen Grotesk',ui-sans-serif,system-ui,sans-serif;
545
- --og-font-display: 'Familjen Grotesk',ui-sans-serif,system-ui,sans-serif;
546
- --og-font-mono: 'JetBrains Mono',ui-monospace,monospace;
547
- --og-font-prose: 'Familjen Grotesk',ui-sans-serif,system-ui,sans-serif;
548
- --og-font-figure: 'JetBrains Mono',ui-monospace,monospace;
549
- --og-positive-soft-fg: 164 217 126; /* #a4d97e */
550
- --og-negative-soft-fg: 238 163 171; /* #eea3ab */
551
- --og-warning-soft-fg: 224 194 116; /* #e0c274 */
552
- /* derived (script-generated, KHÔNG có trong design gốc) */
553
- --og-derived-critical: 254 119 154; /* #fe779a */
554
- --og-derived-critical-soft-bg: 97 46 57; /* #612e39 */
555
- --og-derived-gradient-accent-end: 174 233 134; /* #aee986 */
556
- --og-derived-gradient-positive-end: 157 226 123; /* #9de27b */
557
- --shadow-color: 255 255 255;
558
- /* severity tones — bộ LEGACY (vivid), không lấy từ design V2 */
559
- --og-tone-success: 76 175 80;
560
- --og-tone-warning: 255 188 59;
561
- --og-tone-critical: 236 25 56;
562
- --og-tone-danger: 249 133 7;
563
- --og-tone-information: 62 175 240;
564
- --og-tone-discovery: 119 113 227;
565
- /* severity ramp cho CHART — literal đo trên demo, không phải token design */
566
- --og-sev-critical: 207 103 96; /* #cf6760 — #7f1d1d nâng L cho nền tối */
567
- --og-sev-danger: 246 68 61; /* #f6443d */
568
- --og-sev-warning: 245 158 11; /* #f59e0b */
569
- --og-sev-success: 22 163 74; /* #16a34a */
570
-
571
- /* ---- LEGACY ALIASES (@deprecated — gỡ khi kết thúc campaign V2) ----
572
- Các biến cũ trỏ vào --og-* qua var() nên chỉ cần khai báo MỘT lần:
573
- var() resolve tại element sử dụng, giá trị og đúng theo theme đang active. */
574
- --gradient-primary-start: var(--og-accent);
575
- --gradient-primary-end: var(--og-derived-gradient-accent-end);
576
- --gradient-success-start: var(--og-positive);
577
- --gradient-success-end: var(--og-derived-gradient-positive-end);
578
- --bg-primary: var(--og-surface);
579
- --bg-canvas: var(--og-page-bg);
580
- --primary: var(--og-accent);
581
- --success: var(--og-tone-success);
582
- --warning: var(--og-tone-warning);
583
- --critical: var(--og-tone-critical);
584
- --danger: var(--og-tone-danger);
585
- --discovery: var(--og-tone-discovery);
586
- --information: var(--og-tone-information);
587
- --text-primary: var(--og-text);
588
- --text-secondary: var(--og-text-muted);
589
- --border-default: var(--og-border);
590
- --text-placeholder: var(--og-text-faint);
591
- --step-bg: var(--og-text);
592
- --text-link-primary: var(--og-accent-fg);
593
- --bg-primary-hover: var(--og-surface-sunken);
594
- --text-focus: var(--og-accent-contrast);
595
- --bg-primary-neutral: var(--og-border-strong);
596
- --text-selected-primary: var(--og-accent-fg);
597
- --button-default: var(--og-text);
598
- --text-inverse: var(--og-surface);
599
- --bg-error-bold: var(--og-negative);
600
- --text-error: var(--og-negative);
601
- --border-interactive: var(--og-accent);
602
- --border-selected: var(--og-accent);
603
- --button-primary: var(--og-accent);
604
- --border-strong: var(--og-border-strong);
605
- --border-secondary-hover: var(--og-accent);
606
- --bg-secondary-hover: var(--og-neutral-soft-bg);
607
- }
608
-
609
- html:not([data-og-theme]) body.light_theme {
610
- /* ---- LEGACY ALIASES (@deprecated — gỡ khi kết thúc campaign V2) ----
611
- Các biến cũ trỏ vào --og-* qua var() nên chỉ cần khai báo MỘT lần:
612
- var() resolve tại element sử dụng, giá trị og đúng theo theme đang active. */
613
- --gradient-primary-start: var(--og-accent);
614
- --gradient-primary-end: var(--og-derived-gradient-accent-end);
615
- --gradient-success-start: var(--og-positive);
616
- --gradient-success-end: var(--og-derived-gradient-positive-end);
617
- --bg-primary: var(--og-surface);
618
- --bg-canvas: var(--og-page-bg);
619
- --primary: var(--og-accent);
620
- --success: var(--og-tone-success);
621
- --warning: var(--og-tone-warning);
622
- --critical: var(--og-tone-critical);
623
- --danger: var(--og-tone-danger);
624
- --discovery: var(--og-tone-discovery);
625
- --information: var(--og-tone-information);
626
- --text-primary: var(--og-text);
627
- --text-secondary: var(--og-text-muted);
628
- --border-default: var(--og-border);
629
- --text-placeholder: var(--og-text-faint);
630
- --step-bg: var(--og-text);
631
- --text-link-primary: var(--og-accent-fg);
632
- --bg-primary-hover: var(--og-surface-sunken);
633
- --text-focus: var(--og-accent-contrast);
634
- --bg-primary-neutral: var(--og-border-strong);
635
- --text-selected-primary: var(--og-accent-fg);
636
- --button-default: var(--og-text);
637
- --text-inverse: var(--og-surface);
638
- --bg-error-bold: var(--og-negative);
639
- --text-error: var(--og-negative);
640
- --border-interactive: var(--og-accent);
641
- --border-selected: var(--og-accent);
642
- --button-primary: var(--og-accent);
643
- --border-strong: var(--og-border-strong);
644
- --border-secondary-hover: var(--og-accent);
645
- --bg-secondary-hover: var(--og-neutral-soft-bg);
646
- }
package/theme.css CHANGED
@@ -504,143 +504,3 @@
504
504
  --border-secondary-hover: var(--og-accent);
505
505
  --bg-secondary-hover: var(--og-neutral-soft-bg);
506
506
  }
507
-
508
- /* ---- STALE-HOST FALLBACK (transitional) -----------------------------
509
- Host CŨ không set data-og-theme, chỉ toggle .light_theme trên body.
510
- Map light→porcelain (đã là :root default), dark→charcoal — cả hai kèm
511
- alias ở body-level để đè literal của stylesheet host cũ. Remote chạy
512
- standalone không set theme cũng rơi vào nhánh charcoal (khớp hành vi
513
- dark-default cũ). */
514
- html:not([data-og-theme]) body:not(.light_theme) {
515
- --og-page-bg: 26 24 17; /* #1a1811 */
516
- --og-surface: 34 31 22; /* #221f16 */
517
- --og-surface-raised: 42 38 25; /* #2a2619 */
518
- --og-surface-sunken: 23 21 9; /* #171509 */
519
- --og-border: 58 54 38; /* #3a3626 */
520
- --og-border-subtle: 44 41 25; /* #2c2919 */
521
- --og-border-strong: 76 71 50; /* #4c4732 */
522
- --og-text: 226 221 203; /* #e2ddcb */
523
- --og-text-body: 193 188 166; /* #c1bca6 */
524
- --og-text-muted: 147 141 118; /* #938d76 */
525
- --og-text-faint: 107 102 83; /* #6b6653 */
526
- --og-accent: 143 200 102; /* #8fc866 */
527
- --og-accent-fg: 164 217 126; /* #a4d97e */
528
- --og-accent-contrast: 23 21 9; /* #171509 */
529
- --og-accent-soft-bg: 38 48 26; /* #26301a */
530
- --og-accent-soft-fg: 164 217 126; /* #a4d97e */
531
- --og-positive: 132 200 98; /* #84c862 */
532
- --og-positive-soft-bg: 34 48 15; /* #22300f */
533
- --og-negative: 229 130 142; /* #e5828e */
534
- --og-negative-soft-bg: 63 30 36; /* #3f1e24 */
535
- --og-warning: 214 178 90; /* #d6b25a */
536
- --og-warning-soft-bg: 51 42 18; /* #332a12 */
537
- --og-neutral-soft-bg: 42 39 25; /* #2a2719 */
538
- --og-neutral-soft-fg: 164 158 134; /* #a49e86 */
539
- --og-track: 48 44 30; /* #302c1e */
540
- --og-radius-frame: 10px;
541
- --og-radius-card: 9px;
542
- --og-radius-control: 7px;
543
- --og-radius-pill: 999px;
544
- --og-font-body: 'Familjen Grotesk',ui-sans-serif,system-ui,sans-serif;
545
- --og-font-display: 'Familjen Grotesk',ui-sans-serif,system-ui,sans-serif;
546
- --og-font-mono: 'JetBrains Mono',ui-monospace,monospace;
547
- --og-font-prose: 'Familjen Grotesk',ui-sans-serif,system-ui,sans-serif;
548
- --og-font-figure: 'JetBrains Mono',ui-monospace,monospace;
549
- --og-positive-soft-fg: 164 217 126; /* #a4d97e */
550
- --og-negative-soft-fg: 238 163 171; /* #eea3ab */
551
- --og-warning-soft-fg: 224 194 116; /* #e0c274 */
552
- /* derived (script-generated, KHÔNG có trong design gốc) */
553
- --og-derived-critical: 254 119 154; /* #fe779a */
554
- --og-derived-critical-soft-bg: 97 46 57; /* #612e39 */
555
- --og-derived-gradient-accent-end: 174 233 134; /* #aee986 */
556
- --og-derived-gradient-positive-end: 157 226 123; /* #9de27b */
557
- --shadow-color: 255 255 255;
558
- /* severity tones — bộ LEGACY (vivid), không lấy từ design V2 */
559
- --og-tone-success: 76 175 80;
560
- --og-tone-warning: 255 188 59;
561
- --og-tone-critical: 236 25 56;
562
- --og-tone-danger: 249 133 7;
563
- --og-tone-information: 62 175 240;
564
- --og-tone-discovery: 119 113 227;
565
- /* severity ramp cho CHART — literal đo trên demo, không phải token design */
566
- --og-sev-critical: 207 103 96; /* #cf6760 — #7f1d1d nâng L cho nền tối */
567
- --og-sev-danger: 246 68 61; /* #f6443d */
568
- --og-sev-warning: 245 158 11; /* #f59e0b */
569
- --og-sev-success: 22 163 74; /* #16a34a */
570
-
571
- /* ---- LEGACY ALIASES (@deprecated — gỡ khi kết thúc campaign V2) ----
572
- Các biến cũ trỏ vào --og-* qua var() nên chỉ cần khai báo MỘT lần:
573
- var() resolve tại element sử dụng, giá trị og đúng theo theme đang active. */
574
- --gradient-primary-start: var(--og-accent);
575
- --gradient-primary-end: var(--og-derived-gradient-accent-end);
576
- --gradient-success-start: var(--og-positive);
577
- --gradient-success-end: var(--og-derived-gradient-positive-end);
578
- --bg-primary: var(--og-surface);
579
- --bg-canvas: var(--og-page-bg);
580
- --primary: var(--og-accent);
581
- --success: var(--og-tone-success);
582
- --warning: var(--og-tone-warning);
583
- --critical: var(--og-tone-critical);
584
- --danger: var(--og-tone-danger);
585
- --discovery: var(--og-tone-discovery);
586
- --information: var(--og-tone-information);
587
- --text-primary: var(--og-text);
588
- --text-secondary: var(--og-text-muted);
589
- --border-default: var(--og-border);
590
- --text-placeholder: var(--og-text-faint);
591
- --step-bg: var(--og-text);
592
- --text-link-primary: var(--og-accent-fg);
593
- --bg-primary-hover: var(--og-surface-sunken);
594
- --text-focus: var(--og-accent-contrast);
595
- --bg-primary-neutral: var(--og-border-strong);
596
- --text-selected-primary: var(--og-accent-fg);
597
- --button-default: var(--og-text);
598
- --text-inverse: var(--og-surface);
599
- --bg-error-bold: var(--og-negative);
600
- --text-error: var(--og-negative);
601
- --border-interactive: var(--og-accent);
602
- --border-selected: var(--og-accent);
603
- --button-primary: var(--og-accent);
604
- --border-strong: var(--og-border-strong);
605
- --border-secondary-hover: var(--og-accent);
606
- --bg-secondary-hover: var(--og-neutral-soft-bg);
607
- }
608
-
609
- html:not([data-og-theme]) body.light_theme {
610
- /* ---- LEGACY ALIASES (@deprecated — gỡ khi kết thúc campaign V2) ----
611
- Các biến cũ trỏ vào --og-* qua var() nên chỉ cần khai báo MỘT lần:
612
- var() resolve tại element sử dụng, giá trị og đúng theo theme đang active. */
613
- --gradient-primary-start: var(--og-accent);
614
- --gradient-primary-end: var(--og-derived-gradient-accent-end);
615
- --gradient-success-start: var(--og-positive);
616
- --gradient-success-end: var(--og-derived-gradient-positive-end);
617
- --bg-primary: var(--og-surface);
618
- --bg-canvas: var(--og-page-bg);
619
- --primary: var(--og-accent);
620
- --success: var(--og-tone-success);
621
- --warning: var(--og-tone-warning);
622
- --critical: var(--og-tone-critical);
623
- --danger: var(--og-tone-danger);
624
- --discovery: var(--og-tone-discovery);
625
- --information: var(--og-tone-information);
626
- --text-primary: var(--og-text);
627
- --text-secondary: var(--og-text-muted);
628
- --border-default: var(--og-border);
629
- --text-placeholder: var(--og-text-faint);
630
- --step-bg: var(--og-text);
631
- --text-link-primary: var(--og-accent-fg);
632
- --bg-primary-hover: var(--og-surface-sunken);
633
- --text-focus: var(--og-accent-contrast);
634
- --bg-primary-neutral: var(--og-border-strong);
635
- --text-selected-primary: var(--og-accent-fg);
636
- --button-default: var(--og-text);
637
- --text-inverse: var(--og-surface);
638
- --bg-error-bold: var(--og-negative);
639
- --text-error: var(--og-negative);
640
- --border-interactive: var(--og-accent);
641
- --border-selected: var(--og-accent);
642
- --button-primary: var(--og-accent);
643
- --border-strong: var(--og-border-strong);
644
- --border-secondary-hover: var(--og-accent);
645
- --bg-secondary-hover: var(--og-neutral-soft-bg);
646
- }
@@ -20,10 +20,25 @@ declare class ChartComponent implements OnChanges, AfterViewInit, OnDestroy {
20
20
  readonly showPieLegend: _angular_core.InputSignal<boolean>;
21
21
  /** Caption under the donut's centre total (design: "42 / confirmed"). */
22
22
  readonly pieCenterLabel: _angular_core.InputSignal<string>;
23
+ /**
24
+ * Type size of the donut's centre TOTAL, in px. The default matches what the
25
+ * figure has always been; raise it where the total is the panel's headline
26
+ * rather than an annotation.
27
+ */
28
+ readonly pieCenterValueSize: _angular_core.InputSignal<number>;
23
29
  readonly mobileWidth: _angular_core.InputSignal<number>;
24
30
  /** Override font for canvas text; empty = follow the theme's --og-font-figure. */
25
31
  readonly labelFontFamily: _angular_core.InputSignal<string>;
26
32
  readonly emptyText: _angular_core.InputSignal<string>;
33
+ /**
34
+ * Print each point's value beside a marker on the line.
35
+ *
36
+ * Off by default: on a dense series the labels collide and the line becomes
37
+ * unreadable. Turn it on for the sparse, weekly kind of series where the
38
+ * number at each step IS the content — a reader should not have to hover to
39
+ * learn what a step was.
40
+ */
41
+ readonly showPointLabels: _angular_core.InputSignal<boolean>;
27
42
  readonly chartClick: _angular_core.OutputEmitterRef<any>;
28
43
  readonly chartInit: _angular_core.OutputEmitterRef<ECharts>;
29
44
  chartOptions: EChartsOption;
@@ -143,6 +158,34 @@ declare class ChartComponent implements OnChanges, AfterViewInit, OnDestroy {
143
158
  private registry;
144
159
  private calcPieLayout;
145
160
  private detectType;
161
+ /**
162
+ * Marker and value label for one line series, per `showPointLabels`.
163
+ *
164
+ * Returns the OFF state explicitly (`symbol: 'none'`) rather than nothing, so
165
+ * the caller spreads one object either way and the default stays exactly what
166
+ * it was before this input existed.
167
+ */
168
+ private pointMarks;
169
+ /**
170
+ * Where the donut's centre total and its caption sit, relative to the ring's
171
+ * centre.
172
+ *
173
+ * MEASURED, not guessed. Both numbers below were read off a render at two
174
+ * sizes (glyph ink bounding boxes against the ring's own bounding box):
175
+ * neutral-figure ink is ~0.73 of the font size tall, and an ECharts text with
176
+ * `verticalAlign: 'middle'` places its ANCHOR ~0.095 of the font size BELOW
177
+ * the ink's optical centre — digits have no descender, so the ink rides high
178
+ * in the line box.
179
+ *
180
+ * The line gap is a CONSTANT. That is the whole point of this function: the
181
+ * gap between two lines is typographic and does not scale with the size of
182
+ * the number above it. Deriving it from the font size instead — which the
183
+ * first cut of `pieCenterValueSize` did — inflated a 9.6px gap to 18.2px at
184
+ * 38px type and pushed the pair 4.8px above the ring's centre. The hand-tuned
185
+ * constants it replaced were already 2.5px high at the default size; this
186
+ * lands the block dead centre at every size (verified 24/30/38/48).
187
+ */
188
+ private pieCentreAnchors;
146
189
  private buildOptions;
147
190
  private categoryAxis;
148
191
  private valueAxis;
@@ -152,7 +195,7 @@ declare class ChartComponent implements OnChanges, AfterViewInit, OnDestroy {
152
195
  private resolvedFontFamily;
153
196
  private resolvePalette;
154
197
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<ChartComponent, never>;
155
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<ChartComponent, "fx-ui-chart", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "palette": { "alias": "palette"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "pieLegendAlign": { "alias": "pieLegendAlign"; "required": false; "isSignal": true; }; "pieLegendPosition": { "alias": "pieLegendPosition"; "required": false; "isSignal": true; }; "showPieLabel": { "alias": "showPieLabel"; "required": false; "isSignal": true; }; "showPieLegend": { "alias": "showPieLegend"; "required": false; "isSignal": true; }; "pieCenterLabel": { "alias": "pieCenterLabel"; "required": false; "isSignal": true; }; "mobileWidth": { "alias": "mobileWidth"; "required": false; "isSignal": true; }; "labelFontFamily": { "alias": "labelFontFamily"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; }, { "chartClick": "chartClick"; "chartInit": "chartInit"; }, never, never, true, never>;
198
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ChartComponent, "fx-ui-chart", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "palette": { "alias": "palette"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "pieLegendAlign": { "alias": "pieLegendAlign"; "required": false; "isSignal": true; }; "pieLegendPosition": { "alias": "pieLegendPosition"; "required": false; "isSignal": true; }; "showPieLabel": { "alias": "showPieLabel"; "required": false; "isSignal": true; }; "showPieLegend": { "alias": "showPieLegend"; "required": false; "isSignal": true; }; "pieCenterLabel": { "alias": "pieCenterLabel"; "required": false; "isSignal": true; }; "pieCenterValueSize": { "alias": "pieCenterValueSize"; "required": false; "isSignal": true; }; "mobileWidth": { "alias": "mobileWidth"; "required": false; "isSignal": true; }; "labelFontFamily": { "alias": "labelFontFamily"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "showPointLabels": { "alias": "showPointLabels"; "required": false; "isSignal": true; }; }, { "chartClick": "chartClick"; "chartInit": "chartInit"; }, never, never, true, never>;
156
199
  }
157
200
 
158
201
  /**